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

Feature #1697: Change Template::merge to replace and add attributes

This allows to merge a template with repeated attributes, like
several DISK or NIC atts.
This commit is contained in:
Carlos Martín 2013-02-15 16:07:15 +01:00
parent 9280aa362b
commit 60f0d4bfbd
3 changed files with 20 additions and 47 deletions

View File

@ -313,9 +313,12 @@ public:
int from_xml_node(const xmlNodePtr node);
/**
* Merge attributes from another template
* Merges another Template, adding the new attributes and
* replacing the existing ones
*
* @param from_tmpl the template to be merged
* @param error_str string describing the error
*
* @return 0 on success.
*/
int merge(const Template * from_tmpl, string& error_str);

View File

@ -27,7 +27,7 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
int id = xmlrpc_c::value_int(paramList.getInt(1));
string name = xmlrpc_c::value_string(paramList.getString(2));
bool on_hold = false; //Optional XML-RPC argument
string str_uattrs;
string str_uattrs; //Optional XML-RPC argument
int rc;
int vid;
@ -44,11 +44,10 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
UserPool * upool = nd.get_upool();
VirtualMachineTemplate * tmpl;
VirtualMachineTemplate uattrs;
VMTemplate * rtmpl;
User * user;
VirtualMachineTemplate uattrs;
string error_str;
string aname;
@ -104,6 +103,7 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
// Parse user supplied attributes
rc = uattrs.parse_str_or_xml(str_uattrs, error_str);
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
@ -130,25 +130,28 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
}
}
// Check user attributes for restricted attributes, but only if the Request user
// Check user template for restricted attributes, but only if the Request user
// is not oneadmin
if ( att.uid != UserPool::ONEADMIN_ID && att.gid != GroupPool::ONEADMIN_ID )
{
if (uattrs.check(aname))
{
ostringstream oss;
oss << "User Attributes includes a restricted attribute " << aname;
oss << "User Template includes a restricted attribute " << aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
delete tmpl;
return;
}
}
// Merge user attributes into template
rc = tmpl->merge(&uattrs, error_str);
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);

View File

@ -695,47 +695,14 @@ int Template::merge(const Template * from_tmpl, string& error_str)
{
multimap<string,Attribute *>::const_iterator it;
for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it) {
// Get the attribute to be replaced
vector<Attribute*> attrs;
get(it->first, attrs);
// Insert if attribute does not exist
if ( attrs.size() == 0 )
for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it)
{
attributes.insert(make_pair(it->first,(it->second)->clone()));
continue;
this->erase(it->first);
}
Attribute* attr = attrs[0];
if (attr->type() != it->second->type())
for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it)
{
ostringstream oss;
oss << "Cannot merge attributes of different types " << it->first;
error_str = oss.str();
return -1;
}
if (attr->type() == Attribute::SIMPLE)
{
// Replace an existing Simple Attribute
((SingleAttribute*) attr)->replace( ((SingleAttribute*) it->second)->value());
continue;
}
else
{
// Replace values of an existing Vector Attribute
const map<string,string> values = ((VectorAttribute*) it->second)->value();
map<string,string>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it)
{
((VectorAttribute*) attr)->replace(it->first, it->second);
}
}
this->set(it->second->clone());
}
return 0;