mirror of
https://github.com/OpenNebula/one.git
synced 2024-12-22 13:33:52 +03:00
feature #1099: Moved SQL filters to the corresponding pools
This commit is contained in:
parent
70d5c75d04
commit
7ad3ce1965
@ -62,12 +62,6 @@ public:
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
// ----------------------------------------
|
||||
// DataBase implementation
|
||||
// ----------------------------------------
|
||||
|
||||
static const char * table;
|
||||
|
||||
private:
|
||||
friend class VirtualMachine;
|
||||
friend class VirtualMachinePool;
|
||||
@ -75,7 +69,8 @@ private:
|
||||
// ----------------------------------------
|
||||
// DataBase implementation variables
|
||||
// ----------------------------------------
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
@ -154,19 +154,47 @@ public:
|
||||
*/
|
||||
virtual int dump(ostringstream& oss, const string& where) = 0;
|
||||
|
||||
/**
|
||||
* Dumps the output of the custom sql query into an xml
|
||||
*
|
||||
* @param oss The output stream to dump the xml contents
|
||||
* @param root_elem_name Name of the root xml element name
|
||||
* @param sql_query The SQL query to execute
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int custom_dump(ostringstream& oss,
|
||||
const string& root_elem_name,
|
||||
ostringstream& sql_query);
|
||||
// -------------------------------------------------------------------------
|
||||
// Function to generate dump filters
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a filter for those objects (oids) or objects owned by a given
|
||||
* group that an user can access based on the ACL rules
|
||||
* @param uid the user id
|
||||
* @param gid the group id
|
||||
* @param auth_object object type
|
||||
* @param all returns if the user can access all objects
|
||||
* @param filter the resulting filter string
|
||||
*/
|
||||
static void acl_filter(int uid,
|
||||
int gid,
|
||||
PoolObjectSQL::ObjectType auth_object,
|
||||
bool& all,
|
||||
string& filter);
|
||||
/**
|
||||
* Creates a filter for the objects owned by a given user/group
|
||||
* @param uid the user id
|
||||
* @param gid the group id
|
||||
* @param filter_flag query type (ALL, MINE, GROUP)
|
||||
* @param all user can access all objects
|
||||
* @param filter the resulting filter string
|
||||
*/
|
||||
static void usr_filter(int uid,
|
||||
int gid,
|
||||
int filter_flag,
|
||||
bool all,
|
||||
const string& acl_str,
|
||||
string& filter);
|
||||
/**
|
||||
* Creates a filter for a given set of objects based on their id
|
||||
* @param start_id first id
|
||||
* @param end_id last id
|
||||
* @param filter the resulting filter string
|
||||
*/
|
||||
static void oid_filter(int start_id,
|
||||
int end_id,
|
||||
string& filter);
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -195,8 +223,23 @@ protected:
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& elem_name,
|
||||
const char * table, const string& where);
|
||||
int dump(ostringstream& oss,
|
||||
const string& elem_name,
|
||||
const char * table,
|
||||
const string& where);
|
||||
|
||||
/**
|
||||
* Dumps the output of the custom sql query into an xml
|
||||
*
|
||||
* @param oss The output stream to dump the xml contents
|
||||
* @param root_elem_name Name of the root xml element name
|
||||
* @param sql_query The SQL query to execute
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss,
|
||||
const string& root_elem_name,
|
||||
ostringstream& sql_query);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Interface to access the lastOID assigned by the pool */
|
||||
|
@ -29,6 +29,16 @@ using namespace std;
|
||||
|
||||
class RequestManagerPoolInfoFilter: public Request
|
||||
{
|
||||
public:
|
||||
/** Specify all objects the user has right to USE (-2) */
|
||||
static const int ALL;
|
||||
|
||||
/** Specify user's objects in the pool (-3) */
|
||||
static const int MINE;
|
||||
|
||||
/** Specify user's + group objects (-1) */
|
||||
static const int MINE_GROUP;
|
||||
|
||||
protected:
|
||||
RequestManagerPoolInfoFilter(const string& method_name,
|
||||
const string& help,
|
||||
@ -40,30 +50,18 @@ protected:
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** Specify all objects the user has right to USE (-2) */
|
||||
static const int ALL;
|
||||
|
||||
/** Specify user's objects in the pool (-3) */
|
||||
static const int MINE;
|
||||
|
||||
/** Specify user's + group objects (-1) */
|
||||
static const int MINE_GROUP;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
virtual void request_execute(
|
||||
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void generate_where_string(
|
||||
RequestAttributes& att,
|
||||
int filter_flag,
|
||||
int start_id,
|
||||
int end_id,
|
||||
const string& and_clause,
|
||||
const string& or_clause,
|
||||
ostringstream& where_string);
|
||||
void where_filter(RequestAttributes& att,
|
||||
int filter_flag,
|
||||
int start_id,
|
||||
int end_id,
|
||||
const string& and_clause,
|
||||
const string& or_clause,
|
||||
string& where_string);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
@ -710,13 +710,6 @@ public:
|
||||
static void set_auth_request(int uid,
|
||||
AuthRequest& ar,
|
||||
VirtualMachineTemplate *tmpl);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// DataBase implementation (Public)
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
static const char * table;
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -952,6 +945,8 @@ protected:
|
||||
// *************************************************************************
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
|
@ -145,6 +145,18 @@ public:
|
||||
return PoolSQL::dump(oss, "VM_POOL", VirtualMachine::table, where);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dumps the VM accounting information in XML format. A filter can be also
|
||||
* added to the query as well as a time frame.
|
||||
* @param oss the output stream to dump the pool contents
|
||||
* @param where filter for the objects, defaults to all
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_acct(ostringstream& oss,
|
||||
const string& where,
|
||||
int time_start,
|
||||
int time_end);
|
||||
private:
|
||||
/**
|
||||
* Factory method to produce VM objects
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "RequestManagerPoolInfoFilter.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@ -490,22 +491,22 @@ int PoolSQL::dump(ostringstream& oss,
|
||||
|
||||
cmd << " ORDER BY oid";
|
||||
|
||||
return custom_dump(oss, elem_name, cmd);
|
||||
return dump(oss, elem_name, cmd);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int PoolSQL::custom_dump(ostringstream& oss,
|
||||
const string& root_elem_name,
|
||||
ostringstream& sql_query)
|
||||
int PoolSQL::dump(ostringstream& oss,
|
||||
const string& root_elem_name,
|
||||
ostringstream& sql_query)
|
||||
{
|
||||
int rc;
|
||||
|
||||
oss << "<" << root_elem_name << ">";
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&PoolSQL::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
rc = db->exec(sql_query, this);
|
||||
|
||||
@ -557,3 +558,120 @@ int PoolSQL::search(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void PoolSQL::acl_filter(int uid,
|
||||
int gid,
|
||||
PoolObjectSQL::ObjectType auth_object,
|
||||
bool& all,
|
||||
string& filter)
|
||||
{
|
||||
filter.clear();
|
||||
|
||||
if ( uid == 0 || gid == 0 )
|
||||
{
|
||||
all = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
AclManager* aclm = nd.get_aclm();
|
||||
|
||||
ostringstream acl_filter;
|
||||
vector<int>::iterator it;
|
||||
|
||||
vector<int> oids;
|
||||
vector<int> gids;
|
||||
|
||||
aclm->reverse_search(uid,
|
||||
gid,
|
||||
auth_object,
|
||||
AuthRequest::USE,
|
||||
all,
|
||||
oids,
|
||||
gids);
|
||||
|
||||
for ( it = oids.begin(); it < oids.end(); it++ )
|
||||
{
|
||||
acl_filter << " OR oid = " << *it;
|
||||
}
|
||||
|
||||
for ( it = gids.begin(); it < gids.end(); it++ )
|
||||
{
|
||||
acl_filter << " OR gid = " << *it;
|
||||
}
|
||||
|
||||
filter = acl_filter.str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void PoolSQL::usr_filter(int uid,
|
||||
int gid,
|
||||
int filter_flag,
|
||||
bool all,
|
||||
const string& acl_str,
|
||||
string& filter)
|
||||
{
|
||||
ostringstream uid_filter;
|
||||
|
||||
if ( filter_flag == RequestManagerPoolInfoFilter::MINE )
|
||||
{
|
||||
uid_filter << "uid = " << uid;
|
||||
}
|
||||
else if ( filter_flag == RequestManagerPoolInfoFilter::MINE_GROUP )
|
||||
{
|
||||
uid_filter << " uid = " << uid
|
||||
<< " OR ( gid = " << gid << " AND group_u = 1 )";
|
||||
}
|
||||
else if ( filter_flag == RequestManagerPoolInfoFilter::ALL )
|
||||
{
|
||||
if (!all)
|
||||
{
|
||||
uid_filter << " uid = " << uid
|
||||
<< " OR ( gid = " << gid << " AND group_u = 1 )"
|
||||
<< " OR other_u = 1"
|
||||
<< acl_str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uid_filter << "uid = " << filter_flag;
|
||||
|
||||
if ( filter_flag != uid && !all )
|
||||
{
|
||||
uid_filter << " AND ("
|
||||
<< " ( gid = " << gid << " AND group_u = 1)"
|
||||
<< " OR other_u = 1"
|
||||
<< acl_str
|
||||
<< ")";
|
||||
}
|
||||
}
|
||||
|
||||
filter = uid_filter.str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void PoolSQL::oid_filter(int start_id,
|
||||
int end_id,
|
||||
string& filter)
|
||||
{
|
||||
ostringstream idfilter;
|
||||
|
||||
if ( start_id != -1 )
|
||||
{
|
||||
idfilter << "oid >= " << start_id;
|
||||
|
||||
if ( end_id != -1 )
|
||||
{
|
||||
idfilter << " AND oid <= " << end_id;
|
||||
}
|
||||
}
|
||||
|
||||
filter = idfilter.str();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -100,8 +100,7 @@ void VirtualMachinePoolAccounting::request_execute(
|
||||
int time_end = xmlrpc_c::value_int(paramList.getInt(3));
|
||||
|
||||
ostringstream oss;
|
||||
ostringstream cmd;
|
||||
ostringstream vmpool_where;
|
||||
string where;
|
||||
int rc;
|
||||
|
||||
if ( filter_flag < MINE )
|
||||
@ -112,39 +111,12 @@ void VirtualMachinePoolAccounting::request_execute(
|
||||
return;
|
||||
}
|
||||
|
||||
cmd << "SELECT " << History::table << ".body FROM " << History::table
|
||||
<< " INNER JOIN " << VirtualMachine::table
|
||||
<< " WHERE vid=oid";
|
||||
|
||||
generate_where_string(att, filter_flag, -1, -1,
|
||||
"", "", vmpool_where);
|
||||
|
||||
if ( !vmpool_where.str().empty() ) //TODO: better empty check?
|
||||
{
|
||||
cmd << " AND " << vmpool_where;
|
||||
}
|
||||
|
||||
if ( time_start != -1 || time_end != -1 )
|
||||
{
|
||||
if ( time_start != -1 )
|
||||
{
|
||||
cmd << " AND (etime > " << time_start << " OR etime = 0)";
|
||||
}
|
||||
|
||||
if ( time_end != -1 )
|
||||
{
|
||||
cmd << " AND stime < " << time_end;
|
||||
}
|
||||
}
|
||||
|
||||
cmd << " GROUP BY vid,seq";
|
||||
|
||||
// ------------------------------------------
|
||||
// Dump the history records
|
||||
// ------------------------------------------
|
||||
|
||||
rc = pool->custom_dump(oss, "HISTORY_RECORDS", cmd);
|
||||
where_filter(att, filter_flag, -1, -1, "", "", where);
|
||||
|
||||
rc = (static_cast<VirtualMachinePool *>(pool))->dump_acct(oss,
|
||||
where,
|
||||
time_start,
|
||||
time_end);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
failure_response(INTERNAL,request_error("Internal Error",""), att);
|
||||
@ -209,126 +181,38 @@ void ClusterPoolInfo::request_execute(
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManagerPoolInfoFilter::generate_where_string(
|
||||
void RequestManagerPoolInfoFilter::where_filter(
|
||||
RequestAttributes& att,
|
||||
int filter_flag,
|
||||
int start_id,
|
||||
int end_id,
|
||||
const string& and_clause,
|
||||
const string& or_clause,
|
||||
ostringstream& where_string)
|
||||
string& filter_str)
|
||||
{
|
||||
bool empty = true;
|
||||
bool empty = true;
|
||||
bool all;
|
||||
|
||||
ostringstream uid_filter;
|
||||
ostringstream id_filter;
|
||||
|
||||
string uid_str;
|
||||
string acl_str;
|
||||
string id_str;
|
||||
string uid_str;
|
||||
string oid_str;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
AclManager* aclm = nd.get_aclm();
|
||||
bool all;
|
||||
vector<int> oids;
|
||||
vector<int> gids;
|
||||
ostringstream filter;
|
||||
|
||||
PoolSQL::acl_filter(att.uid, att.gid, auth_object, all, acl_str);
|
||||
|
||||
PoolSQL::usr_filter(att.uid, att.gid, filter_flag, all, acl_str, uid_str);
|
||||
|
||||
PoolSQL::oid_filter(start_id, end_id, oid_str);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// User ID filter
|
||||
// -------------------------------------------------------------------------
|
||||
// Compound WHERE clause
|
||||
// WHERE ( id_str ) AND ( uid_str ) AND ( and_clause ) OR ( or_clause )
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if ( att.uid == 0 || att.gid == 0 )
|
||||
if (!oid_str.empty())
|
||||
{
|
||||
all = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ostringstream acl_filter;
|
||||
vector<int>::iterator it;
|
||||
|
||||
aclm->reverse_search(att.uid,
|
||||
att.gid,
|
||||
auth_object,
|
||||
AuthRequest::USE,
|
||||
all,
|
||||
oids,
|
||||
gids);
|
||||
|
||||
for ( it = oids.begin(); it < oids.end(); it++ )
|
||||
{
|
||||
acl_filter << " OR oid = " << *it;
|
||||
}
|
||||
|
||||
for ( it = gids.begin(); it < gids.end(); it++ )
|
||||
{
|
||||
acl_filter << " OR gid = " << *it;
|
||||
}
|
||||
|
||||
acl_str = acl_filter.str();
|
||||
}
|
||||
|
||||
switch ( filter_flag )
|
||||
{
|
||||
case MINE:
|
||||
uid_filter << "uid = " << att.uid;
|
||||
break;
|
||||
|
||||
case MINE_GROUP:
|
||||
uid_filter << " uid = " << att.uid
|
||||
<< " OR ( gid = " << att.gid << " AND group_u = 1 )";
|
||||
break;
|
||||
|
||||
case ALL:
|
||||
if (!all)
|
||||
{
|
||||
uid_filter << " uid = " << att.uid
|
||||
<< " OR ( gid = " << att.gid << " AND group_u = 1 )"
|
||||
<< " OR other_u = 1"
|
||||
<< acl_str;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
uid_filter << "uid = " << filter_flag;
|
||||
|
||||
if ( filter_flag != att.uid && !all )
|
||||
{
|
||||
uid_filter << " AND ("
|
||||
<< " ( gid = " << att.gid << " AND group_u = 1)"
|
||||
<< " OR other_u = 1"
|
||||
<< acl_str
|
||||
<< ")";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
uid_str = uid_filter.str();
|
||||
|
||||
// ------------------------------------------
|
||||
// Resource ID filter
|
||||
// ------------------------------------------
|
||||
|
||||
if ( start_id != -1 )
|
||||
{
|
||||
id_filter << "oid >= " << start_id;
|
||||
|
||||
if ( end_id != -1 )
|
||||
{
|
||||
id_filter << " AND oid <= " << end_id;
|
||||
}
|
||||
}
|
||||
|
||||
id_str = id_filter.str();
|
||||
|
||||
// ------------------------------------------
|
||||
// Compound WHERE clause
|
||||
// ------------------------------------------
|
||||
|
||||
// WHERE ( id_str ) AND ( uid_str ) AND ( and_clause ) OR ( or_clause )
|
||||
|
||||
if (!id_str.empty())
|
||||
{
|
||||
where_string << "(" << id_str << ")" ;
|
||||
filter << "(" << oid_str << ")" ;
|
||||
empty = false;
|
||||
}
|
||||
|
||||
@ -336,10 +220,10 @@ void RequestManagerPoolInfoFilter::generate_where_string(
|
||||
{
|
||||
if (!empty)
|
||||
{
|
||||
where_string << " AND ";
|
||||
filter << " AND ";
|
||||
}
|
||||
|
||||
where_string << "(" << uid_str << ")";
|
||||
filter << "(" << uid_str << ")";
|
||||
empty = false;
|
||||
}
|
||||
|
||||
@ -347,10 +231,10 @@ void RequestManagerPoolInfoFilter::generate_where_string(
|
||||
{
|
||||
if (!empty)
|
||||
{
|
||||
where_string << " AND ";
|
||||
filter << " AND ";
|
||||
}
|
||||
|
||||
where_string << "(" << and_clause << ")";
|
||||
filter << "(" << and_clause << ")";
|
||||
empty = false;
|
||||
}
|
||||
|
||||
@ -358,15 +242,17 @@ void RequestManagerPoolInfoFilter::generate_where_string(
|
||||
{
|
||||
if (!empty)
|
||||
{
|
||||
where_string << " OR ";
|
||||
filter << " OR ";
|
||||
}
|
||||
|
||||
where_string << "(" << or_clause << ")";
|
||||
filter << "(" << or_clause << ")";
|
||||
}
|
||||
|
||||
filter_str = filter.str();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManagerPoolInfoFilter::dump(
|
||||
RequestAttributes& att,
|
||||
@ -377,7 +263,7 @@ void RequestManagerPoolInfoFilter::dump(
|
||||
const string& or_clause)
|
||||
{
|
||||
ostringstream oss;
|
||||
ostringstream where_string;
|
||||
string where_string;
|
||||
int rc;
|
||||
|
||||
if ( filter_flag < MINE )
|
||||
@ -388,14 +274,15 @@ void RequestManagerPoolInfoFilter::dump(
|
||||
return;
|
||||
}
|
||||
|
||||
generate_where_string(att, filter_flag, start_id, end_id,
|
||||
and_clause, or_clause, where_string);
|
||||
where_filter(att,
|
||||
filter_flag,
|
||||
start_id,
|
||||
end_id,
|
||||
and_clause,
|
||||
or_clause,
|
||||
where_string);
|
||||
|
||||
// ------------------------------------------
|
||||
// Get the pool
|
||||
// ------------------------------------------
|
||||
|
||||
rc = pool->dump(oss, where_string.str());
|
||||
rc = pool->dump(oss, where_string);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
@ -407,4 +294,3 @@ void RequestManagerPoolInfoFilter::dump(
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -266,3 +266,37 @@ int VirtualMachinePool::get_pending(
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachinePool::dump_acct(ostringstream& oss,
|
||||
const string& where,
|
||||
int time_start,
|
||||
int time_end)
|
||||
{
|
||||
ostringstream cmd;
|
||||
|
||||
cmd << "SELECT " << History::table << ".body FROM " << History::table
|
||||
<< " INNER JOIN " << VirtualMachine::table
|
||||
<< " WHERE vid=oid";
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " AND " << where;
|
||||
}
|
||||
|
||||
if ( time_start != -1 || time_end != -1 )
|
||||
{
|
||||
if ( time_start != -1 )
|
||||
{
|
||||
cmd << " AND (etime > " << time_start << " OR etime = 0)";
|
||||
}
|
||||
|
||||
if ( time_end != -1 )
|
||||
{
|
||||
cmd << " AND stime < " << time_end;
|
||||
}
|
||||
}
|
||||
|
||||
cmd << " GROUP BY vid,seq";
|
||||
|
||||
return PoolSQL::dump(oss, "HISTORY_RECORDS", cmd);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user