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

feature #817: Refactor of update functionality and VDC-OCA interaction. Fixes bugs in host_uniqueness.

This commit is contained in:
Ruben S. Montero 2011-09-22 20:03:07 +02:00
parent 4709f6ddb0
commit f95f85ba32
4 changed files with 135 additions and 99 deletions

View File

@ -34,6 +34,7 @@ class VDCHelper < OZonesHelper::OZHelper
puts str % ["ID ", vdc['id'].to_s]
puts str % ["NAME ", vdc['name'].to_s]
puts str % ["GROUP_ID ", vdc['group_id'].to_s]
puts str % ["ZONEID ", vdc['zones_id'].to_s]
puts str % ["VDCADMIN ", vdc['vdcadminname'].to_s]
puts str % ["HOST IDs ", vdc['hosts'].to_s]

View File

@ -21,11 +21,12 @@ module OZones
include OpenNebulaJSON::JSONUtils
extend OpenNebulaJSON::JSONUtils
property :id, Serial
property :name, String, :required => true, :unique => true
property :vdcadminname, String, :required => true
property :acls, String
property :hosts, String
property :id, Serial
property :name, String, :required => true, :unique => true
property :group_id, Integer
property :vdcadminname, String, :required => true
property :acls, String
property :hosts, String
belongs_to :zones
@ -44,6 +45,73 @@ module OZones
vdc_attributes["VDC"] = attributes
return vdc_attributes
end
#######################################################################
# Methods to handle the ACL list
#######################################################################
# The ID of the first host ACL
HOST_ACL_FIRST_ID = 3
# This method returns an Array of ACL strings to create them
# in the target zone
def get_vdc_acls_str(user_id, group_id)
rule_str = Array.new
# Grant permissions to the group
rule_str << "@#{group_id} VM+NET+IMAGE+TEMPLATE/* " \
"CREATE+INFO_POOL_MINE"
# Grant permissions to the vdc admin
rule_str << "##{user_id} USER/* CREATE"
rule_str << "##{user_id} USER/@#{group_id} MANAGE+DELETE+INFO"
###############################################################
#When more rules are added the class constant HOST_ACL_FIRST_ID
#must be modified
###############################################################
puts get_host_acls_str(group_id)
rule_str.concat(self.get_host_acls_str(group_id))
end
def get_host_acls_str(group_id, host_list = nil)
rule_str = Array.new
if host_list == nil
host_list = self.hosts
end
# Grant permissions to use the vdc hosts
host_list.split(',').each{|hostid|
puts hostid
rule_str << "@#{group_id} HOST/##{hostid} USE"
}
return rule_str
end
def get_host_acls
self.acls.split(',')[HOST_ACL_FIRST_ID..-1].collect!{|x| x.to_i}
end
# Returns the host acls as an array of strings.
# The acls of the VDC are updated and the host acl ids removed
def get_host_acls!(new_host_acls = nil)
acl_ids = self.acls.split(',')
vdc_acl = acl_ids.slice!(0,HOST_ACL_FIRST_ID)
newacl = ""
vdc_acl.each{|id|
newacl << id << ','
}
newacl.chomp
newacl << new_host_acls if new_host_acls
self.acls = newacl
return acl_ids
end
end
end

View File

@ -19,7 +19,7 @@ require 'OpenNebula'
class OCAInteraction
# Creates a VDC (user, group, hosts)
def create_vdc_in_zone(zone,vdc,adminname, adminpass)
def create_vdc_in_zone(zone, vdc, adminname, adminpass)
# Create a new client to interact with the zone
client = OpenNebula::Client.new(zone.onename + ":" + zone.onepass,
zone.endpoint,
@ -31,8 +31,8 @@ class OCAInteraction
return result if OpenNebula.is_error?(result)
# Create the VDC admin user in the Zone
user=OpenNebula::User.new(OpenNebula::User.build_xml, client)
result=user.allocate(adminname, adminpass)
user = OpenNebula::User.new(OpenNebula::User.build_xml, client)
result = user.allocate(adminname, adminpass)
return rollback(client, group,
result, user) if OpenNebula.is_error?(result)
@ -42,45 +42,23 @@ class OCAInteraction
result, user) if OpenNebula.is_error?(result)
# Add ACLs
aclp = OpenNebula::AclPool.new client
aclp = OpenNebula::AclPool.new client
rules = vdc.get_vdc_acls_str(user.id, group.id)
# Grant permissions to the group
rule_str = "@#{group.id} VM+NET+IMAGE+TEMPLATE/* " +
"CREATE+INFO_POOL_MINE"
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
result = acl.allocate(*OpenNebula::Acl.parse_rule(rule_str))
return rollback(client, group,
result, user) if OpenNebula.is_error?(result)
acls_str = acl.id.to_s + ","
acls_str = ""
# Grant permissions to the vdc admin
rule_str = "##{user.id} USER/* CREATE"
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
result = acl.allocate(*OpenNebula::Acl.parse_rule(rule_str))
return rollback(client, group,
result,user,acls_str) if OpenNebula.is_error?(result)
acls_str += acl.id.to_s + ","
rules.each{ |rule_str|
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
rc = acl.allocate(*OpenNebula::Acl.parse_rule(rule_str))
rule_str = "##{user.id} USER/@#{group.id} MANAGE+DELETE+INFO"
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
result = acl.allocate(*OpenNebula::Acl.parse_rule(rule_str))
return rollback(client, group,
result,user,acls_str) if OpenNebula.is_error?(result)
acls_str += acl.id.to_s + ","
if OpenNebula.is_error?(rc)
return rollback(client, group, rc, user, acls_str)
end
# Grant permissions to use the vdc hosts
vdc.hosts.split(",").each{|hostid|
rule_str = "@#{group.id} HOST/##{hostid} USE"
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
result = acl.allocate(*OpenNebula::Acl.parse_rule(rule_str))
if OpenNebula.is_error?(result)
return rollback(client, group, result, user, acls_str)
end
acls_str += acl.id.to_s + ","
}
return acls_str.chop
acls_str << acl.id.to_s << ","
}
return acls_str.chop, group.id
end
def delete_vdc_in_zone(id)
@ -92,16 +70,11 @@ class OCAInteraction
zone.endpoint,
false)
vdcgroupid = vdc_group_id(vdc.name, client)
if OpenNebula.is_error?(vdcgroupid)
return vdcgroupid
end
# Delete the resources from the VDC
delete_images(vdcgroupid, client)
delete_templates(vdcgroupid, client)
delete_vms(vdcgroupid, client)
delete_vns(vdcgroupid, client)
delete_images(vdc.group_id, client)
delete_templates(vdc.group_id, client)
delete_vms(vdc.group_id, client)
delete_vns(vdc.group_id, client)
# Delete ACLs
delete_acls(vdc.acls, client)
@ -110,13 +83,13 @@ class OCAInteraction
up = OpenNebula::UserPool.new(client)
up.info
up.each{|user|
if user['GID'].to_i == vdcgroupid
if user['GID'].to_i == vdc.group_id
OpenNebula::User.new_with_id(user['ID'], client).delete
end
}
# Delete the group
rc = OpenNebula::Group.new_with_id(vdcgroupid, client).delete
rc = OpenNebula::Group.new_with_id(vdc.group_id, client).delete
if OpenNebula.is_error?(rc)
return rc
@ -125,21 +98,29 @@ class OCAInteraction
end
end
def update_vdc_hosts(zone, host_list, acl_list)
def update_vdc_hosts(zone, vdc, host_list)
# Create a new client to interact with the zone
client = OpenNebula::Client.new(zone.onename + ":" + zone.onepass,
zone.endpoint,
false)
# Delete existing ACLs
delete_acls(acl_list, client)
# Delete existing host ACLs
vdc.get_host_acls.each{|acl_id|
OpenNebula::Acl.new_with_id(acl_id, client).delete
}
# Create new ACLs
acls_str = ""
host_list.split(",").each{|hostid|
rule_str = "@#{group.id} HOST/##{hostid} USE"
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
result = acl.allocate(*OpenNebula::Acl.parse_rule(rule_str))
return result if OpenNebula.is_error?(result)
acls_str = ""
host_acls = vdc.get_host_acls_str(vdc.group_id, host_list)
host_acls.each{|rule|
acl = OpenNebula::Acl.new(OpenNebula::Acl.build_xml,client)
rc = acl.allocate(*OpenNebula::Acl.parse_rule(rule))
if OpenNebula.is_error?(rc)
return rc
end
acls_str += acl.id.to_s + ","
}
@ -161,14 +142,10 @@ class OCAInteraction
# Deletes resources from failed created VDC
def rollback(client, group, result, user=nil, acls_str=nil)
user.delete if user
user.delete if user
group.delete
return result if !acls_str
acls_str.chop.split(",").each{|acl_id|
OpenNebula::Acl.new_with_id(acl_id, client).delete
}
delete_acls(acls_str, client)
return result
end
@ -219,27 +196,10 @@ class OCAInteraction
# Delete ACLs from a group
def delete_acls(acls_str, client)
acls_str.split(",").each{|acl_id|
OpenNebula::Acl.new_with_id(acl_id, client).delete
}
end
private
def vdc_group_id(name, client)
groups = OpenNebula::GroupPool.new(client)
rc = groups.info
if OpenNebula.is_error?(rc)
return rc
end
group_id = groups["GROUP[NAME=#{name}]/ID"]
if group_id
return group_id.to_i
else
return OpenNebula::Error.new("There is no GROUP called #{name}")
if acls_str != nil && !acls_str.empty?
acls_str.split(",").each{|acl_id|
OpenNebula::Acl.new_with_id(acl_id.to_i, client).delete
}
end
end
end

View File

@ -193,8 +193,10 @@ class OzonesServer
"Error: Couldn't create #{kind}. Reason: " +
rc.message).to_json]
else
vdc.acls = rc
vdc.acls = rc[0]
vdc.group_id = rc[1]
vdc.save
pr.update # Rewrite proxy conf file
return [200, vdc.to_json]
end
@ -262,6 +264,8 @@ class OzonesServer
data = result if !OpenNebula.is_error?(result)
end
puts data
resource = case kind
when "vdc" then
vdc_data=Hash.new
@ -271,6 +275,8 @@ class OzonesServer
vdc_id = value if key=="id"
}
puts vdc_data
# Check parameters
if !vdc_data[:hosts] || !vdc_id
return [400, OZones::Error.new(
@ -287,10 +293,10 @@ class OzonesServer
end
# Get the zone where the Vdc belongs
zone=OZones::Zones.get(vdc.zoneid)
zone=OZones::Zones.get(vdc.zones.id)
if !zone
error = OZones::Error.new("Error: Zone " +
"#{vdc.zoneid} not found, cannot update Vdc.")
"#{vdc.zones.id} not found, cannot update Vdc.")
return [404, error.to_json]
end
@ -303,11 +309,12 @@ class OzonesServer
" were given.").to_json]
end
rc = @ocaInt.update_vdc_hosts(zone, vdc_data[:hosts], vdc.acls)
rc = @ocaInt.update_vdc_hosts(zone, vdc, vdc_data[:hosts])
if !OpenNebula.is_error?(rc)
vdc.hosts = vdc_data[:hosts]
vdc.acls = rc
vdc.get_host_acls!(rc)
vdc.save
if vdc.saved?
@ -365,7 +372,7 @@ class OzonesServer
# Check if hosts are already include in any Vdc of the zone
def host_uniqueness?(zone, host_list)
all_hosts = ""
zone.vdcs.all.each{|vdc| all_hosts += vdcs.hosts}
zone.vdcs.all.each{|vdc| all_hosts += vdc.hosts}
all_hosts = all_hosts.split(",").compact.reject{|host| host.empty?}
host_list.split(",").each{|host|