diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 745bf4c1a8..78030ad6e7 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -488,6 +488,13 @@ public: */ virtual int replace_template(const string& tmpl_str, string& error); + /** + * Append new attributes to this object's template. Object should be updated + * after calling this method + * @param tmpl string representation of the template + */ + virtual int append_template(const string& tmpl_str, string& error); + /** * Fills a auth class to perform an authZ/authN request based on the object diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index 045dfdddf2..83105030cf 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -45,6 +45,9 @@ protected: virtual int replace_template(PoolObjectSQL * object, const string & tmpl, const RequestAttributes &att, string &error_str); + + virtual int append_template(PoolObjectSQL * object, const string & tmpl, + const RequestAttributes &att, string &error_str); }; /* ------------------------------------------------------------------------- */ @@ -86,6 +89,9 @@ public: int replace_template(PoolObjectSQL * object, const string & tmpl, const RequestAttributes &att, string &error_str); + + int append_template(PoolObjectSQL * object, const string & tmpl, + const RequestAttributes &att, string &error_str); }; /* ------------------------------------------------------------------------- */ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 3099feac92..7a01dca4dd 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -853,6 +853,16 @@ public: */ int replace_template(const string& tmpl_str, bool keep_restricted, string& error); + /** + * Append new attributes to the *user template*. + * @param tmpl_str new contents + * @param keep_restricted If true, the restricted attributes of the + * current template will override the new template + * @param error string describing the error if any + * @return 0 on success + */ + int append_template(const string& tmpl_str, bool keep_restricted, string& error); + /** * This function gets an attribute from the user template * @param name of the attribute diff --git a/src/pool/PoolObjectSQL.cc b/src/pool/PoolObjectSQL.cc index fb0ca4b7be..59d1d1a0ef 100644 --- a/src/pool/PoolObjectSQL.cc +++ b/src/pool/PoolObjectSQL.cc @@ -196,6 +196,38 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int PoolObjectSQL::append_template(const string& tmpl_str, string& error) +{ + Template * new_tmpl = get_new_template(); + + if ( new_tmpl == 0 ) + { + error = "Cannot allocate a new template"; + return -1; + } + + if ( new_tmpl->parse_str_or_xml(tmpl_str, error) != 0 ) + { + delete new_tmpl; + return -1; + } + + if ( obj_template != 0 ) + { + obj_template->merge(new_tmpl, error); + delete new_tmpl; + } + else + { + obj_template = new_tmpl; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + string& PoolObjectSQL::perms_to_xml(string& xml) const { ostringstream oss; diff --git a/src/rm/RequestManagerUpdateTemplate.cc b/src/rm/RequestManagerUpdateTemplate.cc index 484699e0d4..36e591c926 100644 --- a/src/rm/RequestManagerUpdateTemplate.cc +++ b/src/rm/RequestManagerUpdateTemplate.cc @@ -33,6 +33,18 @@ int RequestManagerUpdateTemplate::replace_template( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +int RequestManagerUpdateTemplate::append_template( + PoolObjectSQL * object, + const string & tmpl, + const RequestAttributes &att, + string &error_str) +{ + return object->append_template(tmpl, error_str); +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + int VirtualMachineUpdateTemplate::replace_template( PoolObjectSQL * object, const string & tmpl, @@ -55,6 +67,27 @@ int VirtualMachineUpdateTemplate::replace_template( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +int VirtualMachineUpdateTemplate::append_template( + PoolObjectSQL * object, + const string & tmpl, + const RequestAttributes & att, + string & error_str) +{ + VirtualMachine* vm = static_cast(object); + + if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID) + { + return vm->append_template(tmpl, true, error_str); + } + else + { + return vm->append_template(tmpl, false, error_str); + } +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void RequestManagerUpdateTemplate::request_execute( xmlrpc_c::paramList const& paramList, RequestAttributes& att) @@ -64,7 +97,14 @@ void RequestManagerUpdateTemplate::request_execute( int oid = xmlrpc_c::value_int(paramList.getInt(1)); string tmpl = xmlrpc_c::value_string(paramList.getString(2)); - + + int update_type = 0; + + if ( paramList.size() > 3 ) + { + update_type = xmlrpc_c::value_int(paramList.getInt(3)); + } + PoolObjectSQL * object; if ( basic_authorization(oid, att) == false ) @@ -72,6 +112,16 @@ void RequestManagerUpdateTemplate::request_execute( return; } + if ( update_type < 0 || update_type > 1 ) + { + failure_response(XML_RPC_API, + request_error("Wrong update type",error_str), + att); + + return; + } + + object = pool->get(oid,true); if ( object == 0 ) @@ -83,9 +133,14 @@ void RequestManagerUpdateTemplate::request_execute( return; } - rc = replace_template(object, tmpl, att, error_str); - -// rc = object->replace_template(tmpl, error_str); + if (update_type == 0) + { + rc = replace_template(object, tmpl, att, error_str); + } + else //if (update_type == 1) + { + rc = append_template(object, tmpl, att, error_str); + } if ( rc != 0 ) { diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 00f39b1e01..addb63cf8b 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -3304,6 +3304,47 @@ int VirtualMachine::replace_template( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int VirtualMachine::append_template( + const string& tmpl_str, + bool keep_restricted, + string& error) +{ + VirtualMachineTemplate * new_tmpl = + new VirtualMachineTemplate(false,'=',"USER_TEMPLATE"); + + if ( new_tmpl == 0 ) + { + error = "Cannot allocate a new template"; + return -1; + } + + if ( new_tmpl->parse_str_or_xml(tmpl_str, error) != 0 ) + { + delete new_tmpl; + return -1; + } + + if (keep_restricted) + { + new_tmpl->remove_restricted(); + } + + if (user_obj_template != 0) + { + user_obj_template->merge(new_tmpl, error); + delete new_tmpl; + } + else + { + user_obj_template = new_tmpl; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void VirtualMachine::set_template_error_message(const string& message) { set_template_error_message("ERROR", message);