diff --git a/src/ozones/Server/models/OCAInteraction.rb b/src/ozones/Server/models/OCAInteraction.rb index 2a1454662d..b93fdb4711 100644 --- a/src/ozones/Server/models/OCAInteraction.rb +++ b/src/ozones/Server/models/OCAInteraction.rb @@ -124,6 +124,27 @@ class OCAInteraction return nil end end + + def update_vdc_hosts(zone, host_list, acl_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) + + # 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 += acl.id.to_s + "," + } + + return acls_str.chop + end # Creates a VDC (user, group, hosts) def check_oneadmin(oneadminname, oneadminpass, endpoint) diff --git a/src/ozones/Server/models/OzonesServer.rb b/src/ozones/Server/models/OzonesServer.rb index ce085b2054..0092554803 100644 --- a/src/ozones/Server/models/OzonesServer.rb +++ b/src/ozones/Server/models/OzonesServer.rb @@ -161,6 +161,15 @@ class OzonesServer "#{vdc_data[:zoneid]} not found, cannot create Vdc.") return [404, error.to_json] end + + if (!defined? vdc_data[:force] or + (defined? vdc_data[:force] and vdc_data[:force]!="yes")) and + !host_uniqueness?(zone, vdc_data[:hosts]) + return [403, OZones::Error.new( + "Error: Couldn't create resource #{kind}. " + + "Hosts are not unique, and no force option " + + " were given.").to_json] + end vdcadminname = vdc_data[:vdcadminname] vdcadminpass = vdc_data[:vdcadminpass] @@ -241,6 +250,84 @@ class OzonesServer return [404, error.to_json] end end + + ############################################################################ + # Update resources + ############################################################################ + # Updates a resource of a kind, and updates the Proxy Rules if needed + def update_resource(kind, data, body, pr) + + if body.size > 0 + result = parse_json(body,kind) + data = result if !OpenNebula.is_error?(result) + end + + resource = case kind + when "vdc" then + vdc_data=Hash.new + vdc_id = nil + data.each{|key,value| + vdc_data[key.downcase.to_sym]=value if key!="id" + vdc_id = value if key=="id" + } + + # Check parameters + if !vdc_data[:hosts] || !vdc_id + return [400, OZones::Error.new( + "Error: Couldn't update resource #{kind}. " + + "Need ID and HOSTS to update.").to_json] + end + + # Check if the referenced Vdc exists + vdc=OZones::Vdc.get(vdc_id) + if !vdc + error = OZones::Error.new("Error: Vdc " + + "#{vdc_id} not found, cannot update Vdc.") + return [404, error.to_json] + end + + # Get the zone where the Vdc belongs + zone=OZones::Zones.get(vdc.zoneid) + if !zone + error = OZones::Error.new("Error: Zone " + + "#{vdc.zoneid} not found, cannot update Vdc.") + return [404, error.to_json] + end + + if (!defined? vdc_data[:force] or + (defined? vdc_data[:force] and vdc_data[:force]!="yes")) and + !host_uniqueness?(zone, vdc_data[:hosts]) + return [403, OZones::Error.new( + "Error: Couldn't update resource #{kind}. " + + "Hosts are not unique, and no force option " + + " were given.").to_json] + end + + rc = @ocaInt.update_vdc_hosts(zone, vdc_data[:hosts], vdc.acls) + + if !OpenNebula.is_error?(rc) + vdc.hosts = vdc_data[:hosts] + vdc.acls = rc + vdc.save + + if vdc.saved? + return [200, vdc.to_json] + else + return [500, OZones::Error.new( + "Error: Couldn't update resource #{kind}.").to_json] + end + + else + return [500, OZones::Error.new( + "Error: Couldn't update resource #{kind.upcase}." + + " Failed to update ACLs").to_json] + end + else + error = OZones::Error.new( + "Error: #{kind.upcase} resource update not supported") + return [404, error.to_json] + end + end ############################################################################ # Delete resources @@ -272,20 +359,20 @@ class OzonesServer end ############################################################################ - # TODO - ############################################################################ - def perform_action(kind, id, action_json) - resource = retrieve_resource(kind, id) - if OpenNebula.is_error?(resource) - return [404, resource.to_json] - end - - rc = resource.perform_action(action_json) - if OpenNebula.is_error?(rc) - return [500, rc.to_json] - else - return [204, resource.to_json] - end + # Helper functions + ########################################################################## + + # 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} + all_hosts = all_hosts.split(",").compact.reject{|host| host.empty?} + + host_list.split(",").each{|host| + return false if all_hosts.include?(host) + } + return true end + end diff --git a/src/ozones/Server/ozones-server.rb b/src/ozones/Server/ozones-server.rb index f30607b34c..c3b19612b5 100755 --- a/src/ozones/Server/ozones-server.rb +++ b/src/ozones/Server/ozones-server.rb @@ -240,7 +240,20 @@ get '/:pool/:aggpool' do @OzonesServer.get_aggregated_pool(params[:pool], params[:aggpool]) end +############################################################################## +# Create a new Resource +############################################################################## +post '/:pool' do + @OzonesServer.create_resource(params[:pool], params, request.body.read, @pr) +end +############################################################################## +# Update Resource +############################################################################## +put '/:resource/:id' do + @OzonesServer.update_resource(params[:resource], params, + request.body.read, @pr) +end ############################################################################## # Delete Resource @@ -249,12 +262,5 @@ delete '/:resource/:id' do @OzonesServer.delete_resource(params[:resource], params[:id], @pr) end -############################################################################## -# Create a new Resource -############################################################################## -post '/:pool' do - @OzonesServer.create_resource(params[:pool], params, request.body.read, @pr) -end - diff --git a/src/ozones/Server/test/examples/vdc/vdc0.json b/src/ozones/Server/test/examples/vdc/vdc0.json index 1d6813e035..6deb95903d 100644 --- a/src/ozones/Server/test/examples/vdc/vdc0.json +++ b/src/ozones/Server/test/examples/vdc/vdc0.json @@ -1,6 +1,6 @@ { "vdc": { - "hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2", + "hosts": "5,7,9", "zones_id": 1, "name": "testvdc0", "id": 1 diff --git a/src/ozones/Server/test/examples/vdc/vdc0.template b/src/ozones/Server/test/examples/vdc/vdc0.template index c14cbe9527..b2e7e3d4f3 100644 --- a/src/ozones/Server/test/examples/vdc/vdc0.template +++ b/src/ozones/Server/test/examples/vdc/vdc0.template @@ -1,4 +1,5 @@ NAME=testvdc0 ZONEID=1 +HOSTS=5,7,9 VDCADMINNAME=adminname VDCADMINPASS=adminpass diff --git a/src/ozones/Server/test/examples/vdc/vdc1.template b/src/ozones/Server/test/examples/vdc/vdc1.template index afdba5ddcd..4566505bbb 100644 --- a/src/ozones/Server/test/examples/vdc/vdc1.template +++ b/src/ozones/Server/test/examples/vdc/vdc1.template @@ -1,5 +1,5 @@ NAME=testvdc1 -HOSTS=testhostvdc1n0 +HOSTS=8 ZONEID=1 VDCADMINNAME=othername VDCADMINPASS=otherpass \ No newline at end of file diff --git a/src/ozones/Server/test/examples/vdc/vdc2nozone.template b/src/ozones/Server/test/examples/vdc/vdc2nozone.template index 4279b5733c..946c43c46c 100644 --- a/src/ozones/Server/test/examples/vdc/vdc2nozone.template +++ b/src/ozones/Server/test/examples/vdc/vdc2nozone.template @@ -1,3 +1,3 @@ NAME=testvdcnozone -HOSTS=testhostvdcnozone,bogushost +HOSTS=3,7 ZONEID=5 \ No newline at end of file