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:
parent
4709f6ddb0
commit
f95f85ba32
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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|
|
||||
|
Loading…
x
Reference in New Issue
Block a user