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

Feature #407: New XML-RPC, Ruby OCA & CLI method 'chown' for VM,TEMPLATE,NET,USER & IMAGE. Work in progress, only basic functionality without authorization or consistency checks.

This commit is contained in:
Carlos Martín 2011-05-17 19:13:59 +02:00
parent 6329d8b3fa
commit b0ddfd382c
16 changed files with 535 additions and 10 deletions

View File

@ -69,14 +69,28 @@ public:
return uid;
};
// TODO: Check if uid == -1?
// What happens with user, is the user his owner, or uid = -1?
int set_uid(int _uid)
{
uid = _uid;
return 0;
}
int get_gid()
{
return gid;
};
void set_gid(int _gid)
int set_gid(int _gid)
{
if( gid == -1 )
{
return -1;
}
gid = _gid;
return 0;
};
/* --------------------------------------------------------------------- */

View File

@ -312,12 +312,105 @@ private:
return oss.str();
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// TODO: enum of Objects is maintained in AuthManager.h, could be moved
// to Nebula.h
enum Object
{
VM,
HOST,
NET,
IMAGE,
USER,
CLUSTER,
TEMPLATE,
GROUP
};
PoolSQL * get_pool(Object ob)
{
switch (ob)
{
case VM: return static_cast<PoolSQL*>(vmpool);
case HOST: return static_cast<PoolSQL*>(hpool);
case NET: return static_cast<PoolSQL*>(vnpool);
case IMAGE: return static_cast<PoolSQL*>(ipool);
case USER: return static_cast<PoolSQL*>(upool);
case CLUSTER: return static_cast<PoolSQL*>(cpool);
case TEMPLATE: return static_cast<PoolSQL*>(tpool);
case GROUP: return static_cast<PoolSQL*>(gpool);
}
};
string get_method_prefix(Object ob)
{
switch (ob)
{
case VM: return "VirtualMachine";
case HOST: return "Host";
case NET: return "VirtualNetwork";
case IMAGE: return "Image";
case USER: return "User";
case CLUSTER: return "Cluster";
case TEMPLATE: return "Template";
case GROUP: return "Group";
}
};
string get_object_name(Object ob)
{
switch (ob)
{
case VM: return "VM";
case HOST: return "HOST";
case NET: return "NET";
case IMAGE: return "IMAGE";
case USER: return "USER";
case CLUSTER: return "CLUSTER";
case TEMPLATE: return "TEMPLATE";
case GROUP: return "GROUP";
}
};
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// XML-RPC Methods
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
/* ---------------------------------------------------------------------- */
/* Generic Helpers */
/* ---------------------------------------------------------------------- */
class GenericChown: public xmlrpc_c::method
{
public:
GenericChown(RequestManager * _rm,
Object _ob):
rm(_rm),
ob(_ob)
{
_signature="A:siii";
_help="Changes the owner and/or group";
};
~GenericChown(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
RequestManager * rm;
Object ob;
};
/* ---------------------------------------------------------------------- */
/* Virtual Machine Interface */
/* ---------------------------------------------------------------------- */

View File

@ -254,7 +254,13 @@ Commands:
* nonpersistent (Makes an Image non persistent)
oneimage nonpersistent <image_id>
* chown (Changes the Image owner and group)
oneimage chown <image_id> <owner_id> [<group_id>]
* chgrp (Changes the Image group)
oneimage chgrp <image_id> <group_id>
* list (Shows Images in the pool)
oneimage list <filter_flag>
@ -440,7 +446,35 @@ when "nonpersistent"
if is_successful?(result)
puts "Image made nonpersistent" if ops[:verbose]
end
when "chown"
check_parameters("chown", 2)
image_id = get_image_id(ARGV[0])
new_uid = ARGV[1].to_i
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
image = OpenNebula::Image.new_with_id(image_id, get_one_client)
result = image.chown( new_uid, new_gid )
if is_successful?(result)
puts "Image user/group changed" if ops[:verbose]
end
when "chgrp"
check_parameters("chgrp", 2)
image_id = get_image_id(ARGV[0])
new_uid = -1
new_gid = ARGV[1].to_i
image = OpenNebula::Image.new_with_id(image_id, get_one_client)
result = image.chown( new_uid, new_gid )
if is_successful?(result)
puts "Image group changed" if ops[:verbose]
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]

View File

@ -195,6 +195,12 @@ Commands:
* unpublish (Unpublish an Template)
onetemplate unpublish <template_id>
* chown (Changes the Template owner and group)
onetemplate chown <template_id> <owner_id> [<group_id>]
* chgrp (Changes the Template group)
onetemplate chgrp <template_id> <group_id>
* list (Shows Templates in the pool)
onetemplate list <filter_flag>
@ -337,6 +343,34 @@ when "unpublish"
puts "Template unpublished" if ops[:verbose]
end
when "chown"
check_parameters("chown", 2)
obj_id = get_template_id(ARGV[0])
new_uid = ARGV[1].to_i
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
obj = OpenNebula::Template.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid, new_gid )
if is_successful?(result)
puts "Template user/group changed" if ops[:verbose]
end
when "chgrp"
check_parameters("chgrp", 2)
obj_id = get_template_id(ARGV[0])
new_uid = -1
new_gid = ARGV[1].to_i
obj = OpenNebula::Template.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid, new_gid )
if is_successful?(result)
puts "Template group changed" if ops[:verbose]
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]

View File

@ -124,6 +124,8 @@ Commands:
* passwd (Changes the given user's password)
oneuser passwd <id> password
* chgrp (Changes the User group)
oneuser chgrp <id> <group_id>
Information Columns:
@ -265,6 +267,19 @@ when "passwd"
puts
end
when "chgrp"
check_parameters("chgrp", 2)
obj_id = get_user_id(ARGV[0])
new_gid = ARGV[1].to_i
obj = OpenNebula::User.new_with_id(obj_id, get_one_client)
result = obj.chgrp( new_gid )
if is_successful?(result)
puts "User group changed" if ops[:verbose]
end
when "list"
if !ops[:xml]
uplist=UPShow.new

View File

@ -416,6 +416,12 @@ Commands:
States: ANY, except SUSPENDED or DONE
* chown (Changes the VM owner and group)
onevm chown <vm_id> <owner_id> [<group_id>]
* chgrp (Changes the VM group)
onevm chgrp <vm_id> <group_id>
* list (Shows VMs in the pool)
onevm list <filter_flag>
@ -770,6 +776,34 @@ when "resubmit"
end
end
when "chown"
check_parameters("chown", 2)
obj_id = get_vm_id(ARGV[0])
new_uid = ARGV[1].to_i
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
obj = OpenNebula::VirtualMachine.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid, new_gid )
if is_successful?(result)
puts "VM user/group changed" if ops[:verbose]
end
when "chgrp"
check_parameters("chgrp", 2)
obj_id = get_vm_id(ARGV[0])
new_uid = -1
new_gid = ARGV[1].to_i
obj = OpenNebula::VirtualMachine.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid, new_gid )
if is_successful?(result)
puts "VM group changed" if ops[:verbose]
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]

View File

@ -186,6 +186,12 @@ Commands:
* rmleases (Removes a lease fom the virtual network)
onevnet rmleases <network_id> <IP>
* chown (Changes the virtual network owner and group)
onevnet chown <network_id> <owner_id> [<group_id>]
* chgrp (Changes the virtual network group)
onevnet chgrp <network_id> <group_id>
* list (Lists virtual networks in the pool)
onevnet list <filter_flag>
@ -342,6 +348,34 @@ when "rmleases"
puts "Leases removed" if ops[:verbose]
end
when "chown"
check_parameters("chown", 2)
obj_id = get_vn_id(ARGV[0])
new_uid = ARGV[1].to_i
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
obj = OpenNebula::VirtualNetwork.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid, new_gid )
if is_successful?(result)
puts "Virtual Network user/group changed" if ops[:verbose]
end
when "chgrp"
check_parameters("chgrp", 2)
obj_id = get_vn_id(ARGV[0])
new_uid = -1
new_gid = ARGV[1].to_i
obj = OpenNebula::VirtualNetwork.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid, new_gid )
if is_successful?(result)
puts "Virtual Network group changed" if ops[:verbose]
end
when "list"
if ARGV[0]
case ARGV[0]

View File

@ -30,7 +30,8 @@ module OpenNebula
:enable => "image.enable",
:publish => "image.publish",
:persistent => "image.persistent",
:delete => "image.delete"
:delete => "image.delete",
:chown => "image.chown"
}
IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR}
@ -142,7 +143,14 @@ module OpenNebula
def delete()
super(IMAGE_METHODS[:delete])
end
# Changes the owner/group
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(uid, gid)
super(IMAGE_METHODS[:chown], uid, gid)
end
#######################################################################
# Helpers to get Image information

View File

@ -173,6 +173,21 @@ module OpenNebula
return rc
end
# Calls to the corresponding chown method to modify
# the object's owner and group
# xml_method:: _String_ the name of the XML-RPC method
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(xml_method, uid, gid)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(xml_method,@pe_id, uid, gid)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
public
# Creates new element specifying its id

View File

@ -27,7 +27,8 @@ module OpenNebula
:update => "template.update",
:rmattr => "template.rmattr",
:publish => "template.publish",
:delete => "template.delete"
:delete => "template.delete",
:chown => "template.chown"
}
# Creates a Template description with just its identifier
@ -103,6 +104,14 @@ module OpenNebula
set_publish(false)
end
# Changes the owner/group
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(uid, gid)
super(TEMPLATE_METHODS[:chown], uid, gid)
end
# ---------------------------------------------------------------------
# Helpers to get Template information
# ---------------------------------------------------------------------

View File

@ -25,7 +25,8 @@ module OpenNebula
:info => "user.info",
:allocate => "user.allocate",
:delete => "user.delete",
:passwd => "user.passwd"
:passwd => "user.passwd",
:chown => "user.chown"
}
# Creates a User description with just its identifier
@ -89,6 +90,13 @@ module OpenNebula
return rc
end
# Changes the owner/group
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chgrp(gid)
chown(USER_METHODS[:chown], -1, gid)
end
# ---------------------------------------------------------------------
# Helpers to get User information
# ---------------------------------------------------------------------

View File

@ -27,7 +27,8 @@ module OpenNebula
:action => "vm.action",
:migrate => "vm.migrate",
:deploy => "vm.deploy",
:savedisk => "vm.savedisk"
:savedisk => "vm.savedisk",
:chown => "vm.chown"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED}
@ -224,6 +225,14 @@ module OpenNebula
return rc
end
# Changes the owner/group
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(uid, gid)
super(VM_METHODS[:chown], uid, gid)
end
#######################################################################
# Helpers to get VirtualMachine information
#######################################################################

View File

@ -27,7 +27,8 @@ module OpenNebula
:publish => "vn.publish",
:delete => "vn.delete",
:addleases => "vn.addleases",
:rmleases => "vn.rmleases"
:rmleases => "vn.rmleases",
:chown => "vn.chown"
}
# Creates a VirtualNetwork description with just its identifier
@ -111,6 +112,14 @@ module OpenNebula
return rc
end
# Changes the owner/group
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(uid, gid)
super(VN_METHODS[:chown], uid, gid)
end
# ---------------------------------------------------------------------
# Helpers to get VirtualNetwork information
# ---------------------------------------------------------------------

View File

@ -231,6 +231,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_info(new
RequestManager::VirtualMachineInfo(vmpool,upool));
xmlrpc_c::methodPtr vm_chown(new
RequestManager::GenericChown(this,VM));
xmlrpc_c::methodPtr vm_pool_info(new
RequestManager::VirtualMachinePoolInfo(vmpool,upool));
@ -252,6 +255,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr template_publish(new
RequestManager::TemplatePublish(tpool, upool));
xmlrpc_c::methodPtr template_chown(new
RequestManager::GenericChown(this,TEMPLATE));
xmlrpc_c::methodPtr template_pool_info(new
RequestManager::TemplatePoolInfo(tpool,upool));
@ -321,6 +327,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vn_rmleases(new
RequestManager::VirtualNetworkRemoveLeases(vnpool, upool));
xmlrpc_c::methodPtr vn_chown(new
RequestManager::GenericChown(this,NET));
xmlrpc_c::methodPtr user_allocate(new
RequestManager::UserAllocate(upool));
@ -333,6 +342,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr user_change_password(new
RequestManager::UserChangePassword(upool));
xmlrpc_c::methodPtr user_chown(new
RequestManager::GenericChown(this,USER));
xmlrpc_c::methodPtr userpool_info(new
RequestManager::UserPoolInfo(upool));
@ -359,7 +371,10 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr image_enable(new
RequestManager::ImageEnable(ipool, upool));
xmlrpc_c::methodPtr image_chown(new
RequestManager::GenericChown(this,IMAGE));
xmlrpc_c::methodPtr imagepool_info(new
RequestManager::ImagePoolInfo(ipool, upool));
@ -371,6 +386,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
RequestManagerRegistry.addMethod("one.vm.info", vm_info);
RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk);
RequestManagerRegistry.addMethod("one.vm.chown", vm_chown);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
@ -382,6 +398,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.template.update", template_update);
RequestManagerRegistry.addMethod("one.template.rmattr", template_rm_attribute);
RequestManagerRegistry.addMethod("one.template.publish", template_publish);
RequestManagerRegistry.addMethod("one.template.chown", template_chown);
RequestManagerRegistry.addMethod("one.templatepool.info",template_pool_info);
@ -420,6 +437,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vn.delete", vn_delete);
RequestManagerRegistry.addMethod("one.vn.addleases", vn_addleases);
RequestManagerRegistry.addMethod("one.vn.rmleases", vn_rmleases);
RequestManagerRegistry.addMethod("one.vn.chown", vn_chown);
RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info);
@ -430,6 +448,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.user.delete", user_delete);
RequestManagerRegistry.addMethod("one.user.info", user_info);
RequestManagerRegistry.addMethod("one.user.passwd", user_change_password);
RequestManagerRegistry.addMethod("one.user.chown", user_chown);
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);
@ -443,6 +462,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.image.publish", image_publish);
RequestManagerRegistry.addMethod("one.image.persistent", image_persistent);
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
RequestManagerRegistry.addMethod("one.image.chown", image_chown);
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);

View File

@ -0,0 +1,188 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::GenericChown::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int uid, obj_owner;
int oid, ownid, gid;
int rc;
PoolObjectSQL * obj;
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
ostringstream oss;
PoolSQL * pool = rm->get_pool(ob);
string method_name = rm->get_method_prefix(ob) + "Chown";
string obj_name = rm->get_object_name(ob);
oss << method_name << " invoked";
NebulaLog::log("ReM",Log::DEBUG,oss);
oss.str("");
session = xmlrpc_c::value_string (paramList.getString(0));
oid = xmlrpc_c::value_int (paramList.getInt(1));
ownid = xmlrpc_c::value_int (paramList.getInt(2));
gid = xmlrpc_c::value_int (paramList.getInt(3));
// TODO: check destination owner and/or group exist
// First, we need to authenticate the user
uid = rm->upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get object from the pool
obj = pool->get(oid,true);
if ( obj == 0 )
{
goto error_get;
}
obj_owner = obj->get_uid();
obj->unlock();
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
{
goto error_authorize;
}
// TODO use auth manager
/*
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
// ar.add_auth(..);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
*/
// Get the object locked again
obj = pool->get(oid,true);
if ( obj == 0 )
{
goto error_get;
}
if( ownid > -1 )
{
rc = obj->set_uid(ownid);
if( rc != 0 )
{
goto error_set_uid;
}
}
if( gid > -1 )
{
rc = obj->set_gid(gid);
if( rc != 0 )
{
goto error_set_gid;
}
}
pool->update(obj);
obj->unlock();
arrayData.push_back(xmlrpc_c::value_boolean(true));
// Copy arrayresult into retval mem space
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss.str(authenticate_error(method_name));
goto error_common;
error_get:
oss.str(get_error(method_name, obj_name, oid));
goto error_common;
error_authorize:
// TODO: delete development comment
oss << authorization_error(method_name, "MANAGE", obj_name, uid, oid) <<
" Development functionality, only oneamdin can perform chown.";
goto error_common;
error_set_uid:
oss.str(action_error(method_name, "SET_UID", obj_name, oid, rc));
obj->unlock();
goto error_common;
error_set_gid:
oss.str(action_error(method_name, "SET_GID", obj_name, oid, rc));
if( ownid > -1 ) // restore owner user
{
obj->set_uid(obj_owner);
}
obj->unlock();
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
NebulaLog::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -73,6 +73,7 @@ source_files=[
'RequestManagerTemplateRemoveAttribute.cc',
'RequestManagerTemplatePublish.cc',
'RequestManagerTemplatePoolInfo.cc',
'RequestManagerChown.cc',
]
# Build library