diff --git a/SConstruct b/SConstruct index c70767a793..17cf9610b8 100644 --- a/SConstruct +++ b/SConstruct @@ -78,6 +78,7 @@ main_env.Append(LIBPATH=[ cwd+'/src/image', cwd+'/src/rm', cwd+'/src/vnm', + cwd+'/src/vn_template', cwd+'/src/hm', cwd+'/src/um', cwd+'/src/authm', @@ -250,6 +251,7 @@ build_scripts=[ 'src/dm/SConstruct', 'src/scheduler/SConstruct', 'src/vnm/SConstruct', + 'src/vn_template/SConstruct', 'src/hm/SConstruct', 'src/um/SConstruct', 'src/authm/SConstruct', diff --git a/include/Nebula.h b/include/Nebula.h index 16b763b494..9ff26ba199 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -38,6 +38,7 @@ #include "MarketPlacePool.h" #include "MarketPlaceAppPool.h" #include "VMGroupPool.h" +#include "VNTemplatePool.h" #include "VirtualMachineManager.h" #include "LifeCycleManager.h" @@ -168,6 +169,10 @@ public: return vmgrouppool; }; + VNTemplatePool * get_vntpool(){ + return vntpool; + } + // -------------------------------------------------------------- // Manager Accessors // -------------------------------------------------------------- @@ -694,7 +699,7 @@ private: vmpool(0), hpool(0), vnpool(0), upool(0), ipool(0), gpool(0), tpool(0), dspool(0), clpool(0), docpool(0), zonepool(0), secgrouppool(0), vdcpool(0), vrouterpool(0), marketpool(0), apppool(0), vmgrouppool(0), - lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0), aclm(0), + vntpool(0), lcm(0), vmm(0), im(0), tm(0), dm(0), rm(0), hm(0), authm(0), aclm(0), imagem(0), marketm(0), ipamm(0), raftm(0), frm(0) { const char * nl = getenv("ONE_LOCATION"); @@ -765,6 +770,7 @@ private: delete logdb; delete fed_logdb; delete system_db; + delete vntpool; }; Nebula& operator=(Nebula const&){return *this;}; @@ -837,7 +843,7 @@ private: MarketPlacePool * marketpool; MarketPlaceAppPool * apppool; VMGroupPool * vmgrouppool; - + VNTemplatePool * vntpool; // --------------------------------------------------------------- // Nebula Managers // --------------------------------------------------------------- diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 3313acee91..a6f1c7f0d7 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -67,7 +67,8 @@ public: VROUTER = 0x0004000000000000LL, MARKETPLACE = 0x0008000000000000LL, MARKETPLACEAPP = 0x0010000000000000LL, - VMGROUP = 0x0020000000000000LL + VMGROUP = 0x0020000000000000LL, + VNTEMPLATE = 0x0040000000000000LL }; /** @@ -105,6 +106,7 @@ public: case MARKETPLACE: return "MARKETPLACE" ; break; case MARKETPLACEAPP: return "MARKETPLACEAPP" ; break; case VMGROUP: return "VMGROUP" ; break; + case VNTEMPLATE: return "VNTEMPLATE"; break; default: return ""; } }; @@ -129,6 +131,7 @@ public: else if ( type == "MARKETPLACE" ) return MARKETPLACE ; else if ( type == "MARKETPLACEAPP" ) return MARKETPLACEAPP ; else if ( type == "VMGROUP" ) return VMGROUP ; + else if ( type == "VNTEMPLATE" ) return VNTEMPLATE ; else return NONE; }; diff --git a/include/PoolSQL.h b/include/PoolSQL.h index cea11fb131..e9886ee247 100644 --- a/include/PoolSQL.h +++ b/include/PoolSQL.h @@ -98,6 +98,8 @@ public: return PoolObjectSQL::exist(db, table.c_str(), oid); } + void exist(const string& id_str, std::set& id_list); + /** * Finds a set objects that satisfies a given condition * @param oids a vector with the oids of the objects. diff --git a/include/RequestManagerAllocate.h b/include/RequestManagerAllocate.h index 183496785d..6d8a954ee3 100644 --- a/include/RequestManagerAllocate.h +++ b/include/RequestManagerAllocate.h @@ -263,6 +263,39 @@ public: PoolObjectAuth *cluster_perms); }; +class VirtualNetworkTemplateAllocate : public RequestManagerAllocate +{ +public: + VirtualNetworkTemplateAllocate(): + RequestManagerAllocate("one.vntemplate.allocate", + "Allocates a new virtual network template", + "A:ss", + true) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateAllocate(){}; + + /* --------------------------------------------------------------------- */ + + Template * get_object_template() + { + return new VirtualMachineTemplate; + }; + + Request::ErrorCode pool_allocate(xmlrpc_c::paramList const& paramList, + Template * tmpl, + int& id, + RequestAttributes& att); + + bool allocate_authorization(xmlrpc_c::paramList const& paramList, + Template *obj_template, RequestAttributes& att, + PoolObjectAuth *cluster_perms); +}; + /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerChmod.h b/include/RequestManagerChmod.h index 3424e9f90b..ae7fa0d6d3 100644 --- a/include/RequestManagerChmod.h +++ b/include/RequestManagerChmod.h @@ -95,6 +95,32 @@ protected: int other_m, int other_a, bool recursive, RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkTemplateChmod : public RequestManagerChmod +{ +public: + VirtualNetworkTemplateChmod(): + RequestManagerChmod("one.vntemplate.chmod", "Changes permission bits of a " + "virtual network template", "A:siiiiiiiiiib") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateChmod(){}; + + ErrorCode request_execute(PoolSQL * pool, int oid, int owner_u, int owner_m, + int owner_a, int group_u, int group_m, int group_a, int other_u, + int other_m, int other_a, bool recursive, RequestAttributes& att) + { + return chmod(pool, oid, owner_u, owner_m, owner_a, group_u, group_m, + group_a, other_u, other_m, other_a, recursive, att); + } +}; + /* ------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerChown.h b/include/RequestManagerChown.h index 3d2baf6a60..e581285e26 100644 --- a/include/RequestManagerChown.h +++ b/include/RequestManagerChown.h @@ -122,6 +122,25 @@ public: ~TemplateChown(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkTemplateChown : public RequestManagerChown +{ +public: + VirtualNetworkTemplateChown(): + RequestManagerChown("one.vntemplate.chown", + "Changes ownership of a virtual network template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateChown(){}; +}; + + /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerClone.h b/include/RequestManagerClone.h index 7ea9f0dcca..5ac1f00963 100644 --- a/include/RequestManagerClone.h +++ b/include/RequestManagerClone.h @@ -124,6 +124,48 @@ protected: }; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VNTemplateClone : public RequestManagerClone +{ +public: + VNTemplateClone(): + RequestManagerClone("one.vntemplate.clone", + "Clone a virtual network template", "A:sisb") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + + auth_object = PoolObjectSQL::VNTEMPLATE; + auth_op = AuthRequest::USE; + }; + + ~VNTemplateClone(){}; + + ErrorCode request_execute(int source_id, const string &name, int &new_id, + bool recursive, const string& s_uattrs, RequestAttributes& att) + { + return clone(source_id, name, new_id, recursive, s_uattrs, att); + }; + +protected: + + Template * clone_template(PoolObjectSQL* obj) + { + return static_cast(obj)->clone_template(); + }; + + int pool_allocate(int sid, Template * tmpl, int& id, RequestAttributes& att) + { + VNTemplatePool * tpool = static_cast(pool); + VirtualNetworkTemplate * t = static_cast(tmpl); + + return tpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask, + t, &id, att.resp_msg); + }; + +}; /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerDelete.h b/include/RequestManagerDelete.h index 39e1b70b86..8598a3f32f 100644 --- a/include/RequestManagerDelete.h +++ b/include/RequestManagerDelete.h @@ -116,6 +116,31 @@ protected: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualNetworkTemplateDelete : public RequestManagerDelete +{ +public: + VirtualNetworkTemplateDelete(): + RequestManagerDelete("one.vntemplate.delete", + "A:sib", + "Deletes a virtual network template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateDelete(){}; + + ErrorCode request_execute(int oid, bool recursive, RequestAttributes& att) + { + return delete_object(oid, recursive, att); + } + +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class VirtualNetworkDelete: public RequestManagerDelete { public: diff --git a/include/RequestManagerInfo.h b/include/RequestManagerInfo.h index 76ec93e6a5..3dd9c4e72e 100644 --- a/include/RequestManagerInfo.h +++ b/include/RequestManagerInfo.h @@ -125,6 +125,31 @@ public: void to_xml(RequestAttributes& att, PoolObjectSQL * object, string& str); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + + +class VirtualNetworkTemplateInfo: public RequestManagerInfo +{ +public: + VirtualNetworkTemplateInfo(): + RequestManagerInfo("one.vntemplate.info", + "Returns virtual network template information") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateInfo(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + + /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ diff --git a/include/RequestManagerLock.h b/include/RequestManagerLock.h index c2aa58b1d8..07392c722e 100644 --- a/include/RequestManagerLock.h +++ b/include/RequestManagerLock.h @@ -160,6 +160,7 @@ public: ~VMTemplateLock(){}; }; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -180,6 +181,40 @@ public: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +class VNTemplateLock: public RequestManagerLock +{ +public: + VNTemplateLock(): + RequestManagerLock("one.vntemplate.lock", + "Lock a VN Template"){ + Nebula& nd = Nebula::instance(); + auth_object = PoolObjectSQL::VNTEMPLATE; + pool = nd.get_vntpool(); + }; + + ~VNTemplateLock(){}; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +class VNTemplateUnlock: public RequestManagerUnlock +{ +public: + VNTemplateUnlock(): + RequestManagerUnlock("one.vntemplate.unlock", + "Unlock a VN Template"){ + Nebula& nd = Nebula::instance(); + auth_object = PoolObjectSQL::VNTEMPLATE; + pool = nd.get_vntpool(); + }; + + ~VNTemplateUnlock(){}; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + class VirtualNetworkLock: public RequestManagerLock { public: diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index 778c530c4c..19f92120c9 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -247,6 +247,26 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualNetworkTemplatePoolInfo: public RequestManagerPoolInfoFilter +{ +public: + VirtualNetworkTemplatePoolInfo(): + RequestManagerPoolInfoFilter("one.vntemplatepool.info", + "Returns the virtual network template pool", + "A:siii") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplatePoolInfo(){}; + +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class ImagePoolInfo: public RequestManagerPoolInfoFilter { public: diff --git a/include/RequestManagerRename.h b/include/RequestManagerRename.h index f7bbe7bc48..4d7ed3bb1e 100644 --- a/include/RequestManagerRename.h +++ b/include/RequestManagerRename.h @@ -149,6 +149,29 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualNetworkTemplateRename : public RequestManagerRename +{ +public: + VirtualNetworkTemplateRename(): + RequestManagerRename("one.vntemplate.rename", + "Renames a virtual network template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateRename(){}; + + int exist(const string& name, int uid) + { + return pool->exist(name, uid); + } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class VirtualNetworkRename: public RequestManagerRename { diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index 2b92d21460..f05fd31314 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -71,6 +71,24 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class VirtualNetworkTemplateUpdateTemplate: public RequestManagerUpdateTemplate +{ +public: + VirtualNetworkTemplateUpdateTemplate(): + RequestManagerUpdateTemplate("one.vntemplate.update", + "Updates a virtual network template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~VirtualNetworkTemplateUpdateTemplate(){}; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class VirtualMachineUpdateTemplate: public RequestManagerUpdateTemplate { public: diff --git a/include/RequestManagerVNTemplate.h b/include/RequestManagerVNTemplate.h new file mode 100644 index 0000000000..7a8012ea75 --- /dev/null +++ b/include/RequestManagerVNTemplate.h @@ -0,0 +1,99 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2018, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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 REQUEST_MANAGER_VN_TEMPLATE_H +#define REQUEST_MANAGER_VN_TEMPLATE_H + +#include "Request.h" +#include "Nebula.h" + +using namespace std; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class RequestManagerVNTemplate: public Request +{ +protected: + RequestManagerVNTemplate(const string& method_name, + const string& help, + const string& params) + :Request(method_name,params,help) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vntpool(); + + auth_object = PoolObjectSQL::VNTEMPLATE; + }; + + ~RequestManagerVNTemplate(){}; + + /* -------------------------------------------------------------------- */ + + virtual void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att) = 0; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VNTemplateInstantiate : public RequestManagerVNTemplate +{ +public: + VNTemplateInstantiate(): + RequestManagerVNTemplate("one.vntemplate.instantiate", "Instantiates a new " + "virtual network using a template", "A:siss") + { + auth_op = AuthRequest::USE; + }; + + ~VNTemplateInstantiate(){}; + + /** + * Instantiates the VN Template, checking permissions, quotas, etc + * @param id VN Template ID + * @param name Name for the new VN. Can be empty + * @param s_uattr Template supplied by user to merge with the original + * contents. Can be empty + * @param extra_attrs Template to be merged. It should contain internal + * configuration, and it won't be authenticated or checked for restricted + * attributes. Can be 0 + * @param vnid on success of the new VN + * @param att the specific request attributes + * + * @return ErroCode for the request. + */ + ErrorCode request_execute(int id, string name, + const string& s_uattr, Template* extra_attrs, int& vid, + RequestAttributes& att); + + /** + * Parse & merge user attributes (check if the request user is not oneadmin) + * @param tmpl to merge the attributes to + * @param s_uattr Template supplied by user to merge with the original + * contents. Can be empty + * @param att the specific request attributes + */ + ErrorCode merge(Template * tmpl, const string &s_uattr, RequestAttributes& att); + +protected: + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + +#endif diff --git a/include/VNTemplate.h b/include/VNTemplate.h new file mode 100644 index 0000000000..387d4996b8 --- /dev/null +++ b/include/VNTemplate.h @@ -0,0 +1,155 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2018, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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 VNTEMPLATE_H_ +#define VNTEMPLATE_H_ + +#include "PoolObjectSQL.h" +#include "VirtualNetworkTemplate.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * The VNTemplate class. + */ +class VNTemplate : public PoolObjectSQL +{ +public: + + /** + * Function to print the VNTemplate 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; + + // ------------------------------------------------------------------------ + // Template Contents + // ------------------------------------------------------------------------ + + /** + * Factory method for virtual machine templates + */ + Template * get_new_template() const + { + return new VirtualNetworkTemplate; + } + + /** + * Returns a copy of the VirtualNetworkTemplate + * @return A copy of the VirtualNetworkTemplate + */ + VirtualNetworkTemplate * clone_template() const + { + return new VirtualNetworkTemplate( + *(static_cast(obj_template))); + }; + +private: + // ------------------------------------------------------------------------- + // Friends + // ------------------------------------------------------------------------- + + friend class VNTemplatePool; + + // ------------------------------------------------------------------------- + // VNTemplate Attributes + // ------------------------------------------------------------------------- + + /** + * Registration time + */ + time_t regtime; + + // ************************************************************************* + // DataBase implementation (Private) + // ************************************************************************* + + /** + * Execute an INSERT or REPLACE Sql query. + * @param db The SQL DB + * @param replace Execute an INSERT or a REPLACE + * @param error_str Returns the error reason, if any + * @return 0 one success + */ + int insert_replace(SqlDB *db, bool replace, string& error_str); + + /** + * Bootstraps the database table(s) associated to the VNTemplate + * @return 0 on success + */ + static int bootstrap(SqlDB * db) + { + ostringstream oss(VNTemplate::db_bootstrap); + + return db->exec_local_wr(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 + // ************************************************************************* + VNTemplate(int id, + int uid, + int gid, + const string& uname, + const string& gname, + int umask, + VirtualNetworkTemplate * _template_contents); + + ~VNTemplate(); + + // ************************************************************************* + // DataBase implementation + // ************************************************************************* + + static const char * db_names; + + static const char * db_bootstrap; + + static const char * table; + + /** + * Writes the VNTemplate in the database. + * @param db pointer to the db + * @param error_str Returns the error reason, if any + * @return 0 on success + */ + int insert(SqlDB *db, string& error_str); + + /** + * Writes/updates the VNTemplate data fields in the database. + * @param db pointer to the db + * @return 0 on success + */ + int update(SqlDB *db) + { + string err; + return insert_replace(db, true, err); + }; +}; + +#endif /*VNTEMPLATE_H_*/ diff --git a/include/VNTemplatePool.h b/include/VNTemplatePool.h new file mode 100644 index 0000000000..fcb5010728 --- /dev/null +++ b/include/VNTemplatePool.h @@ -0,0 +1,119 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2018, OpenNebula Project, OpenNebula Systems */ +/* */ +/* 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 VNetTEMPLATE_POOL_H_ +#define VNTEMPLATE_POOL_H_ + +#include "PoolSQL.h" +#include "VNTemplate.h" + +/** + * The VNetTemplate Pool class. + */ +class VNTemplatePool : public PoolSQL +{ +public: + + VNTemplatePool(SqlDB * db) : PoolSQL(db, VNTemplate::table){}; + + ~VNTemplatePool(){}; + + /** + * 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 gid the id of the group this object is assigned to + * @param uname user name + * @param gname group name + * @param umask permissions umask + * @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, + int gid, + const string& uname, + const string& gname, + int umask, + VirtualNetworkTemplate * 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 + */ + VNTemplate * get(int oid) + { + return static_cast(PoolSQL::get(oid)); + }; + + /** + * Gets an object from the pool (if needed the object is loaded from the + * database). + * @param oid the object unique identifier + * + * @return a pointer to the object, 0 in case of failure + */ + VNTemplate * get_ro(int oid) + { + return static_cast(PoolSQL::get_ro(oid)); + }; + + /** + * 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 + * @param limit parameters used for pagination + * @param desc descending order of pool elements + * + * @return 0 on success + */ + int dump(string& oss, const string& where, const string& limit, + bool desc) + { + return PoolSQL::dump(oss, "VNTEMPLATE_POOL", "body", VNTemplate::table, where, + limit, desc); + }; + + /** + * Bootstraps the database table(s) associated to the pool + * @return 0 on success + */ + static int bootstrap(SqlDB *_db) + { + return VNTemplate::bootstrap(_db); + }; + +private: + /** + * Factory method to produce VNTemplate objects + * @return a pointer to the new VNTemplate + */ + PoolObjectSQL * create() + { + return new VNTemplate(-1,-1,-1,"","",0,0); + }; +}; + +#endif /*VNTEMPLATE_POOL_H_*/ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 97fee71463..8b06d4bbce 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -167,6 +167,16 @@ public: } }; + /** + * Check consistency of PHYDEV, BRIDGE and VLAN attributes depending on + * the network driver + * @param error_str describing the error + * @return 0 on success -1 otherwise + */ + static int parse_phydev_vlans(const Template& tmpl, const string& vn_mad, const string& phydev, + const string& bridge, const bool auto_id, const string& vlan_id, + const bool auto_outer, const string& outer_id, string& estr); + // ************************************************************************* // Virtual Network Public Methods // ************************************************************************* @@ -638,14 +648,6 @@ private: void parse_vlan_id(const char * id_name, const char * auto_name, string& id, bool& auto_id); - /** - * Check consistency of PHYDEV, BRIDGE and VLAN attributes depending on - * the network driver - * @param error_str describing the error - * @return 0 on success -1 otherwise - */ - int parse_phydev_vlans(string& error_str); - // ************************************************************************* // Address allocation funtions // ************************************************************************* diff --git a/include/VirtualNetworkTemplate.h b/include/VirtualNetworkTemplate.h index 04b43b0892..97dd90fe08 100644 --- a/include/VirtualNetworkTemplate.h +++ b/include/VirtualNetworkTemplate.h @@ -31,6 +31,8 @@ public: ~VirtualNetworkTemplate(){}; + VirtualNetworkTemplate(VirtualNetworkTemplate& vnt):Template(vnt){}; + // ------------------------------------------------------------------------- // Restricted attributes interface implementation // ------------------------------------------------------------------------- diff --git a/share/doc/xsd/vntemplate.xsd b/share/doc/xsd/vntemplate.xsd new file mode 100644 index 0000000000..6b1b011ea9 --- /dev/null +++ b/share/doc/xsd/vntemplate.xsd @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/doc/xsd/vntemplate_pool.xsd b/share/doc/xsd/vntemplate_pool.xsd new file mode 100644 index 0000000000..437c65f542 --- /dev/null +++ b/share/doc/xsd/vntemplate_pool.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 651ecd4246..84fb1e6eb7 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -1083,6 +1083,8 @@ VNET_RESTRICTED_ATTR = "AR/PHYDEV" VNET_RESTRICTED_ATTR = "AR/VLAN_ID" VNET_RESTRICTED_ATTR = "AR/BRIDGE" +VNET_RESTRICTED_ATTR = "CLUSTER_IDS" + #******************************************************************************* # Inherited Attributes Configuration #******************************************************************************* diff --git a/src/acl/AclRule.cc b/src/acl/AclRule.cc index 3251b5255d..7661ddeef1 100644 --- a/src/acl/AclRule.cc +++ b/src/acl/AclRule.cc @@ -28,7 +28,7 @@ const long long AclRule::CLUSTER_ID = 0x0000000800000000LL; const long long AclRule::NONE_ID = 0x1000000000000000LL; -const int AclRule::num_pool_objects = 17; +const int AclRule::num_pool_objects = 18; const PoolObjectSQL::ObjectType AclRule::pool_objects[] = { PoolObjectSQL::VM, PoolObjectSQL::HOST, @@ -46,7 +46,8 @@ const PoolObjectSQL::ObjectType AclRule::pool_objects[] = { PoolObjectSQL::VROUTER, PoolObjectSQL::MARKETPLACE, PoolObjectSQL::MARKETPLACEAPP, - PoolObjectSQL::VMGROUP + PoolObjectSQL::VMGROUP, + PoolObjectSQL::VNTEMPLATE }; const int AclRule::num_auth_operations = 4; @@ -63,7 +64,7 @@ const long long AclRule::INVALID_CLUSTER_OBJECTS = PoolObjectSQL::CLUSTER | PoolObjectSQL::DOCUMENT | PoolObjectSQL::ZONE | PoolObjectSQL::SECGROUP | PoolObjectSQL::VDC | PoolObjectSQL::VROUTER | PoolObjectSQL::MARKETPLACE | PoolObjectSQL::MARKETPLACEAPP | - PoolObjectSQL::VMGROUP; + PoolObjectSQL::VMGROUP | PoolObjectSQL::VNTEMPLATE; const long long AclRule::INVALID_GROUP_OBJECTS = PoolObjectSQL::HOST | PoolObjectSQL::GROUP | PoolObjectSQL::CLUSTER | @@ -239,7 +240,7 @@ bool AclRule::malformed(string& error_str) const oss << "[resource] type is missing"; } - if ( (resource & 0xFFC0000000000000LL) != 0 ) + if ( (resource & 0xFF80000000000000LL) != 0 ) { if ( error ) { diff --git a/src/cli/etc/oneacl.yaml b/src/cli/etc/oneacl.yaml index 035116f78f..8582f4b516 100644 --- a/src/cli/etc/oneacl.yaml +++ b/src/cli/etc/oneacl.yaml @@ -9,9 +9,9 @@ :size: 8 :right: true -:RES_VHNIUTGDCOZSvRMAP: +:RES_VHNIUTGDCOZSvRMAPt: :desc: Which resource the rule applies to - :size: 21 + :size: 22 :RID: :desc: Resource ID @@ -31,7 +31,7 @@ :default: - :ID - :USER -- :RES_VHNIUTGDCOZSvRMAP +- :RES_VHNIUTGDCOZSvRMAPt - :RID - :OPE_UMAC - :ZONE diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index 6ec50d68d0..ae4ca68e60 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -179,6 +179,20 @@ EOT } ] + AS_USER = { + :name => 'as_uid', + :large => '--as_uid uid', + :format => Integer, + :description => 'The User ID to instantiate the VM' + } + + AS_GROUP = { + :name => 'as_gid', + :large => '--as_gid gid', + :format => Integer, + :description => 'The Group ID to instantiate the VM' + } + #NOTE: Other options defined using this array, add new options at the end TEMPLATE_OPTIONS=[ { @@ -368,18 +382,8 @@ EOT :description => "In a vCenter environment sets the the VMs and Template folder where the VM will be placed in." \ " The path uses slashes to separate folders. For example: --vcenter_vm_folder \"/Management/VMs\"" }, - { - :name => 'as_uid', - :large => '--as_uid uid', - :format => Integer, - :description => 'The User ID to instantiate the VM' - }, - { - :name => 'as_gid', - :large => '--as_gid gid', - :format => Integer, - :description => 'The Group ID to instantiate the VM' - } + AS_GROUP, + AS_USER ] FORCE={ @@ -1409,6 +1413,82 @@ EOT [0, template] end + def self.create_ar(options) + ar = 'AR = [ ' + + if options[:ip] + if options[:ip6_global] || options[:ip6_ula] + ar << 'TYPE="IP4_6"' + elsif options[:ip6] + ar << 'TYPE="IP4_6_STATIC"' + else + ar << 'TYPE="IP4"' + end + elsif options[:ip6] + ar << 'TYPE="IP6_STATIC"' + elsif options[:ip6_global] || options[:ip6_ula] + ar << 'TYPE="IP6"' + else + ar << 'TYPE="ETHER"' + end + + if options[:size] + ar << ', SIZE = ' << options[:size] + else + STDERR.puts 'Address range needs to specify size (-s size)' + exit(-1) + end + + if options[:ip6] + m = %r{([\h:]*)\/(\d.*)$}.match(options[:ip6]) + + if m.nil? || m[1].nil? + STDERR.puts 'Missing or wrong IP6' + exit(-1) + else + begin + require 'ipaddr' + + ip = IPAddr.new(m[1]) + + if !ip.ipv6? + STDERR.puts 'Wrong IP6 format address' + exit(-1) + end + rescue StandardError + STDERR.puts 'Wrong IP6 format address' + exit(-1) + end + + end + + if m[2].nil? + STDERR.puts 'IP6 address need to set the prefix length' + exit(-1) + end + + ar << ", PREFIX_LENGTH=\"#{m[2]}\"" + + options[:ip6] = m[1] + end + + ar << ', IP = ' << options[:ip] if options[:ip] + ar << ', IP6 = ' << options[:ip6] if options[:ip6] + ar << ', MAC = ' << options[:mac] if options[:mac] + if options[:ip6_global] + ar << ', GLOBAL_PREFIX = ' << options[:ip6_global] + end + if options[:ip6_ula] + ar << ', ULA_PREFIX = ' << options[:ip6_ula] + end + ar << ', GATEWAY = ' << options[:gateway] if options[:gateway] + ar << ', MASK = ' << options[:netmask] if options[:netmask] + ar << ', VN_MAD = ' << options[:vn_mad] if options[:vn_mad] + ar << ', VLAN_ID = ' << options[:vlanid] if options[:vlanid] + + ar << ']' + end + def self.create_template_options_used?(options) # Get the template options names as symbols. options hash # uses symbols diff --git a/src/cli/one_helper/oneacl_helper.rb b/src/cli/one_helper/oneacl_helper.rb index bc6dc3e2b2..5edad741c6 100644 --- a/src/cli/one_helper/oneacl_helper.rb +++ b/src/cli/one_helper/oneacl_helper.rb @@ -44,7 +44,7 @@ private def self.resource_mask(str) resource_type=str.split("/")[0] - mask = "-----------------" + mask = "------------------" resource_type.split("+").each{|type| case type @@ -82,6 +82,8 @@ private mask[15] = "A" when "VMGROUP" mask[16] = "P" + when "VNTEMPLATE" + mask[17] = "t" end } mask @@ -121,8 +123,8 @@ private d['STRING'].split(" ")[0] end - column :RES_VHNIUTGDCOZSvRMAP, "Resource to which the rule applies", - :size => 21 do |d| + column :RES_VHNIUTGDCOZSvRMAPt, "Resource to which the rule applies", + :size => 22 do |d| OneAclHelper::resource_mask d['STRING'].split(" ")[1] end @@ -139,7 +141,7 @@ private OneAclHelper::right_mask d['STRING'].split(" ")[2] end - default :ID, :USER, :RES_VHNIUTGDCOZSvRMAP, :RID, :OPE_UMAC, :ZONE + default :ID, :USER, :RES_VHNIUTGDCOZSvRMAPt, :RID, :OPE_UMAC, :ZONE end table diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 834cc3b7ed..3db360f110 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -96,33 +96,33 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper # :description => "Number of addresses to reserve" # } - GATEWAY = [ + GATEWAY = { :name => "gateway", :large => "--gateway ip", :format => String, :description=> "IP of the gateway" - ] + } - NETMASK = [ + NETMASK = { :name => "netmask", :large => "--netmask mask", :format => String, :description=> "Netmask in dot notation" - ] + } - VN_MAD = [ + VN_MAD = { :name => "vn_mad", :large => "--vn_mad mad", :format => String, :description=> "Use this driver for the network" - ] + } - VLAN_ID = [ + VLAN_ID = { :name => "vlanid", :large => "--vlanid id", :format => String, :description=> "VLAN ID assigned" - ] + } ADDAR_OPTIONS = [ SIZE, MAC, IP, IP6, IP6_GLOBAL, IP6_ULA, GATEWAY, NETMASK, VN_MAD, @@ -361,4 +361,16 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper end end end + + def self.add_ar_options_used?(options) + # Get the template options names as symbols. options hash + # uses symbols + add_ar_options=OneVNetHelper::ADDAR_OPTIONS.map do |o| + o[:name].to_sym + end + + # Check if one at least one of the template options is + # in options hash + (add_ar_options-options.keys)!=add_ar_options + end end diff --git a/src/cli/one_helper/onevntemplate_helper.rb b/src/cli/one_helper/onevntemplate_helper.rb new file mode 100644 index 0000000000..839448f8f2 --- /dev/null +++ b/src/cli/one_helper/onevntemplate_helper.rb @@ -0,0 +1,104 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems # +# # +# 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 'one_helper' +require 'one_helper/onetemplate_helper' +require 'base64' + +class OneVNTemplateHelper < OneTemplateHelper + VN_NAME={ + :name => "name", + :large => "--name name", + :format => String, + :description => <<-EOT.strip +Name of the new VN TEMPLATE. When instantiating + multiple VNs you can use the \"%i\" wildcard to produce + different names such as vm-0, vm-1... +EOT + } + + MULTIPLE={ + :name => "multiple", + :short => "-m x", + :large => "--multiple x", + :format => Integer, + :description => "Instance multiple VNs" + } + + EXTENDED={ + :name => "extended", + :large => "--extended", + :description => "Process the template and included extended "+ + "information" + } + + def self.rname + "VNTEMPLATE" + end + + def self.conf_file + "onetemplate.yaml" + end + + INT_EXP = /^-?\d+$/ + FLOAT_EXP = /^-?\d+(\.\d+)?$/ + + private + + def factory(id=nil) + if id + OpenNebula::VNTemplate.new_with_id(id, @client) + else + xml=OpenNebula::VNTemplate.build_xml + OpenNebula::VNTemplate.new(xml, @client) + end + end + + def factory_pool(user_flag=-2) + OpenNebula::VNTemplatePool.new(@client, user_flag) + end + + def format_resource(template, options = {}) + str="%-15s: %-20s" + str_h1="%-80s" + + CLIHelper.print_header( + str_h1 % "TEMPLATE #{template['ID']} INFORMATION") + puts str % ["ID", template.id.to_s] + puts str % ["NAME", template.name] + puts str % ["USER", template['UNAME']] + puts str % ["GROUP", template['GNAME']] + puts str % ["LOCK", OpenNebulaHelper.level_lock_to_str(template['LOCK/LOCKED'])] + puts str % ["REGISTER TIME", + OpenNebulaHelper.time_to_str(template['REGTIME'])] + puts + + CLIHelper.print_header(str_h1 % "PERMISSIONS",false) + + ["OWNER", "GROUP", "OTHER"].each { |e| + mask = "---" + mask[0] = "u" if template["PERMISSIONS/#{e}_U"] == "1" + mask[1] = "m" if template["PERMISSIONS/#{e}_M"] == "1" + mask[2] = "a" if template["PERMISSIONS/#{e}_A"] == "1" + + puts str % [e, mask] + } + puts + + CLIHelper.print_header(str_h1 % "TEMPLATE CONTENTS",false) + puts template.template_str + end +end diff --git a/src/cli/onevnet b/src/cli/onevnet index 197e6debbf..b5692c51ae 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -142,79 +142,7 @@ CommandParser::CmdParser.new(ARGV) do if args[1] ar = File.read(args[1]) else - ar = 'AR = [ ' - - if options[:ip] - if options[:ip6_global] || options[:ip6_ula] - ar << 'TYPE="IP4_6"' - elsif options[:ip6] - ar << 'TYPE="IP4_6_STATIC"' - else - ar << 'TYPE="IP4"' - end - elsif options[:ip6] - ar << 'TYPE="IP6_STATIC"' - elsif options[:ip6_global] || options[:ip6_ula] - ar << 'TYPE="IP6"' - else - ar << 'TYPE="ETHER"' - end - - if options[:size] - ar << ', SIZE = ' << options[:size] - else - STDERR.puts 'Address range needs to specify size (-s size)' - exit(-1) - end - - if options[:ip6] - m = %r{([\h:]*)\/(\d.*)$}.match(options[:ip6]) - - if m.nil? || m[1].nil? - STDERR.puts 'Missing or wrong IP6' - exit(-1) - else - begin - require 'ipaddr' - - ip = IPAddr.new(m[1]) - - if !ip.ipv6? - STDERR.puts 'Wrong IP6 format address' - exit(-1) - end - rescue StandardError - STDERR.puts 'Wrong IP6 format address' - exit(-1) - end - - end - - if m[2].nil? - STDERR.puts 'IP6 address need to set the prefix length' - exit(-1) - end - - ar << ", PREFIX_LENGTH=\"#{m[2]}\"" - - options[:ip6] = m[1] - end - - ar << ', IP = ' << options[:ip] if options[:ip] - ar << ', IP6 = ' << options[:ip6] if options[:ip6] - ar << ', MAC = ' << options[:mac] if options[:mac] - if options[:ip6_global] - ar << ', GLOBAL_PREFIX = ' << options[:ip6_global] - end - if options[:ip6_ula] - ar << ', ULA_PREFIX = ' << options[:ip6_ula] - end - ar << ', GATEWAY = ' << options[:gateway] if options[:gateway] - ar << ', MASK = ' << options[:netmask] if options[:netmask] - ar << ', VN_MAD = ' << options[:vn_mad] if options[:vn_mad] - ar << ', VLAN_ID = ' << options[:vlanid] if options[:vlanid] - - ar << ']' + ar = OpenNebulaHelper.create_ar(options) end vn.add_ar(ar) diff --git a/src/cli/onevntemplate b/src/cli/onevntemplate new file mode 100755 index 0000000000..998f7e48cb --- /dev/null +++ b/src/cli/onevntemplate @@ -0,0 +1,365 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2018, OpenNebula Project, OpenNebula Systems # +# # +# 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 + +$LOAD_PATH << RUBY_LIB_LOCATION +$LOAD_PATH << RUBY_LIB_LOCATION + '/cli' + +require 'command_parser' +require 'one_helper/onevntemplate_helper' +require 'one_helper/onevnet_helper' +require 'pry' + +CommandParser::CmdParser.new(ARGV) do + usage '`onevntemplate` [] []' + version OpenNebulaHelper::ONE_VERSION + + helper = OneVNTemplateHelper.new + + before_proc do + helper.set_client(options) + end + + USE = { + :name => 'use', + :large => '--use', + :description => 'lock use actions' + } + + MANAGE = { + :name => 'manage', + :large => '--manage', + :description => 'lock manage actions' + } + + ADMIN = { + :name => 'admin', + :large => '--admin', + :description => 'lock admin actions' + } + + ALL = { + :name => 'all', + :large => '--all', + :description => 'lock all actions' + } + + ######################################################################## + # Global Options + ######################################################################## + set :option, CommandParser::OPTIONS + OpenNebulaHelper::CLIENT_OPTIONS + + list_options = CLIHelper::OPTIONS + list_options << OpenNebulaHelper::XML + list_options << OpenNebulaHelper::NUMERIC + list_options << OpenNebulaHelper::DESCRIBE + + instantiate_options = [ + OneVNTemplateHelper::VN_NAME, + OneVNTemplateHelper::MULTIPLE, + OneVNTemplateHelper::EXTENDED, + OpenNebulaHelper::AS_USER, + OpenNebulaHelper::AS_GROUP + ] + + ######################################################################## + # Formatters for arguments + ######################################################################## + set :format, :groupid, OpenNebulaHelper.rname_to_id_desc('GROUP') do |arg| + OpenNebulaHelper.rname_to_id(arg, 'GROUP') + end + + set :format, :userid, OpenNebulaHelper.rname_to_id_desc('USER') do |arg| + OpenNebulaHelper.rname_to_id(arg, 'USER') + end + + set :format, :templateid, OneVNTemplateHelper.to_id_desc do |arg| + helper.to_id(arg) + end + + set :format, :templateid_list, OneVNTemplateHelper.list_to_id_desc do |arg| + helper.list_to_id(arg) + end + + set :format, :filterflag, OneVNTemplateHelper.filterflag_to_i_desc do |arg| + helper.filterflag_to_i(arg) + end + + ######################################################################## + # Commands + ######################################################################## + + create_desc = <<-EOT.unindent + Creates a new Virtual Network Template from the given description + + Examples: + - using a Virtual Network Template description file: + + onevntemplate create vn_description.tmpl + + EOT + + command :create, create_desc, [:file, nil], :options => + [OpenNebulaHelper::DRY] do + + helper.create_resource(options) do |tmpl| + begin + if args[0] + template = File.read(args[0]) + end + + if options[:dry] + puts template + exit 0 + else + tmpl.allocate(template) + end + rescue StandardError => e + STDERR.puts e.messsage + exit(-1) + end + end + end + + clone_desc = <<-EOT.unindent + Creates a new VN Template from an existing one + EOT + + command :clone, clone_desc, :templateid, :name do + + helper.perform_action(args[0], options, 'cloned') do |t| + res = t.clone(args[1]) + + if !OpenNebula.is_error?(res) + puts "ID: #{res}" + else + puts res.message + end + end + end + + delete_desc = <<-EOT.unindent + Deletes the given VN Template + EOT + + command :delete, delete_desc, [:range, :templateid_list] do + + helper.perform_actions(args[0], options, 'deleted') do |t| + t.delete() + end + end + + instantiate_desc = <<-EOT.unindent + Creates a new VN instance from the given VN Template. This VN can be + managed with the 'onevnet' command. + + The source Template can be modified adding or replacing attributes with + the optional file argument, or with the options. + EOT + + command :instantiate, instantiate_desc, :templateid, [:file, nil], + :options => instantiate_options + OneVNetHelper::ADDAR_OPTIONS do + exit_code = 0 + + number = options[:multiple] || 1 + user_inputs = nil + + number.times do |i| + exit_code = helper.perform_action(args[0], options, + 'instantiated') do |t| + name = options[:name] + name = name.gsub('%i', i.to_s) if name + + extra_template = '' + rc = t.info + + if OpenNebula.is_error?(rc) + STDERR.puts rc.message + exit(-1) + end + + if args[1] + extra_template = File.read(args[1]) + else + res = OpenNebulaHelper.create_template(options, t) + + if res.first != 0 + STDERR.puts res.last + next -1 + end + + extra_template = res.last + + if OneVNetHelper.add_ar_options_used?(options) + extra_template << OpenNebulaHelper.create_ar(options) + end + end + + res = t.instantiate(name, extra_template) + + if !OpenNebula.is_error?(res) + puts "VN ID: #{res}" + end + + res + end + + break if exit_code == -1 + end + + exit_code + end + + chgrp_desc = <<-EOT.unindent + Changes the VN Template group + EOT + + command :chgrp, chgrp_desc, [:range, :templateid_list], :groupid do + helper.perform_actions(args[0], options, 'Group changed') do |t| + t.chown(-1, args[1].to_i) + end + end + + chown_desc = <<-EOT.unindent + Changes the VN Template owner and group + EOT + + command :chown, chown_desc, [:range, :templateid_list], :userid, + [:groupid, nil] do + args[2].nil? ? gid = -1 : gid = args[2].to_i + helper.perform_actions(args[0], options, 'Owner/Group changed') do |t| + t.chown(args[1].to_i, gid) + end + end + + chmod_desc = <<-EOT.unindent + Changes the VN Template permissions + EOT + + command :chmod, chmod_desc, [:range, :templateid_list], :octet do + + recursive = (options[:recursive] == true) + + helper.perform_actions(args[0], options, 'Permissions changed') do |t| + t.chmod_octet(args[1], recursive) + end + end + + update_desc = <<-EOT.unindent + Update the VN template contents. If a path is not provided the editor will + be launched to modify the current content. + EOT + + command :update, update_desc, :templateid, [:file, nil], + :options => OpenNebulaHelper::APPEND do + helper.perform_action(args[0], options, 'modified') do |obj| + if options[:append] + str = OpenNebulaHelper.append_template(args[0], obj, args[1]) + else + str = OpenNebulaHelper.update_template(args[0], obj, args[1]) + end + + helper.set_client(options) + obj = helper.retrieve_resource(obj.id) + + obj.update(str, options[:append]) + end + end + + list_desc = <<-EOT.unindent + Lists VN Templates in the pool + EOT + + rename_desc = <<-EOT.unindent + Renames the VN Template + EOT + + command :rename, rename_desc, :templateid, :name do + helper.perform_action(args[0], options, 'renamed') do |o| + o.rename(args[1]) + end + end + + command :list, list_desc, [:filterflag, nil], :options => list_options do + helper.list_pool(options, false, args[0]) + end + + show_desc = <<-EOT.unindent + Shows information for the given VN Template + EOT + + command :show, show_desc, :templateid, + :options => [OpenNebulaHelper::XML, OneTemplateHelper::EXTENDED] do + + helper.show_resource(args[0], options) + end + + top_desc = <<-EOT.unindent + Lists Templates continuously + EOT + + command :top, top_desc, [:filterflag, nil], :options => list_options do + helper.list_pool(options, true, args[0]) + end + + lock_desc = <<-EOT.unindent + Locks a VN template with differents levels for lock any actions with this VN template, + show and monitoring never will be locked. + Valid states are: All. + Levels: + [Use]: locks Admin, Manage and Use actions. + [Manage]: locks Manage and Use actions. + [Admin]: locks only Admin actions. + EOT + + command :lock, lock_desc, :templateid, + :options => [USE, MANAGE, ADMIN, ALL] do + helper.perform_action(args[0], options, 'VN Template locked') do |t| + if !options[:use].nil? + level = 1 + elsif !options[:manage].nil? + level = 2 + elsif !options[:admin].nil? + level = 3 + elsif !options[:all].nil? + level = 4 + else + level = 1 + end + t.lock(level) + end + end + + unlock_desc = <<-EOT.unindent + Unlocks a VN template for unlock any actions with this VN template. + Valid states are: All. + EOT + + command :unlock, unlock_desc, :templateid do + helper.perform_action(args[0], options, 'VN Template unlocked') do |t| + t.unlock + end + end +end diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 7a32432b05..694a62198e 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -387,6 +387,7 @@ void Nebula::start(bool bootstrap_only) rc += SecurityGroupPool::bootstrap(logdb); rc += VirtualRouterPool::bootstrap(logdb); rc += VMGroupPool::bootstrap(logdb); + rc += VNTemplatePool::bootstrap(logdb); // Create the system tables only if bootstrap went well if (rc == 0) @@ -665,6 +666,7 @@ void Nebula::start(bool bootstrap_only) vdcpool = new VdcPool(db_ptr, is_federation_slave()); tpool = new VMTemplatePool(logdb); + vntpool = new VNTemplatePool(logdb); secgrouppool = new SecurityGroupPool(logdb); diff --git a/src/nebula/SConstruct b/src/nebula/SConstruct index 190f385475..eb6d51106d 100644 --- a/src/nebula/SConstruct +++ b/src/nebula/SConstruct @@ -52,6 +52,7 @@ env.Prepend(LIBS=[ 'nebula_host', 'nebula_cluster', 'nebula_vnm', + 'nebula_vntemplate', 'nebula_vm', 'nebula_vmtemplate', 'nebula_document', diff --git a/src/oca/go/src/goca/vntemplate.go b/src/oca/go/src/goca/vntemplate.go new file mode 100644 index 0000000000..104dd86e0e --- /dev/null +++ b/src/oca/go/src/goca/vntemplate.go @@ -0,0 +1,169 @@ +package goca + +import ( + "errors" +) + +// VNTemplate represents an OpenNebula Virtual Network Template +type VNTemplate struct { + XMLResource + ID uint + Name string +} + +// VNTemplatePool represents an OpenNebula Virtual Network TemplatePool +type VNTemplatePool struct { + XMLResource +} + +// NewVNTemplatePool returns a vntemplate pool. A connection to OpenNebula is +// performed. +func NewVNTemplatePool(args ...int) (*VNTemplatePool, error) { + var who, start, end int + + switch len(args) { + case 0: + who = PoolWhoMine + start = -1 + end = -1 + case 3: + who = args[0] + start = args[1] + end = args[2] + default: + return nil, errors.New("Wrong number of arguments") + } + + response, err := client.Call("one.vntemplatepool.info", who, start, end) + if err != nil { + return nil, err + } + + vntemplatepool := &VNTemplatePool{XMLResource{body: response.Body()}} + + return vntemplatepool, err + +} + +// NewVNTemplate finds a vntemplate object by ID. No connection to OpenNebula. +func NewVNTemplate(id uint) *VNTemplate { + return &VNTemplate{ID: id} +} + +// NewVNTemplateFromName finds a vntemplate object by name. It connects to +// OpenNebula to retrieve the pool, but doesn't perform the Info() call to +// retrieve the attributes of the vntemplate. +func NewVNTemplateFromName(name string) (*VNTemplate, error) { + vntemplatePool, err := NewVNTemplatePool() + if err != nil { + return nil, err + } + + id, err := vntemplatePool.GetIDFromName(name, "/VNTEMPLATE_POOL/VNTEMPLATE") + if err != nil { + return nil, err + } + + return NewVNTemplate(id), nil +} + +// CreateVNTemplate allocates a new vntemplate. It returns the new vntemplate ID. +func CreateVNTemplate(vntemplate string) (uint, error) { + response, err := client.Call("one.vntemplate.allocate", vntemplate) + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Info connects to OpenNebula and fetches the information of the VNTemplate +func (vntemplate *VNTemplate) Info() error { + response, err := client.Call("one.vntemplate.info", vntemplate.ID) + vntemplate.body = response.Body() + return err +} + +// Update will modify the vntemplate. If appendTemplate is 0, it will +// replace the whole vntemplate. If its 1, it will merge. +func (vntemplate *VNTemplate) Update(tpl string, appendTemplate int) error { + _, err := client.Call("one.vntemplate.update", vntemplate.ID, tpl, appendTemplate) + return err +} + +// Chown changes the owner/group of a vntemplate. If uid or gid is -1 it will not +// change +func (vntemplate *VNTemplate) Chown(uid, gid int) error { + _, err := client.Call("one.vntemplate.chown", vntemplate.ID, uid, gid) + return err +} + +// Chmod changes the permissions of a vntemplate. If any perm is -1 it will not +// change +func (vntemplate *VNTemplate) Chmod(uu, um, ua, gu, gm, ga, ou, om, oa int) error { + _, err := client.Call("one.vntemplate.chmod", vntemplate.ID, uu, um, ua, gu, gm, ga, ou, om, oa) + return err +} + +// Rename changes the name of vntemplate +func (vntemplate *VNTemplate) Rename(newName string) error { + _, err := client.Call("one.vntemplate.rename", vntemplate.ID, newName) + return err +} + +// Delete will remove the vntemplate from OpenNebula. +func (vntemplate *VNTemplate) Delete() error { + _, err := client.Call("one.vntemplate.delete", vntemplate.ID) + return err +} + +// Instantiate will instantiate the template +func (vntemplate *VNTemplate) Instantiate(name string, extra string) (uint, error) { + response, err := client.Call("one.vntemplate.instantiate", vntemplate.ID, name, extra) + + if err != nil { + return 0, err + } + + return uint(response.BodyInt()), nil +} + +// Clone an existing vntemplate. +func (vntemplate *VNTemplate) Clone(name string) error { + _, err := client.Call("one.vntemplate.clone", vntemplate.ID, name) + return err +} + +//Lock an existing vntemplate +func (vntemplate *VNTemplate) Lock(level uint) error { + _, err := client.Call("one.vntemplate.lock", vntemplate.ID, level) + return err +} + +//Unlock an existing vntemplate +func (vntemplate *VNTemplate) Unlock() error { + _, err := client.Call("one.vntemplate.unlock", vntemplate.ID) + return err +} + +// Lock actions + +// LockUse locks USE actions for the vntemplate +func (vntemplate *VNTemplate) LockUse() error { + return vntemplate.Lock(1) +} + +// LockManage locks MANAGE actions for the vntemplate +func (vntemplate *VNTemplate) LockManage() error { + return vntemplate.Lock(2) +} + +// LockAdmin locks ADMIN actions for the vntemplate +func (vntemplate *VNTemplate) LockAdmin() error { + return vntemplate.Lock(3) +} + +// LockAll locks all actions for the vntemplate +func (vntemplate *VNTemplate) LockAll() error { + return vntemplate.Lock(4) +} diff --git a/src/oca/java/src/org/opennebula/client/vntemplate/VirtualNetworkTemplate.java b/src/oca/java/src/org/opennebula/client/vntemplate/VirtualNetworkTemplate.java new file mode 100644 index 0000000000..b470c9d8a4 --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/vntemplate/VirtualNetworkTemplate.java @@ -0,0 +1,541 @@ +/******************************************************************************* + * Copyright 2002-2018, OpenNebula Project, OpenNebula Systems + * + * 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.vntemplate; + +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 Virtual Network template. + * It also offers static XML-RPC call wrappers. + */ +public class VirtualNetworkTemplate extends PoolElement +{ + + private static final String METHOD_PREFIX = "vntemplate."; + 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 CHOWN = METHOD_PREFIX + "chown"; + private static final String CHMOD = METHOD_PREFIX + "chmod"; + private static final String INSTANTIATE = METHOD_PREFIX + "instantiate"; + private static final String CLONE = METHOD_PREFIX + "clone"; + private static final String RENAME = METHOD_PREFIX + "rename"; + private static final String LOCK = METHOD_PREFIX + "lock"; + private static final String UNLOCK = METHOD_PREFIX + "unlock"; + + /** + * Creates a new VNTemplate representation. + * @param id The VNtemplate id. + * @param client XML-RPC Client. + */ + public VirtualNetworkTemplate(int id, Client client) + { + super(id, client); + } + + /** + * @see PoolElement + */ + protected VirtualNetworkTemplate(Node xmlElement, Client client) + { + super(xmlElement, client); + } + + // ================================= + // Static XML-RPC methods + // ================================= + + + /** + * Allocates a new VNTemplate in OpenNebula. + * + * @param client XML-RPC Client. + * @param description A string containing the template of the vntemplate. + * @return If successful the message contains the associated + * id generated for this VNTemplate. + */ + public static OneResponse allocate(Client client, String description) + { + return client.call(ALLOCATE, description); + } + + /** + * Retrieves the information of the given VNTemplate. + * + * @param client XML-RPC Client. + * @param id The vntemplate id for the vntemplate 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 info(client, id, false); + } + + /** + * Retrieves the information of the given VNTemplate. + * + * @param client XML-RPC Client. + * @param id The VNtemplate id for the VNtemplate 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, false); + } + + /** + * Deletes a VNTemplate from OpenNebula. + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate we want to delete. + * @return A encapsulated response. + */ + public static OneResponse delete(Client client, int id) + { + return client.call(DELETE, id, false); + } + + /** + * Replaces the VNTemplate contents. + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate we want to modify. + * @param new_template New vntemplate contents. + * @param append True to append new attributes instead of replace the whole vntemplate + * @return If successful the message contains the vntemplate id. + */ + public static OneResponse update(Client client, int id, String new_template, + boolean append) + { + return client.call(UPDATE, id, new_template, append ? 1 : 0); + } + + /** + * Publishes or unpublishes a VNTemplate. + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate we want to modify. + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the vntemplate id. + */ + public static OneResponse publish(Client client, int id, boolean publish) + { + int group_u = publish ? 1 : 0; + + return chmod(client, id, -1, -1, -1, group_u, -1, -1, -1, -1, -1); + } + + /** + * Changes the owner/group + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate we want to modify. + * @param uid The new owner user ID. Set it to -1 to leave the current one. + * @param gid The new group ID. Set it to -1 to leave the current one. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse chown(Client client, int id, int uid, int gid) + { + return client.call(CHOWN, id, uid, gid); + } + + /** + * Changes the vntemplate permissions + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate. + * @param owner_u 1 to allow, 0 deny, -1 do not change + * @param owner_m 1 to allow, 0 deny, -1 do not change + * @param owner_a 1 to allow, 0 deny, -1 do not change + * @param group_u 1 to allow, 0 deny, -1 do not change + * @param group_m 1 to allow, 0 deny, -1 do not change + * @param group_a 1 to allow, 0 deny, -1 do not change + * @param other_u 1 to allow, 0 deny, -1 do not change + * @param other_m 1 to allow, 0 deny, -1 do not change + * @param other_a 1 to allow, 0 deny, -1 do not change + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse chmod(Client client, int id, + int owner_u, int owner_m, int owner_a, + int group_u, int group_m, int group_a, + int other_u, int other_m, int other_a) + { + return client.call(CHMOD, id, + owner_u, owner_m, owner_a, + group_u, group_m, group_a, + other_u, other_m, other_a, + false); + } + + /** + * Changes the permissions + * + * @param client XML-RPC Client. + * @param id The id of the target object. + * @param octet Permissions octed , e.g. 640 + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse chmod(Client client, int id, String octet) + { + return chmod(client, id, octet, false); + } + + /** + * Changes the permissions + * + * @param client XML-RPC Client. + * @param id The id of the target object. + * @param octet Permissions octed , e.g. 640 + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse chmod(Client client, int id, int octet) + { + return chmod(client, id, octet, false); + } + + /** + * Creates a VNET instance from a VNTemplate + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate. + * @param name A string containing the name of the VM instance, can be empty. + * @param template User provided VNTemplate to merge with the one + * being instantiated + * @return If successful the message contains the VM Instance ID. + */ + public static OneResponse instantiate(Client client, int id, String name, String template) + { + return client.call(INSTANTIATE, id, name, template); + } + + /** + * Clones this vntemplate into a new one + * + * @param client XML-RPC Client. + * @param id The vntemplate id of the target vntemplate. + * @param name Name for the new vntemplate. + * @return If successful the message contains the new vntemplate ID. + */ + public static OneResponse clone(Client client, int id, String name) + { + return clone(client, id, name); + } + + /** + * Renames this VNTemplate + * + * @param client XML-RPC Client. + * @param id The VNTemplate id of the target VNTemplate. + * @param name New name for the VNTemplate. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse rename(Client client, int id, String name) + { + return client.call(RENAME, id, name); + } + + /** + * lock this VNtemplate + * + * @param client XML-RPC Client. + * @param id The vntemplate id. + * @param level Lock level. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse lock(Client client, int id, int level) + { + return client.call(LOCK, id, level); + } + + /** + * Unlock this vntemplate + * + * @param client XML-RPC Client. + * @param id The vntemplate id. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse unlock(Client client, int id) + { + return client.call(UNLOCK, id); + } + + // ================================= + // Instanced object XML-RPC methods + // ================================= + + /** + * Retrieves the information of the VNTemplate. + * + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse info() + { + return info(false); + } + + /** + * Retrieves the information of the given VNTemplate. + * + * @param extended optional flag to process the vntemplate and include + * extended information, such as the SIZE for each DISK + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse info(boolean extended) + { + OneResponse response = info(client, id, extended); + super.processInfo(response); + return response; + } + + /** + * Deletes the vntemplate from OpenNebula. + * + * @return A encapsulated response. + */ + public OneResponse delete() + { + return delete(client, id, false); + } + + /** + * Replaces the vntemplate contents. + * + * @param new_template New VNtemplate contents. + * @return If successful the message contains the vntemplate id. + */ + public OneResponse update(String new_template) + { + return update(new_template, false); + } + + /** + * Replaces the vntemplate contents. + * + * @param new_template New vntemplate contents. + * @param append True to append new attributes instead of replace the whole vntemplate + * @return If successful the message contains the vntemplate id. + */ + public OneResponse update(String new_template, boolean append) + { + return update(client, id, new_template, append); + } + + /** + * Publishes or unpublishes the vntemplate. + * + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the vntemplate id. + */ + public OneResponse publish(boolean publish) + { + return publish(client, id, publish); + } + + /** + * Publishes the vntemplate. + * + * @return If successful the message contains the vntemplate id. + */ + public OneResponse publish() + { + return publish(true); + } + + /** + * Unpublishes the vntemplate. + * + * @return If successful the message contains the vntemplate id. + */ + public OneResponse unpublish() + { + return publish(false); + } + + /** + * Changes the owner/group + * + * @param uid The new owner user ID. Set it to -1 to leave the current one. + * @param gid The new group ID. Set it to -1 to leave the current one. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse chown(int uid, int gid) + { + return chown(client, id, uid, gid); + } + + /** + * Changes the owner + * + * @param uid The new owner user ID. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse chown(int uid) + { + return chown(uid, -1); + } + + /** + * Changes the group + * + * @param gid The new group ID. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse chgrp(int gid) + { + return chown(-1, gid); + } + + /** + * Changes the vntemplate permissions + * + * @param owner_u 1 to allow, 0 deny, -1 do not change + * @param owner_m 1 to allow, 0 deny, -1 do not change + * @param owner_a 1 to allow, 0 deny, -1 do not change + * @param group_u 1 to allow, 0 deny, -1 do not change + * @param group_m 1 to allow, 0 deny, -1 do not change + * @param group_a 1 to allow, 0 deny, -1 do not change + * @param other_u 1 to allow, 0 deny, -1 do not change + * @param other_m 1 to allow, 0 deny, -1 do not change + * @param other_a 1 to allow, 0 deny, -1 do not change + * @return If an error occurs the error message contains the reason. + */ + public OneResponse chmod(int owner_u, int owner_m, int owner_a, + int group_u, int group_m, int group_a, + int other_u, int other_m, int other_a) + { + return chmod(client, id, + owner_u, owner_m, owner_a, + group_u, group_m, group_a, + other_u, other_m, other_a, + false); + } + + /** + * Changes the permissions + * + * @param octet Permissions octed , e.g. 640 + * @return If an error occurs the error message contains the reason. + */ + public OneResponse chmod(String octet) + { + return chmod(client, id, octet, false); + } + + /** + * Changes the permissions + * + * @param octet Permissions octed , e.g. 640 + * @return If an error occurs the error message contains the reason. + */ + public OneResponse chmod(int octet) + { + return chmod(client, id, octet, false); + } + + /** + * Creates a VNET instance from a VNTemplate + * + * @param name A string containing the name of the VM instance, can be empty. + * @param onHold False to create this VM in pending state, true on hold + * @param template User provided Template to merge with the one + * being instantiated + * @param persistent true to create a private persistent copy of the + * template plus any image defined in DISK, and instantiate that copy + * + * @return If successful the message contains the VM Instance ID. + */ + public OneResponse instantiate(String name, String template) + { + return instantiate(client, id, name, template); + } + + /** + * Creates a VM instance from a VNTemplate + * + * @param name A string containing the name of the VM instance, can be empty. + * @return If successful the message contains the VM Instance ID. + */ + public OneResponse instantiate(String name) + { + return instantiate(client, id, name, "",); + } + + /** + * Creates a VM instance from a VNTemplate + * + * @return If successful the message contains the VM Instance ID. + */ + public OneResponse instantiate() + { + return instantiate(client, id, "", ""); + } + + /** + * Clones this vntemplate into a new one + * + * @param name Name for the new vntemplate. + * @return If successful the message contains the new vntemplate ID. + */ + public OneResponse clone(String name) + { + return clone(client, id, name); + } + + + /** + * Renames this VNTemplate + * + * @param name New name for the VNTemplate. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse rename(String name) + { + return rename(client, id, name); + } + + /** + * Lock this VNtemplate + * + * @param level Lock level. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse lock(int level) + { + return lock(client, id, level); + } + + /** + * Unlock this VNtemplate + * + * @return If an error occurs the error message contains the reason. + */ + public OneResponse unlock() + { + return unlock(client, id); + } + + // ================================= + // Helpers + // ================================= +} diff --git a/src/oca/java/src/org/opennebula/client/vntemplate/VirtualNetworkTemplatePool.java b/src/oca/java/src/org/opennebula/client/vntemplate/VirtualNetworkTemplatePool.java new file mode 100644 index 0000000000..84ef3107f3 --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/vntemplate/VirtualNetworkTemplatePool.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright 2002-2018, OpenNebula Project, OpenNebula Systems + * + * 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.vntemplate; + +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 Virtual Network Template pool. + * It also offers static XML-RPC call wrappers. + */ +public class VirtualNetworkTemplatePool extends Pool implements Iterable