diff --git a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb index ea7e0b115b..e2446889eb 100644 --- a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb +++ b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb @@ -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] diff --git a/src/ozones/Server/lib/OZones/VDC.rb b/src/ozones/Server/lib/OZones/VDC.rb index 67127bda96..60b734f828 100644 --- a/src/ozones/Server/lib/OZones/VDC.rb +++ b/src/ozones/Server/lib/OZones/VDC.rb @@ -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 diff --git a/src/ozones/Server/models/OCAInteraction.rb b/src/ozones/Server/models/OCAInteraction.rb index b93fdb4711..1b61136ae2 100644 --- a/src/ozones/Server/models/OCAInteraction.rb +++ b/src/ozones/Server/models/OCAInteraction.rb @@ -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 diff --git a/src/ozones/Server/models/OzonesServer.rb b/src/ozones/Server/models/OzonesServer.rb index 0092554803..36dfd4a74c 100644 --- a/src/ozones/Server/models/OzonesServer.rb +++ b/src/ozones/Server/models/OzonesServer.rb @@ -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|