mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-22 18:50:08 +03:00
Merge branch 'feature-687' of git.opennebula.org:one into feature-687
This commit is contained in:
commit
fa2477a79f
@ -32,7 +32,12 @@ class AclManager : public Callbackable
|
||||
public:
|
||||
AclManager(SqlDB * _db);
|
||||
|
||||
~AclManager();
|
||||
AclManager():db(0),lastOID(0)
|
||||
{
|
||||
pthread_mutex_init(&mutex, 0);
|
||||
};
|
||||
|
||||
virtual ~AclManager();
|
||||
|
||||
/**
|
||||
* Loads the ACL rule set from the DB
|
||||
@ -75,10 +80,10 @@ public:
|
||||
* -2 if the rule is malformed,
|
||||
* -3 if the DB insert failed
|
||||
*/
|
||||
int add_rule(long long user,
|
||||
long long resource,
|
||||
long long rights,
|
||||
string& error_str);
|
||||
virtual int add_rule(long long user,
|
||||
long long resource,
|
||||
long long rights,
|
||||
string& error_str);
|
||||
/**
|
||||
* Deletes a rule from the ACL rule set
|
||||
*
|
||||
@ -86,7 +91,7 @@ public:
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int del_rule(int oid, string& error_str);
|
||||
virtual int del_rule(int oid, string& error_str);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* DB management */
|
||||
@ -102,9 +107,9 @@ public:
|
||||
* @param oss The output stream to dump the rule set contents
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss);
|
||||
virtual int dump(ostringstream& oss);
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
// ----------------------------------------
|
||||
// ACL rules management
|
||||
@ -121,6 +126,8 @@ private:
|
||||
*/
|
||||
map<int, AclRule *> acl_rules_oids;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Gets all rules that apply to the user_req and, if any of them grants
|
||||
* permission, returns true.
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -83,11 +84,10 @@ public:
|
||||
/**
|
||||
* Rebuilds the rule from an xml formatted string
|
||||
*
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @param node xml node for the ACL rule
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
int from_xml(xmlNodePtr node);
|
||||
|
||||
/**
|
||||
* Returns the 32 less significant bits of the user long long attribute
|
||||
@ -131,6 +131,20 @@ public:
|
||||
return resource & 0xFFFFFFFF00000000LL;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Functions needed by the Scheduler ACL engine
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
long long get_user() const
|
||||
{
|
||||
return user;
|
||||
}
|
||||
|
||||
long long get_oid() const
|
||||
{
|
||||
return oid;
|
||||
}
|
||||
|
||||
private:
|
||||
// NONE_ID can never be used in a rule. It is useful to create masks that
|
||||
// will never match any existing rule
|
||||
|
@ -94,20 +94,6 @@ public:
|
||||
int xpath(unsigned int& value, const char * xpath_expr,
|
||||
const unsigned int& def);
|
||||
|
||||
/**
|
||||
* Gets and sets a xpath attribute, if the attribute is not found a default
|
||||
* is used
|
||||
* @param value to set
|
||||
* @param xpath_expr of the xml element
|
||||
* @param def default value if the element is not found
|
||||
* @param hex if true, the contents of the element are expected to be in
|
||||
* hexadecimal instead of decimal
|
||||
*
|
||||
* @return -1 if default was set
|
||||
*/
|
||||
long long xpath(long long& value, const char * xpath_expr,
|
||||
const long long& def, bool hex=true);
|
||||
|
||||
/**
|
||||
* Gets and sets a xpath attribute, if the attribute is not found a default
|
||||
* is used
|
||||
|
@ -340,7 +340,6 @@ int AclManager::add_rule(long long user, long long resource, long long rights,
|
||||
goto error_malformed;
|
||||
}
|
||||
|
||||
|
||||
rc = insert(rule);
|
||||
|
||||
if ( rc != 0 )
|
||||
|
@ -350,27 +350,54 @@ string& AclRule::to_xml(string& xml) const
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int AclRule::from_xml(const string &xml_str)
|
||||
int AclRule::from_xml(xmlNodePtr node)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
string tmp_error;
|
||||
|
||||
ObjectXML xml_obj(xml_str);
|
||||
|
||||
rc += xml_obj.xpath(oid , "/ACL/ID" , 0);
|
||||
rc += xml_obj.xpath(user , "/ACL/USER" , 0);
|
||||
rc += xml_obj.xpath(resource, "/ACL/RESOURCE", 0);
|
||||
rc += xml_obj.xpath(rights , "/ACL/RIGHTS" , 0);
|
||||
rc += xml_obj.xpath(str , "/ACL/STRING" , "");
|
||||
|
||||
if ( (rc != 0) || malformed(tmp_error) )
|
||||
for (xmlNodePtr acl = node->children ; acl != 0 ; acl = acl->next)
|
||||
{
|
||||
return -1;
|
||||
if ( acl->type != XML_ELEMENT_NODE )
|
||||
{
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
xmlNodePtr elem = acl->children;
|
||||
|
||||
if ( elem->type != XML_TEXT_NODE )
|
||||
{
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
string name = reinterpret_cast<const char*>(acl->name);
|
||||
istringstream iss(reinterpret_cast<const char*>(elem->content));
|
||||
|
||||
if (name == "ID")
|
||||
{
|
||||
iss >> oid;
|
||||
}
|
||||
else if (name == "USER")
|
||||
{
|
||||
iss >> hex >> user;
|
||||
}
|
||||
else if (name == "RESOURCE")
|
||||
{
|
||||
iss >> hex >> resource;
|
||||
}
|
||||
else if (name == "RIGHTS")
|
||||
{
|
||||
iss >> hex >> rights;
|
||||
}
|
||||
else if (name == "STRING")
|
||||
{
|
||||
str = iss.str();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -35,10 +35,10 @@ class OneAclHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
[-1, rc.message]
|
||||
return [-1, rc.message]
|
||||
else
|
||||
if !rc
|
||||
puts "Rule added" if options[:verbose]
|
||||
if rc.class == Fixnum
|
||||
puts "Rule added with ID #{rc}" if options[:verbose]
|
||||
return 0
|
||||
end
|
||||
return [-1, rc[:users].message] if OpenNebula.is_error?(rc[:users])
|
||||
|
@ -54,7 +54,7 @@ cmd = CommandParser::CmdParser.new(ARGV) do
|
||||
Adds a new ACL rule
|
||||
EOT
|
||||
|
||||
command :addrule, addrule_desc, [:user,:rulestr], [:resource, nil], [:rights, nil] do
|
||||
command :create, addrule_desc, [:user,:rulestr], [:resource, nil], [:rights, nil] do
|
||||
helper.add_rule(options, args[0], args[1], args[2] )
|
||||
end
|
||||
|
||||
@ -62,7 +62,7 @@ cmd = CommandParser::CmdParser.new(ARGV) do
|
||||
Deletes an existing ACL rule
|
||||
EOT
|
||||
|
||||
command :delrule, delrule_desc, :id do
|
||||
command :delete, delrule_desc, :id do
|
||||
helper.delete_rule( options, args[0] )
|
||||
end
|
||||
|
||||
|
@ -111,7 +111,9 @@ module OpenNebula
|
||||
end
|
||||
|
||||
resources[0].split("+").each{ |resource|
|
||||
next if !RESOURCES[resource.upcase]
|
||||
if !RESOURCES[resource.upcase]
|
||||
raise "Resource #{resource} malformed."
|
||||
end
|
||||
@content[:resources] += RESOURCES[resource.upcase]
|
||||
}
|
||||
|
||||
@ -127,7 +129,7 @@ module OpenNebula
|
||||
rights = rights.split("+")
|
||||
|
||||
rights.each{ |right|
|
||||
next if !RIGHTS[right.upcase]
|
||||
raise "Right #{right} malformed." if !RIGHTS[right.upcase]
|
||||
|
||||
@content[:rights] += RIGHTS[right.upcase]
|
||||
}
|
||||
|
@ -56,14 +56,10 @@ module OpenNebula
|
||||
# +resource+ A string containing a hex number, e.g. 0x2100000001
|
||||
# +rights+ A string containing a hex number, e.g. 0x10
|
||||
def addrule(user, resource, rights)
|
||||
rc = @client.call( ACL_POOL_METHODS[:addrule],
|
||||
return @client.call( ACL_POOL_METHODS[:addrule],
|
||||
user,
|
||||
resource,
|
||||
rights )
|
||||
|
||||
rc = nil if !OpenNebula.is_error?(rc)
|
||||
|
||||
return rc
|
||||
end
|
||||
|
||||
# Adds a new ACL rule.
|
||||
|
83
src/scheduler/include/AclXML.h
Normal file
83
src/scheduler/include/AclXML.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef ACL_XML_H_
|
||||
#define ACL_XML_H_
|
||||
|
||||
#include "AclManager.h"
|
||||
#include "Client.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* This class manages the ACL rules and the authorization engine
|
||||
*/
|
||||
class AclXML : public AclManager
|
||||
{
|
||||
public:
|
||||
AclXML(Client * _client):AclManager(), client(_client){};
|
||||
|
||||
virtual ~AclXML(){};
|
||||
|
||||
/**
|
||||
* Loads the ACL rule set from the DB
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int set_up();
|
||||
|
||||
private:
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Re-implement DB public functions not used in scheduler */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
int start()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int add_rule(long long user,
|
||||
long long resource,
|
||||
long long rights,
|
||||
string& error_str)
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
|
||||
int del_rule(int oid, string& error_str)
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
|
||||
int dump(ostringstream& oss)
|
||||
{
|
||||
return -1;
|
||||
};
|
||||
|
||||
Client * client;
|
||||
|
||||
/**
|
||||
* Loads the ACL rule set from its XML representation:
|
||||
* as obtained by a dump call
|
||||
*
|
||||
* @param xml_str string with the XML document for the ACL
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int load_rules(const string& xml_str);
|
||||
|
||||
void flush_rules();
|
||||
};
|
||||
|
||||
#endif /*ACL_XML_H*/
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "VirtualMachinePoolXML.h"
|
||||
#include "SchedulerPolicy.h"
|
||||
#include "ActionManager.h"
|
||||
#include "AclXML.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -50,6 +51,7 @@ protected:
|
||||
hpool(0),
|
||||
vmpool(0),
|
||||
upool(0),
|
||||
acls(0),
|
||||
timer(_timer),
|
||||
url(_url),
|
||||
machines_limit(_machines_limit),
|
||||
@ -78,6 +80,11 @@ protected:
|
||||
delete upool;
|
||||
}
|
||||
|
||||
if ( acls != 0)
|
||||
{
|
||||
delete acls;
|
||||
}
|
||||
|
||||
if ( client != 0)
|
||||
{
|
||||
delete client;
|
||||
@ -91,6 +98,7 @@ protected:
|
||||
HostPoolXML * hpool;
|
||||
VirtualMachinePoolXML * vmpool;
|
||||
UserPoolXML * upool;
|
||||
AclXML * acls;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Scheduler Policies
|
||||
|
@ -41,7 +41,12 @@ public:
|
||||
return oid;
|
||||
};
|
||||
|
||||
set<int> get_groups()
|
||||
int get_gid()
|
||||
{
|
||||
return gid;
|
||||
};
|
||||
|
||||
const set<int>& get_groups()
|
||||
{
|
||||
return group_ids;
|
||||
};
|
||||
|
114
src/scheduler/src/pool/AclXML.cc
Normal file
114
src/scheduler/src/pool/AclXML.cc
Normal file
@ -0,0 +1,114 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
||||
/* not use this file except in compliance with the License. You may obtain */
|
||||
/* a copy of the License at */
|
||||
/* */
|
||||
/* http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* */
|
||||
/* Unless required by applicable law or agreed to in writing, software */
|
||||
/* distributed under the License is distributed on an "AS IS" BASIS, */
|
||||
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
||||
/* See the License for the specific language governing permissions and */
|
||||
/* limitations under the License. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "AclXML.h"
|
||||
#include "ObjectXML.h"
|
||||
#include <vector>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int AclXML::set_up()
|
||||
{
|
||||
xmlrpc_c::value result;
|
||||
|
||||
try
|
||||
{
|
||||
client->call(client->get_endpoint(), // serverUrl
|
||||
"one.acl.info", // methodName
|
||||
"s", // arguments format
|
||||
&result, // resultP
|
||||
client->get_oneauth().c_str());// argument
|
||||
|
||||
vector<xmlrpc_c::value> values =
|
||||
xmlrpc_c::value_array(result).vectorValueValue();
|
||||
|
||||
bool success = xmlrpc_c::value_boolean(values[0]);
|
||||
string message = xmlrpc_c::value_string(values[1]);
|
||||
|
||||
if( !success )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "ONE returned error while retrieving the acls:" << endl;
|
||||
oss << message;
|
||||
|
||||
NebulaLog::log("ACL", Log::ERROR, oss);
|
||||
return -1;
|
||||
}
|
||||
|
||||
flush_rules();
|
||||
|
||||
load_rules(message);
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (exception const& e)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "Exception raised: " << e.what();
|
||||
|
||||
NebulaLog::log("ACL", Log::ERROR, oss);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int AclXML::load_rules(const string& xml_str)
|
||||
{
|
||||
ObjectXML acl_xml(xml_str);
|
||||
|
||||
vector<xmlNodePtr> rules;
|
||||
vector<xmlNodePtr>::iterator it;
|
||||
|
||||
acl_xml.get_nodes("/ACL_POOL/ACL",rules);
|
||||
|
||||
for (it = rules.begin(); it != rules.end() ; it++)
|
||||
{
|
||||
AclRule * rule = new AclRule(0,0,0,0);
|
||||
int rc = rule->from_xml(*it);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
acl_rules.insert( make_pair(rule->get_user(), rule) );
|
||||
acl_rules_oids.insert( make_pair(rule->get_oid(), rule) );
|
||||
}
|
||||
}
|
||||
|
||||
acl_xml.free_nodes(rules);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void AclXML::flush_rules()
|
||||
{
|
||||
multimap<long long, AclRule *>::iterator it;
|
||||
|
||||
for ( it = acl_rules.begin(); it != acl_rules.end(); it++ )
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
acl_rules.clear();
|
||||
acl_rules_oids.clear();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ Import('sched_env')
|
||||
lib_name='scheduler_pool'
|
||||
|
||||
source_files=[
|
||||
'AclXML.cc',
|
||||
'UserPoolXML.cc',
|
||||
'UserXML.cc',
|
||||
'HostPoolXML.cc',
|
||||
|
@ -32,6 +32,7 @@ sched_env.Prepend(LIBS=[
|
||||
'scheduler_pool',
|
||||
'nebula_log',
|
||||
'scheduler_client',
|
||||
'nebula_acl',
|
||||
'nebula_xml',
|
||||
'nebula_common',
|
||||
'crypto',
|
||||
|
@ -122,6 +122,7 @@ void Scheduler::start()
|
||||
hpool = new HostPoolXML(client);
|
||||
vmpool = new VirtualMachinePoolXML(client, machines_limit);
|
||||
upool = new UserPoolXML(client);
|
||||
acls = new AclXML(client);
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Load scheduler policies
|
||||
@ -244,9 +245,12 @@ int Scheduler::set_up_pools()
|
||||
//Cleans the cache and get the ACLs
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//TODO
|
||||
// 1.- one.acl.list
|
||||
// 2.- from_xml
|
||||
rc = acls->set_up();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//Get the matching hosts for each VM
|
||||
@ -326,11 +330,17 @@ void Scheduler::match()
|
||||
|
||||
if ( matched == false )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Host " << host->get_hid() <<
|
||||
" filtered out. It does not fullfil REQUIREMENTS.";
|
||||
|
||||
NebulaLog::log("SCHED",Log::DEBUG,oss);
|
||||
continue;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Check host capacity
|
||||
// Check if user is authorized
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
user = upool->get(uid);
|
||||
@ -338,21 +348,35 @@ void Scheduler::match()
|
||||
|
||||
if ( user != 0 )
|
||||
{
|
||||
set<int> groups = user->get_groups();
|
||||
//TODO Authorization test for this user on this host
|
||||
// 1.- user = uid
|
||||
// 2.- gid
|
||||
// 3.- groups
|
||||
// 4.- DEPLOY on host->get_hid
|
||||
const set<int> groups = user->get_groups();
|
||||
|
||||
if ( uid == 0 || user->get_gid() == 0 )
|
||||
{
|
||||
matched = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
matched = acls->authorize(uid,
|
||||
groups,
|
||||
AuthRequest::HOST,
|
||||
host->get_hid(),
|
||||
-1,
|
||||
AuthRequest::USE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO Log debug info (user not authorized)?
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( matched == false )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Host " << host->get_hid() <<
|
||||
" filtered out. User is not authorized to use it.";
|
||||
|
||||
NebulaLog::log("SCHED",Log::DEBUG,oss);
|
||||
continue;
|
||||
}
|
||||
// -----------------------------------------------------------------
|
||||
@ -370,6 +394,16 @@ void Scheduler::match()
|
||||
vm->add_host(host->get_hid());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Host " << host->get_hid() <<
|
||||
" filtered out. It does not have enough capacity.";
|
||||
|
||||
NebulaLog::log("SCHED",Log::DEBUG,oss);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,47 +222,6 @@ int ObjectXML::xpath(unsigned int& value, const char * xpath_expr,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
long long ObjectXML::xpath(long long& value, const char * xpath_expr,
|
||||
const long long& def, bool hex)
|
||||
{
|
||||
vector<string> values;
|
||||
int rc = 0;
|
||||
|
||||
values = (*this)[xpath_expr];
|
||||
|
||||
if (values.empty() == true)
|
||||
{
|
||||
value = def;
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
istringstream iss;
|
||||
|
||||
iss.str(values[0]);
|
||||
|
||||
if ( hex )
|
||||
{
|
||||
iss >> hex >> value;
|
||||
}
|
||||
else
|
||||
{
|
||||
iss >> dec >> value;
|
||||
}
|
||||
|
||||
if (iss.fail() == true)
|
||||
{
|
||||
value = def;
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ObjectXML::xpath(time_t& value, const char * xpath_expr, const time_t& def)
|
||||
{
|
||||
int int_val;
|
||||
|
Loading…
x
Reference in New Issue
Block a user