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:
commit
276e4bdf4b
@ -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
|
||||
|
@ -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,
|
||||
|
@ -236,7 +236,7 @@ public:
|
||||
UserAllocate():
|
||||
RequestManagerAllocate("UserAllocate",
|
||||
"Returns user information",
|
||||
"A:sss",
|
||||
"A:ssss",
|
||||
false)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
VirtualMachineSaveDisk():
|
||||
RequestManagerVirtualMachine("VirtualMachineSaveDisk",
|
||||
"Saves a disk from virtual machine as a new image",
|
||||
"A:siis"){};
|
||||
"A:siiss"){};
|
||||
|
||||
~VirtualMachineSaveDisk(){};
|
||||
|
||||
|
@ -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_*/
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -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
|
||||
}
|
@ -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
|
@ -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")
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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}"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
###########################################################################
|
||||
|
@ -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
|
||||
############################################################################
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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){
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -94,7 +94,7 @@ private:
|
||||
|
||||
void set_one_endpoint(string endpoint);
|
||||
|
||||
int read_oneauth(string &secret);
|
||||
void read_oneauth(string &secret);
|
||||
};
|
||||
|
||||
#endif /*ONECLIENT_H_*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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:"
|
||||
},
|
||||
|
@ -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>\
|
||||
|
@ -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
|
||||
|
@ -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, ""]
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user