From 5b9fed52f77669bb1b6379ebb6f255cc69020e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 30 Mar 2011 19:03:49 +0200 Subject: [PATCH 01/16] Feature #487: First version of TemplatePool added to the core: DB, Pool and RM methods. --- SConstruct | 2 + include/AuthManager.h | 3 +- include/Nebula.h | 17 +- include/RequestManager.h | 190 ++++++++++++- include/User.h | 2 +- include/VMTemplate.h | 255 ++++++++++++++++++ include/VMTemplatePool.h | 146 ++++++++++ include/VirtualMachinePool.h | 2 + src/authm/AuthManager.cc | 1 + src/nebula/Nebula.cc | 4 + src/nebula/SConstruct | 1 + src/rm/RequestManager.cc | 30 ++- src/rm/RequestManagerImagePoolInfo.cc | 1 - src/rm/RequestManagerTemplateAllocate.cc | 183 +++++++++++++ src/rm/RequestManagerTemplateDelete.cc | 153 +++++++++++ src/rm/RequestManagerTemplateInfo.cc | 107 ++++++++ src/rm/RequestManagerTemplatePoolInfo.cc | 124 +++++++++ src/rm/RequestManagerTemplatePublish.cc | 158 +++++++++++ .../RequestManagerTemplateRemoveAttribute.cc | 159 +++++++++++ src/rm/RequestManagerTemplateUpdate.cc | 160 +++++++++++ src/rm/SConstruct | 9 +- src/vm_template/SConstruct | 30 +++ src/vm_template/VMTemplate.cc | 243 +++++++++++++++++ src/vm_template/VMTemplatePool.cc | 47 ++++ 24 files changed, 2017 insertions(+), 10 deletions(-) create mode 100644 include/VMTemplate.h create mode 100644 include/VMTemplatePool.h create mode 100644 src/rm/RequestManagerTemplateAllocate.cc create mode 100644 src/rm/RequestManagerTemplateDelete.cc create mode 100644 src/rm/RequestManagerTemplateInfo.cc create mode 100644 src/rm/RequestManagerTemplatePoolInfo.cc create mode 100644 src/rm/RequestManagerTemplatePublish.cc create mode 100644 src/rm/RequestManagerTemplateRemoveAttribute.cc create mode 100644 src/rm/RequestManagerTemplateUpdate.cc create mode 100644 src/vm_template/SConstruct create mode 100644 src/vm_template/VMTemplate.cc create mode 100644 src/vm_template/VMTemplatePool.cc diff --git a/SConstruct b/SConstruct index 1c3203d935..fe3d0f24e5 100644 --- a/SConstruct +++ b/SConstruct @@ -63,6 +63,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/pool', cwd+'/src/template', cwd+'/src/vm', + cwd+'/src/vm_template', cwd+'/src/vmm', cwd+'/src/lcm', cwd+'/src/tm', @@ -178,6 +179,7 @@ build_scripts=[ 'src/nebula/SConstruct', 'src/pool/SConstruct', 'src/vm/SConstruct', + 'src/vm_template/SConstruct', 'src/vmm/SConstruct', 'src/lcm/SConstruct', 'src/rm/SConstruct', diff --git a/include/AuthManager.h b/include/AuthManager.h index 307ebc29e1..1451463d94 100644 --- a/include/AuthManager.h +++ b/include/AuthManager.h @@ -293,7 +293,8 @@ public: NET, IMAGE, USER, - CLUSTER + CLUSTER, + TEMPLATE }; /** diff --git a/include/Nebula.h b/include/Nebula.h index 9019ae8ddb..854fc99762 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -25,6 +25,7 @@ #include "VirtualNetworkPool.h" #include "HostPool.h" #include "UserPool.h" +#include "VMTemplatePool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -80,6 +81,11 @@ public: return cpool; }; + VMTemplatePool * get_tpool() + { + return tpool; + }; + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -228,8 +234,9 @@ private: //Constructors and = are private to only access the class through instance // ----------------------------------------------------------------------- - Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0), - ipool(0),cpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0) + Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0), + upool(0),ipool(0),cpool(0),tpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0), + rm(0),hm(0),authm(0) { const char * nl = getenv("ONE_LOCATION"); @@ -294,6 +301,11 @@ private: delete cpool; } + if ( tpool != 0) + { + delete tpool; + } + if ( vmm != 0) { delete vmm; @@ -381,6 +393,7 @@ private: UserPool * upool; ImagePool * ipool; ClusterPool * cpool; + VMTemplatePool * tpool; // --------------------------------------------------------------- // Nebula Managers diff --git a/include/RequestManager.h b/include/RequestManager.h index 4128b20784..89daa75b7b 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -24,6 +24,7 @@ #include "VirtualNetworkPool.h" #include "ImagePool.h" #include "ClusterPool.h" +#include "VMTemplatePool.h" #include #include @@ -46,10 +47,11 @@ public: UserPool * _upool, ImagePool * _ipool, ClusterPool * _cpool, + VMTemplatePool * _tpool, int _port, string _xml_log_file) :vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool), - ipool(_ipool),cpool(_cpool),port(_port),socket_fd(-1), + ipool(_ipool),cpool(_cpool),tpool(_tpool),port(_port),socket_fd(-1), xml_log_file(_xml_log_file) { am.addListener(this); @@ -130,10 +132,15 @@ private: ImagePool * ipool; /** - * Pointer to the Image Pool, to access images + * Pointer to the Cluster Pool, to access clusters */ ClusterPool * cpool; + /** + * Pointer to the Template Pool, to access templates + */ + VMTemplatePool * tpool; + /** * Port number where the connection will be open */ @@ -501,6 +508,185 @@ private: UserPool * upool; }; + /* ---------------------------------------------------------------------- */ + /* Template Interface */ + /* ---------------------------------------------------------------------- */ + + class TemplateAllocate: public xmlrpc_c::method + { + public: + TemplateAllocate( + VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:ss"; + _help="Allocates a template in the pool"; + }; + + ~TemplateAllocate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class TemplateDelete: public xmlrpc_c::method + { + public: + TemplateDelete(VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:si"; + _help="Deletes a Template"; + }; + + ~TemplateDelete(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class TemplateInfo: public xmlrpc_c::method + { + public: + TemplateInfo(VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:si"; + _help="Returns information for a Template"; + }; + + ~TemplateInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class TemplateUpdate: public xmlrpc_c::method + { + public: + TemplateUpdate(VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:siss"; + _help="Modifies Template attribute"; + }; + + ~TemplateUpdate(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class TemplateRemoveAttribute: public xmlrpc_c::method + { + public: + TemplateRemoveAttribute(VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:sis"; + _help="Removes Template attribute"; + }; + + ~TemplateRemoveAttribute(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class TemplatePublish: public xmlrpc_c::method + { + public: + TemplatePublish(VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:sib"; + _help="Publish/Unpublish the Template"; + }; + + ~TemplatePublish(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + + class TemplatePoolInfo: public xmlrpc_c::method + { + public: + TemplatePoolInfo( + VMTemplatePool * _tpool, + UserPool * _upool): + tpool(_tpool), + upool(_upool) + { + _signature="A:sii"; + _help="Returns the template pool"; + }; + + ~TemplatePoolInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + VMTemplatePool * tpool; + UserPool * upool; + }; + /* ---------------------------------------------------------------------- */ /* Host Interface */ /* ---------------------------------------------------------------------- */ diff --git a/include/User.h b/include/User.h index c2437bc617..606684e039 100644 --- a/include/User.h +++ b/include/User.h @@ -141,7 +141,7 @@ private: * @param vaues the column values * @return 0 on success */ - int select_cb(void *nil, int num, char **values, char **names); +// int select_cb(void *nil, int num, char **values, char **names); /** * Bootstraps the database table(s) associated to the User diff --git a/include/VMTemplate.h b/include/VMTemplate.h new file mode 100644 index 0000000000..50bf19dca5 --- /dev/null +++ b/include/VMTemplate.h @@ -0,0 +1,255 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#ifndef VMTEMPLATE_H_ +#define VMTEMPLATE_H_ + +#include "PoolObjectSQL.h" +#include "VirtualMachineTemplate.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The VMTemplate class. + */ +class VMTemplate : public PoolObjectSQL +{ +public: + + /** + * Function to write a VMTemplate on an output stream + */ + friend ostream& operator<<(ostream& os, VMTemplate& u); + + /** + * Function to print the VMTemplate object into a string in XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml(string& xml) const; + + /** + * Returns true if the object is public + * @return true if the Virtual Network is public + */ + bool isPublic() + { + return (public_template == 1); + }; + + /** + * Publish or unpublish an object + * @param pub true to publish the object + * @return 0 on success + */ + bool publish(bool pub) + { + if (pub == true) + { + public_template = 1; + } + else + { + public_template = 0; + } + + return true; + }; + + // ------------------------------------------------------------------------ + // Template Contents + // ------------------------------------------------------------------------ + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + string& name, + vector& values) const + { + return template_contents->get(name,values); + }; + + /** + * Gets the values of a template attribute + * @param name of the attribute + * @param values of the attribute + * @return the number of values + */ + int get_template_attribute( + const char *name, + vector& values) const + { + string str=name; + return template_contents->get(str,values); + }; + + /** + * Gets a string based attribute + * @param name of the attribute + * @param value of the attribute (a string), will be "" if not defined + */ + void get_template_attribute( + const char * name, + string& value) const + { + string str=name; + template_contents->get(str,value); + }; + + /** + * Gets a string based attribute + * @param name of the attribute + * @param value of the attribute (an int), will be 0 if not defined + */ + void get_template_attribute( + const char * name, + int& value) const + { + string str=name; + template_contents->get(str,value); + }; + + /** + * Removes an attribute + * @param name of the attribute + */ + int remove_template_attribute(const string& name) + { + return template_contents->erase(name); + }; + + /** + * Adds a new attribute to the template (replacing it if + * already defined), the object's mutex SHOULD be locked + * @param name of the new attribute + * @param value of the new attribute + * @return 0 on success + */ + int replace_template_attribute( + const string& name, + const string& value) + { + SingleAttribute * sattr; + + template_contents->erase(name); + + sattr = new SingleAttribute(name,value); + template_contents->set(sattr); + + return 0; + }; + +private: + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class VMTemplatePool; + + // ------------------------------------------------------------------------- + // VMTemplate Attributes + // ------------------------------------------------------------------------- + + /** + * Owner's name + */ + string user_name; + + /** + * The Virtual Machine template, holds the VM attributes. + */ + VirtualMachineTemplate* template_contents; + + + /** + * Public scope of the VMTemplate + */ + int public_template; + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + /** + * Execute an INSERT or REPLACE Sql query. + * @param db The SQL DB + * @param replace Execute an INSERT or a REPLACE + * @return 0 one success + */ + int insert_replace(SqlDB *db, bool replace); + + /** + * Bootstraps the database table(s) associated to the VMTemplate + */ + static void bootstrap(SqlDB * db) + { + ostringstream oss(VMTemplate::db_bootstrap); + + db->exec(oss); + }; + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + +protected: + + // ************************************************************************* + // Constructor + // ************************************************************************* + VMTemplate(int id, int uid, string _user_name, + VirtualMachineTemplate * _template_contents); + + ~VMTemplate(); + + // ************************************************************************* + // DataBase implementation + // ************************************************************************* + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + + /** + * Writes the VMTemplate in the database. + * @param db pointer to the db + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str); + + /** + * Writes/updates the VMTemplate data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + int update(SqlDB *db) + { + return insert_replace(db, true); + }; +}; + +#endif /*VMTEMPLATE_H_*/ diff --git a/include/VMTemplatePool.h b/include/VMTemplatePool.h new file mode 100644 index 0000000000..5e9e46c1e6 --- /dev/null +++ b/include/VMTemplatePool.h @@ -0,0 +1,146 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#ifndef VMTEMPLATE_POOL_H_ +#define VMTEMPLATE_POOL_H_ + +#include "PoolSQL.h" +#include "VMTemplate.h" + +/** + * The VMTemplate Pool class. + */ +class VMTemplatePool : public PoolSQL +{ +public: + + VMTemplatePool(SqlDB * db) : PoolSQL(db, VMTemplate::table){}; + + ~VMTemplatePool(){}; + + /** + * Allocates a new object, writting it in the pool database. No memory is + * allocated for the object. + * @param uid user id (the owner of the Template) + * @param user_name Owner's user name + * @param template_contents a VM Template object + * @param oid the id assigned to the Template + * @param error_str Returns the error reason, if any + * + * @return the oid assigned to the object, -1 in case of failure + */ + int allocate(int uid, + string user_name, + VirtualMachineTemplate * template_contents, + int * oid, + string& error_str); + + /** + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param oid the object unique identifier + * @param lock locks the object if true + * + * @return a pointer to the object, 0 in case of failure + */ + VMTemplate * get(int oid, bool lock) + { + return static_cast(PoolSQL::get(oid,lock)); + }; + + /** + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param name of the object + * @param uid id of owner + * @param lock locks the object if true + * + * @return a pointer to the object, 0 in case of failure + */ + VMTemplate * get(const string& name, int uid, bool lock) + { + return static_cast(PoolSQL::get(name,uid,lock)); + }; + + /** + * Updates the object's data in the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to the object + * + * @return 0 on success. + */ + int update(VMTemplate * vm_template) + { + return vm_template->update(db); + }; + + /** + * Drops the object's data in the data base. The object mutex SHOULD be + * locked. + * @param objsql a pointer to the object + * @return 0 on success. + */ + int drop(VMTemplate * vm_template) + { + return PoolSQL::drop(vm_template); + }; + + /** + * Dumps the pool in XML format. A filter can be also added to the + * query + * @param oss the output stream to dump the pool contents + * @param where filter for the objects, defaults to all + * + * @return 0 on success + */ + int dump(ostringstream& oss, const string& where) + { + return PoolSQL::dump(oss, "TEMPLATE_POOL",VMTemplate::table,where); + }; + + /** + * Bootstraps the database table(s) associated to the pool + */ + static void bootstrap(SqlDB *_db) + { + VMTemplate::bootstrap(_db); + }; + +private: + //-------------------------------------------------------------------------- + // Configuration Attributes for Images + // ------------------------------------------------------------------------- + + // TODO + + //-------------------------------------------------------------------------- + // Pool Attributes + // ------------------------------------------------------------------------- + + // TODO + + + /** + * Factory method to produce Image objects + * @return a pointer to the new Image + */ + PoolObjectSQL * create() + { + return new VMTemplate(-1,-1,"", 0); + }; +}; + +#endif /*VMTEMPLATE_POOL_H_*/ diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index c069357f61..cedf998473 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -41,8 +41,10 @@ public: /** * Function to allocate a new VM object * @param uid user id (the owner of the VM) + * @param user_name Owner's user name * @param vm_template a VM Template object describing the VM * @param oid the id assigned to the VM (output) + * @param error_str Returns the error reason, if any * @param on_hold flag to submit on hold * @return oid on success, -1 error inserting in DB or -2 error parsing * the template diff --git a/src/authm/AuthManager.cc b/src/authm/AuthManager.cc index 094f05076a..217eca79b6 100644 --- a/src/authm/AuthManager.cc +++ b/src/authm/AuthManager.cc @@ -86,6 +86,7 @@ void AuthRequest::add_auth(Object ob, case IMAGE: oss << "IMAGE:" ; break; case USER: oss << "USER:" ; break; case CLUSTER: oss << "CLUSTER:" ; break; + case TEMPLATE: oss << "TEMPLATE:" ; break; } if (op == CREATE) //encode the ob_id, it is a template diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index d05290d690..40c3db841f 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -235,6 +235,7 @@ void Nebula::start() UserPool::bootstrap(db); ImagePool::bootstrap(db); ClusterPool::bootstrap(db); + VMTemplatePool::bootstrap(db); } catch (exception&) { @@ -276,6 +277,8 @@ void Nebula::start() default_device_prefix); cpool = new ClusterPool(db); + + tpool = new VMTemplatePool(db); } catch (exception&) { @@ -442,6 +445,7 @@ void Nebula::start() upool, ipool, cpool, + tpool, rm_port, log_location + "one_xmlrpc.log"); } diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 90c3d33dfd..3cd71f38a4 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -50,6 +50,7 @@ env.Prepend(LIBS=[ 'nebula_host', 'nebula_vnm', 'nebula_vm', + 'nebula_vmtemplate', 'nebula_common', 'nebula_sql', 'nebula_log', diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 10606df497..9be461eca2 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -233,7 +233,28 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_pool_info(new RequestManager::VirtualMachinePoolInfo(vmpool,upool)); - + + xmlrpc_c::methodPtr template_allocate(new + RequestManager::TemplateAllocate(tpool,upool)); + + xmlrpc_c::methodPtr template_delete(new + RequestManager::TemplateDelete(tpool, upool)); + + xmlrpc_c::methodPtr template_info(new + RequestManager::TemplateInfo(tpool, upool)); + + xmlrpc_c::methodPtr template_update(new + RequestManager::TemplateUpdate(tpool, upool)); + + xmlrpc_c::methodPtr template_rm_attribute(new + RequestManager::TemplateRemoveAttribute(tpool, upool)); + + xmlrpc_c::methodPtr template_publish(new + RequestManager::TemplatePublish(tpool, upool)); + + xmlrpc_c::methodPtr template_pool_info(new + RequestManager::TemplatePoolInfo(tpool,upool)); + xmlrpc_c::methodPtr host_allocate(new RequestManager::HostAllocate(hpool,upool)); @@ -340,7 +361,12 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk); RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info); - + + /* VM Template related methods*/ + + RequestManagerRegistry.addMethod("one.template.allocate",template_allocate); + RequestManagerRegistry.addMethod("one.templatepool.info",template_pool_info); + /* Host related methods*/ RequestManagerRegistry.addMethod("one.host.allocate", host_allocate); diff --git a/src/rm/RequestManagerImagePoolInfo.cc b/src/rm/RequestManagerImagePoolInfo.cc index a852da53bb..a55d07e230 100644 --- a/src/rm/RequestManagerImagePoolInfo.cc +++ b/src/rm/RequestManagerImagePoolInfo.cc @@ -65,7 +65,6 @@ void RequestManager::ImagePoolInfo::execute( switch(filter_flag) { case -2: - // TODO define authentication bug #278 break; case -1: where_string << "UID=" << rc << " OR PUBLIC=1"; diff --git a/src/rm/RequestManagerTemplateAllocate.cc b/src/rm/RequestManagerTemplateAllocate.cc new file mode 100644 index 0000000000..6ae07c1a44 --- /dev/null +++ b/src/rm/RequestManagerTemplateAllocate.cc @@ -0,0 +1,183 @@ +/* -------------------------------------------------------------------------- */ +/* 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" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void RequestManager::TemplateAllocate::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + string str_template; + string error_str; + string user_name; + + const string method_name = "TemplateAllocate"; + + int oid, uid; + int rc; + + ostringstream oss; + + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + VirtualMachineTemplate * template_contents; + User * user; + char * error_msg = 0; + + + NebulaLog::log("ReM",Log::DEBUG,"TemplateAllocate invoked"); + + session = xmlrpc_c::value_string(paramList.getString(0)); + str_template = xmlrpc_c::value_string(paramList.getString(1)); + str_template += "\n"; + + //-------------------------------------------------------------------------- + // Authenticate the user + //-------------------------------------------------------------------------- + uid = TemplateAllocate::upool->authenticate(session); + + if (uid == -1) + { + goto error_authenticate; + } + + //-------------------------------------------------------------------------- + // Check the template syntax + //-------------------------------------------------------------------------- + template_contents = new VirtualMachineTemplate; + + rc = template_contents->parse(str_template,&error_msg); + + if ( rc != 0 ) + { + goto error_parse; + } + + //-------------------------------------------------------------------------- + // Authorize this request + //-------------------------------------------------------------------------- + if ( uid != 0 ) + { + AuthRequest ar(uid); + string t64; + + ar.add_auth(AuthRequest::TEMPLATE, + template_contents->to_xml(t64), + AuthRequest::CREATE, + uid, + false); + + if (UserPool::authorize(ar) == -1) + { + goto error_authorize; + } + } + + //-------------------------------------------------------------------------- + // Get the User Name + //-------------------------------------------------------------------------- + + user = TemplateAllocate::upool->get(uid,true); + + if ( user == 0 ) + { + goto error_user_get; + } + + user_name = user->get_name(); + + user->unlock(); + + //-------------------------------------------------------------------------- + // Allocate the VMTemplate + //-------------------------------------------------------------------------- + rc = TemplateAllocate::tpool->allocate(uid, + user_name, + template_contents, + &oid, + error_str); + + if ( rc < 0 ) + { + goto error_allocate; + } + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_int(oid)); + + // 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_user_get: + oss.str(get_error(method_name, "USER", uid)); + + delete template_contents; + goto error_common; + +error_authenticate: + oss.str(authenticate_error(method_name)); + goto error_common; + +error_authorize: + oss.str(authorization_error(method_name, "CREATE", "TEMPLATE", uid, -1)); + delete template_contents; + goto error_common; + +error_parse: + oss << action_error(method_name, "PARSE", "VM TEMPLATE",-2,rc); + if (error_msg != 0) + { + oss << ". Reason: " << error_msg; + free(error_msg); + } + + delete template_contents; + goto error_common; + +error_allocate: + oss << action_error(method_name, "CREATE", "TEMPLATE", -2, 0); + oss << " " << error_str; + 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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerTemplateDelete.cc b/src/rm/RequestManagerTemplateDelete.cc new file mode 100644 index 0000000000..b222cc2883 --- /dev/null +++ b/src/rm/RequestManagerTemplateDelete.cc @@ -0,0 +1,153 @@ +/* -------------------------------------------------------------------------- */ +/* 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::TemplateDelete::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + + int oid; + int uid; + int rc; + + int owner; + bool is_public; + + VMTemplate * vm_template; + + ostringstream oss; + + const string method_name = "TemplateDelete"; + + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + + NebulaLog::log("ReM",Log::DEBUG,"TemplateDelete invoked"); + + session = xmlrpc_c::value_string(paramList.getString(0)); + oid = xmlrpc_c::value_int (paramList.getInt(1)); + + + // First, we need to authenticate the user + uid = TemplateDelete::upool->authenticate(session); + + if ( uid == -1 ) + { + goto error_authenticate; + } + + // Get template from the pool + vm_template = TemplateDelete::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + owner = vm_template->get_uid(); + is_public = vm_template->isPublic(); + + vm_template->unlock(); + + //Authorize the operation + if ( uid != 0 ) // uid == 0 means oneadmin + { + AuthRequest ar(uid); + + ar.add_auth(AuthRequest::TEMPLATE, + oid, + AuthRequest::DELETE, + owner, + is_public); + + if (UserPool::authorize(ar) == -1) + { + goto error_authorize; + } + } + + // Get template from the pool + vm_template = TemplateDelete::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + rc = TemplateDelete::tpool->drop(vm_template); + + vm_template->unlock(); + + if ( rc < 0 ) + { + goto error_delete; + } + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_int(oid)); + + // 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, "TEMPLATE", oid)); + goto error_common; + +error_authorize: + oss.str(authorization_error(method_name, "DELETE", "TEMPLATE", uid, oid)); + goto error_common; + +error_delete: + oss.str(action_error(method_name, "DELETE", "TEMPLATE", oid, rc)); + vm_template->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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerTemplateInfo.cc b/src/rm/RequestManagerTemplateInfo.cc new file mode 100644 index 0000000000..8567080f42 --- /dev/null +++ b/src/rm/RequestManagerTemplateInfo.cc @@ -0,0 +1,107 @@ +/* -------------------------------------------------------------------------- */ +/* 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 "AuthManager.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void RequestManager::TemplateInfo::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + + int oid; + int uid; // owner user id + int rc; // Requesting user id + VMTemplate * vm_template; + + ostringstream oss; + + const string method_name = "TemplateInfo"; + + /* -- RPC specific vars -- */ + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + NebulaLog::log("ReM",Log::DEBUG,"TemplateInfo method invoked"); + + // Get the parameters + session = xmlrpc_c::value_string(paramList.getString(0)); + oid = xmlrpc_c::value_int (paramList.getInt(1)); + + // Get template from the pool + vm_template = TemplateInfo::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + uid = vm_template->get_uid(); + + // Check if it is a valid user + rc = TemplateInfo::upool->authenticate(session); + + if ( rc == -1 ) + { + goto error_authenticate; + } + + oss << *vm_template; + + vm_template->unlock(); + + // All nice, return the host info to the client + arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS + arrayData.push_back(xmlrpc_c::value_string(oss.str())); + + // 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_get: + oss.str(get_error(method_name, "TEMPLATE", oid)); + goto error_common; + +error_authenticate: + oss.str(authenticate_error(method_name)); + vm_template->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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerTemplatePoolInfo.cc b/src/rm/RequestManagerTemplatePoolInfo.cc new file mode 100644 index 0000000000..6a16807202 --- /dev/null +++ b/src/rm/RequestManagerTemplatePoolInfo.cc @@ -0,0 +1,124 @@ +/* -------------------------------------------------------------------------- */ +/* 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" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void RequestManager::TemplatePoolInfo::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + + ostringstream oss; + ostringstream where_string; + + int rc; + int filter_flag; + + const string method_name = "TemplatePoolInfo"; + + /* -- RPC specific vars -- */ + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + NebulaLog::log("ReM",Log::DEBUG,"TemplatePoolInfo method invoked"); + + // Get the parameters + session = xmlrpc_c::value_string(paramList.getString(0)); + filter_flag = xmlrpc_c::value_int(paramList.getInt(1)); + + // Check if it is a valid user + rc = TemplatePoolInfo::upool->authenticate(session); + + if ( rc == -1 ) + { + goto error_authenticate; + } + + /** Filter flag meaning table + * -2 :: All Templates + * -1 :: User's Templates AND public templates belonging to any user + * >= 0 :: UID User's Templates + **/ + if ( filter_flag < -2 ) + { + goto error_filter_flag; + } + + switch(filter_flag) + { + case -2: + break; + case -1: + where_string << "UID=" << rc << " OR PUBLIC=1"; + break; + default: + where_string << "UID=" << filter_flag; + } + + // Call the template pool dump + rc = TemplatePoolInfo::tpool->dump(oss,where_string.str()); + + if ( rc != 0 ) + { + goto error_dump; + } + + // All nice, return pool info to the client + arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS + arrayData.push_back(xmlrpc_c::value_string(oss.str())); + + arrayresult = new xmlrpc_c::value_array(arrayData); + + // Copy arrayresult into retval mem space + *retval = *arrayresult; + + // and get rid of the original + delete arrayresult; + + return; + +error_authenticate: + oss.str(authenticate_error(method_name)); + goto error_common; + +error_filter_flag: + oss << "Incorrect filter_flag, must be >= -2."; + goto error_common; + +error_dump: + oss.str(get_error(method_name, "TEMPLATE", -1)); + 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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerTemplatePublish.cc b/src/rm/RequestManagerTemplatePublish.cc new file mode 100644 index 0000000000..3e908c3ae9 --- /dev/null +++ b/src/rm/RequestManagerTemplatePublish.cc @@ -0,0 +1,158 @@ +/* -------------------------------------------------------------------------- */ +/* 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::TemplatePublish::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + + int oid; + bool publish_flag; + int uid; + + int owner; + bool is_public; + + VMTemplate * vm_template; + + bool response; + + ostringstream oss; + + const string method_name = "TemplatePublish"; + + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + + NebulaLog::log("ReM",Log::DEBUG,"TemplatePublish invoked"); + + session = xmlrpc_c::value_string (paramList.getString(0)); + oid = xmlrpc_c::value_int (paramList.getInt(1)); + publish_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2)); + + // First, we need to authenticate the user + uid = TemplatePublish::upool->authenticate(session); + + if ( uid == -1 ) + { + goto error_authenticate; + } + + // Get template from the pool + vm_template = TemplatePublish::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + owner = vm_template->get_uid(); + is_public = vm_template->isPublic(); + + vm_template->unlock(); + + //Authorize the operation + if ( uid != 0 ) // uid == 0 means oneadmin + { + AuthRequest ar(uid); + + ar.add_auth(AuthRequest::TEMPLATE, + oid, + AuthRequest::MANAGE, + owner, + is_public); + + if (UserPool::authorize(ar) == -1) + { + goto error_authorize; + } + } + + // Get the template locked again + vm_template = TemplatePublish::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + response = vm_template->publish(publish_flag); + + if (!response) + { + vm_template->unlock(); + + goto error_publish; + } + + TemplatePublish::tpool->update(vm_template); + + vm_template->unlock(); + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_int(oid)); + + // 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, "TEMPLATE", oid)); + goto error_common; + +error_authorize: + oss.str(authorization_error(method_name, "MANAGE", "TEMPLATE", uid, oid)); + goto error_common; + +error_publish: + oss.str(action_error(method_name, "MANAGE", "TEMPLATE", oid, 0)); + 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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerTemplateRemoveAttribute.cc b/src/rm/RequestManagerTemplateRemoveAttribute.cc new file mode 100644 index 0000000000..c23737fdaa --- /dev/null +++ b/src/rm/RequestManagerTemplateRemoveAttribute.cc @@ -0,0 +1,159 @@ +/* -------------------------------------------------------------------------- */ +/* 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::TemplateRemoveAttribute::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + string name; + + int oid; + int uid; + int rc; + + int owner; + bool is_public; + + VMTemplate * vm_template; + + ostringstream oss; + + const string method_name = "TemplateRemoveAttribute"; + + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + + NebulaLog::log("ReM",Log::DEBUG,"TemplateRemoveAttribute invoked"); + + session = xmlrpc_c::value_string(paramList.getString(0)); + oid = xmlrpc_c::value_int (paramList.getInt(1)); + name = xmlrpc_c::value_string(paramList.getString(2)); + + // First, we need to authenticate the user + uid = TemplateRemoveAttribute::upool->authenticate(session); + + if ( uid == -1 ) + { + goto error_authenticate; + } + + // Get object from the pool + vm_template = TemplateRemoveAttribute::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + owner = vm_template->get_uid(); + is_public = vm_template->isPublic(); + + vm_template->unlock(); + + //Authorize the operation + if ( uid != 0 ) // uid == 0 means oneadmin + { + AuthRequest ar(uid); + + ar.add_auth(AuthRequest::TEMPLATE, + oid, + AuthRequest::MANAGE, + owner, + is_public); + + if (UserPool::authorize(ar) == -1) + { + goto error_authorize; + } + } + + // Get object from the pool + vm_template = TemplateRemoveAttribute::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + rc = vm_template->remove_template_attribute(name); + + if(rc == 0) + { + rc = TemplateRemoveAttribute::tpool->update(vm_template); + } + + if ( rc < 0 ) + { + goto error_remove_attribute; + } + + vm_template->unlock(); + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_int(oid)); + + // 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, "TEMPLATE", oid)); + goto error_common; + +error_authorize: + oss.str(authorization_error(method_name, "MANAGE", "TEMPLATE", uid, oid)); + goto error_common; + +error_remove_attribute: + oss.str(action_error(method_name, "PUBLISH/UNPUBLISH", "TEMPLATE", oid, rc)); + vm_template->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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerTemplateUpdate.cc b/src/rm/RequestManagerTemplateUpdate.cc new file mode 100644 index 0000000000..86e210a718 --- /dev/null +++ b/src/rm/RequestManagerTemplateUpdate.cc @@ -0,0 +1,160 @@ +/* -------------------------------------------------------------------------- */ +/* 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::TemplateUpdate::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + + int oid; + int uid; + string name; + string value; + int rc; + + int owner; + bool is_public; + + VMTemplate * vm_template; + + ostringstream oss; + + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + const string method_name = "TemplateUpdate"; + + NebulaLog::log("ReM",Log::DEBUG,"TemplateUpdate invoked"); + + session = xmlrpc_c::value_string(paramList.getString(0)); + oid = xmlrpc_c::value_int (paramList.getInt(1)); + name = xmlrpc_c::value_string(paramList.getString(2)); + value = xmlrpc_c::value_string(paramList.getString(3)); + + // First, we need to authenticate the user + uid = TemplateUpdate::upool->authenticate(session); + + if ( uid == -1 ) + { + goto error_authenticate; + } + + // Get template from the pool + vm_template = TemplateUpdate::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + owner = vm_template->get_uid(); + is_public = vm_template->isPublic(); + + vm_template->unlock(); + + //Authorize the operation + if ( uid != 0 ) // uid == 0 means oneadmin + { + AuthRequest ar(uid); + + ar.add_auth(AuthRequest::TEMPLATE, + oid, + AuthRequest::MANAGE, + owner, + is_public); + + if (UserPool::authorize(ar) == -1) + { + goto error_authorize; + } + } + + // Get template from the pool + vm_template = TemplateUpdate::tpool->get(oid,true); + + if ( vm_template == 0 ) + { + goto error_get; + } + + rc = vm_template->replace_template_attribute(name, value); + + if(rc == 0) + { + rc = TemplateUpdate::tpool->update(vm_template); + } + + if ( rc < 0 ) + { + goto error_update; + } + + vm_template->unlock(); + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_int(oid)); + + // 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, "TEMPLATE", oid)); + goto error_common; + +error_authorize: + oss.str(authorization_error(method_name, "MANAGE", "TEMPLATE", uid, oid)); + goto error_common; + +error_update: + oss.str(action_error(method_name, "UPDATE ATTRIBUTE", "TEMPLATE", oid, rc)); + vm_template->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; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/SConstruct b/src/rm/SConstruct index 2bdab14e9f..11c674e9ea 100644 --- a/src/rm/SConstruct +++ b/src/rm/SConstruct @@ -61,7 +61,14 @@ source_files=[ 'RequestManagerUserDelete.cc', 'RequestManagerUserChangePassword.cc', 'RequestManagerUserInfo.cc', - 'RequestManagerUserPoolInfo.cc' + 'RequestManagerUserPoolInfo.cc', + 'RequestManagerTemplateAllocate.cc', + 'RequestManagerTemplateDelete.cc', + 'RequestManagerTemplateInfo.cc', + 'RequestManagerTemplateUpdate.cc', + 'RequestManagerTemplateRemoveAttribute.cc', + 'RequestManagerTemplatePublish.cc', + 'RequestManagerTemplatePoolInfo.cc', ] # Build library diff --git a/src/vm_template/SConstruct b/src/vm_template/SConstruct new file mode 100644 index 0000000000..7705f4e7ff --- /dev/null +++ b/src/vm_template/SConstruct @@ -0,0 +1,30 @@ +# SConstruct for src/vm + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +Import('env') + +lib_name='nebula_vmtemplate' + +# Sources to generate the library +source_files=[ + 'VMTemplate.cc', + 'VMTemplatePool.cc' +] + +# Build library +env.StaticLibrary(lib_name, source_files) diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc new file mode 100644 index 0000000000..92b1ef540a --- /dev/null +++ b/src/vm_template/VMTemplate.cc @@ -0,0 +1,243 @@ +/* ------------------------------------------------------------------------ */ +/* 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 "VMTemplate.h" + +#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) + + +/* ************************************************************************ */ +/* VMTemplate :: Constructor/Destructor */ +/* ************************************************************************ */ + +VMTemplate::VMTemplate(int id, + int _uid, + string _user_name, + VirtualMachineTemplate * _template_contents): + PoolObjectSQL(id,"",_uid,table), + user_name(_user_name) +{ + if (_template_contents != 0) + { + template_contents = _template_contents; + } + else + { + template_contents = new VirtualMachineTemplate; + } +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +VMTemplate::~VMTemplate() +{ + if ( template_contents != 0 ) + { + delete template_contents; + } +} + +/* ************************************************************************ */ +/* VMTemplate :: Database Access Functions */ +/* ************************************************************************ */ + +const char * VMTemplate::table = "template_pool"; + +const char * VMTemplate::db_names = "oid, name, body, uid, public"; + +const char * VMTemplate::db_bootstrap = + "CREATE TABLE IF NOT EXISTS template_pool (oid INTEGER PRIMARY KEY, " + "name VARCHAR(256), body TEXT, uid INTEGER, public INTEGER, UNIQUE(name))"; + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int VMTemplate::insert(SqlDB *db, string& error_str) +{ + int rc; + ostringstream oss; + string public_attr; + + + // --------------------------------------------------------------------- + // Check default attributes + // --------------------------------------------------------------------- + + // ------------ NAME -------------------- + get_template_attribute("NAME", name); + + if ( name.empty() == true ) + { + oss.str(""); + oss << "template-" << oid; + name = oss.str(); + } + + // ------------ PUBLIC -------------------- + get_template_attribute("PUBLIC", public_attr); + + template_contents->erase("PUBLIC"); + + TO_UPPER(public_attr); + + public_template = (public_attr == "YES"); + + // ------------------------------------------------------------------------ + // Insert the Template + // ------------------------------------------------------------------------ + + rc = insert_replace(db, false); + + if ( rc != 0 ) + { + error_str = "Error inserting Template in DB."; + } + + return rc; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int VMTemplate::insert_replace(SqlDB *db, bool replace) +{ + ostringstream oss; + + int rc; + string xml_body; + + char * sql_name; + char * sql_xml; + + // Update the Object + + sql_name = db->escape_str(name.c_str()); + + if ( sql_name == 0 ) + { + goto error_name; + } + + sql_xml = db->escape_str(to_xml(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + if(replace) + { + oss << "REPLACE"; + } + else + { + oss << "INSERT"; + } + + // Construct the SQL statement to Insert or Replace + + oss <<" INTO "<exec(oss); + + db->free_str(sql_name); + db->free_str(sql_xml); + + return rc; + +error_body: + db->free_str(sql_name); +error_name: + return -1; +} + +/* ************************************************************************ */ +/* VMTemplate :: Misc */ +/* ************************************************************************ */ + +ostream& operator<<(ostream& os, VMTemplate& vmTemplate) +{ + string xml_str; + + os << vmTemplate.to_xml(xml_str); + + return os; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +string& VMTemplate::to_xml(string& xml) const +{ + ostringstream oss; + string template_xml; + + oss << "" + << "" << oid << "" + << "" << uid << "" + << "" << user_name << "" + << "" << name << "" + << "" << public_template << "" + << template_contents->to_xml(template_xml) + << ""; + + xml = oss.str(); + + return xml; +} + +/* ------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------ */ + +int VMTemplate::from_xml(const string& xml) +{ + vector content; + int rc = 0; + + // Initialize the internal XML object + update_from_str(xml); + + // Get class base attributes + rc += xpath(oid, "/VMTEMPLATE/ID", -1); + rc += xpath(uid, "/VMTEMPLATE/UID", -1); + rc += xpath(user_name, "/VMTEMPLATE/USERNAME", "not_found"); + rc += xpath(name, "/VMTEMPLATE/NAME", "not_found"); + rc += xpath(public_template,"/VMTEMPLATE/PUBLIC", 0); + + // Get associated classes + ObjectXML::get_nodes("/VMTEMPLATE/TEMPLATE", content); + + if( content.size() < 1 ) + { + return -1; + } + + // Template contents + rc += template_contents->from_xml_node(content[0]); + + if (rc != 0) + { + return -1; + } + + return 0; +} diff --git a/src/vm_template/VMTemplatePool.cc b/src/vm_template/VMTemplatePool.cc new file mode 100644 index 0000000000..aaa1feeb8e --- /dev/null +++ b/src/vm_template/VMTemplatePool.cc @@ -0,0 +1,47 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +/* ************************************************************************** */ +/* Template Pool */ +/* ************************************************************************** */ + +#include "VMTemplatePool.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VMTemplatePool::allocate ( + int uid, + string user_name, + VirtualMachineTemplate * template_contents, + int * oid, + string& error_str) +{ + VMTemplate * vm_template; + + // ------------------------------------------------------------------------ + // Build a new VMTemplate object + // ------------------------------------------------------------------------ + vm_template = new VMTemplate(-1, uid, user_name, template_contents); + + // ------------------------------------------------------------------------ + // Insert the Object in the pool + // ------------------------------------------------------------------------ + + *oid = PoolSQL::allocate(vm_template, error_str); + + return *oid; +} From 085d86e12ecb223a51d9156fe17f95d662ccc1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 31 Mar 2011 12:14:12 +0200 Subject: [PATCH 02/16] Feature #487: Fix tests --- include/test/NebulaTest.h | 8 +++++++- src/cluster/test/SConstruct | 2 +- src/host/test/SConstruct | 1 + src/lcm/test/SConstruct | 1 + src/test/Nebula.cc | 12 +++++++++++- src/test/NebulaTest.cc | 7 +++++++ 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/test/NebulaTest.h b/include/test/NebulaTest.h index 18589b0da4..b8050efd45 100644 --- a/include/test/NebulaTest.h +++ b/include/test/NebulaTest.h @@ -26,6 +26,7 @@ #include "HostPool.h" #include "UserPool.h" #include "ClusterPool.h" +#include "VMTemplatePool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -42,7 +43,8 @@ protected: NebulaTest():mysql(false), need_host_pool(false), need_vm_pool(false), need_vnet_pool(false), need_image_pool(false), - need_user_pool(false), need_cluster_pool(false),need_vmm(false), + need_user_pool(false), need_cluster_pool(false), + need_template_pool(false),need_vmm(false), need_im(false), need_tm(false), need_lcm(false), need_dm(false), need_rm(false), need_hm(false), @@ -62,6 +64,7 @@ public: bool need_image_pool; bool need_user_pool; bool need_cluster_pool; + bool need_template_pool; bool need_vmm; bool need_im; @@ -98,6 +101,8 @@ public: virtual ClusterPool* create_cpool(SqlDB* db); + virtual VMTemplatePool* create_tpool(SqlDB* db); + // ------------------------------------------------------------------------ // Managers // ------------------------------------------------------------------------ @@ -127,6 +132,7 @@ public: UserPool * upool, ImagePool * ipool, ClusterPool * cpool, + VMTemplatePool * tpool, string log_file); virtual HookManager* create_hm(VirtualMachinePool * vmpool); diff --git a/src/cluster/test/SConstruct b/src/cluster/test/SConstruct index b55dee66c1..3f31210fa3 100644 --- a/src/cluster/test/SConstruct +++ b/src/cluster/test/SConstruct @@ -26,7 +26,6 @@ env.Prepend(LIBS=[ 'nebula_common', 'nebula_sql', - ### TODO: delete not needed 'nebula_core_test', 'nebula_host', @@ -40,6 +39,7 @@ env.Prepend(LIBS=[ 'nebula_mad', 'nebula_template', 'nebula_vm', + 'nebula_vmtemplate', 'nebula_vnm', 'nebula_image', 'nebula_pool', diff --git a/src/host/test/SConstruct b/src/host/test/SConstruct index 1c44bf24bb..c839508487 100644 --- a/src/host/test/SConstruct +++ b/src/host/test/SConstruct @@ -31,6 +31,7 @@ env.Prepend(LIBS=[ 'nebula_mad', 'nebula_template', 'nebula_vm', + 'nebula_vmtemplate', 'nebula_vnm', 'nebula_image', 'nebula_pool', diff --git a/src/lcm/test/SConstruct b/src/lcm/test/SConstruct index 21f5bea0c7..5fbcbc1687 100644 --- a/src/lcm/test/SConstruct +++ b/src/lcm/test/SConstruct @@ -30,6 +30,7 @@ env.Prepend(LIBS=[ 'nebula_mad', 'nebula_template', 'nebula_vm', + 'nebula_vmtemplate', 'nebula_vnm', 'nebula_image', 'nebula_pool', diff --git a/src/test/Nebula.cc b/src/test/Nebula.cc index 7fbf0642b3..74a8d25941 100644 --- a/src/test/Nebula.cc +++ b/src/test/Nebula.cc @@ -82,6 +82,11 @@ void Nebula::start() delete cpool; } + if ( tpool != 0) + { + delete tpool; + } + if ( vmm != 0) { delete vmm; @@ -214,6 +219,11 @@ void Nebula::start() { cpool = tester->create_cpool(db); } + + if (tester->need_template_pool) + { + tpool = tester->create_tpool(db); + } } catch (exception&) { @@ -358,7 +368,7 @@ void Nebula::start() { try { - rm = tester->create_rm(vmpool,hpool,vnpool,upool,ipool,cpool, + rm = tester->create_rm(vmpool,hpool,vnpool,upool,ipool,cpool,tpool, log_location + "one_xmlrpc.log"); } catch (bad_alloc&) diff --git a/src/test/NebulaTest.cc b/src/test/NebulaTest.cc index d953962b5e..fb17182748 100644 --- a/src/test/NebulaTest.cc +++ b/src/test/NebulaTest.cc @@ -54,6 +54,11 @@ ClusterPool* NebulaTest::create_cpool(SqlDB* db) return new ClusterPool(db); } +VMTemplatePool* NebulaTest::create_tpool(SqlDB* db) +{ + return new VMTemplatePool(db); +} + // ----------------------------------------------------------- // Managers // ----------------------------------------------------------- @@ -112,6 +117,7 @@ RequestManager* NebulaTest::create_rm( UserPool * upool, ImagePool * ipool, ClusterPool * cpool, + VMTemplatePool * tpool, string log_file) { int rm_port = 2633; @@ -122,6 +128,7 @@ RequestManager* NebulaTest::create_rm( upool, ipool, cpool, + tpool, rm_port, log_file); } From 77f861a2b55481b79f600c3c34bb2d25247fae9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 31 Mar 2011 16:34:08 +0200 Subject: [PATCH 03/16] Feature #487: New command onetemplate, with basic operations --- install.sh | 7 +- src/cli/client_utilities.rb | 4 + src/cli/onetemplate | 419 ++++++++++++++++++++++++ src/oca/ruby/OpenNebula.rb | 2 + src/oca/ruby/OpenNebula/Template.rb | 126 +++++++ src/oca/ruby/OpenNebula/TemplatePool.rb | 55 ++++ src/rm/RequestManager.cc | 6 + 7 files changed, 618 insertions(+), 1 deletion(-) create mode 100755 src/cli/onetemplate create mode 100644 src/oca/ruby/OpenNebula/Template.rb create mode 100644 src/oca/ruby/OpenNebula/TemplatePool.rb diff --git a/install.sh b/install.sh index 277d835e6f..92f2791c11 100755 --- a/install.sh +++ b/install.sh @@ -352,6 +352,7 @@ BIN_FILES="src/nebula/oned \ src/cli/oneuser \ src/cli/oneimage \ src/cli/onecluster \ + src/cli/onetemplate \ share/scripts/one \ src/authm_mad/oneauth" @@ -397,6 +398,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \ src/oca/ruby/OpenNebula/ImageRepository.rb \ src/oca/ruby/OpenNebula/Cluster.rb \ src/oca/ruby/OpenNebula/ClusterPool.rb \ + src/oca/ruby/OpenNebula/Template.rb \ + src/oca/ruby/OpenNebula/TemplatePool.rb \ src/oca/ruby/OpenNebula/XMLUtils.rb" #------------------------------------------------------------------------------- @@ -698,7 +701,8 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/onevnet \ src/cli/oneuser \ src/cli/oneimage \ - src/cli/onecluster" + src/cli/onecluster \ + src/cli/onetemplate" #----------------------------------------------------------------------------- # Sunstone files @@ -799,6 +803,7 @@ MAN_FILES="share/man/oneauth.8.gz \ share/man/oneuser.8.gz \ share/man/onevm.8.gz \ share/man/onevnet.8.gz \ + share/man/onetemplate.8.gz \ share/man/econe-describe-images.8.gz \ share/man/econe-describe-instances.8.gz \ share/man/econe-register.8.gz \ diff --git a/src/cli/client_utilities.rb b/src/cli/client_utilities.rb index b177db2c68..f2f96312d0 100644 --- a/src/cli/client_utilities.rb +++ b/src/cli/client_utilities.rb @@ -313,6 +313,10 @@ def get_cluster_id(name) get_entity_id(name, OpenNebula::ClusterPool) end +def get_template_id(name) + get_entity_id(name, OpenNebula::TemplatePool) +end + def str_running_time(data) stime=Time.at(data["STIME"].to_i) if data["ETIME"]=="0" diff --git a/src/cli/onetemplate b/src/cli/onetemplate new file mode 100755 index 0000000000..627a0f177d --- /dev/null +++ b/src/cli/onetemplate @@ -0,0 +1,419 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" +end + +$: << RUBY_LIB_LOCATION + + +require 'OpenNebula' +require 'CommandManager' +require 'client_utilities' +require 'command_parse' + +ShowTableTemplate={ + :id => { + :name => "ID", + :desc => "ONE identifier for the Template", + :size => 4, + :proc => lambda {|d,e| d.id } + }, + :user=> { + :name => "USER", + :desc => "Name of the owner", + :size => 8, + :proc => lambda {|d,e| + d["USERNAME"] + } + }, + :name => { + :name => "NAME", + :desc => "Name of the Template", + :size => 20, + :proc => lambda {|d,e| + d.name + } + }, + :regtime => { + :name => "REGTIME", + :desc => "Registration time of the Template", + :size => 20, + :proc => lambda {|d,e| + str_register_time(d) + } + }, + :public => { + :name => "PUBLIC", + :desc => "Whether the Template is public or not", + :size => 3, + :proc => lambda {|d,e| + if d["PUBLIC"].to_i == 1 then "Yes" else "No" end} + }, + :runningvms => { + :name => "#VMS", + :desc => "Number of VMs currently running from this Template", + :size => 5, + :proc => lambda {|d,e| d['RUNNING_VMS'] } + }, + + :default => [:id, :user, :name, :regtime, :public, :runningvms] +} + + + +class TemplateShow + + def initialize(client, filter_flag="-2") + @templatepool=OpenNebula::TemplatePool.new(client, filter_flag.to_i) + @table=ShowTable.new(ShowTableTemplate) + end + + def header_template_small + scr_bold + scr_underline + print @table.header_str + scr_restore + puts "" + end + + def top(options=nil) + delay=1 + delay=options[:delay] if options && options[:delay] + + result=nil + + begin + while true + scr_cls + scr_move(0,0) + result=list_short(options) + sleep delay + end + rescue Exception + end + result + end + + def list_short(options=nil) + res=@templatepool.info() + + if options + @table.columns=options[:columns] if options[:columns] + end + + if OpenNebula.is_error?(res) + result=res + puts res.message + exit -1 + else + + if options[:filter_flag] + objs=@templatepool.select{|element| + element['USERNAME']==options[:filter_flag] } + else + objs=@templatepool + end + + result=[true, ""] + header_template_small + + if options + puts @table.data_str(objs, options) + else + puts @table.data_str(objs) + end + + result + end + end +end + + +########################## +## COMMAND LINE PARSING ## +########################## + +class OneTemplateParse < CommandParse + + COMMANDS_HELP=<<-EOT + +Description: + +This command enables the user to manage templates. + + +Commands: + +* create (Registers a Template from a template file) + onetemplate create + + file is a file name where the Template description is located + +* addattr (Add a new Template attribute) + onetemplate addattr + +* update (Modifies a Template attribute) + onetemplate update + +* rmattr (Deletes a Template attribute) + onetemplate rmattr + +* publish (Publish a Template) + onetemplate publish + +* unpublish (Unpublish an Template) + onetemplate unpublish + +* list (Shows Templates in the pool) + onetemplate list + + where filter_flag can be + a, all --> all the known Templates + m, mine --> the Templates belonging to the user in ONE_AUTH + and all the Public Templates + uid --> Templates of the user identified by this uid + user --> Templates of the user identified by the username + +* top (Lists Templates continuously) + onetemplate top + +* show (Gets information about an specific Template) + onetemplate show + +* delete (Deletes a Template) + onetemplate delete + +EOT + + def text_commands + COMMANDS_HELP + end + + def text_command_name + "onetemplate" + end + + def list_options + table=ShowTable.new(ShowTableTemplate) + table.print_help + end +end + + +def get_user_flags + ops=Hash.new + if ARGV[0] + case ARGV[0] + when "a", "all" + ops[:filter_user]="-2" + when "m", "mine" + ops[:filter_user]="-1" + else + if !ARGV[0].match(/^[0123456789]+$/) + ops[:filter_user]="-2" + ops[:filter_flag]=ARGV[0] + else + ops[:filter_user]=ARGV[0] + end + end + else + ops[:filter_user]="-2" + end + + ops +end + +def get_template(template_path) + begin + template = File.read(ARGV[0]) + rescue + result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}") + end + + if !is_successful?(result) + puts result.message + exit -1 + end + + return template +end + +onetemplate_opts=OneTemplateParse.new +onetemplate_opts.parse(ARGV) +ops=onetemplate_opts.options + +result=[false, "Unknown error"] + +command=ARGV.shift + +case command +when "create", "register", "add" + check_parameters("create", 1) + template_contents = get_template(ARGV[0]) + + template = OpenNebula::Template.new(OpenNebula::Template.build_xml, get_one_client) + + result=template.allocate(template_contents) + if !OpenNebula.is_error?(result) + puts "ID: " + vn.id.to_s if ops[:verbose] + exit 0 + end + +when "addattr" + check_parameters("update", 3) + template_id = get_template_id(ARGV[0]) + + template = OpenNebula::Template.new_with_id(template_id, get_one_client) + + result = template.update(ARGV[1],ARGV[2]) + if is_successful?(result) + puts "Modified template" if ops[:verbose] + end + +when "rmattr" + check_parameters("rmattr", 2) + template_id = get_template_id(ARGV[0]) + + template = OpenNebula::Template.new_with_id(template_id, get_one_client) + + result = template.remove_attr(ARGV[1]) + if is_successful?(result) + puts "Removed template attribute" if ops[:verbose] + end + +when "publish" + check_parameters("publish", 1) + template_id = get_template_id(ARGV[0]) + + template = OpenNebula::Template.new_with_id(template_id, get_one_client) + + result = template.publish + if is_successful?(result) + puts "Template published" if ops[:verbose] + end + +when "unpublish" + check_parameters("unpublish", 1) + template_id = get_template_id(ARGV[0]) + + template = OpenNebula::Template.new_with_id(template_id, get_one_client) + + result = template.unpublish + if is_successful?(result) + puts "Template unpublished" if ops[:verbose] + end + +when "list" + ops.merge!(get_user_flags) + if !ops[:xml] + templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i) + ops[:columns] = ops[:list] if ops[:list] + result = templatelist.list_short(ops) + else + templatepool = OpenNebula::TemplatePool.new(get_one_client, + ops[:filter_user].to_i) + templatepool.info + puts templatepool.to_xml + end + +when "top" + ops.merge!(get_user_flags) + templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i) + ops[:columns] = ops[:list] if ops[:list] + result = templatelist.top(ops) + +when "show" + check_parameters("get_info", 1) + args = expand_args(ARGV) + + args.each do |param| + template_id = get_template_id(param) + + template = OpenNebula::Template.new_with_id(template_id, get_one_client) + result = template.info + + if is_successful?(result) + if !ops[:xml] + str="%-15s: %-20s" + str_h1="%-80s" + + print_header(str_h1, "TEMPLATE #{template[:id]} INFORMATION", true) + + puts str % ["ID", template.id.to_s] + puts str % ["NAME", template.name] + + value = template['REGTIME'].to_i + if value==0 + value='-' + else + value=Time.at(value).strftime("%m/%d %H:%M:%S") + end + puts str % ["REGISTER TIME", value] + if template['PUBLIC'].to_i == 1 + public_str = "Yes" + else + public_str = "No" + end + puts str % ["PUBLIC", public_str] + + puts str % ["RUNNING_VMS", template['RUNNING_VMS']] + + puts + + print_header(str_h1,"TEMPLATE CONTENTS",false) + + puts template.template_str + else + puts template.to_xml + end + end + end + +when "delete" + check_parameters("delete", 1) + args = expand_args(ARGV) + + args.each do |param| + template_id = get_template_id(param) + template = OpenNebula::Template.new( + OpenNebula::Template.build_xml(template_id), + get_one_client) + + result = img_repo.delete(template) + if is_successful?(result) + puts "Template correctly deleted" if ops[:verbose] + end + end + +else + onetemplate_opts.print_help + exit -1 +end + +if OpenNebula.is_error?(result) + puts "Error: " + result.message + exit -1 +end + + diff --git a/src/oca/ruby/OpenNebula.rb b/src/oca/ruby/OpenNebula.rb index baac4772b2..86b6789c57 100644 --- a/src/oca/ruby/OpenNebula.rb +++ b/src/oca/ruby/OpenNebula.rb @@ -38,6 +38,8 @@ require 'OpenNebula/Host' require 'OpenNebula/HostPool' require 'OpenNebula/Cluster' require 'OpenNebula/ClusterPool' +require 'OpenNebula/Template' +require 'OpenNebula/TemplatePool' module OpenNebula diff --git a/src/oca/ruby/OpenNebula/Template.rb b/src/oca/ruby/OpenNebula/Template.rb new file mode 100644 index 0000000000..5c8b758da6 --- /dev/null +++ b/src/oca/ruby/OpenNebula/Template.rb @@ -0,0 +1,126 @@ +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +require 'OpenNebula/Pool' + +module OpenNebula + class Template < PoolElement + # --------------------------------------------------------------------- + # Constants and Class Methods + # --------------------------------------------------------------------- + TEMPLATE_METHODS = { + :allocate => "template.allocate", + :info => "template.info", + :update => "template.update", + :rmattr => "template.rmattr", + :publish => "template.publish", + :delete => "template.delete" + } + + # Creates a Template description with just its identifier + # this method should be used to create plain Template objects. + # +id+ the id of the user + # + # Example: + # template = Template.new(Template.build_xml(3),rpc_client) + # + def Template.build_xml(pe_id=nil) + if pe_id + obj_xml = "#{pe_id}" + else + obj_xml = "" + end + + XMLElement.build_xml(obj_xml,'VMTEMPLATE') + end + + # --------------------------------------------------------------------- + # Class constructor + # --------------------------------------------------------------------- + def initialize(xml, client) + super(xml,client) + + @client = client + end + + # --------------------------------------------------------------------- + # XML-RPC Methods for the Template Object + # --------------------------------------------------------------------- + + # Retrieves the information of the given Template. + def info() + super(TEMPLATE_METHODS[:info], 'VMTEMPLATE') + end + + # Allocates a new Template in OpenNebula + # + # +templatename+ A string containing the name of the Template. + def allocate(templatename) + super(TEMPLATE_METHODS[:allocate], templatename) + end + + # Deletes the Template + def delete() + super(TEMPLATE_METHODS[:delete]) + end + + # Modifies a template attribute + # + # +name+ Name of the attribute to be changed + # + # +value+ New value for the attribute + def update(name, value) + super(TEMPLATE_METHODS[:update], name, value) + end + + # Deletes a template attribute + # + # +name+ Name of the attribute to be deleted + def remove_attr(name) + do_rm_attr(name) + end + + # Publishes the Template, to be used by other users + def publish + set_publish(true) + end + + # Unplubishes the Image + def unpublish + set_publish(false) + end + + private + + def set_publish(published) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(TEMPLATE_METHODS[:publish], @pe_id, published) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + + def do_rm_attr(name) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(TEMPLATE_METHODS[:rmattr], @pe_id, name) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + end +end diff --git a/src/oca/ruby/OpenNebula/TemplatePool.rb b/src/oca/ruby/OpenNebula/TemplatePool.rb new file mode 100644 index 0000000000..d4ebe1823e --- /dev/null +++ b/src/oca/ruby/OpenNebula/TemplatePool.rb @@ -0,0 +1,55 @@ +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +require 'OpenNebula/Pool' + +module OpenNebula + class TemplatePool < Pool + # --------------------------------------------------------------------- + # Constants and Class attribute accessors + # --------------------------------------------------------------------- + + TEMPLATE_POOL_METHODS = { + :info => "templatepool.info" + } + + # --------------------------------------------------------------------- + # Class constructor & Pool Methods + # --------------------------------------------------------------------- + + # +client+ a Client object that represents an XML-RPC connection + # +user_id+ used to refer to a Pool with Templates from that user + def initialize(client, user_id=-1) + super('TEMPLATE_POOL','VMTEMPLATE',client) + + @user_id = user_id + end + + # Factory method to create Template objects + def factory(element_xml) + OpenNebula::Template.new(element_xml,@client) + end + + # --------------------------------------------------------------------- + # XML-RPC Methods for the Template Object + # --------------------------------------------------------------------- + + # Retrieves all the Templates in the pool. + def info() + super(TEMPLATE_POOL_METHODS[:info], @user_id) + end + end +end \ No newline at end of file diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 9be461eca2..7defc59b91 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -365,6 +365,12 @@ void RequestManager::register_xml_methods() /* VM Template related methods*/ RequestManagerRegistry.addMethod("one.template.allocate",template_allocate); + RequestManagerRegistry.addMethod("one.template.delete", template_delete); + RequestManagerRegistry.addMethod("one.template.info", template_info); + 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.templatepool.info",template_pool_info); /* Host related methods*/ From b27c9372f51320b439d2158330b8987b4c44d8cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 1 Apr 2011 17:17:26 +0200 Subject: [PATCH 04/16] Feature #487: Small auth and DB bugfixes, and support to allocate a VM from a template using its TEMPLATE_ID --- include/RequestManager.h | 3 ++ include/Template.h | 4 ++- include/VMTemplate.h | 11 +++++++- src/authm/AuthManager.cc | 4 +-- src/cli/onetemplate | 12 ++------ src/rm/RequestManager.cc | 2 +- src/rm/RequestManagerAllocate.cc | 48 +++++++++++++++++++++++++++++++- src/template/Template.cc | 5 ++-- src/vm_template/VMTemplate.cc | 7 +++-- 9 files changed, 76 insertions(+), 20 deletions(-) diff --git a/include/RequestManager.h b/include/RequestManager.h index 89daa75b7b..0c873cf8b3 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -321,10 +321,12 @@ private: VirtualMachinePool * _vmpool, VirtualNetworkPool * _vnpool, ImagePool * _ipool, + VMTemplatePool * _tpool, UserPool * _upool): vmpool(_vmpool), vnpool(_vnpool), ipool(_ipool), + tpool(_tpool), upool(_upool) { _signature="A:ss"; @@ -340,6 +342,7 @@ private: VirtualMachinePool * vmpool; VirtualNetworkPool * vnpool; ImagePool * ipool; + VMTemplatePool * tpool; UserPool * upool; }; diff --git a/include/Template.h b/include/Template.h index d81cf4b8c2..334fbfffe9 100644 --- a/include/Template.h +++ b/include/Template.h @@ -161,8 +161,10 @@ public: * @param name the attribute name. * @param value the attribute value, an int, 0 if the attribute is not * defined or not Single + * + * @returns True if the Single attribute was found */ - virtual void get( + virtual bool get( string& name, int& value) const; diff --git a/include/VMTemplate.h b/include/VMTemplate.h index 50bf19dca5..1047f7dca2 100644 --- a/include/VMTemplate.h +++ b/include/VMTemplate.h @@ -74,6 +74,11 @@ public: // Template Contents // ------------------------------------------------------------------------ + VirtualMachineTemplate * get_template_contents() const + { + return new VirtualMachineTemplate(*template_contents); + } + /** * Gets the values of a template attribute * @param name of the attribute @@ -178,12 +183,16 @@ private: */ VirtualMachineTemplate* template_contents; - /** * Public scope of the VMTemplate */ int public_template; + /** + * Registration time + */ + time_t regtime; + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/src/authm/AuthManager.cc b/src/authm/AuthManager.cc index 217eca79b6..67f0b04469 100644 --- a/src/authm/AuthManager.cc +++ b/src/authm/AuthManager.cc @@ -148,7 +148,7 @@ void AuthRequest::add_auth(Object ob, switch (op) { case CREATE: - if ( ob == VM || ob == NET || ob == IMAGE ) + if ( ob == VM || ob == NET || ob == IMAGE || ob == TEMPLATE ) { auth = true; } @@ -159,7 +159,7 @@ void AuthRequest::add_auth(Object ob, break; case USE: - if (ob == NET || ob == IMAGE) + if (ob == NET || ob == IMAGE || ob == TEMPLATE) { auth = (owner == uid) || pub; } diff --git a/src/cli/onetemplate b/src/cli/onetemplate index 627a0f177d..5ba4a25014 100755 --- a/src/cli/onetemplate +++ b/src/cli/onetemplate @@ -70,14 +70,8 @@ ShowTableTemplate={ :proc => lambda {|d,e| if d["PUBLIC"].to_i == 1 then "Yes" else "No" end} }, - :runningvms => { - :name => "#VMS", - :desc => "Number of VMs currently running from this Template", - :size => 5, - :proc => lambda {|d,e| d['RUNNING_VMS'] } - }, - :default => [:id, :user, :name, :regtime, :public, :runningvms] + :default => [:id, :user, :name, :regtime, :public] } @@ -377,8 +371,6 @@ when "show" end puts str % ["PUBLIC", public_str] - puts str % ["RUNNING_VMS", template['RUNNING_VMS']] - puts print_header(str_h1,"TEMPLATE CONTENTS",false) @@ -400,7 +392,7 @@ when "delete" OpenNebula::Template.build_xml(template_id), get_one_client) - result = img_repo.delete(template) + result = template.delete if is_successful?(result) puts "Template correctly deleted" if ops[:verbose] end diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 7defc59b91..9f2c9f64f4 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -214,7 +214,7 @@ void RequestManager::do_action( void RequestManager::register_xml_methods() { xmlrpc_c::methodPtr vm_allocate(new - RequestManager::VirtualMachineAllocate(vmpool, vnpool, ipool, upool)); + RequestManager::VirtualMachineAllocate(vmpool,vnpool,ipool,tpool,upool)); xmlrpc_c::methodPtr vm_deploy(new RequestManager::VirtualMachineDeploy(vmpool,hpool,upool)); diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 6ae73f60bc..836b208574 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -30,10 +30,11 @@ void RequestManager::VirtualMachineAllocate::execute( string str_template; string error_str; string user_name; + string att_name; const string method_name = "VirtualMachineAllocate"; - int vid, uid; + int vid, uid, tid; int rc; ostringstream oss; @@ -43,6 +44,11 @@ void RequestManager::VirtualMachineAllocate::execute( VirtualMachineTemplate * vm_template; User * user; + VMTemplate * registered_template; + bool using_template_pool; + int template_owner; + bool template_public; + char * error_msg = 0; int num; @@ -77,11 +83,46 @@ void RequestManager::VirtualMachineAllocate::execute( goto error_parse; } + //-------------------------------------------------------------------------- + // Look for a template id + //-------------------------------------------------------------------------- + att_name = "TEMPLATE_ID"; + using_template_pool = vm_template->get(att_name, tid); + + if( using_template_pool ) + { + // Get the registered template + registered_template = VirtualMachineAllocate::tpool->get(tid, true); + + if( registered_template == 0 ) + { + goto error_template_get; + } + + delete vm_template; + + // Use the template contents + vm_template = registered_template->get_template_contents(); + template_owner = registered_template->get_uid(); + template_public = registered_template->isPublic(); + + registered_template->unlock(); + } + if ( uid != 0 ) { AuthRequest ar(uid); string t64; + if( using_template_pool ) + { + ar.add_auth(AuthRequest::TEMPLATE, + tid, + AuthRequest::USE, + template_owner, + template_public); + } + num = vm_template->get("DISK",vectors); for(int i=0; i> value; + return true; } /* -------------------------------------------------------------------------- */ diff --git a/src/vm_template/VMTemplate.cc b/src/vm_template/VMTemplate.cc index 92b1ef540a..313b8fe01e 100644 --- a/src/vm_template/VMTemplate.cc +++ b/src/vm_template/VMTemplate.cc @@ -28,7 +28,8 @@ VMTemplate::VMTemplate(int id, string _user_name, VirtualMachineTemplate * _template_contents): PoolObjectSQL(id,"",_uid,table), - user_name(_user_name) + user_name(_user_name), + regtime(time(0)) { if (_template_contents != 0) { @@ -61,7 +62,7 @@ const char * VMTemplate::db_names = "oid, name, body, uid, public"; const char * VMTemplate::db_bootstrap = "CREATE TABLE IF NOT EXISTS template_pool (oid INTEGER PRIMARY KEY, " - "name VARCHAR(256), body TEXT, uid INTEGER, public INTEGER, UNIQUE(name))"; + "name VARCHAR(256), body TEXT, uid INTEGER, public INTEGER)"; /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -197,6 +198,7 @@ string& VMTemplate::to_xml(string& xml) const << "" << user_name << "" << "" << name << "" << "" << public_template << "" + << "" << regtime << "" << template_contents->to_xml(template_xml) << ""; @@ -222,6 +224,7 @@ int VMTemplate::from_xml(const string& xml) rc += xpath(user_name, "/VMTEMPLATE/USERNAME", "not_found"); rc += xpath(name, "/VMTEMPLATE/NAME", "not_found"); rc += xpath(public_template,"/VMTEMPLATE/PUBLIC", 0); + rc += xpath(regtime, "/VMTEMPLATE/REGTIME", 0); // Get associated classes ObjectXML::get_nodes("/VMTEMPLATE/TEMPLATE", content); From 2649590d3456fea74d35f9ced61fada2f7b8d081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 5 Apr 2011 15:58:18 +0200 Subject: [PATCH 05/16] Feature #487: Several bugfixes and new INSTANTIATE auth. operation --- include/AuthManager.h | 11 +++--- include/VMTemplate.h | 15 +++++++-- include/VirtualMachineTemplate.h | 58 ++++++++++++++++++++++++++++++++ src/authm/AuthManager.cc | 13 ++++++- src/cli/onetemplate | 2 +- src/im_mad/dummy/one_im_dummy.rb | 2 +- src/rm/RequestManagerAllocate.cc | 36 +++++++++++++++----- 7 files changed, 119 insertions(+), 18 deletions(-) diff --git a/include/AuthManager.h b/include/AuthManager.h index 1451463d94..e456f02fee 100644 --- a/include/AuthManager.h +++ b/include/AuthManager.h @@ -276,11 +276,12 @@ public: */ enum Operation { - CREATE, /** Authorization to create an object (host, vm, net, image)*/ - DELETE, /** Authorization to delete an object */ - USE, /** Authorization to use an object */ - MANAGE, /** Authorization to manage an object */ - INFO /** Authorization to view an object */ + CREATE, /** Authorization to create an object */ + DELETE, /** Authorization to delete an object */ + USE, /** Authorization to use an object */ + MANAGE, /** Authorization to manage an object */ + INFO, /** Authorization to view an object */ + INSTANTIATE /** Authorization to instantiate a VM from a TEMPLATE */ }; /** diff --git a/include/VMTemplate.h b/include/VMTemplate.h index 1047f7dca2..cae676ca08 100644 --- a/include/VMTemplate.h +++ b/include/VMTemplate.h @@ -74,10 +74,21 @@ public: // Template Contents // ------------------------------------------------------------------------ + /** + * Returns a copy of the VirtualMachineTemplate + * @return A copy of the VirtualMachineTemplate + */ VirtualMachineTemplate * get_template_contents() const { - return new VirtualMachineTemplate(*template_contents); - } + // TODO: Check if there is a more efficient way to do this copy. + string xml_str; + VirtualMachineTemplate * new_template = new VirtualMachineTemplate(); + + template_contents->to_xml(xml_str); + new_template->from_xml(xml_str); + + return new_template; + }; /** * Gets the values of a template attribute diff --git a/include/VirtualMachineTemplate.h b/include/VirtualMachineTemplate.h index a8c76404b6..3f1cb458b6 100644 --- a/include/VirtualMachineTemplate.h +++ b/include/VirtualMachineTemplate.h @@ -19,6 +19,8 @@ #include "Template.h" +#include + using namespace std; /** @@ -32,8 +34,64 @@ public: ~VirtualMachineTemplate(){}; + /** + * Copies the attributes of the original template into this one. + * @param original Original template + * @param error_msg error string, must be freed by the calling funtion. + * This string is null if no error occurred. + */ + int merge(const VirtualMachineTemplate * original, char **error_msg) + { + int rc; + + *error_msg = 0; + + rc = merge_att(original, "TEMPLATE_ID"); + + if( rc != 0 ) + { + goto error_tid; + } + + merge_att(original, "NAME"); + return 0; + + error_tid: + *error_msg = strdup("TEMPLATE_ID attribute not found"); + return -1; + }; + private: friend class VirtualMachine; + + int merge_att(const VirtualMachineTemplate * original, const char * name) + { + vector attrs; + SingleAttribute * sattr; + const SingleAttribute * original_attr; + int number; + + string att_name = name; + + number = original->get(att_name,attrs); + + if( number == 0 ) + { + return -1; + } + + original_attr = dynamic_cast(attrs[0]); + + if ( original_attr != 0 ) + { + erase(att_name); + + sattr = new SingleAttribute(*original_attr); + set(sattr); + } + + return 0; + }; }; /* -------------------------------------------------------------------------- */ diff --git a/src/authm/AuthManager.cc b/src/authm/AuthManager.cc index 67f0b04469..cc88d57de5 100644 --- a/src/authm/AuthManager.cc +++ b/src/authm/AuthManager.cc @@ -89,7 +89,7 @@ void AuthRequest::add_auth(Object ob, case TEMPLATE: oss << "TEMPLATE:" ; break; } - if (op == CREATE) //encode the ob_id, it is a template + if (op == CREATE || op == INSTANTIATE) //encode the ob_id, it is a template { string * encoded_id = base64_encode(ob_id); @@ -129,6 +129,10 @@ void AuthRequest::add_auth(Object ob, case INFO: oss << "INFO:" ; break; + + case INSTANTIATE: + oss << "INSTANTIATE:" ; + break; } oss << owner << ":" << pub; @@ -154,6 +158,13 @@ void AuthRequest::add_auth(Object ob, } break; + case INSTANTIATE: + if ( ob == VM ) + { + auth = true; + } + break; + case DELETE: auth = owner == uid; break; diff --git a/src/cli/onetemplate b/src/cli/onetemplate index 5ba4a25014..f0bf8cf606 100755 --- a/src/cli/onetemplate +++ b/src/cli/onetemplate @@ -274,7 +274,7 @@ when "create", "register", "add" exit 0 end -when "addattr" +when "update", "addattr" check_parameters("update", 3) template_id = get_template_id(ARGV[0]) diff --git a/src/im_mad/dummy/one_im_dummy.rb b/src/im_mad/dummy/one_im_dummy.rb index c01021d331..50865c4574 100755 --- a/src/im_mad/dummy/one_im_dummy.rb +++ b/src/im_mad/dummy/one_im_dummy.rb @@ -51,7 +51,7 @@ class DummyInformationManager < OpenNebulaDriver #--------------------------------------------------------------------------- def action_monitor(number, host, not_used) results = "HYPERVISOR=dummy," - results << "NAME=#{host}," + results << "HOSTNAME=#{host}," results << "TOTALCPU=800," results << "CPUSPEED=2.2GHz," diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 836b208574..c66b5b0237 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -43,6 +43,7 @@ void RequestManager::VirtualMachineAllocate::execute( xmlrpc_c::value_array * arrayresult; VirtualMachineTemplate * vm_template; + VirtualMachineTemplate * vm_template_aux; User * user; VMTemplate * registered_template; bool using_template_pool; @@ -99,14 +100,22 @@ void RequestManager::VirtualMachineAllocate::execute( goto error_template_get; } - delete vm_template; - // Use the template contents - vm_template = registered_template->get_template_contents(); + vm_template_aux = registered_template->get_template_contents(); template_owner = registered_template->get_uid(); template_public = registered_template->isPublic(); registered_template->unlock(); + + rc = vm_template_aux->merge(vm_template, &error_msg); + + delete vm_template; + vm_template = vm_template_aux; + + if ( rc != 0 ) + { + goto error_parse; + } } if ( uid != 0 ) @@ -154,11 +163,22 @@ void RequestManager::VirtualMachineAllocate::execute( VirtualMachineAllocate::vnpool->authorize_nic(vector,uid,&ar); } - ar.add_auth(AuthRequest::VM, - vm_template->to_xml(t64), - AuthRequest::CREATE, - uid, - false); + if( using_template_pool ) + { + ar.add_auth(AuthRequest::VM, + vm_template->to_xml(t64), + AuthRequest::INSTANTIATE, + uid, + false); + } + else + { + ar.add_auth(AuthRequest::VM, + vm_template->to_xml(t64), + AuthRequest::CREATE, + uid, + false); + } if (UserPool::authorize(ar) == -1) { From abca92f7328dcc9a1852cc550f4f2549624f229b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 5 Apr 2011 17:39:15 +0200 Subject: [PATCH 06/16] Feature #487: Add TEMPLATE object and INSTANTIATE operation to authorization driver --- src/authm_mad/simple_permissions.rb | 34 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/authm_mad/simple_permissions.rb b/src/authm_mad/simple_permissions.rb index 51af54cbe5..e69dae12e5 100644 --- a/src/authm_mad/simple_permissions.rb +++ b/src/authm_mad/simple_permissions.rb @@ -48,7 +48,20 @@ class SimplePermissions VmUsage.new(cpu, memory) end - + + # Checks if the quota is enabled, and if it is not exceeded + def check_quota_enabled(uid, object, id, auth_result) + if @quota_enabled and object=='VM' and auth_result + STDERR.puts 'quota enabled' + @quota.update(uid.to_i) + if !@quota.check(uid.to_i, get_vm_usage(id)) + auth_result="Quota exceeded" + end + end + + return auth_result + end + # Method called by authorization driver def auth(uid, tokens) result=true @@ -71,21 +84,18 @@ class SimplePermissions case action when 'CREATE' - auth_result=true if %w{VM NET IMAGE}.include? object - - if @quota_enabled and object=='VM' and auth_result - STDERR.puts 'quota enabled' - @quota.update(uid.to_i) - if !@quota.check(uid.to_i, get_vm_usage(id)) - auth_result="Quota exceeded" - end - end - + auth_result=true if %w{VM NET IMAGE TEMPLATE}.include? object + auth_result = check_quota_enabled(uid, object, id, auth_result) + + when 'INSTANTIATE' + auth_result = true if %w{VM}.include? object + auth_result = check_quota_enabled(uid, object, id, auth_result) + when 'DELETE' auth_result = (owner == uid) when 'USE' - if %w{VM NET IMAGE}.include? object + if %w{VM NET IMAGE TEMPLATE}.include? object auth_result = ((owner == uid) | (pub=='1')) elsif object == 'HOST' auth_result=true From 0b357fbf0958b765c10623885f364f5ba703e812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 6 Apr 2011 18:07:49 +0200 Subject: [PATCH 07/16] Feature #487: Java OCA methods for TemplatePool, and tests --- .../opennebula/client/image/ImagePool.java | 11 +- .../opennebula/client/template/Template.java | 236 ++++++++++++++++++ .../client/template/TemplatePool.java | 132 ++++++++++ src/oca/java/test/ImageTest.java | 1 + src/oca/java/test/TemplateTest.java | 189 ++++++++++++++ src/oca/java/test/all_tests.sh | 3 +- src/oca/java/test/test.sh | 3 +- src/rm/RequestManagerClusterInfo.cc | 3 +- 8 files changed, 568 insertions(+), 10 deletions(-) create mode 100644 src/oca/java/src/org/opennebula/client/template/Template.java create mode 100644 src/oca/java/src/org/opennebula/client/template/TemplatePool.java create mode 100644 src/oca/java/test/TemplateTest.java diff --git a/src/oca/java/src/org/opennebula/client/image/ImagePool.java b/src/oca/java/src/org/opennebula/client/image/ImagePool.java index 37a24176cb..a571ac33ab 100644 --- a/src/oca/java/src/org/opennebula/client/image/ImagePool.java +++ b/src/oca/java/src/org/opennebula/client/image/ImagePool.java @@ -22,7 +22,6 @@ import org.opennebula.client.Client; import org.opennebula.client.OneResponse; import org.opennebula.client.Pool; import org.opennebula.client.PoolElement; -import org.opennebula.client.vm.VirtualMachinePool; import org.w3c.dom.Node; /** @@ -42,7 +41,7 @@ public class ImagePool extends Pool implements Iterable * * @param client XML-RPC Client. * - * @see VirtualMachinePool#VirtualMachinePool(Client, int) + * @see ImagePool#ImagePool(Client, int) */ public ImagePool(Client client) { @@ -58,8 +57,8 @@ public class ImagePool extends Pool implements Iterable * {@link ImagePool#info()}. Possible values: *
    *
  • <= -2: All Images
  • - *
  • -1: Connected user's Images
  • - *
  • >= 0: UID User's VMs
  • + *
  • -1: Connected user's Images and public ones
  • + *
  • >= 0: UID User's Images
  • *
*/ public ImagePool(Client client, int filter) @@ -85,8 +84,8 @@ public class ImagePool extends Pool implements Iterable * {@link ImagePool#info()}. Possible values: *
    *
  • <= -2: All Images
  • - *
  • -1: Connected user's Images
  • - *
  • >= 0: UID User's VMs
  • + *
  • -1: Connected user's Images and public ones
  • + *
  • >= 0: UID User's Images
  • *
* @return If successful the message contains the string * with the information returned by OpenNebula. diff --git a/src/oca/java/src/org/opennebula/client/template/Template.java b/src/oca/java/src/org/opennebula/client/template/Template.java new file mode 100644 index 0000000000..acdb2530c5 --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/template/Template.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +package org.opennebula.client.template; + +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.PoolElement; +import org.w3c.dom.Node; + +/** + * This class represents an OpenNebula template. + * It also offers static XML-RPC call wrappers. + */ +public class Template extends PoolElement +{ + + private static final String METHOD_PREFIX = "template."; + private static final String ALLOCATE = METHOD_PREFIX + "allocate"; + private static final String INFO = METHOD_PREFIX + "info"; + private static final String DELETE = METHOD_PREFIX + "delete"; + private static final String UPDATE = METHOD_PREFIX + "update"; + private static final String RMATTR = METHOD_PREFIX + "rmattr"; + private static final String PUBLISH = METHOD_PREFIX + "publish"; + + /** + * Creates a new Template representation. + * @param id The template id. + * @param client XML-RPC Client. + */ + public Template(int id, Client client) + { + super(id, client); + } + + /** + * @see PoolElement + */ + protected Template(Node xmlElement, Client client) + { + super(xmlElement, client); + } + + // ================================= + // Static XML-RPC methods + // ================================= + + + /** + * Allocates a new Template in OpenNebula. + * + * @param client XML-RPC Client. + * @param description A string containing the template of the template. + * @return If successful the message contains the associated + * id generated for this Template. + */ + public static OneResponse allocate(Client client, String description) + { + return client.call(ALLOCATE, description); + } + + /** + * Retrieves the information of the given Template. + * + * @param client XML-RPC Client. + * @param id The template id for the template to retrieve the information from + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse info(Client client, int id) + { + return client.call(INFO, id); + } + + /** + * Deletes a template from OpenNebula. + * + * @param client XML-RPC Client. + * @param id The template id of the target template we want to delete. + * @return A encapsulated response. + */ + public static OneResponse delete(Client client, int id) + { + return client.call(DELETE, id); + } + + /** + * Modifies a template attribute. + * + * @param client XML-RPC Client. + * @param id The template id of the target template we want to modify. + * @param att_name The name of the attribute to update. + * @param att_val The new value for the attribute. + * @return If successful the message contains the template id. + */ + public static OneResponse update(Client client, int id, + String att_name, String att_val) + { + return client.call(UPDATE, id, att_name, att_val); + } + + /** + * Removes a template attribute. + * + * @param client XML-RPC Client. + * @param id The template id of the target template we want to modify. + * @param att_name The name of the attribute to remove. + * @return If successful the message contains the template id. + */ + public static OneResponse rmattr(Client client, int id, String att_name) + { + return client.call(RMATTR, id, att_name); + } + + /** + * Publishes or unpublishes a template. + * + * @param client XML-RPC Client. + * @param id The template id of the target template we want to modify. + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the template id. + */ + public static OneResponse publish(Client client, int id, boolean publish) + { + return client.call(PUBLISH, id, publish); + } + + + // ================================= + // Instanced object XML-RPC methods + // ================================= + + /** + * Retrieves the information of the Template. + * + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse info() + { + OneResponse response = info(client, id); + super.processInfo(response); + return response; + } + + /** + * Deletes the template from OpenNebula. + * + * @return A encapsulated response. + */ + public OneResponse delete() + { + return delete(client, id); + } + + /** + * Modifies a template attribute. + * + * @param att_name The name of the attribute to update. + * @param att_val The new value for the attribute. + * @return If successful the message contains the template id. + */ + public OneResponse update(String att_name, String att_val) + { + return update(client, id, att_name, att_val); + } + + /** + * Removes a template attribute. + * + * @param att_name The name of the attribute to remove. + * @return If successful the message contains the template id. + */ + public OneResponse rmattr(String att_name) + { + return rmattr(client, id, att_name); + } + + /** + * Publishes or unpublishes the template. + * + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the template id. + */ + public OneResponse publish(boolean publish) + { + return publish(client, id, publish); + } + + /** + * Publishes the template. + * + * @return If successful the message contains the template id. + */ + public OneResponse publish() + { + return publish(true); + } + + /** + * Unpublishes the template. + * + * @return If successful the message contains the template id. + */ + public OneResponse unpublish() + { + return publish(false); + } + + // ================================= + // Helpers + // ================================= + + /** + * Returns true if the template is public. + * + * @return True if the template is public. + */ + public boolean isPublic() + { + String isPub = xpath("PUBLIC"); + return isPub != null && isPub.equals("1"); + } +} diff --git a/src/oca/java/src/org/opennebula/client/template/TemplatePool.java b/src/oca/java/src/org/opennebula/client/template/TemplatePool.java new file mode 100644 index 0000000000..4d95e5dcee --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/template/TemplatePool.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * 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. + ******************************************************************************/ +package org.opennebula.client.template; + +import java.util.AbstractList; +import java.util.Iterator; + +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.Pool; +import org.opennebula.client.PoolElement; +import org.w3c.dom.Node; + +/** + * This class represents an OpenNebula Template pool. + * It also offers static XML-RPC call wrappers. + */ +public class TemplatePool extends Pool implements Iterable