diff --git a/install.sh b/install.sh index 0a550a4781..d4d70ea59c 100755 --- a/install.sh +++ b/install.sh @@ -1283,6 +1283,7 @@ ECO_LIB_FILES="src/cloud/ec2/lib/EC2QueryClient.rb \ src/cloud/ec2/lib/ImageEC2.rb \ src/cloud/ec2/lib/elastic_ip.rb \ src/cloud/ec2/lib/ebs.rb \ + src/cloud/ec2/lib/tags.rb \ src/cloud/ec2/lib/instance.rb \ src/cloud/ec2/lib/keypair.rb \ src/cloud/ec2/lib/net_ssh_replacement.rb \ diff --git a/src/cloud/ec2/lib/EC2QueryServer.rb b/src/cloud/ec2/lib/EC2QueryServer.rb index f788b4a71b..dd3a39375c 100644 --- a/src/cloud/ec2/lib/EC2QueryServer.rb +++ b/src/cloud/ec2/lib/EC2QueryServer.rb @@ -28,6 +28,7 @@ require 'ebs' require 'elastic_ip' require 'instance' require 'keypair' +require 'tags' ################################################################################ # Extends the OpenNebula::Error class to include an EC2 render of error @@ -217,203 +218,6 @@ class EC2QueryServer < CloudServer return response.result(binding), 200 end - # Adds or overwrites one or more tags for the specified EC2 resource or - # resources. Each resource can have a maximum of 10 tags. Each tag - # consists of a key and optional value. Tag keys must be unique per resource. - # - # @param [Hash] params - # @option params [String] ResourceId.n The IDs of one or more resources - # to tag. For example, ami-1a2b3c4d. - # @option params [String] Tag.n.Key The key for a tag. - # @option params [String] Tag.n.Value The value for a tag. If you don't - # want the tag to have a value, specify the parameter with no value, - # and we set the value to an empty string. - # - # TODO: return if error or continue - def create_tags(params) - resources = [] - tags = {} - - params.each { |key, value| - case key - when /ResourceId\./ - resources << case value - when /ami\-(.+)/ - image = ImageEC2.new(Image.build_xml($1), @client) - rc = image.info - if OpenNebula.is_error?(rc) || !image.ec2_ami? - rc ||= OpenNebula::Error.new() - rc.ec2_code = "InvalidAMIID.NotFound" - return rc - else - image - end - when /vol\-(.+)/ - image = ImageEC2.new(Image.build_xml($1), @client) - rc = image.info - if OpenNebula.is_error?(rc) || !image.ebs_volume? - rc ||= OpenNebula::Error.new() - rc.ec2_code = "InvalidVolume.NotFound" - return rc - else - image - end - when /snap\-(.+)/ - image = ImageEC2.new(Image.build_xml($1), @client) - rc = image.info - if OpenNebula.is_error?(rc) || !image.ebs_snapshot? - rc ||= OpenNebula::Error.new() - rc.ec2_code = "InvalidSnapshot.NotFound" - return rc - else - image - end - when /i\-(.+)/ - vm = VirtualMachine.new(VirtualMachine.build_xml($1), @client) - rc = vm.info - if OpenNebula.is_error?(rc) - rc.ec2_code = "InvalidInstanceID.NotFound" - return rc - else - vm - end - end - when /Tag\.(\d+)\.Key/ - tags[value] = params["Tag.#{$1}.Value"] || "" - end - } - - resources.each {|resource| - if resource.is_a?(VirtualMachine) - template_key = "USER_TEMPLATE" - elsif resource.is_a?(Image) - template_key = "TEMPLATE" - end - - former_tags = resource.to_hash.first[1][template_key]["EC2_TAGS"] || {} - resource.delete_element("#{template_key}/EC2_TAGS") - resource.add_element(template_key, {"EC2_TAGS" => former_tags.merge(tags)}) - - rc = resource.update(resource.template_like_str(template_key)) - return rc if OpenNebula::is_error?(rc) - } - - erb_version = params['Version'] - - response = ERB.new(File.read(@config[:views]+"/create_tags.erb")) - return response.result(binding), 200 - end - - # Deletes the specified set of tags from the specified set of resources. - # - # @param [Hash] params - # @option params [String] ResourceId.n The IDs of one or more resources - # to tag. For example, ami-1a2b3c4d. - # @option params [String] Tag.n.Key The key for a tag. - # @option params [String] Tag.n.Value The value for a tag. If you don't - # want the tag to have a value, specify the parameter with no value, - # and we set the value to an empty string. - # - # TODO: return if error or continue - def delete_tags(params) - resources = [] - tags = {} - - params.each { |key, value| - case key - when /ResourceId\./ - resources << case value - when /ami\-(.+)/ - image = ImageEC2.new(Image.build_xml($1), @client) - rc = image.info - if OpenNebula.is_error?(rc) || !image.ec2_ami? - rc ||= OpenNebula::Error.new() - rc.ec2_code = "InvalidAMIID.NotFound" - return rc - else - image - end - when /vol\-(.+)/ - image = ImageEC2.new(Image.build_xml($1), @client) - rc = image.info - if OpenNebula.is_error?(rc) || !image.ebs_volume? - rc ||= OpenNebula::Error.new() - rc.ec2_code = "InvalidVolume.NotFound" - return rc - else - image - end - when /snap\-(.+)/ - image = ImageEC2.new(Image.build_xml($1), @client) - rc = image.info - if OpenNebula.is_error?(rc) || !image.ebs_snapshot? - rc ||= OpenNebula::Error.new() - rc.ec2_code = "InvalidSnapshot.NotFound" - return rc - else - image - end - when /i\-(.+)/ - vm = VirtualMachine.new(VirtualMachine.build_xml($1), @client) - rc = vm.info - if OpenNebula.is_error?(rc) - rc.ec2_code = "InvalidInstanceID.NotFound" - return rc - else - vm - end - end - when /Tag\.(\d+)\.Key/ - tags[value] = params["Tag.#{$1}.Value"] || "" - end - } - - resources.each {|resource| - if resource.is_a?(VirtualMachine) - template_key = "USER_TEMPLATE" - elsif resource.is_a?(Image) - template_key = "TEMPLATE" - end - - tags.each { |key,value| - resource.delete_element("#{template_key}/EC2_TAGS/#{key}") - } - - rc = resource.update(resource.template_like_str(template_key)) - return rc if OpenNebula::is_error?(rc) - } - - erb_version = params['Version'] - - response = ERB.new(File.read(@config[:views]+"/delete_tags.erb")) - return response.result(binding), 200 - end - - def describe_tags(params) - user_flag = OpenNebula::Pool::INFO_ALL - impool = ImageEC2Pool.new(@client, user_flag) - - rc = impool.info - return rc if OpenNebula::is_error?(rc) - - user_flag = OpenNebula::Pool::INFO_ALL - vmpool = VirtualMachinePool.new(@client, user_flag) - - if include_terminated_instances? - rc = vmpool.info(user_flag, -1, -1, - OpenNebula::VirtualMachinePool::INFO_ALL_VM) - else - rc = vmpool.info - end - - return rc if OpenNebula::is_error?(rc) - - erb_version = params['Version'] - - response = ERB.new(File.read(@config[:views]+"/describe_tags.erb")) - return response.result(binding), 200 - end - ########################################################################### # Helper functions ########################################################################### diff --git a/src/cloud/ec2/lib/tags.rb b/src/cloud/ec2/lib/tags.rb new file mode 100644 index 0000000000..dbb14aceef --- /dev/null +++ b/src/cloud/ec2/lib/tags.rb @@ -0,0 +1,214 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +module Tags + # Adds or overwrites one or more tags for the specified EC2 resource or + # resources. Each resource can have a maximum of 10 tags. Each tag + # consists of a key and optional value. Tag keys must be unique per resource. + # + # @param [Hash] params + # @option params [String] ResourceId.n The IDs of one or more resources + # to tag. For example, ami-1a2b3c4d. + # @option params [String] Tag.n.Key The key for a tag. + # @option params [String] Tag.n.Value The value for a tag. If you don't + # want the tag to have a value, specify the parameter with no value, + # and we set the value to an empty string. + # + # TODO: return if error or continue + def create_tags(params) + resources = [] + tags = {} + + params.each { |key, value| + case key + when /ResourceId\./ + resources << case value + when /ami\-(.+)/ + image = ImageEC2.new(Image.build_xml($1), @client) + rc = image.info + if OpenNebula.is_error?(rc) || !image.ec2_ami? + rc ||= OpenNebula::Error.new() + rc.ec2_code = "InvalidAMIID.NotFound" + return rc + else + image + end + when /vol\-(.+)/ + image = ImageEC2.new(Image.build_xml($1), @client) + rc = image.info + if OpenNebula.is_error?(rc) || !image.ebs_volume? + rc ||= OpenNebula::Error.new() + rc.ec2_code = "InvalidVolume.NotFound" + return rc + else + image + end + when /snap\-(.+)/ + image = ImageEC2.new(Image.build_xml($1), @client) + rc = image.info + if OpenNebula.is_error?(rc) || !image.ebs_snapshot? + rc ||= OpenNebula::Error.new() + rc.ec2_code = "InvalidSnapshot.NotFound" + return rc + else + image + end + when /i\-(.+)/ + vm = VirtualMachine.new(VirtualMachine.build_xml($1), @client) + rc = vm.info + if OpenNebula.is_error?(rc) + rc.ec2_code = "InvalidInstanceID.NotFound" + return rc + else + vm + end + end + when /Tag\.(\d+)\.Key/ + tags[value] = params["Tag.#{$1}.Value"] || "" + end + } + + resources.each {|resource| + if resource.is_a?(VirtualMachine) + template_key = "USER_TEMPLATE" + elsif resource.is_a?(Image) + template_key = "TEMPLATE" + end + + former_tags = resource.to_hash.first[1][template_key]["EC2_TAGS"] || {} + resource.delete_element("#{template_key}/EC2_TAGS") + resource.add_element(template_key, {"EC2_TAGS" => former_tags.merge(tags)}) + + rc = resource.update(resource.template_like_str(template_key)) + return rc if OpenNebula::is_error?(rc) + } + + erb_version = params['Version'] + + response = ERB.new(File.read(@config[:views]+"/create_tags.erb")) + return response.result(binding), 200 + end + + # Deletes the specified set of tags from the specified set of resources. + # + # @param [Hash] params + # @option params [String] ResourceId.n The IDs of one or more resources + # to tag. For example, ami-1a2b3c4d. + # @option params [String] Tag.n.Key The key for a tag. + # @option params [String] Tag.n.Value The value for a tag. If you don't + # want the tag to have a value, specify the parameter with no value, + # and we set the value to an empty string. + # + # TODO: return if error or continue + def delete_tags(params) + resources = [] + tags = {} + + params.each { |key, value| + case key + when /ResourceId\./ + resources << case value + when /ami\-(.+)/ + image = ImageEC2.new(Image.build_xml($1), @client) + rc = image.info + if OpenNebula.is_error?(rc) || !image.ec2_ami? + rc ||= OpenNebula::Error.new() + rc.ec2_code = "InvalidAMIID.NotFound" + return rc + else + image + end + when /vol\-(.+)/ + image = ImageEC2.new(Image.build_xml($1), @client) + rc = image.info + if OpenNebula.is_error?(rc) || !image.ebs_volume? + rc ||= OpenNebula::Error.new() + rc.ec2_code = "InvalidVolume.NotFound" + return rc + else + image + end + when /snap\-(.+)/ + image = ImageEC2.new(Image.build_xml($1), @client) + rc = image.info + if OpenNebula.is_error?(rc) || !image.ebs_snapshot? + rc ||= OpenNebula::Error.new() + rc.ec2_code = "InvalidSnapshot.NotFound" + return rc + else + image + end + when /i\-(.+)/ + vm = VirtualMachine.new(VirtualMachine.build_xml($1), @client) + rc = vm.info + if OpenNebula.is_error?(rc) + rc.ec2_code = "InvalidInstanceID.NotFound" + return rc + else + vm + end + end + when /Tag\.(\d+)\.Key/ + tags[value] = params["Tag.#{$1}.Value"] || "" + end + } + + resources.each {|resource| + if resource.is_a?(VirtualMachine) + template_key = "USER_TEMPLATE" + elsif resource.is_a?(Image) + template_key = "TEMPLATE" + end + + tags.each { |key,value| + resource.delete_element("#{template_key}/EC2_TAGS/#{key}") + } + + rc = resource.update(resource.template_like_str(template_key)) + return rc if OpenNebula::is_error?(rc) + } + + erb_version = params['Version'] + + response = ERB.new(File.read(@config[:views]+"/delete_tags.erb")) + return response.result(binding), 200 + end + + def describe_tags(params) + user_flag = OpenNebula::Pool::INFO_ALL + impool = ImageEC2Pool.new(@client, user_flag) + + rc = impool.info + return rc if OpenNebula::is_error?(rc) + + user_flag = OpenNebula::Pool::INFO_ALL + vmpool = VirtualMachinePool.new(@client, user_flag) + + if include_terminated_instances? + rc = vmpool.info(user_flag, -1, -1, + OpenNebula::VirtualMachinePool::INFO_ALL_VM) + else + rc = vmpool.info + end + + return rc if OpenNebula::is_error?(rc) + + erb_version = params['Version'] + + response = ERB.new(File.read(@config[:views]+"/describe_tags.erb")) + return response.result(binding), 200 + end +end