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

Feature #4317: Add option for template delete and chmod to be recursive

This commit is contained in:
Carlos Martín 2016-02-08 16:40:38 +01:00
parent 91ee796cb6
commit 91b1cc7396
8 changed files with 399 additions and 38 deletions

View File

@ -256,6 +256,15 @@ protected:
*/
void failure_response(ErrorCode ec, RequestAttributes& ra);
/**
* Builds an error response. A descriptive error message
* is constructed using att.resp_obj, att.resp_id and/or att.resp_msg and
* the ErrorCode
* @param ec error code for this call
* @param att the specific request attributes
*/
string failure_message(ErrorCode ec, RequestAttributes& att);
/* ---------------------------------------------------------------------- */
/* Authorization methods for requests */
/* ---------------------------------------------------------------------- */

View File

@ -33,12 +33,30 @@ protected:
const string& help)
:Request(method_name, "A:siiiiiiiiii", help){};
RequestManagerChmod(const string& method_name,
const string& params,
const string& help)
:Request(method_name, params, help){};
~RequestManagerChmod(){};
/* -------------------------------------------------------------------- */
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
static ErrorCode chmod( 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,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
@ -67,6 +85,7 @@ class TemplateChmod : public RequestManagerChmod
public:
TemplateChmod():
RequestManagerChmod("TemplateChmod",
"A:siiiiiiiiiib"
"Changes permission bits of a virtual machine template")
{
Nebula& nd = Nebula::instance();
@ -75,6 +94,9 @@ public:
};
~TemplateChmod(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
@ -113,6 +135,17 @@ public:
~ImageChmod(){};
static ErrorCode chmod( 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,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */

View File

@ -30,6 +30,18 @@ using namespace std;
class RequestManagerDelete: public Request
{
protected:
RequestManagerDelete(const string& method_name,
const string& params,
const string& help)
:Request(method_name, params, help)
{
auth_op = AuthRequest::MANAGE;
Nebula& nd = Nebula::instance();
clpool = nd.get_clpool();
aclm = nd.get_aclm();
};
RequestManagerDelete(const string& method_name,
const string& help)
:Request(method_name, "A:si", help)
@ -45,11 +57,14 @@ protected:
/* -------------------------------------------------------------------- */
void request_execute(xmlrpc_c::paramList const& _paramList,
void request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att);
bool delete_authorization(int oid,
RequestAttributes& att);
static ErrorCode delete_authorization(
PoolSQL* pool,
int oid,
AuthRequest::Operation auth_op,
RequestAttributes& att);
/* -------------------------------------------------------------------- */
@ -79,6 +94,7 @@ class TemplateDelete : public RequestManagerDelete
public:
TemplateDelete():
RequestManagerDelete("TemplateDelete",
"A:sib"
"Deletes a virtual machine template")
{
Nebula& nd = Nebula::instance();
@ -87,6 +103,9 @@ public:
};
~TemplateDelete(){};
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
@ -137,7 +156,10 @@ public:
~ImageDelete(){};
int drop(int oid, PoolObjectSQL * object, string& error_msg);
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
static ErrorCode delete_img(int oid, RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */

View File

@ -70,6 +70,13 @@ public:
*(static_cast<VirtualMachineTemplate *>(obj_template)));
};
/**
* Returns all the DISK/IMAGE_IDs in the Template
* @return image IDs
*/
vector<int> get_img_ids();
// TODO: make const
// ------------------------------------------------------------------------
// Virtual Router
// ------------------------------------------------------------------------

View File

@ -585,7 +585,7 @@ void Request::failure_response(ErrorCode ec, const string& str_val,
/* -------------------------------------------------------------------------- */
void Request::failure_response(ErrorCode ec, RequestAttributes& att)
string Request::failure_message(ErrorCode ec, RequestAttributes& att)
{
std::ostringstream oss;
std::string obname;
@ -604,7 +604,7 @@ void Request::failure_response(ErrorCode ec, RequestAttributes& att)
switch(ec)
{
case SUCCESS:
return;
return "";
case AUTHORIZATION:
oss << "User [" << att.uid << "] ";
@ -652,7 +652,15 @@ void Request::failure_response(ErrorCode ec, RequestAttributes& att)
break;
}
failure_response(ec, oss.str(), att);
return oss.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Request::failure_response(ErrorCode ec, RequestAttributes& att)
{
failure_response(ec, failure_message(ec, att), att);
}
/* -------------------------------------------------------------------------- */

View File

@ -16,7 +16,6 @@
#include "RequestManagerChmod.h"
#include "NebulaLog.h"
#include "Nebula.h"
/* -------------------------------------------------------------------------- */
@ -39,6 +38,39 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
int other_m = xmlrpc_c::value_int(paramList.getInt(9));
int other_a = xmlrpc_c::value_int(paramList.getInt(10));
ErrorCode ec = chmod(pool, oid,
owner_u, owner_m, owner_a,
group_u, group_m, group_a,
other_u, other_m, other_a,
att);
if ( ec == SUCCESS )
{
success_response(oid, att);
}
else
{
failure_response(ec, att);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode RequestManagerChmod::chmod(
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,
RequestAttributes& att)
{
PoolObjectSQL * object;
if ( att.uid != 0 && att.gid != 0)
@ -51,8 +83,7 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
return NO_EXISTS;
}
object->get_permissions(perms);
@ -99,8 +130,7 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( !enable_other )
{
att.resp_msg = "'other' permissions is disabled in oned.conf";
failure_response(AUTHORIZATION, att);
return;
return AUTHORIZATION;
}
}
@ -111,9 +141,7 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return;
return AUTHORIZATION;
}
}
@ -124,8 +152,7 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( object == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
return NO_EXISTS;
}
int rc = object->set_permissions(owner_u, owner_m, owner_a, group_u,
@ -133,20 +160,114 @@ void RequestManagerChmod::request_execute(xmlrpc_c::paramList const& paramList,
if ( rc != 0 )
{
failure_response(INTERNAL, att);
object->unlock();
return;
return INTERNAL;
}
pool->update(object);
object->unlock();
success_response(oid, att);
return;
return SUCCESS;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TemplateChmod::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int oid = xmlrpc_c::value_int(paramList.getInt(1));
int owner_u = xmlrpc_c::value_int(paramList.getInt(2));
int owner_m = xmlrpc_c::value_int(paramList.getInt(3));
int owner_a = xmlrpc_c::value_int(paramList.getInt(4));
int group_u = xmlrpc_c::value_int(paramList.getInt(5));
int group_m = xmlrpc_c::value_int(paramList.getInt(6));
int group_a = xmlrpc_c::value_int(paramList.getInt(7));
int other_u = xmlrpc_c::value_int(paramList.getInt(8));
int other_m = xmlrpc_c::value_int(paramList.getInt(9));
int other_a = xmlrpc_c::value_int(paramList.getInt(10));
bool recursive = false;
if (paramList.size() > 11)
{
recursive = xmlrpc_c::value_boolean(paramList.getBoolean(11));
}
ErrorCode ec = chmod(pool, oid,
owner_u, owner_m, owner_a,
group_u, group_m, group_a,
other_u, other_m, other_a,
att);
if ( ec != SUCCESS )
{
failure_response(ec, att);
return;
}
if (recursive)
{
VMTemplate* tmpl = static_cast<VMTemplatePool*>(pool)->get(oid, true);
if ( tmpl == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
vector<int> img_ids = tmpl->get_img_ids();
tmpl->unlock();
ErrorCode ec;
for (vector<int>::iterator it = img_ids.begin(); it != img_ids.end(); it++)
{
ec = ImageChmod::chmod(*it,
owner_u, owner_m, owner_a,
group_u, group_m, group_a,
other_u, other_m, other_a,
att);
if (ec != SUCCESS)
{
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, att));
}
// TODO rollback?
}
}
success_response(oid, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Request::ErrorCode ImageChmod::chmod(
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,
RequestAttributes& att)
{
return RequestManagerChmod::chmod(
Nebula::instance().get_ipool(),
oid,
owner_u, owner_m, owner_a,
group_u, group_m, group_a,
other_u, other_m, other_a,
att);
}

View File

@ -21,25 +21,26 @@ using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool RequestManagerDelete::delete_authorization(
int oid,
RequestAttributes& att)
Request::ErrorCode RequestManagerDelete::delete_authorization(
PoolSQL* pool,
int oid,
AuthRequest::Operation auth_op,
RequestAttributes& att)
{
PoolObjectSQL * object;
PoolObjectAuth perms;
if ( att.uid == 0 )
{
return true;
return SUCCESS;
}
object = pool->get(oid,true);
object = pool->get(oid, true);
if ( object == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return false;
return NO_EXISTS;
}
object->get_permissions(perms);
@ -53,12 +54,10 @@ bool RequestManagerDelete::delete_authorization(
if (UserPool::authorize(ar) == -1)
{
att.resp_msg = ar.message;
failure_response(AUTHORIZATION, att);
return false;
return AUTHORIZATION;
}
return true;
return SUCCESS;
}
/* ------------------------------------------------------------------------- */
@ -70,9 +69,13 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList,
int oid = xmlrpc_c::value_int(paramList.getInt(1));
PoolObjectSQL * object;
string error_msg;
ErrorCode ec;
if ( delete_authorization(oid, att) == false )
ec = delete_authorization(pool, oid, auth_op, att);
if ( ec != SUCCESS )
{
failure_response(ec, att);
return;
}
@ -141,6 +144,81 @@ int RequestManagerDelete::drop(
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void TemplateDelete::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
int oid = xmlrpc_c::value_int(paramList.getInt(1));
bool recursive = false;
VMTemplate * object;
string error_msg;
vector<int> img_ids;
ErrorCode ec;
if (paramList.size() > 2)
{
recursive = xmlrpc_c::value_boolean(paramList.getBoolean(2));
}
ec = delete_authorization(pool, oid, auth_op, att);
if ( ec != SUCCESS )
{
failure_response(ec, att);
return;
}
object = static_cast<VMTemplatePool*>(pool)->get(oid, true);
if ( object == 0 )
{
att.resp_id = oid;
failure_response(NO_EXISTS, att);
return;
}
int rc = pool->drop(object, error_msg);
if (recursive)
{
img_ids = object->get_img_ids();
}
object->unlock();
if ( rc != 0 )
{
att.resp_msg = "Cannot delete " + object_name(auth_object) + ". " + error_msg;
failure_response(ACTION, att);
return;
}
aclm->del_resource_rules(oid, auth_object);
if (recursive)
{
ErrorCode ec;
for (vector<int>::iterator it = img_ids.begin(); it != img_ids.end(); it++)
{
ec = ImageDelete::delete_img(*it, att);
if (ec != SUCCESS)
{
NebulaLog::log("ReM", Log::ERROR, failure_message(ec, att));
}
// TODO rollback?
}
}
success_response(oid, att);
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
{
Nebula& nd = Nebula::instance();
@ -174,14 +252,66 @@ int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
void ImageDelete::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
int oid = xmlrpc_c::value_int(paramList.getInt(1));
ErrorCode ec = delete_img(oid, att);
if ( ec == SUCCESS )
{
success_response(oid, att);
}
else
{
failure_response(ec, att);
}
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
Request::ErrorCode ImageDelete::delete_img(int oid, RequestAttributes& att)
{
Image * object;
string error_msg;
ErrorCode ec;
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
AclManager * aclm = nd.get_aclm();
ImagePool * pool = nd.get_ipool();
object->unlock();
PoolObjectSQL::ObjectType auth_object = PoolObjectSQL::IMAGE;
return imagem->delete_image(oid, error_msg);
ec = delete_authorization(pool, oid, AuthRequest::MANAGE, att);
if ( ec != SUCCESS )
{
att.resp_obj = auth_object;
return ec;
}
object = pool->get(oid, false);
if ( object == 0 )
{
att.resp_id = oid;
return NO_EXISTS;
}
int rc = imagem->delete_image(oid, error_msg);
if ( rc != 0 )
{
att.resp_msg = "Cannot delete " + object_name(auth_object) + ". " + error_msg;
return ACTION;
}
aclm->del_resource_rules(oid, auth_object);
return SUCCESS;
}
/* ------------------------------------------------------------------------- */

View File

@ -257,3 +257,34 @@ bool VMTemplate::is_vrouter()
return vr;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
vector<int> VMTemplate::get_img_ids()
{
vector<int> img_ids;
// TODO: xpaths(vector<int>..) is not working
//xpaths(img_ids,"/VMTEMPLATE/TEMPLATE/DISK/IMAGE_ID");
vector<string> img_ids_st;
vector<string>::iterator it;
xpaths(img_ids_st,"/VMTEMPLATE/TEMPLATE/DISK/IMAGE_ID");
for (it = img_ids_st.begin(); it != img_ids_st.end(); it++)
{
istringstream iss(*it);
int val;
iss >> dec >> val;
if (!iss.fail())
{
img_ids.push_back( val );
}
}
return img_ids;
}