From a6edd2483a8d6a9b0983ef934056a25d0a012c6d Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 17 Jul 2010 06:42:26 +0200 Subject: [PATCH] feature #200: Get rid of Crack library for OCCI. OCCI now uses OpenNebula authorization mechanisms --- src/cloud/common/CloudServer.rb | 45 +-------- src/cloud/occi/bin/occi-storage | 30 +++--- src/cloud/occi/etc/templates/large.erb | 57 ++++++----- src/cloud/occi/etc/templates/medium.erb | 58 ++++++----- src/cloud/occi/etc/templates/small.erb | 58 ++++++----- src/cloud/occi/lib/ImageOCCI.rb | 28 +++--- src/cloud/occi/lib/OCCIServer.rb | 120 +++++------------------ src/cloud/occi/lib/VirtualMachineOCCI.rb | 90 +++++++++-------- src/cloud/occi/lib/VirtualNetworkOCCI.rb | 24 ++--- src/cloud/occi/lib/occi-server.rb | 7 -- src/oca/ruby/OpenNebula/XMLUtils.rb | 71 +++++++++++--- 11 files changed, 269 insertions(+), 319 deletions(-) diff --git a/src/cloud/common/CloudServer.rb b/src/cloud/common/CloudServer.rb index 11c11d1c33..762f51d2ab 100755 --- a/src/cloud/common/CloudServer.rb +++ b/src/cloud/common/CloudServer.rb @@ -82,54 +82,13 @@ class CloudServer # Generates an OpenNebula Session for the given user # user:: _Hash_ the user information # [return] an OpenNebula client session - def one_client_user(user) + def one_client_user(name, password) client = Client.new("dummy:dummy") - client.one_auth = "#{user[:name]}:#{user[:password]}" + client.one_auth = "#{name}:#{password}" return client end - # Authenticates a user - # name:: _String_ of the user - # password:: _String_ of the user - # [return] true if authenticated - def authenticate?(name, password) - user = get_user(name) - - return user && user.password == password - end - - # Gets the data associated with a user - # name:: _String_ the name of the user - # [return] _Hash_ with the user data - def get_user(name) - user = nil - - @user_pool.info - @user_pool.each{ |u| - if u.name==name - user=Hash.new - - user[:id] = u.id - user[:name] = u.name - user[:password] = u[:password] - end - } - return user - end - - def get_template_path(instance_type_name) - - instance_type=@instance_types[instance_type_name] - - if !instance_type - error = OpenNebula::Error.new("Bad instance type") - return error - end - - return @config[:template_location]+"/#{instance_type['TEMPLATE']}" - end - ########################################################################### # Repository Methods ########################################################################### diff --git a/src/cloud/occi/bin/occi-storage b/src/cloud/occi/bin/occi-storage index 93b6436d3f..4387b2ab27 100755 --- a/src/cloud/occi/bin/occi-storage +++ b/src/cloud/occi/bin/occi-storage @@ -31,7 +31,7 @@ $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT ** Synopsis occi-storage - + Manages OCCI storage resource ** Usage @@ -40,7 +40,7 @@ occi-storage [OPTIONS] [PARAMETERS] COMMANDS create - creates a new storage resource described by the provided + creates a new storage resource described by the provided list @@ -81,7 +81,7 @@ EOT require 'occi/OCCIClient' require 'CloudClient' require 'getoptlong' -require "rexml/document" +require 'rexml/document' require 'pp' include CloudCLI @@ -120,12 +120,12 @@ begin when '--debug' debug = true when '--multipart' - curb = false + curb = false end end rescue Exception => e exit(-1) -end +end if !ARGV[0] puts "#{cmd_name}: [COMMAND] not present" @@ -158,21 +158,21 @@ case ARGV[0].downcase when 'show' image_id = ARGV[1] - if !image_id + if !image_id puts "#{cmd_name} show: missing storage id parameter" exit(-1) end - + rc = occi_client.get_image(image_id) when 'delete' image_id = ARGV[1] - if !image_id + if !image_id puts "#{cmd_name} show: missing storage id parameter" exit(-1) end - + rc = occi_client.delete_image(image_id) else @@ -182,22 +182,22 @@ end if CloudClient::is_error?(rc) puts rc.to_s() -else +else begin doc = REXML::Document.new(rc) rescue REXML::ParseException => e - puts e.message + puts e.message exit(-1) end - + xml = doc.root - + if xml.nil? puts rc exit(-1) end - + str = "" REXML::Formatters::Pretty.new(4).write(xml,str) - puts "\n" + str + "\n " + puts "\n" + str + "\n " end diff --git a/src/cloud/occi/etc/templates/large.erb b/src/cloud/occi/etc/templates/large.erb index e59ed9a0f2..e6d1a94155 100644 --- a/src/cloud/occi/etc/templates/large.erb +++ b/src/cloud/occi/etc/templates/large.erb @@ -1,33 +1,40 @@ +# +# Virtual Machine Template generated for large instance types. Adjust this +# by setting the desired capacity (CPU,MEMORY) or adding specific +# attributes for your cloud (e.g. OS). You should not need to change the DISK +# and NIC sections +# + CPU = 8 MEMORY = 8192 -NAME = <%= vm_info['NAME'] %> +NAME = <%= @vm_info['NAME'] %> -<% if vm_info['DISK'] %> - <% vm_info['DISK'].each do |disk| %> - <% if disk['STORAGE'] && disk['STORAGE']['href'] %> - DISK = [ IMAGE_ID = <%= disk['STORAGE']['href'].split('/').last %> - <% if disk.key?('OVERWRITE') %> - ,OVERWRITE = "yes" - <% end %> - <% if disk['SAVE_AS'] %> - ,SAVE_AS = "<%= disk['SAVE_AS'] %>" - <% end %> - ] - <% end %> - <% end %> +<% if @vm_info['DISK'] %> + <% @vm_info.each('DISK') do |disk| %> + <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> + DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> + <% if disk['OVERWRITE'] %> + ,OVERWRITE = "yes" + <% end %> + <% if disk['SAVE_AS'] %> + ,SAVE_AS = "<%= disk['SAVE_AS'] %>" + <% end %> + ] + <% end %> + <% end %> <% end %> -<% if vm_info['NIC'] %> - <% vm_info['NIC'].each do |nic| %> - <% if nic['NETWORK'] && nic['NETWORK']['href'] %> - NIC = [ NETWORK_ID = <%= nic['NETWORK']['href'].split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> +<% if @vm_info['NIC'] %> + <% @vm_info.each('NIC') do |nic| %> + <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> + NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> + <% if nic['IP'] %> + ,IP = <%= nic['IP'] %> + <% end %> + ] + <% end %> + <% end %> <% end %> -INSTANCE_TYPE = <%= vm_info['INSTANCE_TYPE']%> \ No newline at end of file +INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> \ No newline at end of file diff --git a/src/cloud/occi/etc/templates/medium.erb b/src/cloud/occi/etc/templates/medium.erb index 6263c34cf9..ab6bda21c7 100644 --- a/src/cloud/occi/etc/templates/medium.erb +++ b/src/cloud/occi/etc/templates/medium.erb @@ -1,33 +1,41 @@ +# +# Virtual Machine Template generated for medium instance types. Adjust this +# by setting the desired capacity (CPU,MEMORY) or adding specific +# attributes for your cloud (e.g. OS). You should not need to change the DISK +# and NIC sections +# + CPU = 4 MEMORY = 4096 -NAME = <%= vm_info['NAME'] %> +NAME = <%= @vm_info['NAME'] %> -<% if vm_info['DISK'] %> - <% vm_info['DISK'].each do |disk| %> - <% if disk['STORAGE'] && disk['STORAGE']['href'] %> - DISK = [ IMAGE_ID = <%= disk['STORAGE']['href'].split('/').last %> - <% if disk.key?('OVERWRITE') %> - ,OVERWRITE = "yes" - <% end %> - <% if disk['SAVE_AS'] %> - ,SAVE_AS = "<%= disk['SAVE_AS'] %>" - <% end %> - ] - <% end %> - <% end %> +<% if @vm_info['DISK'] %> + <% @vm_info.each('DISK') do |disk| %> + <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> + DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> + <% if disk['OVERWRITE'] %> + ,OVERWRITE = "yes" + <% end %> + <% if disk['SAVE_AS'] %> + ,SAVE_AS = "<%= disk['SAVE_AS'] %>" + <% end %> + ] + <% end %> + <% end %> <% end %> -<% if vm_info['NIC'] %> - <% vm_info['NIC'].each do |nic| %> - <% if nic['NETWORK'] && nic['NETWORK']['href'] %> - NIC = [ NETWORK_ID = <%= nic['NETWORK']['href'].split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> +<% if @vm_info['NIC'] %> + <% @vm_info.each('NIC') do |nic| %> + <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> + NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> + <% if nic['IP'] %> + ,IP = <%= nic['IP'] %> + <% end %> + ] + <% end %> + <% end %> <% end %> -INSTANCE_TYPE = <%= vm_info['INSTANCE_TYPE']%> \ No newline at end of file +INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> + diff --git a/src/cloud/occi/etc/templates/small.erb b/src/cloud/occi/etc/templates/small.erb index fb28e17cb2..9c448bb7fd 100644 --- a/src/cloud/occi/etc/templates/small.erb +++ b/src/cloud/occi/etc/templates/small.erb @@ -1,33 +1,41 @@ +# +# Virtual Machine Template generated for small instance types. Adjust this +# by setting the desired capacity (CPU,MEMORY) or adding specific +# attributes for your cloud (e.g. OS). You should not need to change the DISK +# and NIC sections +# + CPU = 1 MEMORY = 1024 -NAME = <%= vm_info['NAME'] %> +NAME = <%= @vm_info['NAME'] %> -<% if vm_info['DISK'] %> - <% vm_info['DISK'].each do |disk| %> - <% if disk['STORAGE'] && disk['STORAGE']['href'] %> - DISK = [ IMAGE_ID = <%= disk['STORAGE']['href'].split('/').last %> - <% if disk.key?('OVERWRITE') %> - ,OVERWRITE = "yes" - <% end %> - <% if disk['SAVE_AS'] %> - ,SAVE_AS = "<%= disk['SAVE_AS'] %>" - <% end %> - ] - <% end %> - <% end %> +<% if @vm_info['DISK'] %> + <% @vm_info.each('DISK') do |disk| %> + <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> + DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> + <% if disk['OVERWRITE'] %> + ,OVERWRITE = "yes" + <% end %> + <% if disk['SAVE_AS'] %> + ,SAVE_AS = "<%= disk['SAVE_AS'] %>" + <% end %> + ] + <% end %> + <% end %> <% end %> -<% if vm_info['NIC'] %> - <% vm_info['NIC'].each do |nic| %> - <% if nic['NETWORK'] && nic['NETWORK']['href'] %> - NIC = [ NETWORK_ID = <%= nic['NETWORK']['href'].split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> +<% if @vm_info['NIC'] %> + <% @vm_info.each('NIC') do |nic| %> + <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> + NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> + <% if nic['IP'] %> + ,IP = <%= nic['IP'] %> + <% end %> + ] + <% end %> + <% end %> <% end %> -INSTANCE_TYPE = <%= vm_info['INSTANCE_TYPE']%> \ No newline at end of file +INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> + diff --git a/src/cloud/occi/lib/ImageOCCI.rb b/src/cloud/occi/lib/ImageOCCI.rb index c680f8a0b4..62e66a1d1f 100755 --- a/src/cloud/occi/lib/ImageOCCI.rb +++ b/src/cloud/occi/lib/ImageOCCI.rb @@ -37,29 +37,29 @@ class ImageOCCI < Image ONE_IMAGE = %q{ - NAME = "<%= @image_info.elements['NAME'].text %>" - <% if @image_info.elements['DESCRIPTION'] != nil %> - DESCRIPTION = "<%= @image_info.elements['DESCRIPTION'].text %>" + NAME = "<%= @image_info['NAME'] %>" + <% if @image_info['DESCRIPTION'] != nil %> + DESCRIPTION = "<%= @image_info['DESCRIPTION'] %>" <% end %> - <% if @image_info.elements['TYPE'] != nil %> - TYPE = <%= @image_info.elements['TYPE'].text %> + <% if @image_info['TYPE'] != nil %> + TYPE = <%= @image_info['TYPE'] %> <% end %> - <% if @image_info.elements['FSTYPE'] != nil %> - FSTYPE = <%= @image_info.elements['FSTYPE'].text %> + <% if @image_info['FSTYPE'] != nil %> + FSTYPE = <%= @image_info['FSTYPE'] %> <% end %> - <% if @image_info.elements['SIZE'] != nil %> - SIZE = <%= @image_info.elements['SIZE'].text %> + <% if @image_info['SIZE'] != nil %> + SIZE = <%= @image_info['SIZE'] %> <% end %> }.gsub(/^ /, '') # Class constructor def initialize(xml, client, xml_info=nil) super(xml, client) + @image_info = nil if xml_info != nil - @image_info = REXML::Document.new(xml_info).root - else - @image_info = nil + xmldoc = XMLUtilsElement.initialize_xml(xml_info, 'STORAGE') + @image_info = XMLElement.new(xmldoc) if xmldoc != nil end end @@ -81,13 +81,13 @@ class ImageOCCI < Image end def to_one_template() - if @image_info.name != 'STORAGE' + if @image_info == nil error_msg = "Missing STORAGE section in the XML body" error = OpenNebula::Error.new(error_msg) return error end - if @image_info.elements['NAME'] == nil + if @image_info['NAME'] == nil error_msg = "Missing Image NAME in the XML DISK section" error = OpenNebula::Error.new(error_msg) return error diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index e5d85ac827..88de9df234 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -57,41 +57,13 @@ class OCCIServer < CloudServer print_configuration end - # Authorization function - # requestenv:: _Hash_ Hash containing the environment of the request - # [return] _Boolean_ Whether the user is authorized or not - def authenticate?(requestenv) - auth ||= Rack::Auth::Basic::Request.new(requestenv) - - if !(auth.provided? && auth.basic? && auth.credentials) - return false - end - - user = get_user(requestenv, auth) - - if user - if user[:password] == auth.credentials[1] - return true - end - else - return false - end - end - - # Retrieve the user crendentials - # requestenv:: _Hash_ Hash containing the environment of the request - # [return] _User_ User structure - def get_user(requestenv, auth=nil) - auth = Rack::Auth::Basic::Request.new(requestenv) if !auth - super(auth.credentials.first) - end - # Retrieve a client with the user credentials # requestenv:: _Hash_ Hash containing the environment of the request # [return] _Client_ client with the user credentials def get_client(requestenv) - user = get_user(requestenv) - return one_client_user(user) + auth = Rack::Auth::Basic::Request.new(requestenv) + + return one_client_user(auth.credentials[0], auth.credentials[1]) end # Prepare the OCCI XML Response @@ -104,17 +76,6 @@ class OCCIServer < CloudServer return xml_response, 201 end - def get_info_hash(body) - if body - info = XMLUtilsElement::xml_to_hash(body.read) - return info - else - error_msg = "OCCI XML representation not present" - error = OpenNebula::Error.new(error_msg) - return error - end - end - ############################################################################ ############################################################################ # POOL RESOURCE METHODS @@ -192,26 +153,14 @@ class OCCIServer < CloudServer # request:: _Hash_ hash containing the data of the request # [return] _String_,_Integer_ COMPUTE Representation or error, status code def post_compute(request) - # --- Get client with user credentials --- - client = get_client(request.env) - - # --- Check OCCI XML from POST --- - vm_info = get_info_hash(request.body) - return vm_info, 400 if OpenNebula.is_error?(vm_info) - - # --- Get Template Path --- - if vm_info['COMPUTE'] - path = get_template_path(vm_info['COMPUTE']['INSTANCE_TYPE']) - return path, 500 if OpenNebula.is_error?(path) - - vm_info['TEMPLATE_PATH'] = path - end # --- Create the new Instance --- vm = VirtualMachineOCCI.new( - vm_info, VirtualMachine.build_xml, - client) + get_client(request.env), + request.body.read, + @instance_types, + @config[:template_location]) # --- Generate the template and Allocate the new Instance --- template = vm.to_one_template @@ -230,14 +179,11 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ COMPUTE representation or error, # status code def get_compute(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) # --- Get the VM --- vm = VirtualMachineOCCI.new( - nil, VirtualMachine.build_xml(params[:id]), - client) + get_client(request.env)) result = vm.info return result, 404 if OpenNebula::is_error?(result) @@ -252,13 +198,11 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ Delete confirmation msg or error, # status code def delete_compute(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) + # --- Get the VM --- vm = VirtualMachineOCCI.new( - nil, VirtualMachine.build_xml(params[:id]), - client) + get_client(request.env)) # --- Finalize the VM --- result = vm.finalize @@ -272,21 +216,16 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ Update confirmation msg or error, # status code def put_compute(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) - - # --- Check OCCI XML from POST --- - vm_info = get_info_hash(request.body) - return vm_info, 400 if OpenNebula.is_error?(vm_info) + vm_info = XMLUtilsElement.initialize_xml(xml_info, 'COMPUTE') # --- Get the VM and Action on it --- - if vm_info['COMPUTE'] && vm_info['COMPUTE']['STATE'] + if vm_info['STATE'] != nil vm = VirtualMachineOCCI.new( - vm_info, VirtualMachine.build_xml(params[:id]), - client) + get_client(request.env)) + + rc = vm.mk_action(vm_info['STATE']) - rc = vm.mk_action(vm_info['COMPUTE']['STATE']) return rc, 400 if OpenNebula.is_error?(rc) else error_msg = "State not defined in the OCCI XML" @@ -307,13 +246,11 @@ class OCCIServer < CloudServer # request:: _Hash_ hash containing the data of the request # [return] _String_,_Integer_ Network Representation or error, status code def post_network(request) - # --- Get client with user credentials --- - client = get_client(request.env) # --- Create the new Instance --- network = VirtualNetworkOCCI.new( VirtualNetwork.build_xml, - client, + get_client(request.env), request.body, @config[:bridge]) @@ -334,13 +271,10 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ NETWORK occi representation or error, # status code def get_network(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) - # --- Get the VM --- network = VirtualNetworkOCCI.new( VirtualNetwork.build_xml(params[:id]), - client) + get_client(request.env)) result = network.info return result, 404 if OpenNebula::is_error?(result) @@ -354,12 +288,10 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ Delete confirmation msg or error, # status code def delete_network(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) vn = VirtualNetworkOCCI.new( VirtualNetwork.build_xml(params[:id]), - client) + get_client(request.env)) # --- Delete the VNET --- result = vn.delete @@ -376,8 +308,6 @@ class OCCIServer < CloudServer # request:: _Hash_ hash containing the data of the request # [return] _String_,_Integer_ Image representation or error, status code def post_storage(request) - # Get client with user credentials - client = get_client(request.env) # --- Check OCCI XML from POST --- if request.params['occixml'] == nil @@ -388,7 +318,9 @@ class OCCIServer < CloudServer end # --- Create and Add the new Image --- - image = ImageOCCI.new(Image.build_xml,client, request.params['occixml']) + image = ImageOCCI.new(Image.build_xml, + get_client(request.env), + request.params['occixml']) rc = add_image(image, request.params['file']) return rc, 500 if OpenNebula.is_error?(rc) @@ -406,11 +338,10 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ STORAGE occi representation or error, # status code def get_storage(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) # --- Get the Image --- - image = ImageOCCI.new(Image.build_xml(params[:id]), client) + image = ImageOCCI.new(Image.build_xml(params[:id]), + get_client(request.env)) result = image.info return result, 404 if OpenNebula::is_error?(result) @@ -424,10 +355,9 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ Delete confirmation msg or error, # status code def delete_storage(request, params) - # --- Get client with user credentials --- - client = get_client(request.env) - image = ImageOCCI.new(Image.build_xml(params[:id]), client) + image = ImageOCCI.new(Image.build_xml(params[:id]), + get_client(request.env)) # --- Delete the Image --- result = image.delete diff --git a/src/cloud/occi/lib/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb index 4fb2e2e119..91ea253585 100755 --- a/src/cloud/occi/lib/VirtualMachineOCCI.rb +++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb @@ -23,12 +23,12 @@ class VirtualMachineOCCI < VirtualMachine <%= self.id.to_s%> <%= self.name%> - <% if template['INSTANCE_TYPE'] %> - <%= template['INSTANCE_TYPE'] %> + <% if self['TEMPLATE/INSTANCE_TYPE'] %> + <%= self['TEMPLATE/INSTANCE_TYPE'] %> <% end %> <%= self.state_str %> - <% if template['DISK'] %> - <% template['DISK'].each do |disk| %> + <% if self['TEMPLATE/DISK'] %> + <% self.each('TEMPLATE/DISK') do |disk| %> <%= disk['TYPE'] %> @@ -42,8 +42,8 @@ class VirtualMachineOCCI < VirtualMachine <% end %> <% end %> - <% if template['NIC'] %> - <% template['NIC'].each do |nic| %> + <% if self['TEMPLATE/NIC'] %> + <% self.each('TEMPLATE/NIC') do |nic| %> <% if nic['IP'] %> @@ -55,19 +55,33 @@ class VirtualMachineOCCI < VirtualMachine <% end %> <% end %> - + } - - # Class constructor - def initialize(vm_info, xml, client) - super(xml, client) - @vm_info = vm_info + # Class constructor + def initialize(xml, client, xml_info = nil, types=nil, base=nil) + super(xml, client) + @vm_info = nil + @template = nil + + if xml_info != nil + xmldoc = XMLUtilsElement.initialize_xml(xml_info, 'COMPUTE') + @vm_info = XMLElement.new(xmldoc) if xmldoc != nil + end + + if @vm_info != nil + itype = @vm_info['INSTANCE_TYPE'] + + if itype != nil and types[itype] != nil + @template = base + "/#{types[itype]['TEMPLATE']}" + end + end + end - + def mk_action(action_str) case action_str.downcase - when "stopped" + when "stopped" rc = self.stop when "suspended" rc = self.suspend @@ -77,55 +91,47 @@ class VirtualMachineOCCI < VirtualMachine rc = self.cancel when "shutdown" rc = self.shutdown - when "done" - rc = self.finalize - else + when "done" + rc = self.finalize + else error_msg = "Invalid state" error = OpenNebula::Error.new(error_msg) return error end - + return rc end - + def to_one_template() - if @vm_info['COMPUTE'] - vm_info = @vm_info['COMPUTE'] - vm_info['DISK'] = [vm_info['DISK']].flatten if vm_info['DISK'] - vm_info['NIC'] = [vm_info['NIC']].flatten if vm_info['NIC'] - else + if @vm_info == nil error_msg = "Missing COMPUTE section in the XML body" - error = OpenNebula::Error.new(error_msg) - return error, 400 - end - + return OpenNebula::Error.new(error_msg), 400 + end + + if @template == nil + return OpenNebula::Error.new("Bad instance type"), 500 + end + begin - template = ERB.new(File.read(@vm_info['TEMPLATE_PATH'])) - template_text = template.result(binding) + template = ERB.new(File.read(@template)) + template_text = template.result(binding) rescue Exception => e error = OpenNebula::Error.new(e.message) return error - end + end - return template_text + return template_text end - + # Creates the VMI representation of a Virtual Machine def to_occi(base_url) - vm_hash = self.to_hash - return vm_hash, 500 if OpenNebula.is_error?(vm_hash) - - template = vm_hash['VM']['TEMPLATE'] - template['DISK']=[template['DISK']].flatten if template['DISK'] - template['NIC']=[template['NIC']].flatten if template['NIC'] - begin occi_vm = ERB.new(OCCI_VM) - occi_vm_text = occi_vm.result(binding) + occi_vm_text = occi_vm.result(binding) rescue Exception => e error = OpenNebula::Error.new(e.message) return error - end + end return occi_vm_text.gsub(/\n\s*/,'') end diff --git a/src/cloud/occi/lib/VirtualNetworkOCCI.rb b/src/cloud/occi/lib/VirtualNetworkOCCI.rb index 85222223f9..c307c021cd 100755 --- a/src/cloud/occi/lib/VirtualNetworkOCCI.rb +++ b/src/cloud/occi/lib/VirtualNetworkOCCI.rb @@ -31,26 +31,22 @@ class VirtualNetworkOCCI < VirtualNetwork } ONE_NETWORK = %q{ - NAME = <%= @vnet_info.elements['NAME'].text %> + NAME = <%= @vnet_info['NAME'] %> TYPE = RANGED - BRIDGE = <%= @vnet_info.elements['BRIDGE'].text %> - NETWORK_ADDRESS = <%= @vnet_info.elements['ADDRESS'].text %> - NETWORK_SIZE = <%= @vnet_info.elements['SIZE'].text %> + BRIDGE = <%= @bridge %> + NETWORK_ADDRESS = <%= @vnet_info['ADDRESS'] %> + NETWORK_SIZE = <%= @vnet_info['SIZE']%> }.gsub(/^ /, '') # Class constructor def initialize(xml, client, xml_info=nil, bridge=nil) super(xml, client) + @bridge = bridge + @vnet_info = nil - if xml_info != nil and bridge != nil - @vnet_info = REXML::Document.new(xml_info).root - - bridge_element = REXML::Element.new("BRIDGE") - bridge_element.add_text(bridge) - - @vnet_info.add(bridge_element) - else - @vnet_info = nil + if xml_info != nil + xmldoc = XMLUtilsElement.initialize_xml(xml_info, 'NETWORK') + @vnet_info = XMLElement.new(xmldoc) if xmldoc != nil end end @@ -68,7 +64,7 @@ class VirtualNetworkOCCI < VirtualNetwork end def to_one_template() - if @vnet_info.name != 'NETWORK' + if @vnet_info == nil error_msg = "Missing NETWORK section in the XML body" error = OpenNebula::Error.new(error_msg) return error diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index 0c69e43c94..3434824aac 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -61,13 +61,6 @@ set :port, $occi_server.config[:port] # Helpers ############################################################################## -# Authentication -before do - if !$occi_server.authenticate?(request.env) - halt 401, 'Invalid credentials' - end -end - # Response treatment helpers do def treat_response(result,rc) diff --git a/src/oca/ruby/OpenNebula/XMLUtils.rb b/src/oca/ruby/OpenNebula/XMLUtils.rb index 713cc121ed..2163eb5c10 100644 --- a/src/oca/ruby/OpenNebula/XMLUtils.rb +++ b/src/oca/ruby/OpenNebula/XMLUtils.rb @@ -26,10 +26,18 @@ module OpenNebula # [return] _XML_ object for the underlying XML engine def self.initialize_xml(xml, root_element) if NOKOGIRI - Nokogiri::XML(xml).xpath("/#{root_element}") + xmldoc = Nokogiri::XML(xml).xpath("/#{root_element}") + if xmldoc.size == 0 + xmldoc = nil + end else - REXML::Document.new(xml).root + xmldoc = REXML::Document.new(xml).root + if xmldoc.name != root_element + xmldoc = nil + end end + + return xmldoc end # Extract an element from the XML description of the PoolElement. @@ -53,6 +61,45 @@ module OpenNebula end end + # Gets an attribute from an elemenT + # key:: _String_ xpath for the element + # name:: _String_ name of the attribute + def attr(key,name) + value = nil + + if NOKOGIRI + element=@xml.xpath(key.to_s.upcase) + if element.size == 0 + return nil + end + + attribute = element.attr(name) + + value = attribute.text if attribute != nil + else + element=@xml.elements[key.to_s.upcase] + + value = element.attributes[name] if element != nil + end + + return value + end + + # Iterates over every Element in the XPath and calls the block with a + # a XMLElement + # block:: _Block_ + def each(xpath_str,&block) + if NOKOGIRI + @xml.xpath(xpath_str).each { |pelem| + block.call XMLElement.new(pelem) + } + else + @xml.elements.each(xpath_str) { |pelem| + block.call XMLElement.new(pelem) + } + end + end + def template_str(indent=true) template_like_str('TEMPLATE', indent) end @@ -122,18 +169,6 @@ module OpenNebula str end end - - def XMLUtilsElement.xml_to_hash(xml) - begin - hash = Crack::XML.parse(xml) - rescue Exception => e - error = OpenNebula::Error.new(e.message) - return error - end - - return hash - end - end ########################################################################### @@ -190,6 +225,14 @@ module OpenNebula return @hash end end + + class XMLElement + include XMLUtilsElement + + def initialize(xml) + @xml = xml + end + end end