1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

Merge branch 'master' of git.opennebula.org:one

This commit is contained in:
Daniel Molina 2011-11-16 18:38:39 +01:00
commit 276e4bdf4b
41 changed files with 696 additions and 439 deletions

View File

@ -85,6 +85,14 @@ public:
* @return pointer to the image or 0 if could not be acquired
*/
Image * acquire_image(int image_id);
/**
* Try to acquire an image from the repository for a VM.
* @param name of the image
* @param id of owner
* @return pointer to the image or 0 if could not be acquired
*/
Image * acquire_image(const string& name, int uid);
/**
* Releases an image and triggers any needed operations in the repo

View File

@ -135,7 +135,6 @@ public:
* @return 0 on success,
* -1 error,
* -2 not using the pool,
* -3 deprecated NAME found
*/
int disk_attribute(VectorAttribute * disk,
int disk_id,

View File

@ -236,7 +236,7 @@ public:
UserAllocate():
RequestManagerAllocate("UserAllocate",
"Returns user information",
"A:sss",
"A:ssss",
false)
{
Nebula& nd = Nebula::instance();

View File

@ -129,7 +129,7 @@ public:
VirtualMachineSaveDisk():
RequestManagerVirtualMachine("VirtualMachineSaveDisk",
"Saves a disk from virtual machine as a new image",
"A:siis"){};
"A:siiss"){};
~VirtualMachineSaveDisk(){};

View File

@ -94,8 +94,7 @@ public:
* @param vid of the VM requesting the lease
* @return 0 on success,
* -1 error,
* -2 not using the pool,
* -3 unsupported NETWORK attribute
* -2 not using the pool
*/
int nic_attribute(VectorAttribute * nic, int uid, int vid);
@ -165,6 +164,19 @@ private:
{
return new VirtualNetwork(-1,-1,"","",0);
};
/**
* Function to get a VirtualNetwork by its name, as provided by a VM
* template
*/
VirtualNetwork * get_nic_by_name(VectorAttribute * nic,
const string& name,
int _uid);
/**
* Function to get a VirtualNetwork by its id, as provided by a VM template
*/
VirtualNetwork * get_nic_by_id(const string& id_s);
};
#endif /*VIRTUAL_NETWORK_POOL_H_*/

View File

@ -795,8 +795,7 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
src/oca/ruby/OpenNebula/GroupPool.rb \
src/oca/ruby/OpenNebula/Acl.rb \
src/oca/ruby/OpenNebula/AclPool.rb \
src/oca/ruby/OpenNebula/XMLUtils.rb \
src/oca/ruby/OpenNebula/Configuration.rb"
src/oca/ruby/OpenNebula/XMLUtils.rb"
#-------------------------------------------------------------------------------
# Common Cloud Files

View File

@ -556,10 +556,11 @@ HM_MAD = [
# caching
#*******************************************************************************
#AUTH_MAD = [
# executable = "one_auth_mad",
# arguments = "--authn ssh,x509,server_cipher,server_x509"
AUTH_MAD = [
executable = "one_auth_mad",
arguments = "--authn ssh,x509,server_cipher,server_x509"
# arguments = "--authz quota --authn ssh,x509,server_cipher,server_x509"
#]
]
SESSION_EXPIRATION_TIME = 900
SESSION_EXPIRATION_TIME = 900

View File

@ -327,9 +327,9 @@ module WatchHelper
v.name = vm['NAME']
v.uid = vm['UID'].to_i
v.gid = vm['GID'].to_i
v.mem = vm['TEMPLATE/MEMORY'].to_i
v.cpu = vm['TEMPLATE/CPU'].to_f
v.vcpu = vm['TEMPLATE/VCPU'].to_i
v.mem = vm['TEMPLATE']['MEMORY'].to_i
v.cpu = vm['TEMPLATE']['CPU'].to_f
v.vcpu = vm['TEMPLATE']['VCPU'].to_i
v.stime = vm['STIME'].to_i
v.etime = vm['ETIME'].to_i
}

View File

@ -504,4 +504,38 @@ class OCCIServer < CloudServer
return to_occi_xml(user, 200)
end
def get_computes_types
etc_location=ONE_LOCATION ? ONE_LOCATION+"/etc" : "/etc/one"
begin
xml_response = "<ALLOWED_COMPUTE_TYPES>\n"
Dir[etc_location + "/occi_templates/**"].each{| filename |
next if File.basename(filename) == "common.erb"
xml_response += "\t<COMPUTE_TYPE>"
xml_response += "\t\t<NAME>#{File.basename(filename)[0..-5]}</NAME>"
file = File.open(filename, "r")
file.each_line{|line|
next if line.match(/^#/)
match=line.match(/^(.*)=(.*)/)
next if !match
case match[1].strip
when "NAME"
xml_response += "\t\t<NAME>#{match[2].strip}</NAME>"
when "CPU"
xml_response += "\t\t<vCPU>#{match[2].strip}</vCPU>"
when "MEMORY"
xml_response += "\t\t<vMEM>#{match[2].strip}</vMEM>"
end
}
xml_response += "\t</COMPUTE_TYPE>"
}
xml_response += "</ALLOWED_COMPUTE_TYPES>"
return xml_response, 200
rescue Exception => e
return "Error getting the instance types. Reason: #{e.message}", 500
end
end
end

View File

@ -172,7 +172,11 @@ end
###################################################
get '/compute/:id' do
result,rc = @occi_server.get_compute(request, params)
if params[:id] == "types"
result,rc = @occi_server.get_computes_types
else
result,rc = @occi_server.get_compute(request, params)
end
treat_response(result,rc)
end
@ -219,4 +223,4 @@ end
get '/user/:id' do
result,rc = @occi_server.get_user(request, params)
treat_response(result,rc)
end
end

View File

@ -46,6 +46,31 @@ Image * ImageManager::acquire_image(int image_id)
/* -------------------------------------------------------------------------- */
Image * ImageManager::acquire_image(const string& name, int uid)
{
Image * img;
int rc;
img = ipool->get(name,uid,true);
if ( img == 0 )
{
return 0;
}
rc = acquire_image(img);
if ( rc != 0 )
{
img->unlock();
img = 0;
}
return img;
}
/* -------------------------------------------------------------------------- */
int ImageManager::acquire_image(Image *img)
{
int rc = 0;

View File

@ -136,6 +136,69 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static int get_disk_uid(VectorAttribute * disk, int _uid)
{
istringstream is;
string uid_s ;
string uname;
int uid;
if (!(uid_s = disk->vector_value("IMAGE_UID")).empty())
{
is.str(uid_s);
is >> uid;
if( is.fail() )
{
return -1;
}
}
else if (!(uname = disk->vector_value("IMAGE_UNAME")).empty())
{
User * user;
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
user = upool->get(uname,true);
if ( user == 0 )
{
return -1;
}
uid = user->get_oid();
user->unlock();
}
else
{
uid = _uid;
}
return uid;
}
/* -------------------------------------------------------------------------- */
static int get_disk_id(const string& id_s)
{
istringstream is;
int id;
is.str(id_s);
is >> id;
if( is.fail() )
{
return -1;
}
return id;
}
/* -------------------------------------------------------------------------- */
int ImagePool::disk_attribute(VectorAttribute * disk,
int disk_id,
int * index,
@ -152,36 +215,44 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
istringstream is;
source = disk->vector_value("IMAGE");
if (!source.empty())
if (!(source = disk->vector_value("IMAGE")).empty())
{
return -3;
}
source = disk->vector_value("IMAGE_ID");
if (!source.empty())
{
is.str(source);
is >> image_id;
if( !is.fail() )
int uiid = get_disk_uid(disk,uid);
if ( uiid == -1)
{
img = imagem->acquire_image(image_id);
return -1;
}
if (img == 0)
{
return -1;
}
img = imagem->acquire_image(source, uiid);
if ( img == 0 )
{
return -1;
}
}
if (img == 0)
else if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
string type = disk->vector_value("TYPE");
int iid = get_disk_id(source);
if ( iid == -1)
{
return -1;
}
img = imagem->acquire_image(iid);
if ( img == 0 )
{
return -1;
}
}
else //Not using the image repository
{
string type;
rc = -2;
type = disk->vector_value("TYPE");
transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper);
@ -198,13 +269,14 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
disk->replace("TARGET", dev_prefix);
}
}
rc = -2;
}
else
if ( img != 0 )
{
img->disk_attribute(disk, index, img_type);
image_id = img->get_oid();
update(img);
img->unlock();
@ -224,22 +296,27 @@ void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar)
string source;
Image * img = 0;
istringstream is;
int image_id;
source = disk->vector_value("IMAGE_ID");
if (source.empty())
if (!(source = disk->vector_value("IMAGE")).empty())
{
return;
int uiid = get_disk_uid(disk,uid);
if ( uiid == -1)
{
return;
}
img = get(source , uiid, true);
}
is.str(source);
is >> image_id;
if( !is.fail() )
else if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
img = get(image_id,true);
int iid = get_disk_id(source);
if ( iid == -1)
{
return;
}
img = get(iid, true);
}
if (img == 0)

View File

@ -149,7 +149,8 @@ class ImagePoolTest : public PoolTest
CPPUNIT_TEST ( imagepool_disk_attribute );
CPPUNIT_TEST ( dump );
CPPUNIT_TEST ( dump_where );
CPPUNIT_TEST ( get_using_name );
CPPUNIT_TEST ( wrong_get_name );
CPPUNIT_TEST_SUITE_END ();
protected:
@ -904,6 +905,64 @@ public:
/* ********************************************************************* */
void get_using_name()
{
int oid_0, oid_1;
ImagePool * imp = static_cast<ImagePool *>(pool);
// Allocate two objects
oid_0 = allocate(0);
oid_1 = allocate(1);
// ---------------------------------
// Get first object and check its integrity
obj = pool->get(oid_0, false);
CPPUNIT_ASSERT( obj != 0 );
check(0, obj);
// Get using its name
obj = imp->get(names[1], uids[1], true);
CPPUNIT_ASSERT( obj != 0 );
obj->unlock();
check(1, obj);
// ---------------------------------
// Clean the cache, forcing the pool to read the objects from the DB
pool->clean();
// Get first object and check its integrity
obj = imp->get(names[0], uids[0], false);
check(0, obj);
// Get using its name
obj = imp->get(oid_1, false);
check(1, obj);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void wrong_get_name()
{
ImagePool * imp = static_cast<ImagePool *>(pool);
// The pool is empty
// Non existing name
obj = imp->get("Wrong name", 0, true);
CPPUNIT_ASSERT( obj == 0 );
// Allocate an object
allocate(0);
// Ask again for a non-existing name
obj = imp->get("Non existing name",uids[0], true);
CPPUNIT_ASSERT( obj == 0 );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
};
/* ************************************************************************* */

View File

@ -55,7 +55,7 @@ echo "$IMAGE_REPOSITORY_PATH/`echo $CANONICAL_MD5 | cut -d ' ' -f1`"
}
function fs_du {
SIZE=`$(stat -c %s $1)`
SIZE=`stat -c %s $1`
if [ $? -ne 0 ]; then
SIZE=0
@ -67,15 +67,19 @@ function fs_du {
}
function check_restricted {
if [ -n "`find -L $SAFE_DIRS -path $1 2>/dev/null`" ] ; then
echo 0
return
fi
for path in $SAFE_DIRS ; do
if [ -n "`readlink -f $1 | grep -E "^$path"`" ] ; then
echo 0
return
fi
done
if [ -n "`find -L $RESTRICTED_DIRS -path $1 2>/dev/null`" ]; then
echo 1
return
fi
for path in $RESTRICTED_DIRS ; do
if [ -n "`readlink -f $1 | grep -E "^$path"`" ] ; then
echo 1
return
fi
done
echo 0
}

View File

@ -1,108 +0,0 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
module OpenNebula
############################################################################
# The Configuration Class represents a simple configuration file using
# OpenNebula syntax. It does not check syntax.
############################################################################
class Configuration
attr_reader :conf
########################################################################
# Patterns to parse the Configuration File
########################################################################
NAME_REG =/[\w\d_-]+/
VARIABLE_REG =/\s*(#{NAME_REG})\s*=\s*/
SIMPLE_VARIABLE_REG =/#{VARIABLE_REG}([^\[]+?)(#.*)?/
SINGLE_VARIABLE_REG =/^#{SIMPLE_VARIABLE_REG}$/
ARRAY_VARIABLE_REG =/^#{VARIABLE_REG}\[(.*?)\]/m
########################################################################
########################################################################
def initialize(str)
parse_conf(str)
end
def self.new_from_file(file)
conf_file = File.read(file)
self.new(conf_file)
end
def add_value(key, value)
if @conf[key]
if !@conf[key].kind_of?(Array)
@conf[key]=[@conf[key]]
end
@conf[key]<<value
else
@conf[key]=value
end
end
def [](key)
@conf[key.to_s.upcase]
end
########################################################################
########################################################################
private
#
#
#
def parse_conf(conf_file)
@conf=Hash.new
conf_file.scan(SINGLE_VARIABLE_REG) {|m|
key=m[0].strip.upcase
value=m[1].strip
add_value(key, value)
}
conf_file.scan(ARRAY_VARIABLE_REG) {|m|
master_key=m[0].strip.upcase
pieces=m[1].split(',')
vars=Hash.new
pieces.each {|p|
key, value=p.split('=')
vars[key.strip.upcase]=value.strip
}
add_value(master_key, vars)
}
end
end
#
# Test program for the Configuration Parser
#
if $0 == __FILE__
require 'pp'
conf=Configuration.new_from_file('cloud.conf')
pp conf
end
end

View File

@ -31,6 +31,12 @@ module Migrator
# Update table definitions
########################################################################
puts " > Users need to have an authentication driver defined.\n"<<
" If you have AUTH_MAD uncommented in oned.conf, enter the driver name,\n"<<
" or press enter to use the default value.\n\n"
print " Driver name (x509, ssh, ldap): "
auth_driver = gets.chomp
[ [:group_pool, "group"],
[:host_pool, "host"],
[:image_pool, "image"],
@ -100,7 +106,17 @@ module Migrator
# TODO: Try to guess if the password contains a DN and set the
# driver to 'x509', or assume ssh if the password is not hex
auth_elem = doc.root.add_element("AUTH_DRIVER")
auth_elem.text = "core"
pass = ""
doc.root.each_element("PASSWORD") { |e|
pass = e.text
}
if ( auth_driver.empty? || pass =~ /^(\d|[a-fA-F]){40}$/ )
auth_elem.text = "core"
else
auth_elem.text = auth_driver
end
doc.root.add_element("TEMPLATE")

View File

@ -103,7 +103,7 @@ USERNAME={
:description => "MySQL username",
:proc => lambda { |o, options|
options[:backend] = :mysql
options[:username] = o
options[:user] = o
}
}
@ -115,7 +115,7 @@ PASSWORD={
:description => "MySQL password. Leave unset to be prompted for it",
:proc => lambda { |o, options|
options[:backend] = :mysql
options[:password] = o
options[:passwd] = o
}
}
@ -127,20 +127,12 @@ DBNAME={
:description => "MySQL DB name for OpenNebula",
:proc => lambda { |o, options|
options[:backend] = :mysql
options[:dbname] = o
options[:db_name] = o
}
}
cmd=CommandParser::CmdParser.new(ARGV) do
description <<-EOT.unindent
DB Connection options:
By default, onedb reads the connection data from oned.conf
If any of these options is set, oned.conf is ignored (i.e. if you set
MySQL's port onedb won't look for the rest of the options in oned.conf)
Description:
This command enables the user to manage the OpenNebula database. It
provides information about the DB version, means to upgrade it to the
latest version, and backup tools.

View File

@ -14,35 +14,32 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebula/Configuration'
require 'onedb_backend'
class OneDB
def initialize(ops)
if ops[:backend]==nil
from_onedconf
else
if ops[:backend] == :sqlite
@backend = BackEndSQLite.new(ops[:sqlite])
else
passwd = ops[:passwd]
if !passwd
# Hide input characters
`stty -echo`
print "MySQL Password: "
passwd = STDIN.gets.strip
`stty echo`
puts ""
end
@backend = BackEndMySQL.new(
:server => ops[:server],
:port => ops[:port],
:user => ops[:user],
:passwd => passwd,
:db_name => ops[:db_name]
)
if ops[:backend] == :sqlite
@backend = BackEndSQLite.new(ops[:sqlite])
elsif ops[:backend] == :mysql
passwd = ops[:passwd]
if !passwd
# Hide input characters
`stty -echo`
print "MySQL Password: "
passwd = STDIN.gets.strip
`stty echo`
puts ""
end
@backend = BackEndMySQL.new(
:server => ops[:server],
:port => ops[:port],
:user => ops[:user],
:passwd => passwd,
:db_name => ops[:db_name]
)
else
raise "You need to specify the SQLite or MySQL connection options."
end
end
@ -151,32 +148,6 @@ class OneDB
private
def from_onedconf()
config = OpenNebula::Configuration.new_from_file("#{ETC_LOCATION}/oned.conf")
if config[:db] == nil
raise "No DB defined."
end
if config[:db]["BACKEND"].upcase.include? "SQLITE"
sqlite_file = "#{VAR_LOCATION}/one.db"
@backend = BackEndSQLite.new(sqlite_file)
elsif config[:db]["BACKEND"].upcase.include? "MYSQL"
@backend = BackEndMySQL.new(
:server => config[:db]["SERVER"],
:port => config[:db]["PORT"],
:user => config[:db]["USER"],
:passwd => config[:db]["PASSWD"],
:db_name => config[:db]["DB_NAME"]
)
else
raise "Could not load DB configuration from " <<
"#{ETC_LOCATION}/oned.conf"
end
return 0
end
def one_not_running()
if File.exists?(LOCK_FILE)
raise "First stop OpenNebula. Lock file found: #{LOCK_FILE}"

View File

@ -34,9 +34,11 @@ class OneDBBacKEnd
return [version, timestamp, comment]
rescue
# If the DB doesn't have db_version table, it means it is empty or a 2.x
if !db_exists?
rescue Exception => e
if e.class == Sequel::DatabaseConnectionError
raise e
elsif !db_exists?
# If the DB doesn't have db_version table, it means it is empty or a 2.x
raise "Database schema does not look to be created by " <<
"OpenNebula: table user_pool is missing or empty."
end
@ -103,12 +105,16 @@ class OneDBBacKEnd
def db_exists?
begin
found = false
# User with ID 0 (oneadmin) always exists
@db.fetch("SELECT * FROM user_pool WHERE oid=0") { |row| }
return true
@db.fetch("SELECT * FROM user_pool WHERE oid=0") { |row|
found = true
}
rescue
return false
end
return found
end
end

View File

@ -57,7 +57,7 @@ pkill -9 -P $PID oned
echo "All resources created, now 2.2 DB will be upgraded."
# dump current DB and schema
onedb backup results/mysqldb.3.0 -v
onedb backup results/mysqldb.3.0 -v -S localhost -P 0 -u oneadmin -p oneadmin -d onedb_test
if [ $? -ne 0 ]; then
exit -1
fi
@ -68,13 +68,13 @@ if [ $? -ne 0 ]; then
fi
# restore 2.2
onedb restore -v -f 2.2/mysqldb.sql
onedb restore -v -f 2.2/mysqldb.sql -S localhost -P 0 -u oneadmin -p oneadmin -d onedb_test
if [ $? -ne 0 ]; then
exit -1
fi
# upgrade
onedb upgrade -v --backup results/mysqldb.backup
echo "ssh" | onedb upgrade -v --backup results/mysqldb.backup -S localhost -P 0 -u oneadmin -p oneadmin -d onedb_test
if [ $? -ne 0 ]; then
exit -1
fi

View File

@ -61,7 +61,7 @@ echo "All resources created, now 2.2 DB will be upgraded."
cp $VAR_LOCATION/one.db results/one.db.3.0
cp 2.2/one.db results/one.db.upgraded
onedb upgrade -v --sqlite results/one.db.upgraded --backup results/one.db.backup
echo "ssh" | onedb upgrade -v --sqlite results/one.db.upgraded --backup results/one.db.backup
if [ $? -ne 0 ]; then
exit -1

View File

@ -18,7 +18,6 @@
require 'rubygems'
require 'uri'
require 'net/https'
require 'OpenNebula/Configuration'
require 'zona/OZonesJSON'
@ -122,7 +121,7 @@ EOT
# @param [String] tmpl_str OpenNebula template string
# @return [String, Zona::Error] Response string or Error
def post_resource_str(kind, tmpl_str)
tmpl_json = Zona.to_body(kind, tmpl_str)
tmpl_json = Zona.parse_template(kind, tmpl_str)
post_resource(kind, tmpl_json)
end
@ -150,7 +149,7 @@ EOT
# @param [String] tmpl_str OpenNebula template string
# @return [String, Zona::Error] Response string or Error
def put_resource_str(kind, id, tmpl_str)
tmpl_json = Client.to_body(kind, tmpl_str)
tmpl_json = Zona.parse_template(kind, tmpl_str)
put_resource(kind, id, tmpl_json)
end
@ -261,7 +260,7 @@ EOT
else
if Zona.is_http_error?(value)
str = "Operating with #{kind} failed with HTTP error"
str = " " + str + "code: #{value.code}\n"
str += " code: #{value.code}\n"
if value.body
# Try to extract error message
begin
@ -281,13 +280,24 @@ EOT
end
# Turns a OpenNebula template string into a JSON string
# Parses a OpenNebula template string and turns it into a JSON string
# @param [String] kind element kind
# @param [String] tmpl_str template
# @return [String, Zona::Error] JSON string or Error
def self.to_body(kind, tmpl_str)
tmpl = OpenNebula::Configuration.new(tmpl_str)
res = { "#{kind.upcase}" => tmpl.conf }
def self.parse_template(kind, tmpl_str)
name_reg =/[\w\d_-]+/
variable_reg =/\s*(#{name_reg})\s*=\s*/
single_variable_reg =/^#{variable_reg}([^\[]+?)(#.*)?$/
tmpl = Hash.new
tmpl_str.scan(single_variable_reg) do | m |
key = m[0].strip.upcase
value = m[1].strip
tmpl[key] = value
end
res = { "#{kind.upcase}" => tmpl }
return OZonesJSON.to_json(res)
end

View File

@ -34,7 +34,6 @@ require 'base64'
module OZones
CIPHER="aes-256-cbc"
# -------------------------------------------------------------------------
# The Error Class represents a generic error in the OZones
# library. It contains a readable representation of the error.
@ -72,37 +71,4 @@ module OZones
def self.str_to_json(str)
return JSON.pretty_generate({:message => str})
end
def self.readKey
begin
credentials = File.read(ENV['OZONES_AUTH']).strip
return Digest::SHA1.hexdigest(credentials);
rescue
return "";
end
end
def self.encrypt(plain_txt)
#prepare cipher object
cipher = OpenSSL::Cipher.new(CIPHER)
cipher.encrypt
cipher.key = OZones.readKey
enc_txt = cipher.update(plain_txt)
enc_txt << cipher.final
Base64::encode64(enc_txt).strip.delete("\n")
end
def self.decrypt(b64_txt)
#prepare cipher object
cipher = OpenSSL::Cipher.new(CIPHER)
cipher.decrypt
cipher.key = OZones.readKey
enc_txt = Base64::decode64(b64_txt)
plain_txt = cipher.update(enc_txt)
plain_txt << cipher.final
end
end
end

View File

@ -47,31 +47,40 @@ module OZones
zonePoolHash["ZONE_POOL"]["ZONE"] = Array.new unless self.all.empty?
self.all.each{|zone|
zonePoolHash["ZONE_POOL"]["ZONE"] <<
zone.attributes.merge({:NUMBERVDCS => zone.vdcs.all.size})
zattr = zone.attributes.clone
zattr[:ONEPASS] = Zones.encrypt(zattr[:ONEPASS])
zattr[:NUMBERVDCS] = zone.vdcs.all.size
zonePoolHash["ZONE_POOL"]["ZONE"] << zattr
}
return zonePoolHash
end
def to_hash
zone_attributes = Hash.new
zone_attributes["ZONE"] = attributes
zone_attributes["ZONE"][:VDCS] = Array.new
zattr = Hash.new
zattr["ZONE"] = attributes.clone
zattr["ZONE"][:ONEPASS] = Zones.encrypt(zattr["ZONE"][:ONEPASS])
zattr["ZONE"][:VDCS] = Array.new
self.vdcs.all.each{|vdc|
zone_attributes["ZONE"][:VDCS]<< vdc.attributes
zattr["ZONE"][:VDCS]<< vdc.attributes.clone
}
return zone_attributes
return zattr
end
def ONEPASS
pw = super
OZones.decrypt(pw)
Zones.decrypt(pw)
end
def ONEPASS=(plain_pw)
super(Zones.encrypt(plain_pw))
end
#######################################################################
# Zone Data Management
#######################################################################
@ -88,8 +97,6 @@ module OZones
name = zone_data[:ONENAME]
pass = zone_data[:ONEPASS]
zone_data[:ONEPASS] = OZones.encrypt(pass)
rc = OpenNebulaZone::check_oneadmin(name,
pass,
zone_data[:ENDPOINT])
@ -113,6 +120,41 @@ module OZones
return zone
end
########################################################################
# Encryption functions for the class
########################################################################
CIPHER = "aes-256-cbc"
@@cipher = ""
def self.cipher=(cipher)
@@cipher = cipher
end
def self.encrypt(plain_txt)
#prepare cipher object
cipher = OpenSSL::Cipher.new(CIPHER)
cipher.encrypt
cipher.key = @@cipher
enc_txt = cipher.update(plain_txt)
enc_txt << cipher.final
Base64::encode64(enc_txt).strip.delete("\n")
end
def self.decrypt(b64_txt)
#prepare cipher object
cipher = OpenSSL::Cipher.new(CIPHER)
cipher.decrypt
cipher.key = @@cipher
enc_txt = Base64::decode64(b64_txt)
plain_txt = cipher.update(enc_txt)
plain_txt << cipher.final
end
end
###########################################################################

View File

@ -20,6 +20,11 @@ require 'JSONUtils'
class OzonesServer
include OpenNebulaJSON::JSONUtils
def initialize(cipher)
#Set cipher for Zone classes
OZones::Zones.cipher = cipher
end
############################################################################
# Get methods for the Zones and VDC interface
############################################################################

View File

@ -84,7 +84,7 @@ if Auth.all.size == 0
end
credentials[1] = Digest::SHA1.hexdigest(credentials[1])
@auth=Auth.create({:name => credentials[0],
:password => credentials[1]})
:password => credentials[1]})
@auth.save
else
warn "oZones admin credentials not set, missing OZONES_AUTH file."
@ -119,32 +119,23 @@ set :show_exceptions, false
helpers do
def authorized?
if session[:ip] && session[:ip]==request.ip
return true
end
auth = Rack::Auth::Basic::Request.new(request.env)
if auth.provided? && auth.basic? && auth.credentials
user = auth.credentials[0]
sha1_pass = Digest::SHA1.hexdigest(auth.credentials[1])
if user == ADMIN_NAME && sha1_pass == ADMIN_PASS
return true
end
end
return false
session[:ip] && session[:ip]==request.ip ? true : false
end
def build_session
auth = Rack::Auth::Basic::Request.new(request.env)
if auth.provided? && auth.basic? && auth.credentials
user = auth.credentials[0]
sha1_pass = Digest::SHA1.hexdigest(auth.credentials[1])
user = auth.credentials[0]
pass = auth.credentials[1]
sha1_pass = Digest::SHA1.hexdigest(pass)
if user == ADMIN_NAME && sha1_pass == ADMIN_PASS
session[:user] = user
session[:password] = sha1_pass
session[:ip] = request.ip
session[:user] = user
session[:ip] = request.ip
session[:key] = Digest::SHA1.hexdigest("#{user}:#{pass}")
session[:remember] = params[:remember]
if params[:remember]
@ -164,15 +155,21 @@ helpers do
session.clear
return [204, ""]
end
end
before do
unless request.path=='/login' || request.path=='/'
halt 401 unless authorized?
@OzonesServer = OzonesServer.new
@pr = OZones::ProxyRules.new("apache",config[:htaccess])
unless authorized?
rc , msg = build_session
if rc == 401
halt 401
end
end
@OzonesServer = OzonesServer.new(session[:key])
@pr = OZones::ProxyRules.new("apache",config[:htaccess])
end
end

View File

@ -175,7 +175,7 @@ fieldset textarea{
border-bottom:1px solid #ccc;
border-right:1px solid #ccc;*/
padding:1px;color:#333;
vertical-align: top;
vertical-align: middle;
margin: 0 2px;
margin-bottom: 4px;
}
@ -382,7 +382,7 @@ tr.even:hover{
.info_table td.key_td{
width: 100%;
width: 55%;
text-align:left;
font-weight:bold;
}
@ -395,6 +395,7 @@ tr.even:hover{
.info_table td.value_td{
text-align:left;
width: 45%;
}
#dialog > div > div {

View File

@ -271,6 +271,21 @@ function updateVDCsView(req,vdc_list){
function updateVDCInfo(req,vdc_json){
var vdc = vdc_json.VDC;
var zone_endpoint = getElementData(vdc.ZONES_ID,
"#zone",
dataTable_zones)[3];
var zone_host = "";
var zone_port = "";
var sun_link = "";
var zone_match = zone_endpoint.match(/^http:\/\/(\w+):(\d+)\/RPC2$/);
if (zone_match){
zone_host = zone_match[1];
zone_port = zone_match[2];
sun_link = "http://" + zone_host +"/sunstone_"+ vdc.NAME;
};
var info_tab = {
title: "VDC Information",
content :
@ -307,12 +322,24 @@ function updateVDCInfo(req,vdc_json){
<td class="key_td">ACLs</td>\
<td class="value_td">'+vdc.ACLS+'</td>\
</tr>\
<tr>\
<td class="key_td">Sunstone public link</td>\
<td class="value_td">'+(sun_link.length? '<a href="'+sun_link+'" target="_blank">'+sun_link+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "")+'</td>\
</tr>\
<tr>\
<td class="key_td">ONE_XMLPRC (to export for CLI access)</td>\
<td class="value_td"><input type="text" id="one_xmlrpc" value="'+(zone_host.length? "http://" + zone_host +"/"+ vdc.NAME: "--")+'" style="width:100%;"/></td>\
</tr>\
</tbody>\
</table>'
};
Sunstone.updateInfoPanelTab("vdc_info_panel","vdc_info_tab",info_tab);
Sunstone.popUpInfoPanel("vdc_info_panel");
$('#vdc_info_panel input#one_xmlrpc').select();
setTimeout(function(){
$('#vdc_info_panel input#one_xmlrpc').select();
}, 700);
}
function fillHostList(req, host_list_json){

View File

@ -39,14 +39,20 @@ var create_zone_tmpl =
<div>\
<label for="name">Name:</label>\
<input type="text" name="name" id="name" /><br />\
<label for="endpoint">End point:</label>\
<input type="text" name="endpoint" id="endpoint" /><br />\
<label for="endpoint">End point (host,port):</label>\
<input type="text" name="endpoint" id="endpoint" value="localhost"/> :\
<input type="text" name="endpoint_port" id="endpoint_port" value="2633" style="width:3em;"/>\
<br />\
<label for="onename">Oneadmin user:</label>\
<input type="text" name="onename" id="onename" /><br />\
<input type="text" name="onename" id="onename" value="oneadmin"/><br />\
<label for="onepass">Password:</label>\
<input type="password" name="onepass" id="onepass" />\
<input type="password" name="onepass" id="onepass" /><br />\
<label for="sunsendpoint">Sunstone end point:</label>\
<input type="text" name="sunsendpoint" id="sunsendpoint" /><br />\
<input type="text" name="sunsendpoint_ptc" id="sunsendpoint_ptc" value="http" style="width:2em;"/> ://\
<input type="text" name="sunsendpoint" id="sunsendpoint" style="width:7em;" value="localhost"/> :\
<input type="text" name="sunsendpoint_port" id="sunsendpoint_port" value="9869" style="width:3em;"/> /\
<input type="text" name="sunsendpoint_path" id="sunsendpoint_path" value="" style="width:4em;"/>\
<br />\
</div>\
</fieldset>\
<fieldset>\
@ -301,7 +307,7 @@ function updateZoneInfo(req,zone_json){
<td class="value_td">'+zone.ENDPOINT+'</td>\
</tr>\
<tr>\
<td class="key_td">Sunstone endpoint</td>\
<td class="key_td">Sunstone endpoint</td>\
<td class="value_td">'+ (zone.SUNSENDPOINT.length? '<a href="'+zone.SUNSENDPOINT+'" target="_blank">'+zone.SUNSENDPOINT+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "") +'</td>\
</tr>\
<tr>\
@ -539,7 +545,7 @@ function setupCreateZoneDialog(){
$('#create_zone_dialog').dialog({
autoOpen: false,
modal: true,
width: 500
width: 540
});
$('#create_zone_dialog button').button();
@ -548,9 +554,13 @@ function setupCreateZoneDialog(){
$('#create_zone_form').submit(function(){
var name = $('#name', this).val();
var endpoint = $('#endpoint',this).val();
var endpoint_port = $('#endpoint_port',this).val();
var onename = $('#onename',this).val();
var onepass = $('#onepass',this).val();
var sunsendpoint = $('#sunsendpoint',this).val();
var se = $('#sunsendpoint',this).val();
var se_ptc = $('#sunsendpoint_ptc',this).val();
var se_port = $('#sunsendpoint_port',this).val();
var se_path = $('#sunsendpoint_path',this).val();
if (!name.length || !endpoint.length ||
!onename.length || !onepass.length){
@ -558,13 +568,20 @@ function setupCreateZoneDialog(){
return false;
}
endpoint = "http://"+
endpoint+":"+endpoint_port+"/RPC2"
if (se.length)
se = se_ptc + "://" + se + ":" + se_port +
"/" + se_path;
var zone_json = {
"ZONE": {
"NAME": name,
"ENDPOINT": endpoint,
"ONENAME": onename,
"ONEPASS": onepass,
"SUNSENDPOINT" : sunsendpoint
"SUNSENDPOINT" : se
}
};

View File

@ -94,7 +94,7 @@ private:
void set_one_endpoint(string endpoint);
int read_oneauth(string &secret);
void read_oneauth(string &secret);
};
#endif /*ONECLIENT_H_*/

View File

@ -38,11 +38,9 @@ const int Client::MESSAGE_SIZE = 51200;
void Client::set_one_auth(string secret)
{
int rc = 0;
if( secret == "" )
if (secret.empty())
{
rc = read_oneauth(secret);
read_oneauth(secret);
}
one_auth = secret;
@ -51,7 +49,7 @@ void Client::set_one_auth(string secret)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Client::read_oneauth(string &secret)
void Client::read_oneauth(string &secret)
{
ostringstream oss;
string one_auth_file;
@ -59,7 +57,7 @@ int Client::read_oneauth(string &secret)
const char * one_auth_env;
ifstream file;
bool rc = -1;
int rc = -1;
// Read $ONE_AUTH file and copy its contents into secret.
one_auth_env = getenv("ONE_AUTH");
@ -111,8 +109,6 @@ int Client::read_oneauth(string &secret)
NebulaLog::log("XMLRPC",Log::ERROR,oss);
throw runtime_error( oss.str() );
}
return rc;
}
/* -------------------------------------------------------------------------- */

View File

@ -51,6 +51,7 @@ module OpenNebulaJSON
when "unpublish" then self.unpublish
when "update" then self.update(action_hash['params'])
when "chown" then self.chown(action_hash['params'])
when "chtype" then self.chtype(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
@ -69,5 +70,9 @@ module OpenNebulaJSON
def chown(params=Hash.new)
super(params['owner_id'].to_i,params['group_id'].to_i)
end
def chtype(params=Hash.new)
super(params['type'])
end
end
end

View File

@ -745,6 +745,13 @@ var OpenNebula = {
},
"nonpersistent": function(params){
OpenNebula.Action.simple_action(params,OpenNebula.Image.resource,"nonpersistent");
},
"chtype": function(params){
var action_obj = {"type" : params.data.extra_param};
OpenNebula.Action.simple_action(params,
OpenNebula.Image.resource,
"chtype",
action_obj);
}
},

View File

@ -28,6 +28,7 @@ var images_tab_content =
<th>Owner</th>\
<th>Group</th>\
<th>Name</th>\
<th>Size</th>\
<th>Type</th>\
<th>Registration time</th>\
<th>Public</th>\
@ -95,6 +96,11 @@ var create_image_tmpl =
</select>\
<div class="tip">Type of disk device to emulate.</div>\
</div>\
<div class="img_param">\
<label for="img_driver">Driver:</label>\
<input type="text" name="img_driver" id="img_driver" />\
<div class="tip">Specific image mapping driver. KVM: raw, qcow2 and Xen:tap:aio:, file:</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="" id="src_path_select">\
@ -372,7 +378,19 @@ var image_actions = {
elements: imageElements,
error: onError,
notify: true
},
"Image.chtype" : {
type: "single",
call: OpenNebula.Image.chtype,
callback: function (req) {
Sunstone.runAction("Image.show",req.request.data[0]);
},
elements: imageElements,
error: onError,
notify: true
}
}
@ -473,13 +491,26 @@ function imageElements() {
function imageElementArray(image_json){
//Changing this? It may affect to the is_public() and is_persistent() functions.
var image = image_json.IMAGE;
var type = $('<select>\
<option value="OS">OS</option>\
<option value="CDROM">CD-ROM</option>\
<option value="DATABLOCK">Datablock</option>\
</select>');
var value = OpenNebula.Helper.image_type(image.TYPE);
$('option[value="'+value+'"]',type).replaceWith('<option value="'+value+'" selected="selected">'+value+'</option>');
return [
'<input class="check_item" type="checkbox" id="image_'+image.ID+'" name="selected_items" value="'+image.ID+'"/>',
image.ID,
image.UNAME,
image.GNAME,
image.NAME,
OpenNebula.Helper.image_type(image.TYPE),
image.SIZE,
'<select class="action_cb" id="select_chtype_image" elem_id="'+image.ID+'" style="width:100px">'+type.html()+'</select>',
pretty_time(image.REGTIME),
parseInt(image.PUBLIC) ? '<input class="action_cb" id="cb_public_image" type="checkbox" elem_id="'+image.ID+'" checked="checked"/>'
: '<input class="action_cb" id="cb_public_image" type="checkbox" elem_id="'+image.ID+'"/>',
@ -493,7 +524,11 @@ function imageElementArray(image_json){
// Set up the listener on the table TDs to show the info panel
function imageInfoListener(){
$('#tbodyimages tr',dataTable_images).live("click",function(e){
if ($(e.target).is('input')) {return true;}
var target = $(e.target);
if (target.is('input') || target.is('select') || target.is('option'))
return true;
popDialogLoading();
var aData = dataTable_images.fnGetData(this);
var id = $(aData[0]).val();
@ -595,12 +630,28 @@ function updateImageInfo(request,img){
</tr>\
<tr>\
<td class="key_td">Source</td>\
<td class="value_td">'+img_info.SOURCE+'</td>\
<td class="value_td">'+(typeof img_info.SOURCE === "string" ? img_info.SOURCE : "--")+'</td>\
</tr>\
<tr>\
<td class="key_td">Path</td>\
<td class="value_td">'+(typeof img_info.PATH === "string" ? img_info.PATH : "--")+'</td>\
</tr>\
<tr>\
<td class="key_td">Filesystem type</td>\
<td class="value_td">'+(typeof img_info.FSTYPE === "string" ? img_info.FSTYPE : "--")+'</td>\
</tr>\
<tr>\
<td class="key_td">Size (Mb)</td>\
<td class="value_td">'+img_info.SIZE+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("image",img_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Running #VMS</td>\
<td class="value_td">'+img_info.RUNNING_VMS+'</td>\
</tr>\
</table>'
}
@ -755,6 +806,10 @@ function setupCreateImageDialog(){
var bus = $('#img_bus',this).val();
img_json["BUS"] = bus;
var driver = $('#img_driver',this).val();
if (driver.length)
img_json["DRIVER"] = driver;
switch ($('#src_path_select input:checked',this).val()){
case "path":
path = $('#img_path',this).val();
@ -970,6 +1025,15 @@ function setupImageActionCheckboxes(){
return true;
});
$('select.action_cb#select_chtype_image', dataTable_images).live("change",function(){
var $this = $(this);
var value = $this.val();
var id = $this.attr("elem_id");
Sunstone.runAction("Image.chtype", id, value);
});
}
//The DOM is ready at this point
@ -982,17 +1046,17 @@ $(document).ready(function(){
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,2,3,5,7,8,9] },
{ "sWidth": "35px", "aTargets": [1,10] },
{ "sWidth": "100px", "aTargets": [9] },
{ "sWidth": "150px", "aTargets": [6] }
{ "sWidth": "60px", "aTargets": [0,2,3,8,9,10] },
{ "sWidth": "35px", "aTargets": [1,5,11] },
{ "sWidth": "100px", "aTargets": [6] },
{ "sWidth": "150px", "aTargets": [7] }
]
});
dataTable_images.fnClearTable();
addElement([
spinner,
'','','','','','','','','',''],dataTable_images);
'','','','','','','','','','',''],dataTable_images);
Sunstone.runAction("Image.list");
setupCreateImageDialog();

View File

@ -50,9 +50,11 @@ var create_user_tmpl =
<label for="driver">Authentication:</label>\
<select name="driver" id="driver">\
<option value="core" selected="selected">Core</option>\
<option value="ssh" selected="selected">SSH</option>\
<option value="x509" selected="selected">x509</option>\
<option value="server" selected="selected">Server</option>\
<option value="ssh">SSH</option>\
<option value="x509">x509</option>\
<option value="server_cipher">Server (Cipher)</option>\
<option value="server_x509">Server (x509)</option>\
<option value="public">Public</option>\
</select>\
</div>\
</fieldset>\
@ -256,10 +258,12 @@ var user_buttons = {
type: "confirm_with_select",
text: "Change authentication",
select: function() {
return '<option value="core" selected="selected">Core</option>\
<option value="ssh" selected="selected">SSH</option>\
<option value="x509" selected="selected">x509</option>\
<option value="server" selected="selected">Server</option>'
return '<option value="core" selected="selected">Core</option>\
<option value="ssh">SSH</option>\
<option value="x509">x509</option>\
<option value="server_cipher">Server (Cipher)</option>\
<option value="server_x509">Server (x509)</option>\
<option value="public">Public</option>'
},
tip: "Please choose the new type of authentication for the selected users:"
},

View File

@ -526,6 +526,10 @@ function updateVNetworkInfo(request,vn){
<td class="key_td">Public</td>\
<td class="value_td">'+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'</td>\
</tr>\
<tr>\
<td class="key_td">Physical device</td>\
<td class="value_td">'+(vn_info.PHYDEV ? vn_info.PHYDEV : "--" )+'</td>\
</tr>\
</table>\
<table id="vn_leases_info_table" class="info_table">\
<thead>\

View File

@ -196,19 +196,19 @@ function notifySubmit(action, args, extra_param){
msg += " >> " + extra_param;
};
$.jGrowl(msg, {theme: "jGrowl-notify-submit"});
$.jGrowl(msg, {theme: "jGrowl-notify-submit", position: "bottom-right"});
}
//Notification on error
function notifyError(msg){
msg = "<h1>Error</h1>" + msg;
$.jGrowl(msg, {theme: "jGrowl-notify-error", sticky: true });
$.jGrowl(msg, {theme: "jGrowl-notify-error", position: "bottom-right", sticky: true });
}
//Standard notification
function notifyMessage(msg){
msg = "<h1>Info</h1>" + msg;
$.jGrowl(msg, {theme: "jGrowl-notify-submit"});
$.jGrowl(msg, {theme: "jGrowl-notify-submit", position: "bottom-right"});
}
// Returns an HTML string with the json keys and values

View File

@ -88,11 +88,11 @@ helpers do
end
def build_session
# begin
begin
result = settings.cloud_auth.auth(request.env, params)
# rescue Exception => e
# error 500, e.message
# end
rescue Exception => e
error 500, e.message
end
if result.nil?
return [401, ""]

View File

@ -759,14 +759,6 @@ int VirtualMachine::get_disk_images(string& error_str)
{
goto error_image;
}
else if ( rc == -3)
{
goto error_name;
}
else if ( rc != -2 ) // The only known code left
{
goto error_unknown;
}
}
return 0;
@ -787,13 +779,6 @@ error_image:
error_str = "Could not get disk image for VM.";
goto error_common;
error_name:
error_str = "IMAGE is not supported for DISK. Use IMAGE_ID instead.";
goto error_common;
error_unknown:
error_str = "Unknown error code.";
error_common:
ImageManager * imagem = nd.get_imagem();
@ -890,22 +875,12 @@ int VirtualMachine::get_network_leases(string& estr)
{
goto error_vnet;
}
else if ( rc == -3 )
{
goto error_name;
}
}
return 0;
error_vnet:
estr = "Could not get virtual network for VM.";
goto error_common;
error_name:
estr = "NETWORK is not supported for NIC. Use NETWORK_ID instead.";
error_common:
return -1;
}

View File

@ -15,7 +15,9 @@
/* -------------------------------------------------------------------------- */
#include "VirtualNetworkPool.h"
#include "UserPool.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
#include <sstream>
@ -137,35 +139,86 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VirtualNetwork * VirtualNetworkPool::get_nic_by_name(VectorAttribute * nic,
const string& name,
int _uid)
{
istringstream is;
string uid_s ;
string uname;
int uid;
if (!(uid_s = nic->vector_value("NETWORK_UID")).empty())
{
is.str(uid_s);
is >> uid;
if( is.fail() )
{
return 0;
}
}
else if (!(uname = nic->vector_value("NETWORK_UNAME")).empty())
{
User * user;
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
user = upool->get(uname,true);
if ( user == 0 )
{
return 0;
}
uid = user->get_oid();
user->unlock();
}
else
{
uid = _uid;
}
return get(name,uid,true);
}
/* -------------------------------------------------------------------------- */
VirtualNetwork * VirtualNetworkPool::get_nic_by_id(const string& id_s)
{
istringstream is;
int id;
is.str(id_s);
is >> id;
if( is.fail() )
{
return 0;
}
return get(id,true);
}
int VirtualNetworkPool::nic_attribute(VectorAttribute * nic, int uid, int vid)
{
string network;
VirtualNetwork * vnet = 0;
istringstream is;
int network_id;
network = nic->vector_value("NETWORK");
if (!network.empty())
if (!(network = nic->vector_value("NETWORK")).empty())
{
return -3;
vnet = get_nic_by_name (nic, network, uid);
}
network = nic->vector_value("NETWORK_ID");
if(network.empty())
else if (!(network = nic->vector_value("NETWORK_ID")).empty())
{
vnet = get_nic_by_id(network);
}
else //Not using a pre-defined network
{
return -2;
}
is.str(network);
is >> network_id;
if( !is.fail() )
{
vnet = get(network_id,true);
}
}
if (vnet == 0)
{
@ -194,23 +247,18 @@ void VirtualNetworkPool::authorize_nic(VectorAttribute * nic,
string network;
VirtualNetwork * vnet = 0;
istringstream is;
int network_id;
network = nic->vector_value("NETWORK_ID");
if(network.empty())
if (!(network = nic->vector_value("NETWORK")).empty())
{
vnet = get_nic_by_name (nic, network, uid);
}
else if (!(network = nic->vector_value("NETWORK_ID")).empty())
{
vnet = get_nic_by_id(network);
}
else //Not using a pre-defined network
{
return;
}
is.str(network);
is >> network_id;
if( !is.fail() )
{
vnet = get(network_id,true);
}
}
if (vnet == 0)
{
@ -225,4 +273,4 @@ void VirtualNetworkPool::authorize_nic(VectorAttribute * nic,
vnet->isPublic());
vnet->unlock();
}
}

View File

@ -1151,17 +1151,7 @@ public:
// Disk using network 0
disk = new VectorAttribute("DISK");
disk->replace("NETWORK", "A net");
int rc = ((VirtualNetworkPool*)vnp)->nic_attribute(disk, 0, 0);
CPPUNIT_ASSERT( rc == -3 );
delete disk;
// Disk using network 0
disk = new VectorAttribute("DISK");
disk->replace("NETWORK_ID", "0");
disk->replace("NETWORK", "Net 0");
((VirtualNetworkPool*)vnp)->nic_attribute(disk, 0, 0);