1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

Feature #687: Refactor Acl and AclPool ruby OCA classes to follow the common Pool/PoolElement structure

This commit is contained in:
Carlos Martín and Javi Fontan 2011-07-06 15:56:38 +02:00 committed by Carlos Martín
parent fa2477a79f
commit 43e44040f7
4 changed files with 171 additions and 150 deletions

View File

@ -24,51 +24,23 @@ class OneAclHelper < OpenNebulaHelper::OneHelper
def self.conf_file
"oneacl.yaml"
end
def add_rule(options, arg0, arg1=nil, arg2=nil)
aclp = OpenNebula::AclPool.new( OpenNebula::Client.new() )
if arg2
rc = aclp.addrule( arg0, arg1, arg2 )
private
def factory(id = nil)
if id
OpenNebula::Acl.new_with_id(id, @client)
else
rc = aclp.addrule_with_str( arg0 )
end
if OpenNebula.is_error?(rc)
return [-1, rc.message]
else
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])
return [-1, rc[:resources].message] if OpenNebula.is_error?(
rc[:resources])
return [-1, rc[:rights].message] if OpenNebula.is_error?(
rc[:rights])
xml = OpenNebula::Acl.build_xml
OpenNebula::Acl.new(xml, @client)
end
end
def delete_rule(options, id)
acl = OpenNebula::AclPool.new( OpenNebula::Client.new() )
rc = acl.delrule( id )
if OpenNebula.is_error?(rc)
[-1, rc.message]
else
puts "Rule deleted" if options[:verbose]
0
end
end
private
def factory_pool(filter)
OpenNebula::AclPool.new(@client)
end
# TODO check that @content[:resources_str] is valid
# TODO check that @content[:resources_str] is valid
def self.resource_mask(str)
resource_type=str.split("/")[0]

View File

@ -44,7 +44,9 @@ cmd = CommandParser::CmdParser.new(ARGV) do
########################################################################
# Formatters for arguments
########################################################################
# TODO
set :format, :aclid_list, OneAclHelper.list_to_id_desc do |arg|
helper.list_to_id(arg)
end
########################################################################
# Commands
@ -55,15 +57,42 @@ cmd = CommandParser::CmdParser.new(ARGV) do
EOT
command :create, addrule_desc, [:user,:rulestr], [:resource, nil], [:rights, nil] do
helper.add_rule(options, args[0], args[1], args[2] )
case args.length
when 1
new_args=Acl.parse_rule(args[0])
when 3
new_args=args
else
next -1, "Wrong number of arguments, must be 1 or 3"
end
errors=new_args.map do |arg|
if OpenNebula.is_error?(arg)
arg.message
else
nil
end
end
errors.compact!
if errors.length>0
next -1, errors.join(', ')
end
helper.create_resource(options) do |rule|
rule.allocate(*new_args)
end
end
delrule_desc = <<-EOT.unindent
Deletes an existing ACL rule
EOT
command :delete, delrule_desc, :id do
helper.delete_rule( options, args[0] )
command :delete, delrule_desc, [:range] do
helper.perform_actions(args[0],options,"deleted") do |obj|
obj.delete
end
end
list_desc = <<-EOT.unindent

View File

@ -39,13 +39,14 @@ module OpenNebula
# INFO_POOL_MINE
# INSTANTIATE
# CHOWN
class Acl
class Acl < PoolElement
USERS = {
"UID" => 0x100000000,
"GID" => 0x200000000,
"ALL" => 0x400000000
}
RESOURCES =
{
"VM" => 0x1000000000,
@ -70,121 +71,180 @@ module OpenNebula
"CHOWN" => 0x100 # Auth. to change ownership of an object
}
def initialize(rule_str=nil)
# Content stores numbers
@content = {
:users => 0,
:resources => 0,
:rights => 0
}
parse_rule(rule_str) if rule_str
# Constructor
#
# @param xml [String] must be an xml built with {#build_xml}
# @param client [Client] represents an XML-RPC connection
def initialize(xml, client)
super(xml,client)
end
def parse_rule(rule_str)
begin
rule_str = rule_str.split(" ")
parse_users(rule_str[0])
parse_resources(rule_str[1])
parse_rights(rule_str[2])
rescue Exception => e
@content[:users] = OpenNebula::Error.new(e.message)
# Creates an empty XML representation. It contains the id, if it is
# specified.
#
# @param pe_id [Integer] rule ID
# @param client [Client] represents an XML-RPC connection
#
# @return [String] an empty XML representation
def self.build_xml(pe_id=nil)
if pe_id
acl_xml = "<ACL><ID>#{pe_id}</ID></ACL>"
else
acl_xml = "<ACL></ACL>"
end
XMLElement.build_xml(acl_xml,'ACL')
end
def parse_users(users)
# Creates a new ACL rule.
#
# @param user [String]
# A string containing a hex number, e.g. 0x100000001
# @param resource [String]
# A string containing a hex number, e.g. 0x2100000001
# @param rights [String]
# A string containing a hex number, e.g. 0x10
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def allocate(user, resource, rights)
return super( AclPool::ACL_POOL_METHODS[:addrule],
user,
resource,
rights )
end
# Deletes the Acl rule
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def delete()
super(AclPool::ACL_POOL_METHODS[:delrule])
end
# Does nothing, individual ACL rules info can't be retrieved from
# OpenNebula
#
# @return [nil] nil
def info()
return nil
end
# Parses a rule string, e.g. "#5 HOST+VM/@12 INFO+CREATE+DELETE"
#
# @param rule_str [String] an ACL rule in string format
#
# @return [Array] an Array containing 3 strings (hex 64b numbers),
# or OpenNebula::Error objects
def self.parse_rule(rule_str)
ret = Array.new
rule_str = rule_str.split(" ")
if rule_str.length != 3
return [OpenNebula::Error.new(
"String needs three components: User, Resource, Rights")]
end
ret << parse_users(rule_str[0])
ret << parse_resources(rule_str[1])
ret << parse_rights(rule_str[2])
return ret
end
private
# Converts a string in the form [#<id>, @<id>, *] to a hex. number
#
# @param users [String] Users component string
#
# @return [String] A string containing a hex number
def self.parse_users(users)
begin
@content[:users] = calculate_users(users)
return calculate_ids(users).to_i.to_s(16)
rescue Exception => e
@content[:resources] = OpenNebula::Error.new(e.message)
return OpenNebula::Error.new(e.message)
end
end
def parse_resources(resources)
# Converts a resources string to a hex. number
#
# @param resources [String] Resources component string
#
# @return [String] A string containing a hex number
def self.parse_resources(resources)
begin
ret = 0
resources = resources.split("/")
if resources.size != 2
@content[:resources] = OpenNebula::Error.new(
"Resource #{resources} not well formed")
return
raise "Resource '#{resources}' malformed"
end
resources[0].split("+").each{ |resource|
if !RESOURCES[resource.upcase]
raise "Resource #{resource} malformed."
raise "Resource '#{resource}' does not exist"
end
@content[:resources] += RESOURCES[resource.upcase]
ret += RESOURCES[resource.upcase]
}
@content[:resources] += calculate_users(resources[1])
ret += calculate_ids(resources[1])
return ret.to_i.to_s(16)
rescue Exception => e
@content[:resources] = OpenNebula::Error.new(e.message)
return OpenNebula::Error.new(e.message)
end
end
def parse_rights(rights)
# Converts a rights string to a hex. number
#
# @param rights [String] Rights component string
#
# @return [String] A string containing a hex number
def self.parse_rights(rights)
begin
ret = 0
rights = rights.split("+")
rights.each{ |right|
raise "Right #{right} malformed." if !RIGHTS[right.upcase]
raise "Right '#{right}' does not exist" if !RIGHTS[right.upcase]
@content[:rights] += RIGHTS[right.upcase]
ret += RIGHTS[right.upcase]
}
return ret.to_i.to_s(16)
rescue Exception => e
@content[:rights] = OpenNebula::Error.new(e.message)
return OpenNebula::Error.new(e.message)
end
end
def calculate_users(users_str)
if users_str == "*"
return USERS["ALL"]
end
# Calculates the numeric value for a String containing an individual
# (#<id>), group (@<id>) or all (*) ID component
#
# @param id_str [String] Rule Id string
#
# @return [Integer] the numeric value for the given id_str
def self.calculate_ids(id_str)
raise "ID string '#{id_str}' malformed" if
!id_str.match(/^([\#@]\d+|\*)$/)
value = 0
case users_str[0..0]
case id_str[0..0]
when "#"
value = USERS["UID"]
users_value = id_str[1..-1].to_i + value
when "@"
value = USERS["GID"]
end
users_value = id_str[1..-1].to_i + value
users_value = users_str[1..-1].to_i + value
when "*"
value = USERS["ALL"]
end
return users_value
end
def users_hex_str
@content[:users].to_i.to_s(16)
end
def resources_hex_str
@content[:resources].to_i.to_s(16)
end
def rights_hex_str
@content[:rights].to_i.to_s(16)
end
def is_error?
OpenNebula.is_error?(@content[:users]) ||
OpenNebula.is_error?(@content[:resources]) ||
OpenNebula.is_error?(@content[:rights]) ||
@content[:users] == 0 ||
@content[:resources] == 0 ||
@content[:rights] == 0
end
def error
@content.each{ |part|
return part if OpenNebula.is_error?(part)
}
end
end
end

View File

@ -49,45 +49,5 @@ module OpenNebula
# Retrieves all the Acls in the pool.
super(ACL_POOL_METHODS[:info])
end
# Adds a new ACL rule.
#
# +user+ A string containing a hex number, e.g. 0x100000001
# +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)
return @client.call( ACL_POOL_METHODS[:addrule],
user,
resource,
rights )
end
# Adds a new ACL rule.
#
# +rule+ Rule tring
def addrule_with_str(rule_str)
rule = Acl.new rule_str
return rule.error if rule.is_error?
return addrule( rule.users_hex_str,
rule.resources_hex_str,
rule.rights_hex_str )
end
# Deletes an existing ACL rule.
#
# +id+ An existing ACL rule ID
def delrule(id)
rc = @client.call( ACL_POOL_METHODS[:delrule], id.to_i )
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
private
end
end