1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

Feature #4369: ACL engine uses multple clusters

This commit is contained in:
Carlos Martín 2016-03-11 15:42:17 +01:00
parent e8a05ca1d7
commit 621a186947
13 changed files with 242 additions and 82 deletions

View File

@ -261,16 +261,16 @@ private:
* @return true if any rule grants permission
*/
bool match_rules(
long long user_req,
long long resource_oid_req,
long long resource_gid_req,
long long resource_cid_req,
long long resource_all_req,
long long rights_req,
long long individual_obj_type,
long long group_obj_type,
long long cluster_obj_type,
multimap<long long, AclRule*> &rules);
const long long &user_req,
const long long &resource_oid_req,
const long long &resource_gid_req,
const set<long long> &resource_cid_req,
const long long &resource_all_req,
const long long &rights_req,
const long long &resource_oid_mask,
const long long &resource_gid_mask,
const long long &resource_cid_mask,
const multimap<long long, AclRule*> &rules);
/**
* Wrapper for match_rules. It will check if any rules in the temporary
@ -290,16 +290,16 @@ private:
* @return true if any rule grants permission
*/
bool match_rules_wrapper(
long long user_req,
long long resource_oid_req,
long long resource_gid_req,
long long resource_cid_req,
long long resource_all_req,
long long rights_req,
long long individual_obj_type,
long long group_obj_type,
long long cluster_obj_type,
multimap<long long, AclRule*> &tmp_rules);
const long long &user_req,
const long long &resource_oid_req,
const long long &resource_gid_req,
const set<long long> &resource_cid_req,
const long long &resource_all_req,
const long long &rights_req,
const long long &individual_obj_type,
const long long &group_obj_type,
const long long &cluster_obj_type,
const multimap<long long, AclRule*> &tmp_rules);
/**
* Deletes all rules that match the user mask

View File

@ -201,6 +201,12 @@ public:
*/
int from_xml(const string &xml_str);
static const char * host_table;
static const char * datastore_table;
static const char * network_table;
private:
// -------------------------------------------------------------------------
@ -232,11 +238,18 @@ private:
// *************************************************************************
static const char * db_names;
static const char * db_bootstrap;
static const char * table;
static const char * host_db_names;
static const char * host_db_bootstrap;
static const char * datastore_db_names;
static const char * datastore_db_bootstrap;
static const char * network_db_names;
static const char * network_db_bootstrap;
/**
* Execute an INSERT or REPLACE Sql query.
* @param db The SQL DB
@ -252,9 +265,22 @@ private:
*/
static int bootstrap(SqlDB * db)
{
ostringstream oss(Cluster::db_bootstrap);
int rc;
ostringstream oss;
return db->exec(oss);
oss.str(Cluster::db_bootstrap);
rc = db->exec(oss);
oss.str(Cluster::host_db_bootstrap);
rc += db->exec(oss);
oss.str(Cluster::datastore_db_bootstrap);
rc += db->exec(oss);
oss.str(Cluster::network_db_bootstrap);
rc += db->exec(oss);
return rc;
};
/**

View File

@ -34,7 +34,6 @@ public:
oid(-1),
uid(-1),
gid(-1),
cid(-1),
owner_u(1),
owner_m(1),
owner_a(0),
@ -65,7 +64,7 @@ public:
int oid;
int uid;
int gid;
int cid;
set<int> cids;
int owner_u;
int owner_m;

View File

@ -241,17 +241,19 @@ const bool AclManager::authorize(
resource_gid_req = AclRule::NONE_ID;
}
long long resource_cid_req;
set<long long> resource_cid_req;
if ((obj_perms.cid >= 0) && (!obj_perms.disable_cluster_acl))
if (!obj_perms.disable_cluster_acl)
{
resource_cid_req = obj_perms.obj_type |
AclRule::CLUSTER_ID |
obj_perms.cid;
}
else
{
resource_cid_req = AclRule::NONE_ID;
set<int>::iterator i;
for(i = obj_perms.cids.begin(); i != obj_perms.cids.end(); i++)
{
resource_cid_req.insert( obj_perms.obj_type |
AclRule::CLUSTER_ID |
*i
);
}
}
long long resource_all_req ;
@ -290,10 +292,6 @@ const bool AclManager::authorize(
{
log_resource = resource_gid_req;
}
else if ( obj_perms.cid >= 0 )
{
log_resource = resource_cid_req;
}
else
{
log_resource = resource_all_req;
@ -398,16 +396,16 @@ const bool AclManager::authorize(
/* -------------------------------------------------------------------------- */
bool AclManager::match_rules_wrapper(
long long user_req,
long long resource_oid_req,
long long resource_gid_req,
long long resource_cid_req,
long long resource_all_req,
long long rights_req,
long long individual_obj_type,
long long group_obj_type,
long long cluster_obj_type,
multimap<long long, AclRule*> &tmp_rules)
const long long &user_req,
const long long &resource_oid_req,
const long long &resource_gid_req,
const set<long long> &resource_cid_req,
const long long &resource_all_req,
const long long &rights_req,
const long long &individual_obj_type,
const long long &group_obj_type,
const long long &cluster_obj_type,
const multimap<long long, AclRule*> &tmp_rules)
{
bool auth = false;
@ -452,26 +450,47 @@ bool AclManager::match_rules_wrapper(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
inline bool match_cluster_req(
const set<long long> &resource_cid_req,
const long long &resource_cid_mask,
const long long &rule_resource)
{
set<long long>::iterator i;
for(i = resource_cid_req.begin(); i != resource_cid_req.end(); i++)
{
// rule's object type and cluster object ID match
if ( ( rule_resource & resource_cid_mask ) == *i )
{
return true;
}
}
return false;
}
/* -------------------------------------------------------------------------- */
bool AclManager::match_rules(
long long user_req,
long long resource_oid_req,
long long resource_gid_req,
long long resource_cid_req,
long long resource_all_req,
long long rights_req,
long long resource_oid_mask,
long long resource_gid_mask,
long long resource_cid_mask,
multimap<long long, AclRule*> &rules)
const long long &user_req,
const long long &resource_oid_req,
const long long &resource_gid_req,
const set<long long> &resource_cid_req,
const long long &resource_all_req,
const long long &rights_req,
const long long &resource_oid_mask,
const long long &resource_gid_mask,
const long long &resource_cid_mask,
const multimap<long long, AclRule*> &rules)
{
bool auth = false;
ostringstream oss;
multimap<long long, AclRule *>::iterator it;
multimap<long long, AclRule *>::const_iterator it;
pair<multimap<long long, AclRule *>::iterator,
multimap<long long, AclRule *>::iterator> index;
pair<multimap<long long, AclRule *>::const_iterator,
multimap<long long, AclRule *>::const_iterator> index;
long long zone_oid_mask = AclRule::INDIVIDUAL_ID | 0x00000000FFFFFFFFLL;
long long zone_req = AclRule::INDIVIDUAL_ID | zone_id;
@ -507,8 +526,8 @@ bool AclManager::match_rules(
// Or rule's object type and individual object ID match
( ( it->second->resource & resource_oid_mask ) == resource_oid_req )
||
// Or rule's object type and cluster object ID match
( ( it->second->resource & resource_cid_mask ) == resource_cid_req )
// Or rule's object type and one of the cluster object ID match
match_cluster_req(resource_cid_req, resource_cid_mask, it->second->resource)
);
if ( auth == true )

View File

@ -34,6 +34,24 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool ("
"gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, "
"UNIQUE(name))";
const char * Cluster::host_table = "cluster_host_relation";
const char * Cluster::host_db_names = "cid, oid";
const char * Cluster::host_db_bootstrap =
"CREATE TABLE IF NOT EXISTS cluster_host_relation ("
"cid INTEGER, oid INTEGER, PRIMARY KEY(cid, oid))";
const char * Cluster::datastore_table = "cluster_datastore_relation";
const char * Cluster::datastore_db_names = "cid, oid";
const char * Cluster::datastore_db_bootstrap =
"CREATE TABLE IF NOT EXISTS cluster_datastore_relation ("
"cid INTEGER, oid INTEGER, PRIMARY KEY(cid, oid))";
const char * Cluster::network_table = "cluster_network_relation";
const char * Cluster::network_db_names = "cid, oid";
const char * Cluster::network_db_bootstrap =
"CREATE TABLE IF NOT EXISTS cluster_network_relation ("
"cid INTEGER, oid INTEGER, PRIMARY KEY(cid, oid))";
/* ************************************************************************** */
/* Cluster :: Constructor/Destructor */
/* ************************************************************************** */
@ -247,6 +265,59 @@ int Cluster::insert_replace(SqlDB *db, bool replace, string& error_str)
db->free_str(sql_name);
db->free_str(sql_xml);
if (rc == 0)
{
oss.str("");
oss << "BEGIN TRANSACTION; "
<< "DELETE FROM " << host_table << " WHERE cid = " << oid << "; "
<< "DELETE FROM " << network_table << " WHERE cid = " << oid << "; "
<< "DELETE FROM " << datastore_table<< " WHERE cid = " << oid << "; ";
// TODO
//if (db->multiple_values_support())
if (false)
{
}
else
{
set<int>::iterator i;
set<int> host_set = hosts.get_collection();
for(i = host_set.begin(); i != host_set.end(); i++)
{
oss << "INSERT INTO " << host_table
<< " (" << host_db_names << ") VALUES ("
<< oid << ","
<< *i << "); ";
}
set<int> datastore_set = datastores.get_collection();
for(i = datastore_set.begin(); i != datastore_set.end(); i++)
{
oss << "INSERT INTO " << datastore_table
<< " (" << datastore_db_names << ") VALUES ("
<< oid << ","
<< *i << "); ";
}
set<int> vnet_set = vnets.get_collection();
for(i = vnet_set.begin(); i != vnet_set.end(); i++)
{
oss << "INSERT INTO " << network_table
<< " (" << network_db_names << ") VALUES ("
<< oid << ","
<< *i << "); ";
}
}
oss << "COMMIT";
rc = db->exec(oss);
}
return rc;
error_xml:

View File

@ -362,7 +362,7 @@ void PoolObjectSQL::get_permissions(PoolObjectAuth& auth)
if(cl != 0)
{
auth.cid = cl->get_cluster_id();
auth.cids = cl->get_cluster_ids();
}
}

View File

@ -740,9 +740,29 @@ void PoolSQL::acl_filter(int uid,
acl_filter << " OR gid = " << *it;
}
for ( it = cids.begin(); it < cids.end(); it++ )
string cl_table;
if (auth_object == PoolObjectSQL::HOST)
{
acl_filter << " OR cid = " << *it;
cl_table = Cluster::host_table;
}
else if (auth_object == PoolObjectSQL::DATASTORE)
{
cl_table = Cluster::datastore_table;
}
else if (auth_object == PoolObjectSQL::NET)
{
cl_table = Cluster::network_table;
}
if (!cl_table.empty())
{
for ( it = cids.begin(); it < cids.end(); it++ )
{
acl_filter << " OR oid IN ("
<< "SELECT oid from " << cl_table
<< " WHERE cid = " << *it << ")";
}
}
filter = acl_filter.str();

View File

@ -70,9 +70,19 @@ public:
return oid;
};
int get_cid() const
bool is_in_cluster(const set<int> &cids) const
{
return cluster_id;
set<int>::const_iterator i;
for (i = cids.begin(); i != cids.end(); i++)
{
if (cluster_ids.find(*i) != cluster_ids.end())
{
return true;
}
}
return false;
};
/**
@ -103,7 +113,7 @@ public:
private:
int oid;
int cluster_id;
set<int> cluster_ids;
int uid;
int gid;

View File

@ -42,9 +42,9 @@ public:
return oid;
};
int get_cid() const
set<int> get_cids() const
{
return cluster_id;
return cluster_ids;
};
/**
@ -160,7 +160,7 @@ public:
private:
int oid;
int cluster_id;
set<int> cluster_ids;
// Host share values
long long mem_usage; /**< Memory allocated to VMs (in KB) */

View File

@ -19,6 +19,7 @@
#include "DatastoreXML.h"
#include "NebulaUtil.h"
#include "NebulaLog.h"
#include "ObjectCollection.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -35,8 +36,12 @@ const char * DatastoreXML::ds_paths[] = {
void DatastoreXML::init_attributes()
{
xpath(oid, "/DATASTORE/ID", -1);
xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1);
xpath(oid, "/DATASTORE/ID", -1);
ObjectCollection cluster_collection("CLUSTERS");
cluster_collection.from_xml(this, "/DATASTORE/");
cluster_ids = cluster_collection.clone();
xpath(uid, "/DATASTORE/UID", -1);
xpath(gid, "/DATASTORE/GID", -1);
@ -125,7 +130,7 @@ void DatastoreXML::get_permissions(PoolObjectAuth& auth)
auth.oid = oid;
auth.uid = uid;
auth.gid = gid;
auth.cid = cluster_id;
auth.cids = cluster_ids;
auth.owner_u = owner_u;
auth.owner_m = owner_m;

View File

@ -98,6 +98,8 @@ int HostPoolXML::load_info(xmlrpc_c::value &result)
void HostPoolXML::merge_clusters(ClusterPoolXML * clpool)
{
// TODO
/*
map<int,ObjectXML*>::iterator it;
ClusterXML* cluster;
@ -131,6 +133,7 @@ void HostPoolXML::merge_clusters(ClusterPoolXML * clpool)
}
}
}
*/
}
/* -------------------------------------------------------------------------- */

View File

@ -22,6 +22,7 @@
#include "HostXML.h"
#include "NebulaUtil.h"
#include "NebulaLog.h"
#include "ObjectCollection.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -39,7 +40,12 @@ const char *HostXML::host_paths[] = {
void HostXML::init_attributes()
{
xpath(oid, "/HOST/ID", -1);
xpath(cluster_id, "/HOST/CLUSTER_ID", -1);
ObjectCollection cluster_collection("CLUSTERS");
cluster_collection.from_xml(this, "/HOST/");
cluster_ids = cluster_collection.clone();
xpath<long long>(mem_usage, "/HOST/HOST_SHARE/MEM_USAGE", 0);
xpath<long long>(cpu_usage, "/HOST/HOST_SHARE/CPU_USAGE", 0);
xpath<long long>(max_mem, "/HOST/HOST_SHARE/MAX_MEM", 0);
@ -172,7 +178,7 @@ ostream& operator<<(ostream& o, const HostXML& p)
map<int, long long>::const_iterator it;
o << "ID : " << p.oid << endl;
o << "CLUSTER_ID : " << p.cluster_id << endl;
o << "CLUSTER_IDS : " << one_util::join(p.cluster_ids, ',') << endl;
o << "MEM_USAGE : " << p.mem_usage << endl;
o << "CPU_USAGE : " << p.cpu_usage << endl;
o << "MAX_MEM : " << p.max_mem << endl;

View File

@ -546,7 +546,7 @@ static bool match_host(AclXML * acls, UserPoolXML * upool, VirtualMachineXML* vm
PoolObjectAuth hperms;
hperms.oid = host->get_hid();
hperms.cid = host->get_cid();
hperms.cids = host->get_cids();
hperms.obj_type = PoolObjectSQL::HOST;
UserXML * user = upool->get(vm->get_uid());
@ -1050,7 +1050,8 @@ void Scheduler::dispatch()
long long dsk;
vector<VectorAttribute *> pci;
int hid, dsid, cid;
int hid, dsid;
set<int> cids;
bool test_cap_result;
unsigned int dispatched_vms = 0;
@ -1113,7 +1114,7 @@ void Scheduler::dispatch()
continue;
}
cid = host->get_cid();
cids = host->get_cids();
//------------------------------------------------------------------
// Test host capacity
@ -1170,7 +1171,7 @@ void Scheduler::dispatch()
//--------------------------------------------------------------
// Test cluster membership for datastore and selected host
//--------------------------------------------------------------
if (ds->get_cid() != cid)
if (!ds->is_in_cluster(cids))
{
continue;
}