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:
parent
e8a05ca1d7
commit
621a186947
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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 )
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user