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

feature #1013: Abstract hook registration. Add hook support for images, users and groups.

This commit is contained in:
Ruben S. Montero 2012-10-09 11:56:01 +02:00
parent 621f615a0c
commit 29ad5368d2
11 changed files with 161 additions and 133 deletions

View File

@ -26,7 +26,9 @@ using namespace std;
class GroupPool : public PoolSQL
{
public:
GroupPool(SqlDB * db);
GroupPool(SqlDB * db,
vector<const Attribute *> hook_mads,
const string& remotes_location);
~GroupPool(){};

View File

@ -41,7 +41,9 @@ public:
ImagePool(SqlDB * db,
const string& _default_type,
const string& _default_dev_prefix,
vector<const Attribute *>& restricted_attrs);
vector<const Attribute *>& restricted_attrs,
vector<const Attribute *> hook_mads,
const string& remotes_location);
~ImagePool(){};
@ -57,7 +59,7 @@ public:
* @param ds_type disk type for the image
* @param ds_data the datastore data
* @param source_img_id If the new Image is a clone, this must be the
* source Image ID. Otherwise, it must be set to -1
* source Image ID. Otherwise, it must be set to -1
* @param oid the id assigned to the Image
* @param error_str Returns the error reason, if any
* @return the oid assigned to the object,
@ -74,7 +76,7 @@ public:
const string& ds_name,
Image::DiskType ds_type,
const string& ds_data,
int source_img_id,
int source_img_id,
int * oid,
string& error_str);
@ -104,7 +106,7 @@ public:
return static_cast<Image *>(PoolSQL::get(name,uid,lock));
};
/**
/**
* Update a particular Image
* @param image pointer to Image
* @return 0 on success

View File

@ -201,6 +201,17 @@ public:
string& filter);
protected:
/**
* Register on "CREATE" and on "REMOVE" hooks for the pool. The hooks are
* meant to be executed locally by the generic AllocateHook and RemoveHook
* classes.
* @param hook_mads, array of HOOKs to be installed
* @param remotes_location, path to remotes in the front-end where the
* hooks are installed
*/
void register_hooks(vector<const Attribute *> hook_mads,
const string& remotes_location);
/**
* Gets an object from the pool (if needed the object is loaded from the
* database).

View File

@ -40,7 +40,9 @@ class UserPool : public PoolSQL
public:
UserPool(SqlDB * db,
time_t __session_expiration_time);
time_t __session_expiration_time,
vector<const Attribute *> hook_mads,
const string& remotes_location);
~UserPool(){};
@ -125,8 +127,8 @@ public:
*
* @return false if authn failed, true otherwise
*/
bool authenticate(const string& session,
int& uid,
bool authenticate(const string& session,
int& uid,
int& gid,
string& uname,
string& gname);
@ -152,12 +154,12 @@ public:
};
/**
* Name for the OpenNebula core authentication process
* Name for the OpenNebula core authentication process
*/
static const char * CORE_AUTH;
/**
* Name for the OpenNebula server (delegated) authentication process
* Name for the OpenNebula server (delegated) authentication process
*/
static const char * SERVER_AUTH;
@ -217,7 +219,7 @@ private:
string& uname,
string& gname);
/**
* Function to authenticate external (not known) users
*/

View File

@ -37,7 +37,6 @@ public:
const string& str_mac_prefix,
int default_size,
vector<const Attribute *> hook_mads,
const string& hook_location,
const string& remotes_location);
~VirtualNetworkPool(){};

View File

@ -37,7 +37,10 @@ const int GroupPool::USERS_ID = 1;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
GroupPool::GroupPool(SqlDB * db):PoolSQL(db, Group::table, true)
GroupPool::GroupPool(SqlDB * db,
vector<const Attribute *> hook_mads,
const string& remotes_location)
:PoolSQL(db, Group::table, true)
{
ostringstream oss;
string error_str;
@ -68,7 +71,9 @@ GroupPool::GroupPool(SqlDB * db):PoolSQL(db, Group::table, true)
set_update_lastOID(99);
}
register_hooks(hook_mads, remotes_location);
return;
error_groups:

View File

@ -34,8 +34,10 @@ string ImagePool::_default_dev_prefix;
ImagePool::ImagePool(SqlDB * db,
const string& __default_type,
const string& __default_dev_prefix,
vector<const Attribute *>& restricted_attrs):
PoolSQL(db, Image::table, true)
vector<const Attribute *>& restricted_attrs,
vector<const Attribute *> hook_mads,
const string& remotes_location)
:PoolSQL(db, Image::table, true)
{
ostringstream sql;
@ -52,8 +54,9 @@ ImagePool::ImagePool(SqlDB * db,
_default_type = "OS";
}
// Set restricted attributes
ImageTemplate::set_restricted_attributes(restricted_attrs);
register_hooks(hook_mads, remotes_location);
}
/* -------------------------------------------------------------------------- */
@ -104,7 +107,7 @@ int ImagePool::allocate (
img->ds_name = ds_name;
img->ds_id = ds_id;
img->disk_type = disk_type;
if ( cloning_id != -1 )
@ -116,7 +119,7 @@ int ImagePool::allocate (
// Insert the Object in the pool & Register the image in the repository
// ---------------------------------------------------------------------
*oid = PoolSQL::allocate(img, error_str);
if ( *oid != -1 )
{
Nebula& nd = Nebula::instance();
@ -190,9 +193,9 @@ static int get_disk_uid(VectorAttribute * disk, int _uid)
User * user;
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
user = upool->get(uname,true);
if ( user == 0 )
{
return -1;
@ -204,12 +207,12 @@ static int get_disk_uid(VectorAttribute * disk, int _uid)
}
else
{
uid = _uid;
uid = _uid;
}
return uid;
}
/* -------------------------------------------------------------------------- */
static int get_disk_id(const string& id_s)
@ -252,7 +255,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
if (!(source = disk->vector_value("IMAGE")).empty())
{
int uiid = get_disk_uid(disk,uid);
if ( uiid == -1)
{
ostringstream oss;
@ -261,7 +264,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
<< source << " . Set IMAGE_UNAME or IMAGE_UID of owner in DISK.";
error_str = oss.str();
return -1;
return -1;
}
img = imagem->acquire_image(source, uiid, error_str);
@ -280,7 +283,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
if ( iid == -1)
{
error_str = "Wrong ID set in IMAGE_ID";
return -1;
return -1;
}
img = imagem->acquire_image(iid, error_str);
@ -296,7 +299,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper);
if ( type != "SWAP" && type != "FS" )
if ( type != "SWAP" && type != "FS" )
{
error_str = "Unknown disk type " + type;
return -1;
@ -362,16 +365,16 @@ void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar)
{
string source;
Image * img = 0;
PoolObjectAuth perm;
if (!(source = disk->vector_value("IMAGE")).empty())
{
int uiid = get_disk_uid(disk,uid);
if ( uiid == -1)
{
return;
return;
}
img = get(source , uiid, true);
@ -387,7 +390,7 @@ void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar)
if ( iid == -1)
{
return;
return;
}
img = get(iid, true);

View File

@ -277,6 +277,9 @@ void Nebula::start()
vector<const Attribute *> vm_hooks;
vector<const Attribute *> host_hooks;
vector<const Attribute *> vnet_hooks;
vector<const Attribute *> user_hooks;
vector<const Attribute *> group_hooks;
vector<const Attribute *> image_hooks;
vector<const Attribute *> vm_restricted_attrs;
vector<const Attribute *> img_restricted_attrs;
@ -285,8 +288,11 @@ void Nebula::start()
docpool = new DocumentPool(db);
nebula_configuration->get("VM_HOOK", vm_hooks);
nebula_configuration->get("HOST_HOOK", host_hooks);
nebula_configuration->get("VNET_HOOK", vnet_hooks);
nebula_configuration->get("HOST_HOOK", host_hooks);
nebula_configuration->get("VNET_HOOK", vnet_hooks);
nebula_configuration->get("USER_HOOK", user_hooks);
nebula_configuration->get("GROUP_HOOK", group_hooks);
nebula_configuration->get("IMAGE_HOOK", image_hooks);
nebula_configuration->get("VM_RESTRICTED_ATTR", vm_restricted_attrs);
nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs);
@ -313,13 +319,12 @@ void Nebula::start()
mac_prefix,
size,
vnet_hooks,
hook_location,
remotes_location);
gpool = new GroupPool(db);
gpool = new GroupPool(db, group_hooks, remotes_location);
nebula_configuration->get("SESSION_EXPIRATION_TIME", expiration_time);
upool = new UserPool(db, expiration_time);
upool = new UserPool(db, expiration_time, user_hooks, remotes_location);
nebula_configuration->get("DEFAULT_IMAGE_TYPE", default_image_type);
nebula_configuration->get("DEFAULT_DEVICE_PREFIX",
@ -328,7 +333,9 @@ void Nebula::start()
ipool = new ImagePool(db,
default_image_type,
default_device_prefix,
img_restricted_attrs);
img_restricted_attrs,
image_hooks,
remotes_location);
tpool = new VMTemplatePool(db);

View File

@ -223,7 +223,7 @@ PoolObjectSQL * PoolSQL::get(
}
if ( uses_name_pool )
{
{
map<string,PoolObjectSQL *>::iterator name_index;
string okey;
@ -271,7 +271,7 @@ PoolObjectSQL * PoolSQL::get(
PoolObjectSQL * PoolSQL::get(const string& name, int ouid, bool olock)
{
map<string,PoolObjectSQL *>::iterator index;
PoolObjectSQL * objectsql;
int rc;
@ -381,9 +381,9 @@ void PoolSQL::update_cache_index(string& old_name,
if ( index != name_pool.end() )
{
name_pool.erase(old_key);
if ( name_pool.find(new_key) == name_pool.end())
{
{
name_pool.insert(make_pair(new_key, index->second));
}
}
@ -568,8 +568,8 @@ int PoolSQL::search(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void PoolSQL::acl_filter(int uid,
int gid,
void PoolSQL::acl_filter(int uid,
int gid,
PoolObjectSQL::ObjectType auth_object,
bool& all,
string& filter)
@ -591,12 +591,12 @@ void PoolSQL::acl_filter(int uid,
vector<int> oids;
vector<int> gids;
aclm->reverse_search(uid,
gid,
aclm->reverse_search(uid,
gid,
auth_object,
AuthRequest::USE,
all,
oids,
AuthRequest::USE,
all,
oids,
gids);
for ( it = oids.begin(); it < oids.end(); it++ )
@ -614,8 +614,8 @@ void PoolSQL::acl_filter(int uid,
/* -------------------------------------------------------------------------- */
void PoolSQL::usr_filter(int uid,
int gid,
void PoolSQL::usr_filter(int uid,
int gid,
int filter_flag,
bool all,
const string& acl_str,
@ -629,14 +629,14 @@ void PoolSQL::usr_filter(int uid,
}
else if ( filter_flag == RequestManagerPoolInfoFilter::MINE_GROUP )
{
uid_filter << " uid = " << uid
<< " OR ( gid = " << gid << " AND group_u = 1 )";
uid_filter << " uid = " << uid
<< " OR ( gid = " << gid << " AND group_u = 1 )";
}
else if ( filter_flag == RequestManagerPoolInfoFilter::ALL )
{
if (!all)
{
uid_filter << " uid = " << uid
uid_filter << " uid = " << uid
<< " OR ( gid = " << gid << " AND group_u = 1 )"
<< " OR other_u = 1"
<< acl_str;
@ -682,3 +682,65 @@ void PoolSQL::oid_filter(int start_id,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void PoolSQL::register_hooks(vector<const Attribute *> hook_mads,
const string& remotes_location)
{
const VectorAttribute * vattr;
string name;
string on;
string cmd;
string arg;
for (unsigned int i = 0 ; i < hook_mads.size() ; i++ )
{
vattr = static_cast<const VectorAttribute *>(hook_mads[i]);
name = vattr->vector_value("NAME");
on = vattr->vector_value("ON");
cmd = vattr->vector_value("COMMAND");
arg = vattr->vector_value("ARGUMENTS");
transform (on.begin(),on.end(),on.begin(),(int(*)(int))toupper);
if ( on.empty() || cmd.empty() )
{
NebulaLog::log("VM", Log::WARNING, "Empty ON or COMMAND attribute"
" in Hook, not registered!");
continue;
}
if ( name.empty() )
{
name = cmd;
}
if (cmd[0] != '/')
{
ostringstream cmd_os;
cmd_os << remotes_location << "/hooks/" << cmd;
cmd = cmd_os.str();
}
if ( on == "CREATE" )
{
AllocateHook * hook;
hook = new AllocateHook(name, cmd, arg, false);
add_hook(hook);
}
else if ( on == "REMOVE" )
{
RemoveHook * hook;
hook = new RemoveHook(name, cmd, arg, false);
add_hook(hook);
}
}
}

View File

@ -53,7 +53,9 @@ string UserPool::oneadmin_name;
/* -------------------------------------------------------------------------- */
UserPool::UserPool(SqlDB * db,
time_t __session_expiration_time):
time_t __session_expiration_time,
vector<const Attribute *> hook_mads,
const string& remotes_location):
PoolSQL(db, User::table, true)
{
int one_uid = -1;
@ -115,7 +117,7 @@ UserPool::UserPool(SqlDB * db,
if (!file.good())
{
goto error_file;
}
}
getline(file,one_token);
@ -194,6 +196,8 @@ UserPool::UserPool(SqlDB * db,
goto error_serveradmin;
}
register_hooks(hook_mads, remotes_location);
return;
error_no_file:
@ -293,7 +297,7 @@ int UserPool::allocate (
*oid = PoolSQL::allocate(user, error_str);
if ( *oid < 0 )
{
{
return *oid;
}
@ -572,7 +576,7 @@ auth_failure:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool UserPool::authenticate_external(const string& username,
const string& token,
int& user_id,
@ -605,7 +609,7 @@ bool UserPool::authenticate_external(const string& username,
ar.wait();
if (ar.result != true) //User was not authenticated
{
{
goto auth_failure_driver;
}
@ -651,9 +655,9 @@ bool UserPool::authenticate_external(const string& username,
gname = GroupPool::USERS_NAME;
return true;
auth_failure_user:
oss << "Can't create user: " << error_str << ". Driver response: "
oss << "Can't create user: " << error_str << ". Driver response: "
<< ar.message;
NebulaLog::log("AuM",Log::ERROR,oss);
@ -682,9 +686,9 @@ auth_failure:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool UserPool::authenticate(const string& session,
int& user_id,
bool UserPool::authenticate(const string& session,
int& user_id,
int& group_id,
string& uname,
string& gname)

View File

@ -36,7 +36,6 @@ VirtualNetworkPool::VirtualNetworkPool(
const string& prefix,
int __default_size,
vector<const Attribute *> hook_mads,
const string& hook_location,
const string& remotes_location):
PoolSQL(db, VirtualNetwork::table, true)
{
@ -47,15 +46,6 @@ VirtualNetworkPool::VirtualNetworkPool(
string mac = prefix;
const VectorAttribute * vattr;
string name;
string on;
string cmd;
string arg;
string rmt;
bool remote;
_mac_prefix = 0;
_default_size = __default_size;
@ -80,66 +70,7 @@ VirtualNetworkPool::VirtualNetworkPool(
_mac_prefix <<= 8;
_mac_prefix += tmp;
for (unsigned int i = 0 ; i < hook_mads.size() ; i++ )
{
vattr = static_cast<const VectorAttribute *>(hook_mads[i]);
name = vattr->vector_value("NAME");
on = vattr->vector_value("ON");
cmd = vattr->vector_value("COMMAND");
arg = vattr->vector_value("ARGUMENTS");
transform (on.begin(),on.end(),on.begin(),(int(*)(int))toupper);
if ( on.empty() || cmd.empty() )
{
ostringstream oss;
oss << "Empty ON or COMMAND attribute in VNET_HOOK. Hook "
<< "not registered!";
NebulaLog::log("VM",Log::WARNING,oss);
continue;
}
if ( name.empty() )
{
name = cmd;
}
if (cmd[0] != '/')
{
ostringstream cmd_os;
if ( remote )
{
cmd_os << hook_location << "/" << cmd;
}
else
{
cmd_os << remotes_location << "/hooks/" << cmd;
}
cmd = cmd_os.str();
}
if ( on == "CREATE" )
{
AllocateHook * hook;
hook = new AllocateHook(name, cmd, arg, false);
add_hook(hook);
}
else if ( on == "REMOVE" )
{
RemoveHook * hook;
hook = new RemoveHook(name, cmd, arg, false);
add_hook(hook);
}
}
register_hooks(hook_mads, remotes_location);
}
/* -------------------------------------------------------------------------- */