1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-21 18:03:38 +03:00

F #826 Authorize user/group to create restricted networks (#2625)

This commit is contained in:
Christian González 2018-11-20 17:24:59 +01:00 committed by Ruben S. Montero
parent 82690013e7
commit d921610d15
55 changed files with 3491 additions and 139 deletions

View File

@ -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',

View File

@ -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
// ---------------------------------------------------------------

View File

@ -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;
};

View File

@ -98,6 +98,8 @@ public:
return PoolObjectSQL::exist(db, table.c_str(), oid);
}
void exist(const string& id_str, std::set<int>& id_list);
/**
* Finds a set objects that satisfies a given condition
* @param oids a vector with the oids of the objects.

View File

@ -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);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

View File

@ -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);
}
};
/* ------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

View File

@ -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(){};
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

View File

@ -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<VNTemplate*>(obj)->clone_template();
};
int pool_allocate(int sid, Template * tmpl, int& id, RequestAttributes& att)
{
VNTemplatePool * tpool = static_cast<VNTemplatePool *>(pool);
VirtualNetworkTemplate * t = static_cast<VirtualNetworkTemplate*>(tmpl);
return tpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
t, &id, att.resp_msg);
};
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

View File

@ -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:

View File

@ -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);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

View File

@ -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:

View File

@ -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:

View File

@ -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
{

View File

@ -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:

View File

@ -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

155
include/VNTemplate.h Normal file
View File

@ -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<VirtualNetworkTemplate *>(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_*/

119
include/VNTemplatePool.h Normal file
View File

@ -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<VNTemplate *>(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<VNTemplate *>(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_*/

View File

@ -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
// *************************************************************************

View File

@ -31,6 +31,8 @@ public:
~VirtualNetworkTemplate(){};
VirtualNetworkTemplate(VirtualNetworkTemplate& vnt):Template(vnt){};
// -------------------------------------------------------------------------
// Restricted attributes interface implementation
// -------------------------------------------------------------------------

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://opennebula.org/XMLSchema" elementFormDefault="qualified" targetNamespace="http://opennebula.org/XMLSchema">
<xs:element name="VNTEMPLATE">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:integer"/>
<xs:element name="UID" type="xs:integer"/>
<xs:element name="GID" type="xs:integer"/>
<xs:element name="UNAME" type="xs:string"/>
<xs:element name="GNAME" type="xs:string"/>
<xs:element name="NAME" type="xs:string"/>
<xs:element name="LOCK" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="LOCKED" type="xs:integer"/>
<xs:element name="OWNER" type="xs:integer"/>
<xs:element name="TIME" type="xs:integer"/>
<xs:element name="REQ_ID" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="PERMISSIONS" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="OWNER_U" type="xs:integer"/>
<xs:element name="OWNER_M" type="xs:integer"/>
<xs:element name="OWNER_A" type="xs:integer"/>
<xs:element name="GROUP_U" type="xs:integer"/>
<xs:element name="GROUP_M" type="xs:integer"/>
<xs:element name="GROUP_A" type="xs:integer"/>
<xs:element name="OTHER_U" type="xs:integer"/>
<xs:element name="OTHER_M" type="xs:integer"/>
<xs:element name="OTHER_A" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="REGTIME" type="xs:integer"/>
<xs:element name="TEMPLATE">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
<xs:element name="VN_MAD" type="xs:string"/>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="http://opennebula.org/XMLSchema" xmlns="http://opennebula.org/XMLSchema">
<xs:include schemaLocation="vntemplate.xsd"/>
<xs:element name="VNTEMPLATE_POOL">
<xs:complexType>
<xs:sequence maxOccurs="1" minOccurs="1">
<xs:element ref="VNTEMPLATE" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -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
#*******************************************************************************

View File

@ -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 )
{

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

365
src/cli/onevntemplate Executable file
View File

@ -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` <command> [<args>] [<options>]'
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

View File

@ -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);

View File

@ -52,6 +52,7 @@ env.Prepend(LIBS=[
'nebula_host',
'nebula_cluster',
'nebula_vnm',
'nebula_vntemplate',
'nebula_vm',
'nebula_vmtemplate',
'nebula_document',

View File

@ -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)
}

View File

@ -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
// =================================
}

View File

@ -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<Template>
{
private static final String ELEMENT_NAME = "VNTEMPLATE";
private static final String INFO_METHOD = "vntemplatepool.info";
private int filter;
/**
* Creates a new Virtual Network Template pool with the default filter flag value
* set to (Template belonging to the connected user,
* and the ones in his group)
*
* @param client XML-RPC Client.
*
* @see TemplatePool#TemplatePool(Client, int)
*/
public VirtualNetworkTemplatePool(Client client)
{
super(ELEMENT_NAME, client, INFO_METHOD);
this.filter = MINE_GROUP;
}
/**
* Creates a new Virtuan Network Template pool.
*
* @param client XML-RPC Client.
* @param filter Filter flag to use by default in the method
*/
public VirtualNetworkTemplatePool(Client client, int filter)
{
super(ELEMENT_NAME, client, INFO_METHOD);
this.filter = filter;
}
/* (non-Javadoc)
* @see org.opennebula.client.Pool#factory(org.w3c.dom.Node)
*/
@Override
public PoolElement factory(Node node)
{
return new VirtualNetworkTemplate(node, client);
}
/**
* Retrieves all or part of the VNTemplates in the pool.
*
* @param client XML-RPC Client.
* @param filter Filter flag to use. Possible values:
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse info(Client client, int filter)
{
return Pool.info(client, INFO_METHOD, filter, -1, -1);
}
/**
* Retrieves all the VNTemplates in the pool.
*
* @param client XML-RPC Client.
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse infoAll(Client client)
{
return Pool.infoAll(client, INFO_METHOD);
}
/**
* Retrieves all the connected user's VNTemplates.
*
* @param client XML-RPC Client.
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse infoMine(Client client)
{
return Pool.infoMine(client, INFO_METHOD);
}
/**
* Retrieves all the connected user's VNTemplates and the ones in
* his group.
*
* @param client XML-RPC Client.
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse infoGroup(Client client)
{
return Pool.infoGroup(client, INFO_METHOD);
}
/**
* Retrieves all or part of the VNTemplates in the pool. The VNTemplates to retrieve
* can be also filtered by Id, specifying the first and last Id to include.
*
* @param client XML-RPC Client.
* @param filter Filter flag to use. Possible values:
* @param startId Lowest Id to retrieve
* @param endId Biggest Id to retrieve
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public static OneResponse info(Client client, int filter,
int startId, int endId)
{
return Pool.info(client, INFO_METHOD, filter, startId, endId);
}
/**
* Loads the xml representation of all or part of the
* VNTemplates in the pool. The filter used is the one set in
* the constructor.
*
* @see TemplatePool#info(Client, int)
*
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse info()
{
return super.info(filter, -1, -1);
}
/**
* Loads the xml representation of all the VNTemplates in the pool.
*
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse infoAll()
{
return super.infoAll();
}
/**
* Loads the xml representation of all the connected user's VNTemplates.
*
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse infoMine()
{
return super.infoMine();
}
/**
* Loads the xml representation of all the connected user's VNTemplates and
* the ones in his group.
*
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse infoGroup()
{
return super.infoGroup();
}
/**
* Retrieves all or part of the Templates in the pool. The Templates to retrieve
* can be also filtered by Id, specifying the first and last Id to include.
*
* @param filter Filter flag to use. Possible values:
* @param startId Lowest Id to retrieve
* @param endId Biggest Id to retrieve
* @return If successful the message contains the string
* with the information returned by OpenNebula.
*/
public OneResponse info(int filter, int startId, int endId)
{
return super.info(filter, startId, endId);
}
public Iterator<VirtualNetworkTemplate> iterator()
{
AbstractList<VirtualNetworkTemplate> ab = new AbstractList<VirtualNetworkTemplate>()
{
public int size()
{
return getLength();
}
public VirtualNetworkTemplate get(int index)
{
return (VirtualNetworkTemplate) item(index);
}
};
return ab.iterator();
}
/**
* Returns the VNTemplate with the given Id from the pool. If it is not found,
* then returns null. The method {@link #info()} must be called before.
*
* @param id of the ACl rule to retrieve
* @return The VNTemplate with the given Id, or null if it was not found.
*/
public VirtualNetworkTemplate getById(int id)
{
return (VirtualNetworkTemplate) super.getById(id);
}
}

View File

@ -65,6 +65,8 @@ require 'opennebula/marketplaceapp'
require 'opennebula/marketplaceapp_pool'
require 'opennebula/vm_group'
require 'opennebula/vm_group_pool'
require 'opennebula/vntemplate'
require 'opennebula/vntemplate_pool'
module OpenNebula

View File

@ -72,7 +72,8 @@ module OpenNebula
"VROUTER" => 0x4000000000000,
"MARKETPLACE" => 0x8000000000000,
"MARKETPLACEAPP"=> 0x10000000000000,
"VMGROUP" => 0x20000000000000
"VMGROUP" => 0x20000000000000,
"VNTEMPLATE" => 0x40000000000000
}
RIGHTS =

View File

@ -0,0 +1,260 @@
# -------------------------------------------------------------------------- #
# 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 'opennebula/pool_element'
module OpenNebula
class VNTemplate < PoolElement
#######################################################################
# Constants and Class Methods
#######################################################################
TEMPLATE_METHODS = {
:allocate => "vntemplate.allocate",
:instantiate => "vntemplate.instantiate",
:info => "vntemplate.info",
:update => "vntemplate.update",
:delete => "vntemplate.delete",
:chown => "vntemplate.chown",
:chmod => "vntemplate.chmod",
:clone => "vntemplate.clone",
:rename => "vntemplate.rename",
:lock => "vntemplate.lock",
:unlock => "vntemplate.unlock"
}
# Creates a VNTemplate description with just its identifier
# this method should be used to create plain VNTemplate objects.
# +id+ the id of the user
#
# Example:
# vntemplate = VNTemplate.new(VNTemplate.build_xml(3),rpc_client)
#
def VNTemplate.build_xml(pe_id=nil)
if pe_id
obj_xml = "<VNTEMPLATE><ID>#{pe_id}</ID></VNTEMPLATE>"
else
obj_xml = "<VNTEMPLATE></VNTEMPLATE>"
end
XMLElement.build_xml(obj_xml,'VNTEMPLATE')
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 VNTemplate.
# include extended information, such as the SIZE for each DISK
def info()
return Error.new('ID not defined') if !@pe_id
rc = @client.call(TEMPLATE_METHODS[:info], @pe_id, false)
if !OpenNebula.is_error?(rc)
initialize_xml(rc, 'VNTEMPLATE')
rc = nil
@pe_id = self['ID'].to_i if self['ID']
@name = self['NAME'] if self['NAME']
end
return rc
end
alias_method :info!, :info
# Allocates a new VNTemplate in OpenNebula
#
# @param description [String] The contents of the VNTemplate.
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def allocate(description)
super(TEMPLATE_METHODS[:allocate], description)
end
# Deletes the Template
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def delete()
return call(TEMPLATE_METHODS[:delete], @pe_id, false)
end
# Creates a VNet instance from a VNTemplate
#
# @param name [String] Name for the VNet instance. If it is an empty
# string OpenNebula will set a default name
# @param template [String] User provided VNTemplate to merge with the
# one being instantiated
#
# @return [Integer, OpenNebula::Error] The new VNet id, Error
# otherwise
def instantiate(name="", template="")
return Error.new('ID not defined') if !@pe_id
name ||= ""
template ||= ""
rc = @client.call(TEMPLATE_METHODS[:instantiate], @pe_id,
name, template)
return rc
end
# Replaces the vntemplate contents
#
# @param new_template [String] New vntemplate contents
# @param append [true, false] True to append new attributes instead of
# replace the whole template
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def update(new_template, append=false)
super(TEMPLATE_METHODS[:update], new_template, append ? 1 : 0)
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
# Changes the owner/group
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# gid:: _Integer_ the new group id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(uid, gid)
super(TEMPLATE_METHODS[:chown], uid, gid)
end
# Changes the VNTemplate permissions.
#
# @param octet [String] Permissions octed , e.g. 640
# @param recursive [true,false] optional, chmods the vntemplate plus
# any image defined in DISK.
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def chmod_octet(octet, recursive=false)
owner_u = octet[0..0].to_i & 4 != 0 ? 1 : 0
owner_m = octet[0..0].to_i & 2 != 0 ? 1 : 0
owner_a = octet[0..0].to_i & 1 != 0 ? 1 : 0
group_u = octet[1..1].to_i & 4 != 0 ? 1 : 0
group_m = octet[1..1].to_i & 2 != 0 ? 1 : 0
group_a = octet[1..1].to_i & 1 != 0 ? 1 : 0
other_u = octet[2..2].to_i & 4 != 0 ? 1 : 0
other_m = octet[2..2].to_i & 2 != 0 ? 1 : 0
other_a = octet[2..2].to_i & 1 != 0 ? 1 : 0
chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u,
other_m, other_a, recursive)
end
# Changes the VNTemplate permissions.
# Each [Integer] argument must be 1 to allow, 0 deny, -1 do not change
#
# @param recursive [true,false] optional, chmods the vntemplate plus
# any image defined in DISK.
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u,
other_m, other_a, recursive=false)
return call(TEMPLATE_METHODS[:chmod], @pe_id, owner_u, owner_m, owner_a, group_u,
group_m, group_a, other_u, other_m, other_a, recursive)
end
# Clones this VNTemplate into a new one
#
# @param [String] name for the new VNTemplate.
# any image defined in DISK. The new IMAGE_ID is set into each DISK.
#
# @return [Integer, OpenNebula::Error] The new Template ID in case
# of success, Error otherwise
def clone(name)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(TEMPLATE_METHODS[:clone], @pe_id, name, false)
return rc
end
# Renames this VNTemplate
#
# @param name [String] New name for the VNTemplate.
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def rename(name)
return call(TEMPLATE_METHODS[:rename], @pe_id, name)
end
#######################################################################
# Helpers to get VNTemplate information
#######################################################################
# Returns the group identifier
# [return] _Integer_ the element's group ID
def gid
self['GID'].to_i
end
def owner_id
self['UID'].to_i
end
# Lock a VNTemplate
def lock(level)
return call(TEMPLATE_METHODS[:lock], @pe_id, level)
end
# Unlock a VNTemplate
def unlock()
return call(TEMPLATE_METHODS[:unlock], @pe_id)
end
def public?
if self['PERMISSIONS/GROUP_U'] == "1" || self['PERMISSIONS/OTHER_U'] == "1"
true
else
false
end
end
private
def set_publish(published)
group_u = published ? 1 : 0
chmod(-1, -1, -1, group_u, -1, -1, -1, -1, -1)
end
end
end

View File

@ -0,0 +1,79 @@
# -------------------------------------------------------------------------- #
# 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 'opennebula/pool'
module OpenNebula
class VNTemplatePool < Pool
#######################################################################
# Constants and Class attribute accessors
#######################################################################
TEMPLATE_POOL_METHODS = {
:info => "vntemplatepool.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('VNTEMPLATE_POOL','VNTEMPLATE',client)
@user_id = user_id
end
# Factory method to create Template objects
def factory(element_xml)
OpenNebula::VNTemplate.new(element_xml,@client)
end
#######################################################################
# XML-RPC Methods for the Template Object
#######################################################################
# Retrieves all or part of the Templates in the pool.
def info(*args)
case args.size
when 0
info_filter(TEMPLATE_POOL_METHODS[:info],@user_id,-1,-1)
when 3
info_filter(TEMPLATE_POOL_METHODS[:info],args[0],args[1],args[2])
end
end
def info_all()
return super(TEMPLATE_POOL_METHODS[:info])
end
def info_mine()
return super(TEMPLATE_POOL_METHODS[:info])
end
def info_group()
return super(TEMPLATE_POOL_METHODS[:info])
end
alias_method :info!, :info
alias_method :info_all!, :info_all
alias_method :info_mine!, :info_mine
alias_method :info_group!, :info_group
end
end

View File

@ -92,6 +92,10 @@ class OneDBBacKEnd
"body MEDIUMTEXT, uid INTEGER, gid INTEGER, " <<
"last_poll INTEGER, state INTEGER, lcm_state INTEGER, " <<
"owner_u INTEGER, group_u INTEGER, other_u INTEGER, short_body MEDIUMTEXT",
vn_template_pool: "oid INTEGER PRIMARY KEY, name VARCHAR(128), " <<
"body MEDIUMTEXT, uid INTEGER, gid INTEGER," <<
"owner_u INTEGER, group_u INTEGER, other_u INTEGER"
}
}

View File

@ -38,6 +38,7 @@ module Migrator
def up
feature_2253
feature_2489
feature_826
true
end
@ -233,4 +234,8 @@ module Migrator
Nokogiri::XML(short_body.to_xml).root.to_s
end
def feature_826
create_table(:vn_template_pool)
end
end

View File

@ -30,7 +30,8 @@ const long int PoolObjectSQL::LockableObject = PoolObjectSQL::ObjectType::VM
| PoolObjectSQL::ObjectType::MARKETPLACEAPP
| PoolObjectSQL::ObjectType::NET
| PoolObjectSQL::ObjectType::VROUTER
| PoolObjectSQL::ObjectType::VMGROUP;
| PoolObjectSQL::ObjectType::VMGROUP
| PoolObjectSQL::ObjectType::VNTEMPLATE;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -219,6 +219,26 @@ PoolObjectSQL * PoolSQL::get_ro(int oid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void PoolSQL::exist(const string& id_str, std::set<int>& id_list)
{
std::vector<int> existing_items;
std::set<int>::iterator iterator;
one_util::split_unique(id_str, ',', id_list);
search(existing_items, table.c_str(), "true order by 1 ASC");
for (iterator = id_list.begin(); iterator != id_list.end(); ++iterator)
{
if (!std::binary_search(existing_items.begin(), existing_items.end(), *iterator))
{
id_list.erase(iterator);
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
PoolObjectSQL * PoolSQL::get(const string& name, int ouid)
{

View File

@ -71,6 +71,8 @@ string Request::object_name(PoolObjectSQL::ObjectType ob)
return "marketplaceapp";
case PoolObjectSQL::VMGROUP:
return "vm group";
case PoolObjectSQL::VNTEMPLATE:
return "virtual network template";
default:
return "-";
}

View File

@ -50,6 +50,7 @@
#include "RequestManagerMarketPlaceApp.h"
#include "RequestManagerVirtualRouter.h"
#include "RequestManagerSecurityGroup.h"
#include "RequestManagerVNTemplate.h"
#include "RequestManagerSystem.h"
#include "RequestManagerProxy.h"
@ -359,6 +360,9 @@ void RequestManager::register_xml_methods()
// VMTemplate Methods
xmlrpc_c::methodPtr template_instantiate(new VMTemplateInstantiate());
// VNTemplate Methods
xmlrpc_c::methodPtr vntemplate_instantiate(new VNTemplateInstantiate());
// VirtualMachine Methods
xmlrpc_c::methodPtr vm_deploy(new VirtualMachineDeploy());
xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
@ -408,6 +412,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_update(new SecurityGroupUpdateTemplate());
xmlrpc_c::methodPtr vrouter_update(new VirtualRouterUpdateTemplate());
xmlrpc_c::methodPtr vmg_update(new VMGroupUpdateTemplate());
xmlrpc_c::methodPtr vntemplate_update(new VirtualNetworkTemplateUpdateTemplate());
// Allocate Methods
xmlrpc_c::methodPtr vm_allocate(new VirtualMachineAllocate());
@ -421,11 +426,13 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_allocate(new SecurityGroupAllocate());
xmlrpc_c::methodPtr vrouter_allocate(new VirtualRouterAllocate());
xmlrpc_c::methodPtr vmg_allocate(new VMGroupAllocate());
xmlrpc_c::methodPtr vntemplate_allocate(new VirtualNetworkTemplateAllocate());
// Clone Methods
xmlrpc_c::methodPtr template_clone(new VMTemplateClone());
xmlrpc_c::methodPtr doc_clone(new DocumentClone());
xmlrpc_c::methodPtr secg_clone(new SecurityGroupClone());
xmlrpc_c::methodPtr vntemplate_clone(new VNTemplateClone());
// Delete Methods
xmlrpc_c::methodPtr host_delete(new HostDelete());
@ -438,12 +445,14 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_delete(new SecurityGroupDelete());
xmlrpc_c::methodPtr vrouter_delete(new VirtualRouterDelete());
xmlrpc_c::methodPtr vmg_delete(new VMGroupDelete());
xmlrpc_c::methodPtr vntemplate_delete(new VirtualNetworkTemplateDelete());
// Info Methods
xmlrpc_c::methodPtr vm_info(new VirtualMachineInfo());
xmlrpc_c::methodPtr host_info(new HostInfo());
xmlrpc_c::methodPtr template_info(new TemplateInfo());
xmlrpc_c::methodPtr vn_info(new VirtualNetworkInfo());
xmlrpc_c::methodPtr vntemplate_info(new VirtualNetworkTemplateInfo());
xmlrpc_c::methodPtr image_info(new ImageInfo());
xmlrpc_c::methodPtr datastore_info(new DatastoreInfo());
xmlrpc_c::methodPtr cluster_info(new ClusterInfo());
@ -467,6 +476,8 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vrouter_unlock(new VirtualRouterUnlock());
xmlrpc_c::methodPtr vmg_lock(new VMGroupLock());
xmlrpc_c::methodPtr vmg_unlock(new VMGroupUnlock());
xmlrpc_c::methodPtr vntemplate_lock(new VNTemplateLock());
xmlrpc_c::methodPtr vntemplate_unlock(new VNTemplateUnlock());
// PoolInfo Methods
xmlrpc_c::methodPtr hostpool_info(new HostPoolInfo());
@ -474,6 +485,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_pool_info(new VirtualMachinePoolInfo());
xmlrpc_c::methodPtr template_pool_info(new TemplatePoolInfo());
xmlrpc_c::methodPtr vnpool_info(new VirtualNetworkPoolInfo());
xmlrpc_c::methodPtr vntemplate_pool_info(new VirtualNetworkTemplatePoolInfo());
xmlrpc_c::methodPtr imagepool_info(new ImagePoolInfo());
xmlrpc_c::methodPtr clusterpool_info(new ClusterPoolInfo());
xmlrpc_c::methodPtr docpool_info(new DocumentPoolInfo());
@ -508,6 +520,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_chown(new SecurityGroupChown());
xmlrpc_c::methodPtr vrouter_chown(new VirtualRouterChown());
xmlrpc_c::methodPtr vmg_chown(new VMGroupChown());
xmlrpc_c::methodPtr vntemplate_chown(new VirtualNetworkTemplateChown());
// Chmod Methods
xmlrpc_c::methodPtr vm_chmod(new VirtualMachineChmod());
@ -519,6 +532,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_chmod(new SecurityGroupChmod());
xmlrpc_c::methodPtr vrouter_chmod(new VirtualRouterChmod());
xmlrpc_c::methodPtr vmg_chmod(new VMGroupChmod());
xmlrpc_c::methodPtr vntemplate_chmod(new VirtualNetworkTemplateChmod());
// Cluster Methods
xmlrpc_c::methodPtr cluster_addhost(new ClusterAddHost());
@ -546,6 +560,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr secg_rename(new SecurityGroupRename());
xmlrpc_c::methodPtr vrouter_rename(new VirtualRouterRename());
xmlrpc_c::methodPtr vmg_rename(new VMGroupRename());
xmlrpc_c::methodPtr vntemplate_rename(new VirtualNetworkTemplateRename());
// Virtual Router Methods
xmlrpc_c::methodPtr vrouter_instantiate(new VirtualRouterInstantiate());
@ -605,6 +620,20 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.template.unlock", template_unlock);
RequestManagerRegistry.addMethod("one.templatepool.info",template_pool_info);
/* VN Template related methods */
RequestManagerRegistry.addMethod("one.vntemplate.update", vntemplate_update);
RequestManagerRegistry.addMethod("one.vntemplate.instantiate",vntemplate_instantiate);
RequestManagerRegistry.addMethod("one.vntemplate.allocate",vntemplate_allocate);
RequestManagerRegistry.addMethod("one.vntemplate.delete", vntemplate_delete);
RequestManagerRegistry.addMethod("one.vntemplate.info", vntemplate_info);
RequestManagerRegistry.addMethod("one.vntemplate.chown", vntemplate_chown);
RequestManagerRegistry.addMethod("one.vntemplate.chmod", vntemplate_chmod);
RequestManagerRegistry.addMethod("one.vntemplate.clone", vntemplate_clone);
RequestManagerRegistry.addMethod("one.vntemplate.rename", vntemplate_rename);
RequestManagerRegistry.addMethod("one.vntemplate.lock", vntemplate_lock);
RequestManagerRegistry.addMethod("one.vntemplate.unlock", vntemplate_unlock);
RequestManagerRegistry.addMethod("one.vntemplatepool.info",vntemplate_pool_info);
/* Host related methods*/
RequestManagerRegistry.addMethod("one.host.status", host_status);
RequestManagerRegistry.addMethod("one.host.update", host_update);

View File

@ -704,6 +704,66 @@ bool TemplateAllocate::allocate_authorization(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode VirtualNetworkTemplateAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
int& id,
RequestAttributes& att)
{
VNTemplatePool * vnpool = static_cast<VNTemplatePool *>(pool);
VirtualNetworkTemplate * ttmpl=static_cast<VirtualNetworkTemplate *>(tmpl);
int rc = vnpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
ttmpl, &id, att.resp_msg);
if (rc < 0)
{
return Request::INTERNAL;
}
return Request::SUCCESS;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualNetworkTemplateAllocate::allocate_authorization(
xmlrpc_c::paramList const& paramList,
Template * tmpl,
RequestAttributes& att,
PoolObjectAuth * cluster_perms)
{
AuthRequest ar(att.uid, att.group_ids);
string t64;
string aname;
if (!RequestManagerAllocate::allocate_authorization(paramList, tmpl, att, cluster_perms))
{
return false;
}
VirtualNetworkTemplate * ttmpl = static_cast<VirtualNetworkTemplate *>(tmpl);
// ------------ Check template for restricted attributes -------------------
if (!att.is_admin())
{
if (ttmpl->check_restricted(aname))
{
att.resp_msg = "VM Template includes a restricted attribute "+aname;
failure_response(AUTHORIZATION, att);
return false;
}
}
return true;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode HostAllocate::pool_allocate(
xmlrpc_c::paramList const& paramList,
Template * tmpl,

View File

@ -156,6 +156,67 @@ void TemplateInfo::request_execute(xmlrpc_c::paramList const& paramList,
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void VirtualNetworkTemplateInfo::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
VNTemplatePool * tpool = static_cast<VNTemplatePool *>(pool);
VirtualNetworkTemplate * extended_tmpl = 0;
VNTemplate * vn_tmpl;
PoolObjectAuth perms;
int oid = xmlrpc_c::value_int(paramList.getInt(1));
string str;
vn_tmpl = tpool->get_ro(oid);
if ( vn_tmpl == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
vn_tmpl->get_permissions(perms);
vn_tmpl->unlock();
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(auth_op, perms); //USE TEMPLATE
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
delete extended_tmpl;
return;
}
vn_tmpl = tpool->get_ro(oid);
if ( vn_tmpl == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
delete extended_tmpl;
return;
}
vn_tmpl->to_xml(str);
vn_tmpl->unlock();
success_response(str, att);
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void VirtualNetworkInfo::to_xml(RequestAttributes& att, PoolObjectSQL * object,
string& str)
{

View File

@ -314,8 +314,6 @@ Request::ErrorCode VMTemplateInstantiate::merge(
const string &str_uattrs,
RequestAttributes& att)
{
int rc;
VirtualMachineTemplate uattrs;

View File

@ -0,0 +1,242 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#include "RequestManagerVNTemplate.h"
#include "VirtualMachineDisk.h"
#include "PoolObjectAuth.h"
#include "Nebula.h"
#include "RequestManagerClone.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VNTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int id = xmlrpc_c::value_int(paramList.getInt(1));
string name = xmlrpc_c::value_string(paramList.getString(2));
string str_uattrs = xmlrpc_c::value_string(paramList.getString(3));
VNTemplate * tmpl = static_cast<VNTemplatePool* > (pool)->get_ro(id);
if ( tmpl == 0 )
{
att.resp_id = id;
failure_response(NO_EXISTS, att);
return;
}
string original_tmpl_name = tmpl->get_name();
tmpl->unlock();
int instantiate_id = id;
int vid;
ErrorCode ec;
ec = request_execute(instantiate_id, name, str_uattrs, 0, vid, att);
if ( ec == SUCCESS )
{
success_response(vid, att);
}
else
{
failure_response(ec, att);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode VNTemplateInstantiate::request_execute(int id, string name,
const string &str_uattrs, Template* extra_attrs, int& vid,
RequestAttributes& att)
{
int rc;
PoolObjectAuth perms;
Nebula& nd = Nebula::instance();
VirtualNetworkPool* vnpool = nd.get_vnpool();
VNTemplatePool* vntpool = nd.get_vntpool();
ClusterPool* clpool = nd.get_clpool();
VirtualNetworkTemplate * tmpl;
VirtualNetworkTemplate extended_tmpl;
VNTemplate * rtmpl;
string tmpl_name;
string cluster_ids_str;
set<int> cluster_ids;
set<int>::iterator clusters_it;
/* ---------------------------------------------------------------------- */
/* Get, check and clone the template */
/* ---------------------------------------------------------------------- */
rtmpl = vntpool->get_ro(id);
if ( rtmpl == 0 )
{
att.resp_id = id;
return NO_EXISTS;
}
tmpl_name = rtmpl->get_name();
tmpl = rtmpl->clone_template();
rtmpl->get_permissions(perms);
/* ---------------------------------------------------------------------- */
/* Get network clusters */
/* ---------------------------------------------------------------------- */
rtmpl->get_template_attribute("CLUSTER_IDS", cluster_ids_str);
rtmpl->unlock();
if (!cluster_ids_str.empty())
{
clpool->exist(cluster_ids_str, cluster_ids);
}
if (cluster_ids_str.empty())
{
cluster_ids.insert(0);
}
ErrorCode ec = merge(tmpl, str_uattrs, att);
if (ec != SUCCESS)
{
delete tmpl;
return ec;
}
if ( extra_attrs != 0 )
{
tmpl->merge(extra_attrs);
}
ec = as_uid_gid(tmpl, att);
if ( ec != SUCCESS )
{
delete tmpl;
return ec;
}
/* ---------------------------------------------------------------------- */
/* Store the template attributes in the VN */
/* ---------------------------------------------------------------------- */
tmpl->erase("NAME");
tmpl->replace("TEMPLATE_NAME", tmpl_name);
tmpl->replace("TEMPLATE_ID", id);
if (!name.empty())
{
tmpl->set(new SingleAttribute("NAME",name));
}
//--------------------------------------------------------------------------
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(AuthRequest::USE, perms); //USE TEMPLATE
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
delete tmpl;
return AUTHORIZATION;
}
rc = vnpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
-1, tmpl, &vid, cluster_ids, att.resp_msg);
if ( rc < 0 )
{
return ALLOCATE;
}
for (clusters_it = cluster_ids.begin(); clusters_it != cluster_ids.end(); ++clusters_it)
{
Cluster* cluster;
string str_error;
cluster = clpool->get(*clusters_it);
if (cluster == 0)
{
continue;
}
cluster->add_vnet(vid, str_error);
clpool->update(cluster);
cluster->unlock();
}
return SUCCESS;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode VNTemplateInstantiate::merge(
Template * tmpl,
const string &str_uattrs,
RequestAttributes& att)
{
int rc;
VirtualNetworkTemplate uattrs;
string aname;
rc = uattrs.parse_str_or_xml(str_uattrs, att.resp_msg);
if ( rc != 0 )
{
return INTERNAL;
}
else if (uattrs.empty())
{
return SUCCESS;
}
if (!att.is_admin())
{
if (uattrs.check_restricted(aname, tmpl))
{
att.resp_msg ="User Template includes a restricted attribute " + aname;
return AUTHORIZATION;
}
}
tmpl->merge(&uattrs);
return SUCCESS;
}

View File

@ -50,7 +50,8 @@ source_files=[
'RequestManagerLock.cc',
'RequestManagerMarketPlaceApp.cc',
'RequestManagerVirtualRouter.cc',
'RequestManagerSecurityGroup.cc'
'RequestManagerSecurityGroup.cc',
'RequestManagerVNTemplate.cc'
]
# Build library

View File

@ -0,0 +1,30 @@
# SConstruct for src/vn_template
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
Import('env')
lib_name='nebula_vntemplate'
# Sources to generate the library
source_files=[
'VNTemplate.cc',
'VNTemplatePool.cc',
]
# Build library
env.StaticLibrary(lib_name, source_files)

View File

@ -0,0 +1,281 @@
/* ------------------------------------------------------------------------ */
/* 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. */
/* ------------------------------------------------------------------------ */
#include "VNTemplate.h"
#include "VirtualNetwork.h"
/* ************************************************************************ */
/* VNTemplate :: Constructor/Destructor */
/* ************************************************************************ */
VNTemplate::VNTemplate(int id,
int _uid,
int _gid,
const string& _uname,
const string& _gname,
int umask,
VirtualNetworkTemplate * _template_contents):
PoolObjectSQL(id,VNTEMPLATE,"",_uid,_gid,_uname,_gname,table),
regtime(time(0))
{
if (_template_contents != 0)
{
obj_template = _template_contents;
}
else
{
obj_template = new VirtualNetworkTemplate;
}
set_umask(umask);
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
VNTemplate::~VNTemplate(){};
/* ************************************************************************ */
/* VNTemplate :: Database Access Functions */
/* ************************************************************************ */
const char * VNTemplate::table = "vn_template_pool";
const char * VNTemplate::db_names =
"oid, name, body, uid, gid, owner_u, group_u, other_u";
const char * VNTemplate::db_bootstrap =
"CREATE TABLE IF NOT EXISTS vn_template_pool (oid INTEGER PRIMARY KEY, "
"name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, "
"owner_u INTEGER, group_u INTEGER, other_u INTEGER)";
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VNTemplate::insert(SqlDB *db, string& error_str)
{
string vn_mad, phydev, bridge, auto_id_str, vlan_id, auto_outer_str, outer_id;
bool auto_id = false, auto_outer = false;
int rc;
// ---------------------------------------------------------------------
// Check always mandatory attributes
// ---------------------------------------------------------------------
erase_template_attribute("NAME", name);
get_template_attribute("VN_MAD", vn_mad);
if (vn_mad.empty())
{
goto error_vnmad;
}
get_template_attribute("PHYDEV", phydev);
get_template_attribute("BRIDGE", bridge);
get_template_attribute("AUTOMATIC_VLAN_ID", auto_id_str);
if (auto_id_str == "YES")
{
auto_id = true;
}
get_template_attribute("VLAN_ID", vlan_id);
get_template_attribute("AUTOMATIC_OUTER_VLAN_ID", auto_outer_str);
if (auto_outer_str == "YES")
{
auto_outer = true;
}
get_template_attribute("OUTER_VLAN_ID", outer_id);
rc = VirtualNetwork::parse_phydev_vlans(obj_template, vn_mad, phydev, bridge, auto_id, vlan_id, auto_outer, outer_id, error_str);
if (rc == -1)
{
return -1;
}
// ------------------------------------------------------------------------
// Insert the Template
// ------------------------------------------------------------------------
return insert_replace(db, false, error_str);
error_vnmad:
error_str = "Error inserting Template in DB. VN_MAD is mandatory";
return -1;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VNTemplate::insert_replace(SqlDB *db, bool replace, string& error_str)
{
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 ( validate_xml(sql_xml) != 0 )
{
goto error_xml;
}
if(replace)
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
// Construct the SQL statement to Insert or Replace
oss <<" INTO " << table <<" ("<< db_names <<") VALUES ("
<< oid << ","
<< "'" << sql_name << "',"
<< "'" << sql_xml << "',"
<< uid << ","
<< gid << ","
<< owner_u << ","
<< group_u << ","
<< other_u << ")";
rc = db->exec_wr(oss);
db->free_str(sql_name);
db->free_str(sql_xml);
return rc;
error_xml:
db->free_str(sql_name);
db->free_str(sql_xml);
error_str = "Error transforming the Template to XML.";
goto error_common;
error_body:
db->free_str(sql_name);
goto error_generic;
error_name:
goto error_generic;
error_generic:
error_str = "Error inserting Template in DB.";
error_common:
return -1;
}
/* ************************************************************************ */
/* VNTemplate :: Misc */
/* ************************************************************************ */
string& VNTemplate::to_xml(string& xml) const
{
ostringstream oss;
string template_xml;
string perm_str;
string lock_str;
oss << "<VNTEMPLATE>"
<< "<ID>" << oid << "</ID>"
<< "<UID>" << uid << "</UID>"
<< "<GID>" << gid << "</GID>"
<< "<UNAME>" << uname << "</UNAME>"
<< "<GNAME>" << gname << "</GNAME>"
<< "<NAME>" << name << "</NAME>"
<< lock_db_to_xml(lock_str)
<< perms_to_xml(perm_str)
<< "<REGTIME>" << regtime << "</REGTIME>"
<< obj_template->to_xml(template_xml)
<< "</VNTEMPLATE>";
xml = oss.str();
return xml;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int VNTemplate::from_xml(const string& xml)
{
vector<xmlNodePtr> content;
int rc = 0;
// Initialize the internal XML object
update_from_str(xml);
// Get class base attributes
rc += xpath(oid, "/VNTEMPLATE/ID", -1);
rc += xpath(uid, "/VNTEMPLATE/UID", -1);
rc += xpath(gid, "/VNTEMPLATE/GID", -1);
rc += xpath(uname, "/VNTEMPLATE/UNAME", "not_found");
rc += xpath(gname, "/VNTEMPLATE/GNAME", "not_found");
rc += xpath(name, "/VNTEMPLATE/NAME", "not_found");
rc += xpath<time_t>(regtime, "/VNTEMPLATE/REGTIME", 0);
rc += lock_db_from_xml();
// Permissions
rc += perms_from_xml();
// Get associated classes
ObjectXML::get_nodes("/VNTEMPLATE/TEMPLATE", content);
if (content.empty())
{
return -1;
}
// Template contents
rc += obj_template->from_xml_node(content[0]);
ObjectXML::free_nodes(content);
if (rc != 0)
{
return -1;
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */

View File

@ -0,0 +1,82 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
/* ************************************************************************** */
/* Template Pool */
/* ************************************************************************** */
#include "VNTemplatePool.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VNTemplatePool::allocate (
int uid,
int gid,
const string& uname,
const string& gname,
int umask,
VirtualNetworkTemplate * template_contents,
int * oid,
string& error_str)
{
VNTemplate * vn_template;
int db_oid;
string name;
ostringstream oss;
// ------------------------------------------------------------------------
// Build a new VNTemplate object
// ------------------------------------------------------------------------
vn_template = new VNTemplate(-1, uid, gid, uname, gname, umask, template_contents);
// Check name
vn_template->get_template_attribute("NAME", name);
if ( !PoolObjectSQL::name_is_valid(name, error_str) )
{
goto error_name;
}
// Check for duplicates
db_oid = exist(name, uid);
if( db_oid != -1 )
{
goto error_duplicated;
}
// ------------------------------------------------------------------------
// Insert the Object in the pool
// ------------------------------------------------------------------------
*oid = PoolSQL::allocate(vn_template, error_str);
return *oid;
error_duplicated:
oss << "NAME is already taken by VN TEMPLATE " << db_oid << ".";
error_str = oss.str();
error_name:
delete vn_template;
*oid = -1;
return *oid;
}

View File

@ -141,7 +141,9 @@ LIST OF MANDATORY ARGUMENTS FOR NETWORK DEFINITION
| ovswitch_vxlan | yes | no | OUTER or AUTOMATIC_OUTER | |
+----------------+---------+--------+--------------------------+----------------+
*/
int VirtualNetwork::parse_phydev_vlans(string& estr)
int VirtualNetwork::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)
{
bool check_phydev = false;
bool check_bridge = false;
@ -155,6 +157,7 @@ int VirtualNetwork::parse_phydev_vlans(string& estr)
{
case VirtualNetwork::VCENTER:
other.push_back("VCENTER_NET_REF");
check_other = true;
case VirtualNetwork::DUMMY:
check_bridge = true;
@ -191,13 +194,13 @@ int VirtualNetwork::parse_phydev_vlans(string& estr)
return -1;
}
if ( check_vlan && !vlan_id_automatic && vlan_id.empty() )
if ( check_vlan && !auto_id && vlan_id.empty() )
{
estr = "VLAN_ID (or AUTOMATIC) is mandatory for driver " + vn_mad;
return -1;
}
if ( check_outer && !outer_vlan_id_automatic && outer_vlan_id.empty() )
if ( check_outer && !auto_outer && outer_id.empty() )
{
estr = "OUTER_VLAN_ID (or AUTOMATIC) is mandatory for driver " + vn_mad;
return -1;
@ -210,7 +213,7 @@ int VirtualNetwork::parse_phydev_vlans(string& estr)
for ( it = other.begin(); it != other.end() ; ++it)
{
if (!PoolObjectSQL::get_template_attribute((*it).c_str(), value))
if (!tmpl.get((*it).c_str(), value))
{
estr = *it + " is mandatory for driver " + vn_mad;
return -1;
@ -230,9 +233,53 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
ostringstream ose;
string sg_str, vis;
string value;
string name;
string prefix;
int rc, num_ars;
ostringstream oss;
// ------------------------------------------------------------------------
// Set a name if the VN has not got one (and is created via template)
// ------------------------------------------------------------------------
obj_template->get("TEMPLATE_ID", value);
obj_template->erase("TEMPLATE_ID");
if (!value.empty())
{
obj_template->add("TEMPLATE_ID", value);
}
obj_template->get("NAME",name);
obj_template->erase("NAME");
obj_template->get("TEMPLATE_NAME", prefix);
obj_template->erase("TEMPLATE_NAME");
if (prefix.empty() && name.empty())
{
goto error_name;
}
if (name.empty() == true)
{
oss.str("");
oss << prefix << "-" << oid;
name = oss.str();
}
if ( !PoolObjectSQL::name_is_valid(name, error_str) )
{
goto error_name;
}
this->name = name;
//--------------------------------------------------------------------------
// VirtualNetwork Attributes from the template
// NAME
@ -244,12 +291,6 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
//
// Note: VLAN_IDs if not set will be allocated in VirtualNetworkPool
//--------------------------------------------------------------------------
erase_template_attribute("NAME",name);
if (name.empty())
{
goto error_name;
}
erase_template_attribute("VN_MAD", vn_mad);
@ -274,7 +315,8 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
// -------------------------------------------------------------------------
// Check consistency for PHYDEV, BRIDGE and VLAN_IDs based on the driver
// -------------------------------------------------------------------------
rc = parse_phydev_vlans(error_str);
rc = parse_phydev_vlans(obj_template, vn_mad, phydev, bridge, vlan_id_automatic, vlan_id,
outer_vlan_id_automatic, outer_vlan_id, error_str);
if (rc != 0)
{

View File

@ -128,13 +128,7 @@ int VirtualNetworkPool::allocate (
vn = new VirtualNetwork(uid, gid, uname, gname, umask, pvid,
cluster_ids, vn_template);
// Check name
vn->PoolObjectSQL::get_template_attribute("NAME", name);
if ( !PoolObjectSQL::name_is_valid(name, error_str) )
{
goto error_name;
}
// Check for duplicates
db_oid = exist(name, uid);
@ -169,8 +163,7 @@ int VirtualNetworkPool::allocate (
error_duplicated:
oss << "NAME is already taken by NET " << db_oid << ".";
error_str = oss.str();
error_name:
delete vn;
*oid = -1;