From 75841719ba877f7d88e892fae761c3e5c1d74fde Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Tue, 14 Jun 2016 13:24:39 +0200 Subject: [PATCH 01/37] snapshots capabilities added --- lib/ruby_vcloud_sdk/vapp.rb | 33 +++++++++++++++++++ lib/ruby_vcloud_sdk/xml/wrapper.rb | 18 ++++++++++ .../xml_templates/CreateSnapshotParams.xml | 6 ++++ 3 files changed, 57 insertions(+) create mode 100644 lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml diff --git a/lib/ruby_vcloud_sdk/vapp.rb b/lib/ruby_vcloud_sdk/vapp.rb index bb499c5..d0d3674 100644 --- a/lib/ruby_vcloud_sdk/vapp.rb +++ b/lib/ruby_vcloud_sdk/vapp.rb @@ -145,6 +145,39 @@ def delete_network_by_name(name) self end + def create_snapshot + target = entity_xml + create_snapshot_link = target.create_snapshot_link + params = Xml::WrapperFactory.create_instance("CreateSnapshotParams") + + Config.logger.info "Creating a snapshot on vApp #{vapp.name}." + task = connection.post(target.create_snapshot_link.href,params) + monitor_task(task) + Config.logger.error "vApp #{vapp.name} has created a snapshot" + end + + def remove_snapshot + target = entity_xml + remove_snapshot_link = target.remove_snapshot_link + + Config.logger.info "Removing all snapshots on vApp #{vapp.name}." + task = connection.post(target.remove_snapshot_link.href,nil) + monitor_task(task) + Config.logger.error "vApp #{vapp.name} has removed all snapshots" + + end + + def revert_snapshot + target = entity_xml + puts target + revert_snapshot_link = target.revert_snapshot_link + + Config.logger.info "Reverting to current snapshot on vApp #{vapp.name}." + task = connection.post(target.revert_snapshot_link.href,nil) + monitor_task(task) + Config.logger.error "vApp #{vapp.name} has reverted a snapshot" + end + private def recompose_from_vapp_template_param(template) diff --git a/lib/ruby_vcloud_sdk/xml/wrapper.rb b/lib/ruby_vcloud_sdk/xml/wrapper.rb index 1f24e67..8d4fa5d 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper.rb @@ -147,6 +147,24 @@ def power_off_link true).first end + def create_snapshot_link + get_nodes(XML_TYPE[:LINK], + { rel: "snapshot:create"}, + true).first + end + + def revert_snapshot_link + get_nodes(XML_TYPE[:LINK], + { rel: "snapshot:revertToCurrent"}, + true).first + end + + def remove_snapshot_link + get_nodes(XML_TYPE[:LINK], + { rel: "snapshot:removeAll"}, + true).first + end + def undeploy_link get_nodes(XML_TYPE[:LINK], { rel: "undeploy" }, diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml new file mode 100644 index 0000000..a23e18c --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml @@ -0,0 +1,6 @@ + + + Snapshot1 + Date: Wed, 15 Jun 2016 14:01:35 +0200 Subject: [PATCH 02/37] added more functions --- lib/ruby_vcloud_sdk/cpu.rb | 5 +- lib/ruby_vcloud_sdk/memory.rb | 5 +- lib/ruby_vcloud_sdk/powerable.rb | 59 ++++++++++++++++++- lib/ruby_vcloud_sdk/resources.rb | 11 ++-- lib/ruby_vcloud_sdk/vapp.rb | 26 ++++---- lib/ruby_vcloud_sdk/vdc.rb | 18 ++++-- lib/ruby_vcloud_sdk/version.rb | 2 +- lib/ruby_vcloud_sdk/vm.rb | 19 ++++++ lib/ruby_vcloud_sdk/xml/wrapper.rb | 16 +---- .../xml/wrapper_classes/vapp.rb | 23 ++++++++ .../xml/wrapper_classes/vdc.rb | 15 ++++- lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 14 ++++- 12 files changed, 170 insertions(+), 43 deletions(-) diff --git a/lib/ruby_vcloud_sdk/cpu.rb b/lib/ruby_vcloud_sdk/cpu.rb index 971cf20..040301d 100644 --- a/lib/ruby_vcloud_sdk/cpu.rb +++ b/lib/ruby_vcloud_sdk/cpu.rb @@ -1,10 +1,11 @@ module VCloudSdk class CPU - attr_reader :available_cores + attr_reader :available_cores, :limit_cores - def initialize(available_cores) + def initialize(available_cores,limit_cores) @available_cores = available_cores + @limit_cores = limit_cores end end diff --git a/lib/ruby_vcloud_sdk/memory.rb b/lib/ruby_vcloud_sdk/memory.rb index 7fede01..36e9a52 100644 --- a/lib/ruby_vcloud_sdk/memory.rb +++ b/lib/ruby_vcloud_sdk/memory.rb @@ -1,10 +1,11 @@ module VCloudSdk class Memory - attr_reader :available_mb + attr_reader :available_mb, :limit_mb - def initialize(available_mb) + def initialize(available_mb,limit_mb) @available_mb = available_mb + @limit_mb = limit_mb end end diff --git a/lib/ruby_vcloud_sdk/powerable.rb b/lib/ruby_vcloud_sdk/powerable.rb index e939f5d..f487064 100644 --- a/lib/ruby_vcloud_sdk/powerable.rb +++ b/lib/ruby_vcloud_sdk/powerable.rb @@ -3,7 +3,7 @@ module VCloudSdk module Powerable def status status_code = entity_xml[:status].to_i - Xml::RESOURCE_ENTITY_STATUS.each_pair do |k, v| + Xml::RESOURCE_ENTITY_STATUS.each_pair do |k, v| return k.to_s if v == status_code end @@ -62,6 +62,63 @@ def power_off self end + def reboot + target = entity_xml + class_name = self.class.name.split("::").last + Config.logger.debug "#{class_name} status: #{target[:status]}" + if !is_status?(target, :POWERED_ON) + Config.logger.info "#{class_name} #{target.name} must be powered-on." + return + end + + reboot_link = target.reboot_link + + Config.logger.info "Rebooting #{class_name} #{target.name}." + task = connection.post(reboot_link.href, nil) + task = monitor_task task, @session.time_limit[:power_on] + Config.logger.info "#{class_name} #{target.name} is rebooted." + self + + end + + def reset + target = entity_xml + class_name = self.class.name.split("::").last + Config.logger.debug "#{class_name} status: #{target[:status]}" + if !is_status?(target, :POWERED_ON) + Config.logger.info "#{class_name} #{target.name} must be powered-on." + return + end + + reset_link = target.reset_link + + Config.logger.info "Reseting #{class_name} #{target.name}." + task = connection.post(reset_link.href, nil) + task = monitor_task task, @session.time_limit[:power_on] + Config.logger.info "#{class_name} #{target.name} is reseted." + self + + end + + def suspend + target = entity_xml + class_name = self.class.name.split("::").last + Config.logger.debug "#{class_name} status: #{target[:status]}" + puts "hola" + if !is_status?(target, :POWERED_ON) + Config.logger.info "#{class_name} #{target.name} must be powered-on." + return + end + + suspend_link = target.suspend_link + + Config.logger.info "Suspending #{class_name} #{target.name}." + task = connection.post(suspend_link.href, nil) + task = monitor_task task, @session.time_limit[:power_on] + Config.logger.info "#{class_name} #{target.name} is suspended." + self + end + private def is_status?(target, status) diff --git a/lib/ruby_vcloud_sdk/resources.rb b/lib/ruby_vcloud_sdk/resources.rb index 24f9486..aa08cf3 100644 --- a/lib/ruby_vcloud_sdk/resources.rb +++ b/lib/ruby_vcloud_sdk/resources.rb @@ -1,12 +1,13 @@ module VCloudSdk class Resources - attr_reader :cpu - attr_reader :memory + attr_reader :cpu_available, :cpu_limit, :memory_available, :memory_limit - def initialize(cpu, memory) - @cpu = cpu - @memory = memory + def initialize(cpu,memory) + @cpu_available = cpu.available_cores + @cpu_limit = cpu.limit_cores + @memory_available = memory.available_mb + @memory_limit = memory.limit_mb end end diff --git a/lib/ruby_vcloud_sdk/vapp.rb b/lib/ruby_vcloud_sdk/vapp.rb index d0d3674..7002418 100644 --- a/lib/ruby_vcloud_sdk/vapp.rb +++ b/lib/ruby_vcloud_sdk/vapp.rb @@ -13,6 +13,11 @@ def initialize(session, link) @link = link end + def id + id = entity_xml.urn + id.split(":")[3] + end + def name entity_xml.name end @@ -145,37 +150,36 @@ def delete_network_by_name(name) self end - def create_snapshot - target = entity_xml - create_snapshot_link = target.create_snapshot_link + def create_snapshot(snapshot_hash) + target = entity_xml + create_snapshot_link = target.create_snapshot_link params = Xml::WrapperFactory.create_instance("CreateSnapshotParams") - Config.logger.info "Creating a snapshot on vApp #{vapp.name}." + Config.logger.info "Creating a snapshot on vApp #{name}." task = connection.post(target.create_snapshot_link.href,params) monitor_task(task) - Config.logger.error "vApp #{vapp.name} has created a snapshot" + Config.logger.error "vApp #{name} has created a snapshot" end def remove_snapshot target = entity_xml remove_snapshot_link = target.remove_snapshot_link - - Config.logger.info "Removing all snapshots on vApp #{vapp.name}." + + Config.logger.info "Removing all snapshots on vApp #{name}." task = connection.post(target.remove_snapshot_link.href,nil) monitor_task(task) - Config.logger.error "vApp #{vapp.name} has removed all snapshots" + Config.logger.error "vApp #{name} has removed all snapshots" end def revert_snapshot target = entity_xml - puts target revert_snapshot_link = target.revert_snapshot_link - Config.logger.info "Reverting to current snapshot on vApp #{vapp.name}." + Config.logger.info "Reverting to current snapshot on vApp #{name}." task = connection.post(target.revert_snapshot_link.href,nil) monitor_task(task) - Config.logger.error "vApp #{vapp.name} has reverted a snapshot" + Config.logger.error "vApp #{name} has reverted a snapshot" end private diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb index 4837f12..be33afe 100644 --- a/lib/ruby_vcloud_sdk/vdc.rb +++ b/lib/ruby_vcloud_sdk/vdc.rb @@ -76,16 +76,26 @@ def find_vapp_by_name(name) fail ObjectNotFoundError, "VApp '#{name}' is not found" end + def find_vapp_by_id(uuid) + entity_xml.vapps.each do |vapp_link| + if vapp_link.href.split("/")[5] == "vapp-#{uuid}" + return VCloudSdk::VApp.new(@session, vapp_link) + end + end + + fail ObjectNotFoundError, "VApp '#{uuid}' is not found" + end + def vapp_exists?(name) entity_xml.vapps.any? do |vapp| vapp.name == name end end - def resources - cpu = VCloudSdk::CPU.new(entity_xml.available_cpu_cores) - memory = VCloudSdk::Memory.new(entity_xml.available_memory_mb) - VCloudSdk::Resources.new(cpu, memory) + def resources + cpu = VCloudSdk::CPU.new(entity_xml.available_cpu_cores,entity_xml.limit_cpu_cores) + memory = VCloudSdk::Memory.new(entity_xml.available_memory_mb,entity_xml.limit_memory_mb) + VCloudSdk::Resources.new(cpu,memory) end def networks diff --git a/lib/ruby_vcloud_sdk/version.rb b/lib/ruby_vcloud_sdk/version.rb index 0d399cf..3b8386c 100644 --- a/lib/ruby_vcloud_sdk/version.rb +++ b/lib/ruby_vcloud_sdk/version.rb @@ -1,3 +1,3 @@ module VCloudSdk - VERSION = '0.7.3' + VERSION = '0.7.4' end diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index ec7152a..2c8845d 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -17,6 +17,11 @@ def initialize(session, link) @link = link end + def id + id = entity_xml.urn + id.split(":")[3] + end + def href @link end @@ -86,6 +91,11 @@ def vcpu=(count) self end + def ip_address + entity_xml.ip_address + + end + def list_networks entity_xml .network_connection_section @@ -262,6 +272,15 @@ def delete_nics(*nics) self end + def install_vmtools + Config.logger.info( + "Installing VMware tools on #{name} ...") + task = connection.put(entity_xml.install_vmtools_link.href,nil) + monitor_task(task) + self + end + + def product_section_properties product_section = entity_xml.product_section return [] if product_section.nil? diff --git a/lib/ruby_vcloud_sdk/xml/wrapper.rb b/lib/ruby_vcloud_sdk/xml/wrapper.rb index 8d4fa5d..a14d9b7 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper.rb @@ -147,21 +147,9 @@ def power_off_link true).first end - def create_snapshot_link + def suspend_link get_nodes(XML_TYPE[:LINK], - { rel: "snapshot:create"}, - true).first - end - - def revert_snapshot_link - get_nodes(XML_TYPE[:LINK], - { rel: "snapshot:revertToCurrent"}, - true).first - end - - def remove_snapshot_link - get_nodes(XML_TYPE[:LINK], - { rel: "snapshot:removeAll"}, + { rel: "power:suspend"}, true).first end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb index a71e5b6..b6bd086 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb @@ -1,6 +1,7 @@ module VCloudSdk module Xml class VApp < Wrapper + def description get_nodes("Description").first.content end @@ -13,6 +14,10 @@ def reboot_link get_nodes("Link", {"rel" => "power:reboot"}, true).first end + def reset_link + get_nodes("Link", {"rel" => "power:reset"}, true).first + end + def tasks get_nodes(XML_TYPE[:TASK]) end @@ -27,6 +32,24 @@ def recompose_vapp_link true).first end + def create_snapshot_link + get_nodes(XML_TYPE[:LINK], + { rel: "snapshot:create"}, + true).first + end + + def revert_snapshot_link + get_nodes(XML_TYPE[:LINK], + { rel: "snapshot:revertToCurrent"}, + true).first + end + + def remove_snapshot_link + get_nodes(XML_TYPE[:LINK], + { rel: "snapshot:removeAll"}, + true).first + end + def vdc_link get_nodes(XML_TYPE[:LINK], { type: MEDIA_TYPE[:VDC] }, diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb index def4a0e..100ec09 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb @@ -73,21 +73,32 @@ def storage_profile(name) .first end + def limit_cpu_cores + cpu_limit = get_nodes("ComputeCapacity") + .first.get_nodes("Cpu").first.get_nodes("Limit").first.content + end + def available_cpu_cores cpu_resource = get_nodes("ComputeCapacity") .first.get_nodes("Cpu").first available_cpu_clock_speed = get_available_resource(cpu_resource) - +=begin # clock units can only be MHz or GHz units = cpu_resource.get_nodes("Units").first.content if units == "MHz" available_cpu_clock_speed = available_cpu_clock_speed / 1000 end - +=end # We assume 1 GHz is converted to 1 vCpu core available_cpu_clock_speed end + def limit_memory_mb + memory_limit = get_nodes("ComputeCapacity") + .first.get_nodes("Memory").first.get_nodes("Limit").first.content + + end + def available_memory_mb memory_resource = get_nodes("ComputeCapacity") .first.get_nodes("Memory").first diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index 1dcf64a..64f442a 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -4,7 +4,7 @@ class Vm < Wrapper def initialize(xml, ns = nil, ns_definitions = nil) super(xml, ns, ns_definitions) @logger = Config.logger - end + end def vapp_link get_nodes(XML_TYPE[:LINK], @@ -51,6 +51,10 @@ def description=(value) value end + def ip_address + ip = get_nodes("IpAddress").first.content + end + def reconfigure_link get_nodes(XML_TYPE[:LINK], { rel: "reconfigureVm" }, @@ -63,6 +67,14 @@ def insert_media_link true).first end + def install_vmtools_link + get_nodes(XML_TYPE[:LINK], + { rel: "installVmwareTools" }, + true).first + end + + def + def eject_media_link get_nodes(XML_TYPE[:LINK], { rel: "media:ejectMedia" }, From 5611ecb9a8ab04098064c055f36414b69299a900 Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Thu, 16 Jun 2016 13:11:06 +0200 Subject: [PATCH 03/37] README changed with new functionalities, modified catalog class --- README.md | 66 +++++++++++++++++++ lib/ruby_vcloud_sdk/catalog.rb | 18 ++++- lib/ruby_vcloud_sdk/catalog_item.rb | 19 +++++- lib/ruby_vcloud_sdk/resources.rb | 11 ++-- .../xml/wrapper_classes/catalog_item.rb | 8 +++ 5 files changed, 115 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ae66567..7a543b2 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,15 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' when vapp with the name does not exist 'RestClient::BadRequest' for un-expected errors + find_vapp_by_id + parameters: + id (String): id of vapp + returns: + vapp object matching id + throws: + 'ObjectNotFoundError' when vapp with the id does not exist + 'RestClient::BadRequest' for un-expected errors + vapp_exists? parameters: name (String): name of vapp @@ -312,6 +321,15 @@ Copyright (c) VMware, Inc. 'RestClient::BadRequest' for un-expected errors VApp + + id + returns: vApp's id + + name + returns: vApp's name + + status: + returns: vApp's status delete returns: nil @@ -332,6 +350,15 @@ Copyright (c) VMware, Inc. 'VappSuspendedError' if VApp is suspended 'RestClient::BadRequest' for un-expected errors + reboot + returns: vApp object + + reset + returns: vApp object + + suspend: + returns: vApp object + recompose_from_vapp_template parameters: catalog_name (String): name of catalog @@ -403,7 +430,29 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' when network with the name does not exist 'RestClient::BadRequest' for un-expected errors + create_snapshot + parameters: + snapshot_hash (Hash): hash with :name and :description + returns: nil + throws: + + remove_snapshot + returns: nil + throws: + + revert_snapshot + returns: nil + throws: + VM + id + returns: VM's id + + status + returns: VM's status + + href + returns: VM's href vcpu: returns: number of virtual cpus of VM @@ -434,6 +483,9 @@ Copyright (c) VMware, Inc. 'CloudError' when the memory size is less than or equal to 0 'RestClient::BadRequest' for un-expected errors + ip_address + returns: The IP address(es) of the VM + nics returns: array of NIC objects throws: @@ -479,6 +531,17 @@ Copyright (c) VMware, Inc. 'VmSuspendedError' if VM is suspended 'RestClient::BadRequest' for un-expected errors + reboot + returns: VM object + + reset + returns: VM object + + suspend: + returns: VM object + + undeploy: + insert_media parameters: catalog_name (String): name of catalog @@ -522,6 +585,9 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' if specified nic index does not exist 'RestClient::BadRequest' for un-expected errors + install_vmtools + returns: nil + product_section_properties returns: array of hash values representing properties of product section of VM diff --git a/lib/ruby_vcloud_sdk/catalog.rb b/lib/ruby_vcloud_sdk/catalog.rb index 5ec0e24..5dc0616 100644 --- a/lib/ruby_vcloud_sdk/catalog.rb +++ b/lib/ruby_vcloud_sdk/catalog.rb @@ -132,16 +132,30 @@ def upload_vapp_template( find_vapp_template_by_name(template_name) end + def find_vapp_template_by_id(uuid) + ##CUTRE + link = nil + admin_xml.catalog_items.each do |item_link| + link = item_link if uuid == item_link[:id] + end + fail ObjectNotFoundError, "Catalog Item '#{uuid}' is not found" if link.nil? + + item = VCloudSdk::CatalogItem.new(@session, link) + check_item_type(item, Xml::MEDIA_TYPE[:VAPP_TEMPLATE]) + item + + end + def find_vapp_template_by_name(name) find_item(name, Xml::MEDIA_TYPE[:VAPP_TEMPLATE]) end def instantiate_vapp_template(template_name, vdc_name, vapp_name, description = nil, disk_locality = nil, network_config = nil) - + instantiate_vapp_params = create_instantiate_vapp_params( template_name, vapp_name, description, disk_locality, network_config) - + vdc = find_vdc_by_name vdc_name vapp = connection.post(vdc.instantiate_vapp_template_link, diff --git a/lib/ruby_vcloud_sdk/catalog_item.rb b/lib/ruby_vcloud_sdk/catalog_item.rb index fee1cf6..5212989 100644 --- a/lib/ruby_vcloud_sdk/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/catalog_item.rb @@ -2,7 +2,7 @@ require_relative "infrastructure" module VCloudSdk - # Represents the calalog item in calalog. + # Represents the calalog item in catalog. class CatalogItem include Infrastructure @@ -15,6 +15,19 @@ def name entity_xml.entity[:name] end + def id + id = entity_xml.urn + id.split(":")[3] + end + + def description + entity_xml.description + end + + def vapp_template_id + entity_xml.entity[:href].split("/")[5] + end + def type entity_xml.entity[:type] end @@ -22,5 +35,9 @@ def type def href entity_xml.entity[:href] end + + def date + entity_xml.date + end end end diff --git a/lib/ruby_vcloud_sdk/resources.rb b/lib/ruby_vcloud_sdk/resources.rb index aa08cf3..edbe883 100644 --- a/lib/ruby_vcloud_sdk/resources.rb +++ b/lib/ruby_vcloud_sdk/resources.rb @@ -1,13 +1,16 @@ module VCloudSdk class Resources - attr_reader :cpu_available, :cpu_limit, :memory_available, :memory_limit + attr_reader :cpu_available, :cpu_limit, :cpu_used, :memory_available, :memory_limit, :memory_used def initialize(cpu,memory) - @cpu_available = cpu.available_cores - @cpu_limit = cpu.limit_cores + @cpu_available = cpu.available_cores + @cpu_limit = cpu.limit_cores + @cpu_used = cpu.limit_cores.to_i - cpu.available_cores.to_i + @memory_available = memory.available_mb - @memory_limit = memory.limit_mb + @memory_limit = memory.limit_mb + @memory_used = memory.limit_mb.to_i - memory.available_mb.to_i end end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb index 36b10cc..6ca176a 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb @@ -13,6 +13,14 @@ def entity=(entity) def entity get_nodes(XML_TYPE[:ENTITY]).first end + + def description + get_nodes("Description").first.content + end + + def date + get_nodes("DateCreated").first.content + end end end From 158d7d22d9de37f13181f824bb096d6f83c9f2fb Mon Sep 17 00:00:00 2001 From: Arnau Colominas Illa Date: Thu, 16 Jun 2016 16:28:07 +0200 Subject: [PATCH 04/37] README modified with objects structure --- README.md | 27 +++++++++++++++++++++++++++ lib/ruby_vcloud_sdk/powerable.rb | 3 +-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a543b2..4aec394 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,32 @@ ## Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. Copyright (c) VMware, Inc. +## Object Structure + + Client -> VDC -> Vapp -> Vm -> Nic + + -> Disk + + + -> Network + + + -> Network -> IpRanges + + -> Disk + + -> Resource + + -> Edge Gateway -> IpRanges + + -> Storage Profile + + -> Catalog -> Catalog Item + + + -> RightRecord + + ## Object Model Client @@ -445,6 +471,7 @@ Copyright (c) VMware, Inc. throws: VM + id returns: VM's id diff --git a/lib/ruby_vcloud_sdk/powerable.rb b/lib/ruby_vcloud_sdk/powerable.rb index f487064..2e2157a 100644 --- a/lib/ruby_vcloud_sdk/powerable.rb +++ b/lib/ruby_vcloud_sdk/powerable.rb @@ -103,8 +103,7 @@ def reset def suspend target = entity_xml class_name = self.class.name.split("::").last - Config.logger.debug "#{class_name} status: #{target[:status]}" - puts "hola" + Config.logger.debug "#{class_name} status: #{target[:status]}" if !is_status?(target, :POWERED_ON) Config.logger.info "#{class_name} #{target.name} must be powered-on." return From 31b97517877605ad62ccc5073dc7d77f54b3140a Mon Sep 17 00:00:00 2001 From: Arnau Colominas Illa Date: Thu, 16 Jun 2016 16:33:57 +0200 Subject: [PATCH 05/37] README --- README.md | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 4aec394..76f0495 100644 --- a/README.md +++ b/README.md @@ -3,30 +3,17 @@ Copyright (c) VMware, Inc. ## Object Structure - Client -> VDC -> Vapp -> Vm -> Nic - - -> Disk - - + Client -> VDC -> Vapp -> Vm -> Nic + -> Disk -> Network - - - -> Network -> IpRanges - + -> Network -> IpRanges -> Disk - -> Resource - -> Edge Gateway -> IpRanges - -> Storage Profile - -> Catalog -> Catalog Item - - -> RightRecord - ## Object Model Client From c14bb3b82a9a186ad9272a65bf03f5df807a29a7 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:38:36 +0200 Subject: [PATCH 06/37] Update README.md --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76f0495..d74a28b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Copyright (c) VMware, Inc. ## Object Structure +=================== Client -> VDC -> Vapp -> Vm -> Nic -> Disk @@ -15,8 +16,10 @@ Copyright (c) VMware, Inc. -> RightRecord ## Object Model +=============== Client + ------ find_vdc_by_name parameters: @@ -69,6 +72,7 @@ Copyright (c) VMware, Inc. 'RestClient::BadRequest' for un-expected errors VDC + --- storage_profiles returns: array of storage profile objects @@ -225,6 +229,7 @@ Copyright (c) VMware, Inc. 'RestClient::BadRequest' for un-expected errors Catalog + ------- items returns: array of catalog item objects @@ -322,6 +327,7 @@ Copyright (c) VMware, Inc. 'RestClient::BadRequest' for un-expected error Network + ------- ip_ranges returns: IpRanges object @@ -334,6 +340,7 @@ Copyright (c) VMware, Inc. 'RestClient::BadRequest' for un-expected errors VApp + ---- id returns: vApp's id @@ -458,6 +465,7 @@ Copyright (c) VMware, Inc. throws: VM + -- id returns: VM's id @@ -644,6 +652,7 @@ Copyright (c) VMware, Inc. 'RestClient::BadRequest' for un-expected errors VdcStorageProfile + ----------------- available_storage returns: @@ -651,6 +660,7 @@ Copyright (c) VMware, Inc. -1 if 'storageLimitMB' is 0 EdgeGateway + ----------- public_ips: returns: IpRanges object @@ -659,6 +669,7 @@ Copyright (c) VMware, Inc. ## Example +========== VCloud_SDK is straightforward to use. Here is an example of creating vApp from vApp template. 1. Create vCloud client object @@ -673,5 +684,5 @@ Copyright (c) VMware, Inc. catalog = client.find_catalog_by_name(catalog_name) 3. Create vApp from that vapp template - vapp = instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name) - \ No newline at end of file + vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name) + From e0f60d4a483b652b92b9f231255f613121acf880 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:39:51 +0200 Subject: [PATCH 07/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d74a28b..a9123cb 100644 --- a/README.md +++ b/README.md @@ -465,7 +465,7 @@ Copyright (c) VMware, Inc. throws: VM - -- + --- id returns: VM's id From 4721d91ac5e0b2ebca61e1e70f8e311704892d82 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:41:18 +0200 Subject: [PATCH 08/37] Update README.md --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a9123cb..50a7564 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,26 @@ Copyright (c) VMware, Inc. ## Object Structure -=================== +================= - Client -> VDC -> Vapp -> Vm -> Nic - -> Disk + Client -> VDC -> Vapp -> Vm -> Nic + + -> Disk + -> Network - -> Network -> IpRanges + + -> Network -> IpRanges + -> Disk + -> Resource + -> Edge Gateway -> IpRanges + -> Storage Profile + -> Catalog -> Catalog Item + -> RightRecord ## Object Model From 80ab6df51adb61bf8a2452ee2c765bafa6f8b9d8 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:50:14 +0200 Subject: [PATCH 09/37] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 50a7564..572bb23 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Copyright (c) VMware, Inc. ## Object Structure ================= + Client -> VDC -> Vapp -> Vm -> Nic -> Disk From 13e5ed708381b2d4842f0cb29fbbc6be163d320d Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:51:06 +0200 Subject: [PATCH 10/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 572bb23..7afaef5 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Copyright (c) VMware, Inc. ================= - Client -> VDC -> Vapp -> Vm -> Nic + Client -> VDC -> Vapp -> Vm -> Nic -> Disk From 3e90c979fdeed396be16a6b60b9a248313311ac3 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:52:11 +0200 Subject: [PATCH 11/37] Update README.md --- README.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7afaef5..8f1f13e 100644 --- a/README.md +++ b/README.md @@ -5,25 +5,16 @@ Copyright (c) VMware, Inc. ================= - Client -> VDC -> Vapp -> Vm -> Nic - + Client -> VDC -> Vapp -> Vm -> Nic -> Disk - -> Network - -> Network -> IpRanges - -> Disk - -> Resource - -> Edge Gateway -> IpRanges - -> Storage Profile - - -> Catalog -> Catalog Item - - -> RightRecord + -> Catalog -> Catalog Item + -> RightRecord ## Object Model =============== From 7e620c070d25ff403ca5ce2c8a7c947e38af20ae Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:53:06 +0200 Subject: [PATCH 12/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f1f13e..8037c5a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. +# Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. Copyright (c) VMware, Inc. ## Object Structure From b12bbe569a1a255c89ec6972f8a09df5381646d9 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:53:45 +0200 Subject: [PATCH 13/37] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8037c5a..1092301 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. +#Ruby VCloud SDK +================ + +Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. Copyright (c) VMware, Inc. ## Object Structure From 861951207bf9d551433cbc8c517ad22c45dc3757 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:54:04 +0200 Subject: [PATCH 14/37] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1092301..2cd203e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ #Ruby VCloud SDK -================ - +========= Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. Copyright (c) VMware, Inc. ## Object Structure -================= +============ Client -> VDC -> Vapp -> Vm -> Nic From ec8c85c20f28ce2e7498922309f99bcdd207171b Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:57:25 +0200 Subject: [PATCH 15/37] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2cd203e..2f52558 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ #Ruby VCloud SDK -========= + Ruby VCloud SDK is a gem to simplify making vCloud Director API calls. Copyright (c) VMware, Inc. ## Object Structure -============ + Client -> VDC -> Vapp -> Vm -> Nic @@ -19,7 +19,7 @@ Copyright (c) VMware, Inc. -> RightRecord ## Object Model -=============== + Client ------ @@ -672,20 +672,20 @@ Copyright (c) VMware, Inc. ## Example -========== + VCloud_SDK is straightforward to use. Here is an example of creating vApp from vApp template. 1. Create vCloud client object - client = VCloudSdk::Client.new(url, username, password) + client = VCloudSdk::Client.new(url, username, password) Note that the parameter 'username' should be the VDC user_name@organization_name. For example, the VDC user name is admin, the organization name is myorg, then the 'username' parameter here should be admin@myorg. 2. Find the catalog where the vapp template is stored - catalog = client.find_catalog_by_name(catalog_name) + catalog = client.find_catalog_by_name(catalog_name) 3. Create vApp from that vapp template - vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name) + vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name) From 6737a1408dfb41c7c0b9515f579aa9079da171a6 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 16:59:24 +0200 Subject: [PATCH 16/37] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2f52558..a288e89 100644 --- a/README.md +++ b/README.md @@ -677,15 +677,15 @@ Copyright (c) VMware, Inc. 1. Create vCloud client object - client = VCloudSdk::Client.new(url, username, password) + 'client = VCloudSdk::Client.new(url, username, password)' Note that the parameter 'username' should be the VDC user_name@organization_name. For example, the VDC user name is admin, the organization name is myorg, then the 'username' parameter here should be admin@myorg. 2. Find the catalog where the vapp template is stored - catalog = client.find_catalog_by_name(catalog_name) + 'catalog = client.find_catalog_by_name(catalog_name)' 3. Create vApp from that vapp template - vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name) + 'vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name)' From 53201419ad376433475801a718a3f9c7e2f425ba Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:00:53 +0200 Subject: [PATCH 17/37] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a288e89..dc6dd51 100644 --- a/README.md +++ b/README.md @@ -677,15 +677,15 @@ Copyright (c) VMware, Inc. 1. Create vCloud client object - 'client = VCloudSdk::Client.new(url, username, password)' + `client = VCloudSdk::Client.new(url, username, password)` Note that the parameter 'username' should be the VDC user_name@organization_name. For example, the VDC user name is admin, the organization name is myorg, then the 'username' parameter here should be admin@myorg. 2. Find the catalog where the vapp template is stored - 'catalog = client.find_catalog_by_name(catalog_name)' + `catalog = client.find_catalog_by_name(catalog_name)` 3. Create vApp from that vapp template - 'vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name)' + `vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name)` From 2fa4b7bbae31b63bf1ce65f7bb3721863edde835 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:02:54 +0200 Subject: [PATCH 18/37] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dc6dd51..274dabd 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Copyright (c) VMware, Inc. ## Object Model - Client + ###Client ------ find_vdc_by_name @@ -74,7 +74,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors - VDC + ###VDC --- storage_profiles @@ -231,7 +231,7 @@ Copyright (c) VMware, Inc. 'CloudError' when any disk deletion failure occurs 'RestClient::BadRequest' for un-expected errors - Catalog + ###Catalog ------- items @@ -329,7 +329,7 @@ Copyright (c) VMware, Inc. 'ApiError' when instantiating vapp template task is not successful 'RestClient::BadRequest' for un-expected error - Network + ###Network ------- ip_ranges @@ -342,7 +342,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors - VApp + ###VApp ---- id @@ -467,7 +467,7 @@ Copyright (c) VMware, Inc. returns: nil throws: - VM + ###VM --- id @@ -654,7 +654,7 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' if no disk matching the given name 'RestClient::BadRequest' for un-expected errors - VdcStorageProfile + ###VdcStorageProfile ----------------- available_storage @@ -662,7 +662,7 @@ Copyright (c) VMware, Inc. integer number of available storage in MB, i.e. storageLimitMB - storageUsedMB -1 if 'storageLimitMB' is 0 - EdgeGateway + ###EdgeGateway ----------- public_ips: From 5ba29ba55c8bb34acb78db76653fbd675bbf181a Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:04:05 +0200 Subject: [PATCH 19/37] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 274dabd..6893e11 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Copyright (c) VMware, Inc. ## Object Model - ###Client + ### Client ------ find_vdc_by_name @@ -74,7 +74,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors - ###VDC + ### VDC --- storage_profiles @@ -231,7 +231,7 @@ Copyright (c) VMware, Inc. 'CloudError' when any disk deletion failure occurs 'RestClient::BadRequest' for un-expected errors - ###Catalog + ### Catalog ------- items @@ -329,7 +329,7 @@ Copyright (c) VMware, Inc. 'ApiError' when instantiating vapp template task is not successful 'RestClient::BadRequest' for un-expected error - ###Network + ### Network ------- ip_ranges @@ -342,7 +342,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors - ###VApp + ### VApp ---- id @@ -467,7 +467,7 @@ Copyright (c) VMware, Inc. returns: nil throws: - ###VM + ### VM --- id @@ -654,7 +654,7 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' if no disk matching the given name 'RestClient::BadRequest' for un-expected errors - ###VdcStorageProfile + ### VdcStorageProfile ----------------- available_storage @@ -662,7 +662,7 @@ Copyright (c) VMware, Inc. integer number of available storage in MB, i.e. storageLimitMB - storageUsedMB -1 if 'storageLimitMB' is 0 - ###EdgeGateway + ### EdgeGateway ----------- public_ips: From c01028de2de57ae7290903b410529f4932092717 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:05:49 +0200 Subject: [PATCH 20/37] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6893e11..aaccb45 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ Copyright (c) VMware, Inc. ## Object Model - ### Client - ------ +### Client + ------ find_vdc_by_name parameters: @@ -74,7 +74,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors - ### VDC +### VDC --- storage_profiles @@ -231,7 +231,7 @@ Copyright (c) VMware, Inc. 'CloudError' when any disk deletion failure occurs 'RestClient::BadRequest' for un-expected errors - ### Catalog +### Catalog ------- items @@ -329,7 +329,7 @@ Copyright (c) VMware, Inc. 'ApiError' when instantiating vapp template task is not successful 'RestClient::BadRequest' for un-expected error - ### Network +### Network ------- ip_ranges @@ -342,7 +342,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors - ### VApp +### VApp ---- id @@ -467,7 +467,7 @@ Copyright (c) VMware, Inc. returns: nil throws: - ### VM +### VM --- id @@ -654,7 +654,7 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' if no disk matching the given name 'RestClient::BadRequest' for un-expected errors - ### VdcStorageProfile +### VdcStorageProfile ----------------- available_storage @@ -662,7 +662,7 @@ Copyright (c) VMware, Inc. integer number of available storage in MB, i.e. storageLimitMB - storageUsedMB -1 if 'storageLimitMB' is 0 - ### EdgeGateway +### EdgeGateway ----------- public_ips: From d4bcf654e1d65552bdbb7a56e979cc53615424af Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:06:57 +0200 Subject: [PATCH 21/37] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aaccb45..2cef100 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Copyright (c) VMware, Inc. ### Client ------ - find_vdc_by_name +#### find_vdc_by_name parameters: name (String): name of VDC returns: VDC object matching name @@ -32,19 +32,19 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' when VDC with the name does not exist 'RestClient::BadRequest' for un-expected errors - vdc_exists? +#### vdc_exists? parameters: name (String): name of VDC returns: boolean throws: 'RestClient::BadRequest' for un-expected errors - catalogs +#### catalogs returns: array of catalog objects throws: 'RestClient::BadRequest' for un-expected errors - list_catalogs +#### list_catalogs returns: array of catalog names throws: 'RestClient::BadRequest' for un-expected errors From 50c05c821e91e11bde4755c690108c1c239989ed Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:07:53 +0200 Subject: [PATCH 22/37] Update README.md --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2cef100..17380da 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,7 @@ Copyright (c) VMware, Inc. ### Client ------ - -#### find_vdc_by_name + find_vdc_by_name parameters: name (String): name of VDC returns: VDC object matching name @@ -32,19 +31,19 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' when VDC with the name does not exist 'RestClient::BadRequest' for un-expected errors -#### vdc_exists? + vdc_exists? parameters: name (String): name of VDC returns: boolean throws: 'RestClient::BadRequest' for un-expected errors -#### catalogs + catalogs returns: array of catalog objects throws: 'RestClient::BadRequest' for un-expected errors -#### list_catalogs + list_catalogs returns: array of catalog names throws: 'RestClient::BadRequest' for un-expected errors From 2393d6135bb0b2ef8e6ac111178dc7b172cd2a38 Mon Sep 17 00:00:00 2001 From: Arnau Date: Thu, 16 Jun 2016 17:08:41 +0200 Subject: [PATCH 23/37] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 17380da..aaebae8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Copyright (c) VMware, Inc. ## Object Model -### Client +#### Client ------ find_vdc_by_name parameters: @@ -73,7 +73,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors -### VDC +#### VDC --- storage_profiles @@ -230,7 +230,7 @@ Copyright (c) VMware, Inc. 'CloudError' when any disk deletion failure occurs 'RestClient::BadRequest' for un-expected errors -### Catalog +#### Catalog ------- items @@ -328,7 +328,7 @@ Copyright (c) VMware, Inc. 'ApiError' when instantiating vapp template task is not successful 'RestClient::BadRequest' for un-expected error -### Network +#### Network ------- ip_ranges @@ -341,7 +341,7 @@ Copyright (c) VMware, Inc. throws: 'RestClient::BadRequest' for un-expected errors -### VApp +#### VApp ---- id @@ -466,7 +466,7 @@ Copyright (c) VMware, Inc. returns: nil throws: -### VM +#### VM --- id @@ -653,7 +653,7 @@ Copyright (c) VMware, Inc. 'ObjectNotFoundError' if no disk matching the given name 'RestClient::BadRequest' for un-expected errors -### VdcStorageProfile +#### VdcStorageProfile ----------------- available_storage @@ -661,7 +661,7 @@ Copyright (c) VMware, Inc. integer number of available storage in MB, i.e. storageLimitMB - storageUsedMB -1 if 'storageLimitMB' is 0 -### EdgeGateway +#### EdgeGateway ----------- public_ips: From 7445242e43c1b6217c0ebbd4020bb97e7640271f Mon Sep 17 00:00:00 2001 From: Arnau Colominas Illa Date: Thu, 16 Jun 2016 17:51:16 +0200 Subject: [PATCH 24/37] README Object Structure --- README.md | 13 ++++++++----- lib/ruby_vcloud_sdk/resources.rb | 11 +++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index aaebae8..4517144 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,18 @@ Copyright (c) VMware, Inc. - Client -> VDC -> Vapp -> Vm -> Nic - -> Disk + Client -> VDC -> Vapp -> Vm -> Nic + -> Internal Disk + -> Disk + -> Vapp -> Network -> Network -> IpRanges - -> Disk - -> Resource + -> Disk -> Vm + -> Resources -> Edge Gateway -> IpRanges - -> Storage Profile + -> Vdc Storage Profile -> Catalog -> Catalog Item + -> OVF Directory -> RightRecord ## Object Model diff --git a/lib/ruby_vcloud_sdk/resources.rb b/lib/ruby_vcloud_sdk/resources.rb index edbe883..6094665 100644 --- a/lib/ruby_vcloud_sdk/resources.rb +++ b/lib/ruby_vcloud_sdk/resources.rb @@ -4,14 +4,13 @@ class Resources attr_reader :cpu_available, :cpu_limit, :cpu_used, :memory_available, :memory_limit, :memory_used def initialize(cpu,memory) - @cpu_available = cpu.available_cores - @cpu_limit = cpu.limit_cores - @cpu_used = cpu.limit_cores.to_i - cpu.available_cores.to_i + @cpu_available = cpu.available_cores + @cpu_limit = cpu.limit_cores + @cpu_used = cpu.limit_cores.to_i - cpu.available_cores.to_i @memory_available = memory.available_mb - @memory_limit = memory.limit_mb - @memory_used = memory.limit_mb.to_i - memory.available_mb.to_i + @memory_limit = memory.limit_mb + @memory_used = memory.limit_mb.to_i - memory.available_mb.to_i end - end end From 75c990bc6493d4c74e54c56e09bae6a3119f7e25 Mon Sep 17 00:00:00 2001 From: Arnau Colominas Illa Date: Thu, 16 Jun 2016 19:13:48 +0200 Subject: [PATCH 25/37] README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4517144..b213601 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Copyright (c) VMware, Inc. -> Catalog -> Catalog Item -> OVF Directory -> RightRecord + -> Session -> Connection ## Object Model From a5b8abd4cd2c824870a69389b1b584c226ccc844 Mon Sep 17 00:00:00 2001 From: Arnau Colominas Illa Date: Fri, 17 Jun 2016 00:31:14 +0200 Subject: [PATCH 26/37] README --- README.md | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b213601..da58150 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,33 @@ Copyright (c) VMware, Inc. - Client -> VDC -> Vapp -> Vm -> Nic - -> Internal Disk - -> Disk - -> Vapp - -> Network - -> Network -> IpRanges - -> Disk -> Vm - -> Resources - -> Edge Gateway -> IpRanges - -> Vdc Storage Profile - -> Catalog -> Catalog Item - -> OVF Directory - -> RightRecord - -> Session -> Connection + Client |-> VDC |-> Vapp |-> Vm |-> Nic + | | | | + | | | |-> Internal Disk + | | | | + | | | |-> Disk + | | | | + | | | |-> Vapp + | | | + | | |-> Network + | | + | |-> Network |-> IpRanges + | | + | |-> Disk |-> Vm + | | + | |-> Resources + | | + | |-> Edge Gateway |-> IpRanges + | | + | |-> Vdc Storage Profile + | + |-> Catalog |-> Catalog Item + | | + | |-> OVF Directory + | + |-> RightRecord + | + |-> Session |-> Connection ## Object Model From c2b1a46fda269d4e8fecdc2df0697ff5d07961db Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Tue, 21 Jun 2016 12:32:07 +0200 Subject: [PATCH 27/37] afegida documentacio --- README.md | 12 +- lib/ruby_vcloud_sdk/catalog_item.rb | 40 ++++++- lib/ruby_vcloud_sdk/client.rb | 30 +++++ lib/ruby_vcloud_sdk/cpu.rb | 8 ++ lib/ruby_vcloud_sdk/memory.rb | 8 ++ lib/ruby_vcloud_sdk/network.rb | 14 ++- lib/ruby_vcloud_sdk/network_config.rb | 7 +- lib/ruby_vcloud_sdk/nic.rb | 21 +++- lib/ruby_vcloud_sdk/powerable.rb | 44 ++++++- lib/ruby_vcloud_sdk/resources.rb | 24 ++-- lib/ruby_vcloud_sdk/vapp.rb | 99 +++++++++++++++- lib/ruby_vcloud_sdk/vm.rb | 111 ++++++++++++++++-- .../xml/wrapper_classes/org_vdc_network.rb | 8 ++ lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 23 +++- 14 files changed, 407 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index da58150..45dc98a 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ Copyright (c) VMware, Inc. | | | | | |-> Network | | - | |-> Network |-> IpRanges + | |-> Network |-> IpRanges | | - | |-> Disk |-> Vm + | |-> Disk |-> Vm | | | |-> Resources | | @@ -696,12 +696,12 @@ Copyright (c) VMware, Inc. `client = VCloudSdk::Client.new(url, username, password)` Note that the parameter 'username' should be the VDC user_name@organization_name. For example, - the VDC user name is admin, the organization name is myorg, then the 'username' parameter + the VDC user name is admin, the organization name is myorg, then the 'username' parameter here should be admin@myorg. - + 2. Find the catalog where the vapp template is stored `catalog = client.find_catalog_by_name(catalog_name)` 3. Create vApp from that vapp template - `vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name)` - + `vapp = catalog.instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name)` + \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/catalog_item.rb b/lib/ruby_vcloud_sdk/catalog_item.rb index 5212989..eb79e43 100644 --- a/lib/ruby_vcloud_sdk/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/catalog_item.rb @@ -2,40 +2,78 @@ require_relative "infrastructure" module VCloudSdk - # Represents the calalog item in catalog. + + ############################################################################## + # This class represents a catalog item in catalog. + # It can be a vApp Template or media&other, + ############################################################################## class CatalogItem include Infrastructure + ############################################################################ + # Initializes a Catalog Item object associated with a vCloud Session and the + # the catalog item's link + # @param session [Session] The client's session + # @param link [String] The xml representation of catalog item + ############################################################################ def initialize(session, link) @session = session @link = link end + ############################################################################ + # Return the name of the Catalog Item object + # @return [String] The name of the catalog item + ############################################################################ def name entity_xml.entity[:name] end + ############################################################################ + # Return the identifier of the Catalog Item object + # @return [String] The identifier of the catalog item + ############################################################################ def id id = entity_xml.urn id.split(":")[3] end + ############################################################################ + # Return the description of the Catalog Item object + # @return [String] The description of the catalog item + ############################################################################ def description entity_xml.description end + ############################################################################ + # Return the vApp template id of the Catalog Item object + # @return [String] The vApp template id of the catalog item + ############################################################################ def vapp_template_id entity_xml.entity[:href].split("/")[5] end + ############################################################################ + # Return the type of the Catalog Item object. It can be: + # @return [String] The type of the catalog item + ############################################################################ def type entity_xml.entity[:type] end + ############################################################################ + # Return the vCloud href of the Catalog Item object. + # @return [String] The href of the catalog item + ############################################################################ def href entity_xml.entity[:href] end + ############################################################################ + # Return the date of creation of the Catalog Item object. + # @return [String] The creation date of the catalog item + ############################################################################ def date entity_xml.date end diff --git a/lib/ruby_vcloud_sdk/client.rb b/lib/ruby_vcloud_sdk/client.rb index 87b1cea..28ea90f 100644 --- a/lib/ruby_vcloud_sdk/client.rb +++ b/lib/ruby_vcloud_sdk/client.rb @@ -6,6 +6,10 @@ module VCloudSdk + ################################################################################ + # This class represents a vCloud connection and an associated client + # The connection is associated to the vCloud API. + ################################################################################ class Client include Infrastructure @@ -15,6 +19,17 @@ class Client :catalog_exists?, :find_catalog_by_name, :vdc_exists? + ############################################################################## + # Initializes the Client and creates a Session to vCloud API. + # @param url [String] The url of vCloud host [http://api.example.com] + # @param username [String] The username of vCloud account [username@org_name] + # @param password [String] The password for vCloud user. + # @param options [Hash] The options (RETRIES, TIME_LIMIT_SEC,DELAY) for + # the session.Use 'options = {}' for default options. + # See session.rb for more info. + # @param logger [Logger] Optional.The logger for the connection. It manages + # response messages.By default STDOUT + ############################################################################## def initialize(url, username, password, options = {}, logger = nil) @url = url Config.configure(logger: logger || Logger.new(STDOUT)) @@ -23,6 +38,12 @@ def initialize(url, username, password, options = {}, logger = nil) Config.logger.info("Successfully connected.") end + ############################################################################## + # Creates a catalog for the organization. + # @param name [String] The catalog's name. + # @param description [String] The catalog's description. + # @return [Catalog] The new created catalog. + ############################################################################## def create_catalog(name, description = "") catalog = Xml::WrapperFactory.create_instance("AdminCatalog") catalog.name = name @@ -33,6 +54,11 @@ def create_catalog(name, description = "") find_catalog_by_name name end + ############################################################################## + # Deletes the catalog identified with "name" for the organization. + # @param name [String] The catalog's name to delete + # @return [Catalog] The deleted catalog + ############################################################################## def delete_catalog_by_name(name) catalog = find_catalog_by_name(name) catalog.delete_all_items @@ -40,6 +66,10 @@ def delete_catalog_by_name(name) self end + ############################################################################## + # Returns Right Records. + # @return [Right Record] an array of Right Record. + ############################################################################## def right_records right_records = connection.get("/api/admin/rights/query").right_records diff --git a/lib/ruby_vcloud_sdk/cpu.rb b/lib/ruby_vcloud_sdk/cpu.rb index 040301d..0f4c543 100644 --- a/lib/ruby_vcloud_sdk/cpu.rb +++ b/lib/ruby_vcloud_sdk/cpu.rb @@ -1,8 +1,16 @@ module VCloudSdk + ################################################################################ + # This class represents the CPU resource of the Virtual Data Center. + ################################################################################ class CPU attr_reader :available_cores, :limit_cores + ############################################################################## + # Initialize a CPU resource of the VDC. + # @param available_cores [String] The cores not used in the VDC. + # @param limit_cores [String] The maximum cores to use in the VDC. + ############################################################################## def initialize(available_cores,limit_cores) @available_cores = available_cores @limit_cores = limit_cores diff --git a/lib/ruby_vcloud_sdk/memory.rb b/lib/ruby_vcloud_sdk/memory.rb index 36e9a52..e9b5522 100644 --- a/lib/ruby_vcloud_sdk/memory.rb +++ b/lib/ruby_vcloud_sdk/memory.rb @@ -1,8 +1,16 @@ module VCloudSdk + ################################################################################ + # This class represents the Memory resource of the Virtual Data Center. + ################################################################################ class Memory attr_reader :available_mb, :limit_mb + ############################################################################## + # Initialize a Memory resource of the VDC. + # @param available_mb [String] The amount memory not used in the VDC in MB + # @param limit_mb [String] The amount memory to use in the VDC in MB + ############################################################################## def initialize(available_mb,limit_mb) @available_mb = available_mb @limit_mb = limit_mb diff --git a/lib/ruby_vcloud_sdk/network.rb b/lib/ruby_vcloud_sdk/network.rb index 865b37e..25544b5 100644 --- a/lib/ruby_vcloud_sdk/network.rb +++ b/lib/ruby_vcloud_sdk/network.rb @@ -7,12 +7,24 @@ class Network extend Forwardable def_delegator :entity_xml, :name - + def initialize(session, link) @session = session @link = link end + def id + @link.href.split("/")[5] + end + + def description + entity_xml.description + end + + def fence_mode + entity_xml.fence_mode + end + def href @link end diff --git a/lib/ruby_vcloud_sdk/network_config.rb b/lib/ruby_vcloud_sdk/network_config.rb index 591b5d8..64d8996 100644 --- a/lib/ruby_vcloud_sdk/network_config.rb +++ b/lib/ruby_vcloud_sdk/network_config.rb @@ -7,9 +7,10 @@ def initialize( network_name, vapp_net_name = nil, fence_mode = Xml::FENCE_MODES[:BRIDGED]) - @network_name = network_name - @vapp_net_name = vapp_net_name - @fence_mode = fence_mode + + @network_name = network_name + @vapp_net_name = vapp_net_name + @fence_mode = fence_mode end end diff --git a/lib/ruby_vcloud_sdk/nic.rb b/lib/ruby_vcloud_sdk/nic.rb index ab896fb..1319dd2 100644 --- a/lib/ruby_vcloud_sdk/nic.rb +++ b/lib/ruby_vcloud_sdk/nic.rb @@ -1,4 +1,9 @@ module VCloudSdk + + ################################################################################ + # This class represents a NIC (Network Interface Card). + # The NIC are attached to VM and connected to Networks. + ################################################################################ class NIC extend Forwardable @@ -8,15 +13,29 @@ class NIC attr_reader :is_primary + ############################################################################## + # Initialize a NIC. + # @param entity_xml [String] The XML representation for the NIC. + # @param is_primary [Boolean] It defines if the NIC is the main or not. + ############################################################################## def initialize(entity_xml, is_primary) - @entity_xml = entity_xml + @entity_xml = entity_xml @is_primary = is_primary end + ############################################################################## + # Retrun the network connection index. + # @return [Integer] The newtork connection index. + ############################################################################## def network_connection_index @entity_xml.network_connection_index.to_i end + ############################################################################## + # Retuns the NIC status. + # @return [Boolean] Return "True" if the NIC is connected + # "False" otherwise + ############################################################################## def is_connected @entity_xml.is_connected == "true" end diff --git a/lib/ruby_vcloud_sdk/powerable.rb b/lib/ruby_vcloud_sdk/powerable.rb index 2e2157a..38e62c0 100644 --- a/lib/ruby_vcloud_sdk/powerable.rb +++ b/lib/ruby_vcloud_sdk/powerable.rb @@ -1,6 +1,25 @@ module VCloudSdk - # Shared functions by classes VM and VApp + + ############################################################################################### + # This module defines the shared functions by classes VM and VApp + # We can retrieve the status, power on, power off, reboots, resets and suspend any VM or VApp + ############################################################################################### module Powerable + + ############################################################################################# + # Returns the status of the vApp or VM + # @return [String] The vApp or VM status: + # - FAILED_CREATION. + # - UNRESOLVED. + # - RESOLVED. + # - SUSPENDED. + # - POWERED_ON. + # - WAITING_FOR_INPUT. + # - UNKNOWN. + # - UNRECOGNIZED. + # - POWERED_OFF. + # - other. + ############################################################################################# def status status_code = entity_xml[:status].to_i Xml::RESOURCE_ENTITY_STATUS.each_pair do |k, v| @@ -11,7 +30,10 @@ def status "Fail to find corresponding status for code '#{status_code}'" end - # Power on VApp or VM + ############################################################################################# + # Power on vApp or VM + # @return [vApp] or [VM] Returns the object + ############################################################################################# def power_on target = entity_xml class_name = self.class.name.split("::").last @@ -34,7 +56,10 @@ def power_on self end - # Power off VApp or VM + ############################################################################################# + # Power off vApp or VM + # @return [vApp] or [VM] Returns the object + ############################################################################################# def power_off target = entity_xml class_name = self.class.name.split("::").last @@ -62,6 +87,10 @@ def power_off self end + ############################################################################################# + # Reboots vApp or VM + # @return [vApp] or [VM] Returns the object + ############################################################################################# def reboot target = entity_xml class_name = self.class.name.split("::").last @@ -81,6 +110,10 @@ def reboot end + ############################################################################################# + # Resets vApp or VM + # @return [vApp] or [VM] Returns the object + ############################################################################################# def reset target = entity_xml class_name = self.class.name.split("::").last @@ -97,9 +130,12 @@ def reset task = monitor_task task, @session.time_limit[:power_on] Config.logger.info "#{class_name} #{target.name} is reseted." self - end + ############################################################################################# + # Suspends vApp or VM + # @return [vApp] or [VM] Returns the object + ############################################################################################# def suspend target = entity_xml class_name = self.class.name.split("::").last diff --git a/lib/ruby_vcloud_sdk/resources.rb b/lib/ruby_vcloud_sdk/resources.rb index 6094665..b630339 100644 --- a/lib/ruby_vcloud_sdk/resources.rb +++ b/lib/ruby_vcloud_sdk/resources.rb @@ -1,16 +1,24 @@ module VCloudSdk + ################################################################################ + # This class represents the resource of the Virtual Data Center. + ################################################################################ class Resources - attr_reader :cpu_available, :cpu_limit, :cpu_used, :memory_available, :memory_limit, :memory_used - + attr_reader :cpu_available, :cpu_limit, :cpu_used + attr_reader :memory_available, :memory_limit, :memory_used + ############################################################################## + # Initialize a Resource for the VDC. + # @param cpu [CPU] The CPU resource of the VDC. + # @param memory [Memory] The Memory resource of the VDC. + ############################################################################## def initialize(cpu,memory) - @cpu_available = cpu.available_cores - @cpu_limit = cpu.limit_cores - @cpu_used = cpu.limit_cores.to_i - cpu.available_cores.to_i + @cpu_available = cpu.available_cores + @cpu_limit = cpu.limit_cores + @cpu_used = cpu.limit_cores.to_i - cpu.available_cores.to_i - @memory_available = memory.available_mb - @memory_limit = memory.limit_mb - @memory_used = memory.limit_mb.to_i - memory.available_mb.to_i + @memory_available = memory.available_mb + @memory_limit = memory.limit_mb + @memory_used = memory.limit_mb.to_i - memory.available_mb.to_i end end end diff --git a/lib/ruby_vcloud_sdk/vapp.rb b/lib/ruby_vcloud_sdk/vapp.rb index 7002418..c405b99 100644 --- a/lib/ruby_vcloud_sdk/vapp.rb +++ b/lib/ruby_vcloud_sdk/vapp.rb @@ -4,24 +4,45 @@ require_relative "network_config" module VCloudSdk + + ###################################################################################### + # This class represents a vApp of the Virtual Data Center. + ###################################################################################### class VApp include Infrastructure include Powerable + #################################################################################### + # Initializes a vApp object associated with a vCloud Session and the vApp's link. + # @param session [Session] The client's session + # @param link [String] The XML representation of the vApp + #################################################################################### def initialize(session, link) @session = session @link = link end + #################################################################################### + # Returns the identifier of the vApp (uuid) + # @return [String] The identifier of the vApp + #################################################################################### def id id = entity_xml.urn id.split(":")[3] end + #################################################################################### + # Returns the name of the vApp + # @return [String] The name of the vApp + #################################################################################### def name entity_xml.name end + #################################################################################### + # Deletes the vApp in the VDC. + # To delete the vApp, it must be on power off state. + #################################################################################### def delete vapp = entity_xml vapp_name = name @@ -44,10 +65,17 @@ def delete "Fail to delete vApp #{vapp_name}" end + #################################################################################### + # Recompose the vApp with a vApp template + # @param catalog_name [String] The name of Catalog + # @param template_name [String] The name of vApp Template + # @return [VApp] The recomposed vApp + #################################################################################### def recompose_from_vapp_template(catalog_name, template_name) recompose_vapp_link = get_recompose_vapp_link - Config.logger.info "Recomposing from template '#{template_name}' in catalog '#{catalog_name}'." + Config.logger.info "Recomposing from template '#{template_name}' in catalog + '#{catalog_name}'." catalog = find_catalog_by_name catalog_name template = catalog.find_vapp_template_by_name template_name @@ -60,24 +88,41 @@ def recompose_from_vapp_template(catalog_name, template_name) self end + #################################################################################### + # Returns array of Vm objects associated with vApp + # @return [VApp] an array of vApp + #################################################################################### def vms entity_xml.vms.map do |vm| VCloudSdk::VM.new(@session, vm.href) end end + #################################################################################### + # Returns array with the names of the Vms associated with vApp + # @return [String] an array of VM's names + #################################################################################### def list_vms entity_xml.vms.map do |vm| vm.name end end + #################################################################################### + # Returns if the VM identified by name exists. + # @return [Boolean] True => the VM exists. + # False => otherwise. + #################################################################################### def vm_exists?(name) entity_xml.vms.any? do |vm| vm.name == name end end + #################################################################################### + # Returns the VM identified by name. + # @return [Vm] The VM identified by name, if it exists. + #################################################################################### def find_vm_by_name(name) entity_xml.vms.each do |vm| return VCloudSdk::VM.new(@session, vm.href) if vm.name == name @@ -86,6 +131,10 @@ def find_vm_by_name(name) fail ObjectNotFoundError, "VM '#{name}' is not found" end + #################################################################################### + # Deletes the VM identified by name. + # @return [Vm] The VM deleted. + #################################################################################### def remove_vm_by_name(vm_name) target_vm = find_vm_by_name vm_name recompose_vapp_link = get_recompose_vapp_link @@ -98,6 +147,10 @@ def remove_vm_by_name(vm_name) self end + #################################################################################### + # Returns the names of networks asociated with the vApp. + # @return [String] an array of network's names + #################################################################################### def list_networks entity_xml .network_config_section @@ -105,6 +158,19 @@ def list_networks .map { |network_config| network_config.network_name } end + #################################################################################### + # Adds a network to the vApp. + # @param network_name [String] The name of network in vdc org to add to vapp. + # @param vapp_net_name [String] Optional. What to name the network of the vapp. + # Default to network_name + # @param fence_mode [String] Optional. Fencing allows identical virtual + # machines in different vApps to be powered on + # without conflict by isolating the MAC and IP + # addresses of the virtual machines. Available + # options are "BRIDGED","ISOLATED" and "NAT_ROUTED" + # Default to "BRIDGED". + # @return [VApp] The vApp + #################################################################################### def add_network_by_name( network_name, vapp_net_name = nil, @@ -128,6 +194,11 @@ def add_network_by_name( self end + #################################################################################### + # Deletes the network identified with name. + # To delete the network, it cannot be used by any VM's. + # @return [VApp] The vApp. + #################################################################################### def delete_network_by_name(name) unless list_networks.any? { |network_name| network_name == name } fail ObjectNotFoundError, @@ -150,7 +221,16 @@ def delete_network_by_name(name) self end - def create_snapshot(snapshot_hash) + #################################################################################### + # Creates a snapshot of the vApp. + # @param snapshot_name [String] Optional.The name of the snapshot + #################################################################################### + def create_snapshot(snapshot_name) + new_snapshot_name = snapshot_name.nil? ? "#{name} Snapshot" : snapshot_name + options = { + :name => new_snapshot_name, + :description => "Snapshot of vApp #{name}" + } target = entity_xml create_snapshot_link = target.create_snapshot_link params = Xml::WrapperFactory.create_instance("CreateSnapshotParams") @@ -161,17 +241,22 @@ def create_snapshot(snapshot_hash) Config.logger.error "vApp #{name} has created a snapshot" end + #################################################################################### + # Deletes ALL the snapshots of the vApp. + #################################################################################### def remove_snapshot target = entity_xml remove_snapshot_link = target.remove_snapshot_link - + Config.logger.info "Removing all snapshots on vApp #{name}." task = connection.post(target.remove_snapshot_link.href,nil) monitor_task(task) - Config.logger.error "vApp #{name} has removed all snapshots" - + Config.logger.error "vApp #{name} has removed all snapshots" end + #################################################################################### + # Revert the LAST snapshot of the vApp created. + #################################################################################### def revert_snapshot target = entity_xml revert_snapshot_link = target.revert_snapshot_link @@ -219,6 +304,7 @@ def network_config_param( network, vapp_net_name, fence_mode) + puts "hola" Xml::WrapperFactory.create_instance("NetworkConfig").tap do |params| network_entity_xml = connection.get(network.href) params.ip_scope.tap do |ip_scope| @@ -226,7 +312,8 @@ def network_config_param( ip_scope.is_inherited = net_ip_scope.is_inherited? ip_scope.gateway = net_ip_scope.gateway ip_scope.netmask = net_ip_scope.netmask - ip_scope.ip_ranges.add_ranges(net_ip_scope.ip_ranges.ranges) + puts "hola2" + ip_scope.ip_ranges.add_ranges(net_ip_scope.ip_ranges.ranges) if !net_ip_scope.ip_ranges.nil? ##per poder afegir xarxes amb DHCP que no tenen POOL IP STATIC end params.fence_mode = fence_mode params.parent_network["name"] = network_entity_xml["name"] diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index 2c8845d..33e94c7 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -5,6 +5,10 @@ require_relative "nic" module VCloudSdk + + ###################################################################################### + # This class represents a VM belonging a vApp of the Virtual Data Center. + ###################################################################################### class VM include Infrastructure include Powerable @@ -12,21 +16,37 @@ class VM extend Forwardable def_delegator :entity_xml, :name + #################################################################################### + # Initializes a VM object associated with a vCloud Session and the VMs link. + # @param session [Session] The client's session + # @param link [String] The XML representation of the VM + #################################################################################### def initialize(session, link) @session = session @link = link end + #################################################################################### + # Returns the identifier of the VM (uuid) + # @return [String] The identifier of the VM + #################################################################################### def id id = entity_xml.urn id.split(":")[3] end + #################################################################################### + # Returns the vCloud link of the VM + # @return [String] The vCloud link of the VM + #################################################################################### def href @link end - # returns size of memory in megabytes + #################################################################################### + # Returns the memory of the VM + # @return [String] The memory in MB of the VM + #################################################################################### def memory m = entity_xml .hardware_section @@ -41,7 +61,12 @@ def memory memory_mb end - # sets size of memory in megabytes + + #################################################################################### + # Modifies the memory size of the VM. + # @param size [String] The new memory size in MB. + # @throw + #################################################################################### def memory=(size) fail(CloudError, "Invalid vm memory size #{size}MB") if size <= 0 @@ -60,7 +85,12 @@ def memory=(size) self end - # returns number of virtual cpus of VM + + #################################################################################### + # Returns the number of virtual cpus of the VM. + # @return [Integer] The number of virtual cpus of the VM + # @throw + #################################################################################### def vcpu cpus = entity_xml .hardware_section @@ -72,7 +102,11 @@ def vcpu cpus.to_i end - # sets number of virtual cpus of VM + #################################################################################### + # Modifies the number of virtual cpus of the VM. + # @param count [String] The new number of virtual cpus. + # @throw + #################################################################################### def vcpu=(count) fail(CloudError, "Invalid virtual CPU count #{count}") if count <= 0 @@ -91,12 +125,34 @@ def vcpu=(count) self end - def ip_address + def reconfigure(options) + + puts entity_xml + + puts "------------------------" + + payload = entity_xml + payload.name = options[:name] + payload.description = options[:description] + payload.change_cpu_count(options[:vcpu]) + payload.change_memory(options[:memory]) + + puts payload + + #task = connection.post(payload.reconfigure_link.href, + # payload, + # Xml::MEDIA_TYPE[:VM]) + #monitor_task(task) + self + end + + def ip_address entity_xml.ip_address end def list_networks + entity_xml .network_connection_section .network_connections @@ -116,6 +172,23 @@ def nics end end + def find_nic_by_mac(mac) + primary_index = entity_xml + .network_connection_section + .primary_network_connection_index + net = entity_xml + .network_connection_section + .network_connections.find do |n| + n.mac_address == mac.to_s + end + if net + return VCloudSdk::NIC.new(net,net.network_connection_index == primary_index) + else + fail(CloudError, + "No NIC found with MAC #{mac}") + end + end + def independent_disks hardware_section = entity_xml.hardware_section disks = [] @@ -210,7 +283,9 @@ def eject_media(catalog_name, media_file_name) def add_nic( network_name, ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:POOL], - ip = nil) + mac_address = nil, + ip = nil) + fail CloudError, "Invalid IP_ADDRESSING_MODE '#{ip_addressing_mode}'" unless Xml::IP_ADDRESSING_MODE .each_value @@ -224,10 +299,9 @@ def add_nic( "Network #{network_name} is not added to parent VApp #{vapp.name}" unless vapp .list_networks .any? { |n| n == network_name } - payload = entity_xml fail CloudError, - "VM #{name} is powered-on and cannot add NIC." if is_status?(payload, :POWERED_ON) + "VM #{name} is powered-on and vmware tools are not installed, cannot add NIC." if is_status?(payload, :POWERED_ON) && !self.vmtools? ##si està power-on i no té les vmware tools, error nic_index = add_nic_index @@ -242,7 +316,6 @@ def add_nic( network_name, ip_addressing_mode, ip)) - # Connect NIC payload .network_connection_section @@ -252,6 +325,14 @@ def add_nic( ip_addressing_mode, ip)) + # Si li subministrem una mac, li afegeix la que li diem + if mac_address + payload + .network_connection_section + .network_connections.last + .mac_address = mac_address + end + task = connection.post(payload.reconfigure_link.href, payload, Xml::MEDIA_TYPE[:VM]) @@ -272,16 +353,26 @@ def delete_nics(*nics) self end + def vmtools_version + entity_xml.vm_tools + end + + def vmtools? + #puts entity_xml + !entity_xml.vm_tools.nil? + end + def install_vmtools Config.logger.info( "Installing VMware tools on #{name} ...") - task = connection.put(entity_xml.install_vmtools_link.href,nil) + task = connection.post(entity_xml.install_vmtools_link.href,nil) monitor_task(task) self end def product_section_properties + puts entity_xml product_section = entity_xml.product_section return [] if product_section.nil? diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb index 9b38ac0..bf2477b 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb @@ -10,6 +10,14 @@ def allocated_addresses_link { type: MEDIA_TYPE[:ALLOCATED_NETWORK_IPS] }, true).first end + + def description + get_nodes("Description").first.content + end + + def fence_mode + get_nodes("FenceMode").first.content + end end end end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index 64f442a..72e2cd7 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -51,8 +51,20 @@ def description=(value) value end + def vm_tools + get_nodes("VMWareTools").first["version"] + end + def ip_address - ip = get_nodes("IpAddress").first.content + #puts get_nodes("IpAddress").first.content + #puts get_nodes("NetworkConnection") + ips = [] + get_nodes("NetworkConnection").each do |ip| + ips << ip.ip_address + end + ips.pop #elimina l'ultim element, que es un nil + return ips + #get_nodes("IpAddress").first.content if !get_nodes("IpAddress").first.nil? end def reconfigure_link @@ -72,7 +84,7 @@ def install_vmtools_link { rel: "installVmwareTools" }, true).first end - + def def eject_media_link @@ -152,6 +164,13 @@ def change_memory(mb) item.set_rasd("VirtualQuantity", mb) end + def change_name(name) + @logger.debug("Updating name on vm #{name} to #{name} ") + item = hardware_section.cpu + item.set_rasd("VirtualQuantity", quantity) + end + + # Deletes NIC from VM. Accepts variable number of arguments for NICs. # To delete all NICs from VM use the splat operator # ex: delete_nic(vm, *vm.hardware_section.nics) From 7ad13e0b729459624a6c9328d6c24b134e545a3c Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Thu, 23 Jun 2016 12:26:58 +0200 Subject: [PATCH 28/37] Added shutdown VM/VAPP, find_nic_by_mac --- lib/ruby_vcloud_sdk/network.rb | 34 +++++++++++++++++++ lib/ruby_vcloud_sdk/powerable.rb | 28 +++++++++++++++ lib/ruby_vcloud_sdk/vapp.rb | 10 +++--- lib/ruby_vcloud_sdk/vm.rb | 28 ++++++++++----- lib/ruby_vcloud_sdk/xml/wrapper.rb | 6 ++++ lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 2 +- 6 files changed, 92 insertions(+), 16 deletions(-) diff --git a/lib/ruby_vcloud_sdk/network.rb b/lib/ruby_vcloud_sdk/network.rb index 25544b5..0d94dcd 100644 --- a/lib/ruby_vcloud_sdk/network.rb +++ b/lib/ruby_vcloud_sdk/network.rb @@ -2,33 +2,63 @@ require_relative "ip_ranges" module VCloudSdk + + ###################################################################################### + # This class represents a virtual Network in the virtual data center. + ###################################################################################### class Network include Infrastructure extend Forwardable def_delegator :entity_xml, :name + #################################################################################### + # Initializes a vApp object associated with a vCloud Session and the Network's link. + # @param session [Session] The client's session. + # @param link [String] The vCloud link of the network. + #################################################################################### def initialize(session, link) @session = session @link = link end + #################################################################################### + # Returns the identifier of the Network (uuid). + # @return [String] The identifier of the Network. + #################################################################################### def id @link.href.split("/")[5] end + #################################################################################### + # Returns the description of the Network. + # @return [String] The identifier of the Network. + #################################################################################### def description entity_xml.description end + #################################################################################### + # Returns the fence mode of the Network. + # @return [String] The fence mode of the Network. + #################################################################################### def fence_mode entity_xml.fence_mode end + #################################################################################### + # Returns the vCloud link of the Network. + # @return [String] The vCloud link of the Network. + #################################################################################### def href + #puts entity_xml @link end + #################################################################################### + # Returns array of IpRanges objects of the Network + # @return [IpRanges] an array of IpRanges + #################################################################################### def ip_ranges entity_xml .ip_scope @@ -39,6 +69,10 @@ def ip_ranges end end + #################################################################################### + # Returns the list of allocated ips of the Network + # @return [String] an array of allocated ip addresses + #################################################################################### def allocated_ips allocated_addresses = connection.get(entity_xml.allocated_addresses_link) allocated_addresses.ip_addresses.map do |i| diff --git a/lib/ruby_vcloud_sdk/powerable.rb b/lib/ruby_vcloud_sdk/powerable.rb index 38e62c0..5a79d87 100644 --- a/lib/ruby_vcloud_sdk/powerable.rb +++ b/lib/ruby_vcloud_sdk/powerable.rb @@ -87,6 +87,34 @@ def power_off self end + def shutdown + target = entity_xml + class_name = self.class.name.split("::").last + Config.logger.debug "#{class_name} status: #{target[:status]}" + if is_status?(target, :SUSPENDED) + error_msg = "#{class_name} #{target.name} suspended, discard state before powering off." + fail class_name == "VApp" ? VappSuspendedError : VmSuspendedError, + error_msg + end + if is_status?(target, :POWERED_OFF) + Config.logger.info "#{class_name} #{target.name} is already powered off." + return + end + + shutdown_link = target.shutdown_link + unless shutdown_link + fail CloudError, "#{class_name} #{target.name} is not in a state that could be powered off." + end + + task = connection.post(shutdown_link.href, nil) + monitor_task task, @session.time_limit[:power_off] + Config.logger.info "#{class_name} #{target.name} is powered off." + + undeploy(target, class_name) + self + + end + ############################################################################################# # Reboots vApp or VM # @return [vApp] or [VM] Returns the object diff --git a/lib/ruby_vcloud_sdk/vapp.rb b/lib/ruby_vcloud_sdk/vapp.rb index c405b99..acae095 100644 --- a/lib/ruby_vcloud_sdk/vapp.rb +++ b/lib/ruby_vcloud_sdk/vapp.rb @@ -15,7 +15,7 @@ class VApp #################################################################################### # Initializes a vApp object associated with a vCloud Session and the vApp's link. # @param session [Session] The client's session - # @param link [String] The XML representation of the vApp + # @param link [String] The vCloud link of the vApp #################################################################################### def initialize(session, link) @session = session @@ -255,7 +255,7 @@ def remove_snapshot end #################################################################################### - # Revert the LAST snapshot of the vApp created. + # Revert the LAST snapshot created in the vApp. #################################################################################### def revert_snapshot target = entity_xml @@ -303,16 +303,14 @@ def remove_vm_param(vm) def network_config_param( network, vapp_net_name, - fence_mode) - puts "hola" + fence_mode) Xml::WrapperFactory.create_instance("NetworkConfig").tap do |params| network_entity_xml = connection.get(network.href) params.ip_scope.tap do |ip_scope| net_ip_scope = network_entity_xml.ip_scope ip_scope.is_inherited = net_ip_scope.is_inherited? ip_scope.gateway = net_ip_scope.gateway - ip_scope.netmask = net_ip_scope.netmask - puts "hola2" + ip_scope.netmask = net_ip_scope.netmask ip_scope.ip_ranges.add_ranges(net_ip_scope.ip_ranges.ranges) if !net_ip_scope.ip_ranges.nil? ##per poder afegir xarxes amb DHCP que no tenen POOL IP STATIC end params.fence_mode = fence_mode diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index 33e94c7..62acafa 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -61,7 +61,6 @@ def memory memory_mb end - #################################################################################### # Modifies the memory size of the VM. # @param size [String] The new memory size in MB. @@ -104,7 +103,7 @@ def vcpu #################################################################################### # Modifies the number of virtual cpus of the VM. - # @param count [String] The new number of virtual cpus. + # @param count [Integer] The new number of virtual cpus. # @throw #################################################################################### def vcpu=(count) @@ -125,11 +124,21 @@ def vcpu=(count) self end + def name=(name) + payload = entity_xml + payload.name = name + task = connection.post(payload.reconfigure_link.href, + payload, + Xml::MEDIA_TYPE[:VM]) + monitor_task(task) + self + end + def reconfigure(options) - puts entity_xml + #puts entity_xml - puts "------------------------" + #puts "------------------------" payload = entity_xml payload.name = options[:name] @@ -137,16 +146,17 @@ def reconfigure(options) payload.change_cpu_count(options[:vcpu]) payload.change_memory(options[:memory]) - puts payload + #puts payload #task = connection.post(payload.reconfigure_link.href, # payload, # Xml::MEDIA_TYPE[:VM]) #monitor_task(task) - self + #self end - def ip_address + def ip_address + #puts entity_xml entity_xml.ip_address end @@ -185,7 +195,7 @@ def find_nic_by_mac(mac) return VCloudSdk::NIC.new(net,net.network_connection_index == primary_index) else fail(CloudError, - "No NIC found with MAC #{mac}") + "No NIC found with MAC #{mac} in VM #{name}") end end @@ -372,7 +382,7 @@ def install_vmtools def product_section_properties - puts entity_xml + #puts entity_xml product_section = entity_xml.product_section return [] if product_section.nil? diff --git a/lib/ruby_vcloud_sdk/xml/wrapper.rb b/lib/ruby_vcloud_sdk/xml/wrapper.rb index a14d9b7..08952cb 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper.rb @@ -147,6 +147,12 @@ def power_off_link true).first end + def shutdown_link + get_nodes(XML_TYPE[:LINK], + { rel: "power:shutdown"}, + true).first + end + def suspend_link get_nodes(XML_TYPE[:LINK], { rel: "power:suspend"}, diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index 72e2cd7..2134f42 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -62,7 +62,7 @@ def ip_address get_nodes("NetworkConnection").each do |ip| ips << ip.ip_address end - ips.pop #elimina l'ultim element, que es un nil + ips.pop if ips.length > 1 #elimina l'ultim element, que es un nil, sempre i quan tingui mes d'una ip return ips #get_nodes("IpAddress").first.content if !get_nodes("IpAddress").first.nil? end From 8776e8cd4f9272637136b71c38f0fd0ba63b96cf Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Tue, 28 Jun 2016 09:50:41 +0200 Subject: [PATCH 29/37] working in reconfigure --- lib/ruby_vcloud_sdk/vdc.rb | 10 +- lib/ruby_vcloud_sdk/vm.rb | 129 +++++++++++++----- lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 5 + 3 files changed, 108 insertions(+), 36 deletions(-) diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb index be33afe..1a86ad2 100644 --- a/lib/ruby_vcloud_sdk/vdc.rb +++ b/lib/ruby_vcloud_sdk/vdc.rb @@ -150,12 +150,18 @@ def disk_exists?(name) end end + #################################################################################### + # Creates a disk. + # @param name [String] The disk's name. + # @param capacity [Integer] The capacity in MB of the disk. + # @return [Disk] The object created.disk_create_param + #################################################################################### def create_disk( name, capacity, vm = nil, bus_type = "scsi", - bus_sub_type = "lsilogic") + bus_sub_type = "lsilogic") fail(CloudError, "Invalid size in MB #{capacity}") if capacity <= 0 @@ -174,7 +180,7 @@ def create_disk( disk = connection.post(entity_xml.add_disk_link, disk_create_params(name, capacity, bus_type, bus_sub_type, vm), - Xml::MEDIA_TYPE[:DISK_CREATE_PARAMS]) + Xml::MEDIA_TYPE[:DISK_CREATE_PARAMS]) wait_for_running_tasks(disk, "Disk #{name}") diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index 62acafa..d61267f 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -6,9 +6,9 @@ module VCloudSdk - ###################################################################################### + ################################################################################################# # This class represents a VM belonging a vApp of the Virtual Data Center. - ###################################################################################### + ################################################################################################# class VM include Infrastructure include Powerable @@ -16,37 +16,37 @@ class VM extend Forwardable def_delegator :entity_xml, :name - #################################################################################### + ############################################################################################### # Initializes a VM object associated with a vCloud Session and the VMs link. # @param session [Session] The client's session # @param link [String] The XML representation of the VM - #################################################################################### + ############################################################################################### def initialize(session, link) @session = session @link = link end - #################################################################################### + ############################################################################################### # Returns the identifier of the VM (uuid) # @return [String] The identifier of the VM - #################################################################################### + ############################################################################################### def id id = entity_xml.urn id.split(":")[3] end - #################################################################################### + ############################################################################################### # Returns the vCloud link of the VM # @return [String] The vCloud link of the VM - #################################################################################### + ############################################################################################### def href @link end - #################################################################################### + ############################################################################################### # Returns the memory of the VM # @return [String] The memory in MB of the VM - #################################################################################### + ############################################################################################### def memory m = entity_xml .hardware_section @@ -61,11 +61,11 @@ def memory memory_mb end - #################################################################################### + ############################################################################################### # Modifies the memory size of the VM. # @param size [String] The new memory size in MB. # @throw - #################################################################################### + ############################################################################################### def memory=(size) fail(CloudError, "Invalid vm memory size #{size}MB") if size <= 0 @@ -85,11 +85,11 @@ def memory=(size) end - #################################################################################### + ############################################################################################### # Returns the number of virtual cpus of the VM. # @return [Integer] The number of virtual cpus of the VM # @throw - #################################################################################### + ############################################################################################### def vcpu cpus = entity_xml .hardware_section @@ -101,11 +101,11 @@ def vcpu cpus.to_i end - #################################################################################### + ############################################################################################### # Modifies the number of virtual cpus of the VM. # @param count [Integer] The new number of virtual cpus. # @throw - #################################################################################### + ############################################################################################### def vcpu=(count) fail(CloudError, "Invalid virtual CPU count #{count}") if count <= 0 @@ -134,35 +134,86 @@ def name=(name) self end - def reconfigure(options) - - #puts entity_xml - - #puts "------------------------" + ############################################################################################### + # Reconfigures the VM with the parameters passed in a hash. + # @param options [Hash] The parameters of the VM. + # :name [String] The name of the VM + # :description [String] The description of the VM + # :vcpu [String] The value for number of CPU + # :memory [String] The value for memory in MB + # :nics [Hash] Optional.Array of Hashes representing the nics + # to attach to VM + # :network_name [String] The network to attach nic + # :mac [String] Optional. The MAC of the nic + # :vapp_name [String] The name of the vApp + # @return [VM] + ############################################################################################### + def reconfigure(options) payload = entity_xml - payload.name = options[:name] - payload.description = options[:description] - payload.change_cpu_count(options[:vcpu]) - payload.change_memory(options[:memory]) + payload.name = options[:name] if !options[:name].nil? + payload.description = options[:description] if !options[:name].nil? + payload.change_cpu_count(options[:vcpu]) if !options[:name].nil? + payload.change_memory(options[:memory]) if !options[:name].nil? + + if options[:nics] !=[] + #ADD NICS + options[:nics].each { |nic| + + nic_index = add_nic_index + network_name = nic[:network_name] + ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:POOL] + ip = "" + mac_address = nic[:mac] + + # Add Network to vapp + vapp.add_network_by_name(network_name) if !vapp.list_networks.include? "#{network_name}" + # Add NIC + payload.hardware_section.add_item(nic_params(payload.hardware_section, + nic_index, + network_name, + ip_addressing_mode, + ip)) + # Connect NIC + payload.network_connection_section.add_item(network_connection_params(payload.network_connection_section, + nic_index, + network_name, + ip_addressing_mode, + ip)) + #Add the mac address passed + if mac_address + payload + .network_connection_section + .network_connections.last + .mac_address = mac_address + end + + #STDERR.puts payload + } + end + + #DELETE NICS + nics.each{ |nc| + if options[:nic].nil? or !options[:nic][:mac].include? "#{nc.mac_address}" + payload.delete_nics(nc) + end + } + #puts payload - #task = connection.post(payload.reconfigure_link.href, - # payload, - # Xml::MEDIA_TYPE[:VM]) - #monitor_task(task) - #self + task = connection.post(payload.reconfigure_link.href, + payload, + Xml::MEDIA_TYPE[:VM]) + monitor_task(task) + self end - def ip_address - #puts entity_xml + def ip_address entity_xml.ip_address - end def list_networks - entity_xml .network_connection_section .network_connections @@ -194,6 +245,7 @@ def find_nic_by_mac(mac) if net return VCloudSdk::NIC.new(net,net.network_connection_index == primary_index) else + return false fail(CloudError, "No NIC found with MAC #{mac} in VM #{name}") end @@ -222,6 +274,11 @@ def list_disks end end + ############################################################################################### + # Attaches a disk to VM. + # @param disk [Disk] The disk object to attach. + # @throw + ############################################################################################### def attach_disk(disk) fail CloudError, "Disk '#{disk.name}' of link #{disk.href} is attached to VM '#{disk.vm.name}'" if disk.attached? @@ -363,6 +420,10 @@ def delete_nics(*nics) self end + def operating_ssystem + entity_xml.operating_system + end + def vmtools_version entity_xml.vm_tools end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index 2134f42..8352627 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -51,6 +51,11 @@ def description=(value) value end + def operating_system + get_nodes("OperatingSystemSection",nil,false,OVF).first. + get_nodes("Description",nil,false,OVF).first.content + end + def vm_tools get_nodes("VMWareTools").first["version"] end From 4fd0d86827bb3f490595f3a00ce1687611645109 Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Mon, 11 Jul 2016 10:09:23 +0200 Subject: [PATCH 30/37] Guest customization capability added --- lib/ruby_vcloud_sdk/catalog.rb | 2 +- lib/ruby_vcloud_sdk/catalog_item.rb | 2 +- lib/ruby_vcloud_sdk/powerable.rb | 10 +- lib/ruby_vcloud_sdk/vapp.rb | 52 ++++++--- lib/ruby_vcloud_sdk/vdc_storage_profile.rb | 2 +- lib/ruby_vcloud_sdk/vm.rb | 102 +++++++++++++----- lib/ruby_vcloud_sdk/xml/wrapper_classes.rb | 1 + .../xml/wrapper_classes/vapp.rb | 6 +- lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 15 ++- .../xml_templates/CreateSnapshotParams.xml | 4 +- .../GuestCustomizationSection.xml | 79 +++++++++++++- 11 files changed, 221 insertions(+), 54 deletions(-) diff --git a/lib/ruby_vcloud_sdk/catalog.rb b/lib/ruby_vcloud_sdk/catalog.rb index 5dc0616..a6daf6d 100644 --- a/lib/ruby_vcloud_sdk/catalog.rb +++ b/lib/ruby_vcloud_sdk/catalog.rb @@ -12,7 +12,7 @@ def initialize(session, link) @link = link end - def name + def name admin_xml.name end diff --git a/lib/ruby_vcloud_sdk/catalog_item.rb b/lib/ruby_vcloud_sdk/catalog_item.rb index eb79e43..aaeaca9 100644 --- a/lib/ruby_vcloud_sdk/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/catalog_item.rb @@ -25,7 +25,7 @@ def initialize(session, link) # Return the name of the Catalog Item object # @return [String] The name of the catalog item ############################################################################ - def name + def name entity_xml.entity[:name] end diff --git a/lib/ruby_vcloud_sdk/powerable.rb b/lib/ruby_vcloud_sdk/powerable.rb index 5a79d87..2a42709 100644 --- a/lib/ruby_vcloud_sdk/powerable.rb +++ b/lib/ruby_vcloud_sdk/powerable.rb @@ -87,9 +87,15 @@ def power_off self end + ############################################################################################# + # Shutdown the GuestOS of vApp or VM + # Depending the version of vmtools installed on VM it could fail. Version 9227 on Windows KO + # @return [vApp] or [VM] Returns the object + ############################################################################################# def shutdown target = entity_xml - class_name = self.class.name.split("::").last + class_name = self.class.name.split("::").last + Config.logger.debug "#{class_name} status: #{target[:status]}" if is_status?(target, :SUSPENDED) error_msg = "#{class_name} #{target.name} suspended, discard state before powering off." @@ -179,6 +185,8 @@ def suspend task = connection.post(suspend_link.href, nil) task = monitor_task task, @session.time_limit[:power_on] Config.logger.info "#{class_name} #{target.name} is suspended." + + undeploy(target, class_name) self end diff --git a/lib/ruby_vcloud_sdk/vapp.rb b/lib/ruby_vcloud_sdk/vapp.rb index acae095..b093d12 100644 --- a/lib/ruby_vcloud_sdk/vapp.rb +++ b/lib/ruby_vcloud_sdk/vapp.rb @@ -92,7 +92,7 @@ def recompose_from_vapp_template(catalog_name, template_name) # Returns array of Vm objects associated with vApp # @return [VApp] an array of vApp #################################################################################### - def vms + def vms entity_xml.vms.map do |vm| VCloudSdk::VM.new(@session, vm.href) end @@ -197,7 +197,8 @@ def add_network_by_name( #################################################################################### # Deletes the network identified with name. # To delete the network, it cannot be used by any VM's. - # @return [VApp] The vApp. + # @param name [String] The name of the network. + # @return [VApp] The vApp. #################################################################################### def delete_network_by_name(name) unless list_networks.any? { |network_name| network_name == name } @@ -222,42 +223,47 @@ def delete_network_by_name(name) end #################################################################################### - # Creates a snapshot of the vApp. - # @param snapshot_name [String] Optional.The name of the snapshot + # Creates a snapshot of the vApp. There is only one snapshot. It will replace any + # existing snapshot + # @param snapshot_name [Hash] Optional.The options of the snapshot + # :name [String] The name of snapshot + # :description [String] The snapshot's description + # @return [VApp] The vApp #################################################################################### - def create_snapshot(snapshot_name) - new_snapshot_name = snapshot_name.nil? ? "#{name} Snapshot" : snapshot_name - options = { - :name => new_snapshot_name, - :description => "Snapshot of vApp #{name}" - } + def create_snapshot(snapshot_hash=nil) + new_snapshot_name = snapshot_hash.nil? ? "#{name} Snapshot" : snapshot_hash[:name] + target = entity_xml create_snapshot_link = target.create_snapshot_link - params = Xml::WrapperFactory.create_instance("CreateSnapshotParams") + params = Xml::WrapperFactory.create_instance("CreateSnapshotParams") Config.logger.info "Creating a snapshot on vApp #{name}." task = connection.post(target.create_snapshot_link.href,params) monitor_task(task) Config.logger.error "vApp #{name} has created a snapshot" + self end #################################################################################### - # Deletes ALL the snapshots of the vApp. + # Delete the current snapshot of the vApp. + # @return [VApp] The vApp #################################################################################### def remove_snapshot target = entity_xml remove_snapshot_link = target.remove_snapshot_link - Config.logger.info "Removing all snapshots on vApp #{name}." + Config.logger.info "Removing the snapshot on vApp #{name}." task = connection.post(target.remove_snapshot_link.href,nil) monitor_task(task) - Config.logger.error "vApp #{name} has removed all snapshots" + Config.logger.error "vApp #{name} has removed the current snapshot" + self end #################################################################################### - # Revert the LAST snapshot created in the vApp. + # Revert the snapshot created in the vApp. + # @return [VApp] The vApp #################################################################################### - def revert_snapshot + def revert_snapshot target = entity_xml revert_snapshot_link = target.revert_snapshot_link @@ -267,6 +273,20 @@ def revert_snapshot Config.logger.error "vApp #{name} has reverted a snapshot" end + #################################################################################### + # Return the snapshot info in the vApp. + # @return [String] Info of the Snapshot. + # [False] If no snapshot has been created in the vApp. + #################################################################################### + def snapshot_info + info = entity_xml.snapshot_section.get_nodes("Snapshot") + if info != [] + return info + else + return false + end + end + private def recompose_from_vapp_template_param(template) diff --git a/lib/ruby_vcloud_sdk/vdc_storage_profile.rb b/lib/ruby_vcloud_sdk/vdc_storage_profile.rb index 5d9eec8..af1c27a 100644 --- a/lib/ruby_vcloud_sdk/vdc_storage_profile.rb +++ b/lib/ruby_vcloud_sdk/vdc_storage_profile.rb @@ -1,7 +1,7 @@ module VCloudSdk class VdcStorageProfile - attr_reader :name + attr_reader :name, :storage_used_mb, :storage_limit_mb def initialize(storage_profile_xml_obj) @storage_profile_xml_obj = storage_profile_xml_obj diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index d61267f..775ff43 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -136,15 +136,18 @@ def name=(name) ############################################################################################### # Reconfigures the VM with the parameters passed in a hash. + # All params are optional. # @param options [Hash] The parameters of the VM. # :name [String] The name of the VM # :description [String] The description of the VM # :vcpu [String] The value for number of CPU # :memory [String] The value for memory in MB - # :nics [Hash] Optional.Array of Hashes representing the nics + # :nics [Array] Array of Hashes representing the nics # to attach to VM # :network_name [String] The network to attach nic # :mac [String] Optional. The MAC of the nic + # :disks [Array] Array of Hases representing the disks to + # attach to VM # :vapp_name [String] The name of the vApp # @return [VM] ############################################################################################### @@ -159,36 +162,38 @@ def reconfigure(options) if options[:nics] !=[] #ADD NICS options[:nics].each { |nic| - - nic_index = add_nic_index - network_name = nic[:network_name] - ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:POOL] - ip = "" + mac_address = nic[:mac] - # Add Network to vapp - vapp.add_network_by_name(network_name) if !vapp.list_networks.include? "#{network_name}" - # Add NIC - payload.hardware_section.add_item(nic_params(payload.hardware_section, + if !mac_address or (mac_address and !find_nic_by_mac(mac_address)) ###NOMES S'AFEGEIX NIC NI NO ESTÀ JA AFEGIDA + + nic_index = add_nic_index + network_name = nic[:network_name] + ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:POOL] + ip = "" + + # Add Network to vapp + vapp.add_network_by_name(network_name) if !vapp.list_networks.include? "#{network_name}" + # Add NIC + payload.hardware_section.add_item(nic_params(payload.hardware_section, nic_index, network_name, ip_addressing_mode, ip)) - # Connect NIC - payload.network_connection_section.add_item(network_connection_params(payload.network_connection_section, + # Connect NIC + payload.network_connection_section.add_item(network_connection_params(payload.network_connection_section, nic_index, network_name, ip_addressing_mode, ip)) - #Add the mac address passed - if mac_address - payload - .network_connection_section - .network_connections.last - .mac_address = mac_address + #Add the mac address passed + if mac_address + payload + .network_connection_section + .network_connections.last + .mac_address = mac_address + end end - - #STDERR.puts payload } end @@ -198,10 +203,7 @@ def reconfigure(options) payload.delete_nics(nc) end } - - - #puts payload - + task = connection.post(payload.reconfigure_link.href, payload, Xml::MEDIA_TYPE[:VM]) @@ -420,7 +422,7 @@ def delete_nics(*nics) self end - def operating_ssystem + def operating_system entity_xml.operating_system end @@ -516,6 +518,32 @@ def delete_internal_disk_by_name(name) self end + ############################################################################################################ + # Set up the options for the OS of the VM + # All params are optional. + # @param customization [Hash] The parameters of the guestOS customization. All parameters are + # optional. + # :computer_name [String] The name of the computer + # :admin_pass [String] The password for the Administrator/root user + # :reset_pass [String] Values "true" or "false". To reset password. + # :custom_script [String] The customization script (Max 49,000 characters) + # + # @return [VM] + ############################################################################################################ + def customization(customization) + link = entity_xml.guest_customization_link + payload = connection.get(link) + #puts payload + payload = add_customization(payload,customization) + + #puts payload + task = connection.put(link, + payload, + Xml::MEDIA_TYPE[:GUEST_CUSTOMIZATION_SECTION]) + monitor_task(task) + self + end + private def add_nic_index @@ -588,6 +616,30 @@ def network_connection_params(section, nic_index, network_name, addressing_mode, end end + def add_customization(section, customization) +#=begin + section + .tap do |params| + params.enable + params.computer_name = customization[:computer_name] + params.admin_pass = customization[:admin_pass] unless customization[:admin_pass].nil? + #params.reset_pass = customization[:reset_pass] unless customization[:reset_pass].nil? + params.script = customization[:custom_script] unless customization[:custom_script].nil? + end +#=end + +=begin + Xml::WrapperFactory.create_instance("GuestCustomizationSection", nil, section.doc_namespaces) + .tap do |params| + #params.href = section.href + params.enable(self.id) + params.computer_name = customization[:computer_name] + params.admin_pass = customization[:admin_pass] unless customization[:admin_pass].nil? + params.script = customization[:custom_script] unless customization[:custom_script].nil? + end +=end + end + def product_section_list_params(properties) Xml::WrapperFactory.create_instance("ProductSectionList").tap do |params| properties.each do |property| diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb index f5bf51a..2ed6cfc 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb @@ -4,6 +4,7 @@ require "ruby_vcloud_sdk/xml/wrapper_classes/admin_org" require "ruby_vcloud_sdk/xml/wrapper_classes/allocated_ip_addresses" require "ruby_vcloud_sdk/xml/wrapper_classes/catalog_item" +require "ruby_vcloud_sdk/xml/wrapper_classes/customization" require "ruby_vcloud_sdk/xml/wrapper_classes/disk" require "ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params" require "ruby_vcloud_sdk/xml/wrapper_classes/disk_create_params" diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb index b6bd086..25824dc 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb @@ -50,13 +50,17 @@ def remove_snapshot_link true).first end + def snapshot_section + get_nodes("SnapshotSection").first + end + def vdc_link get_nodes(XML_TYPE[:LINK], { type: MEDIA_TYPE[:VDC] }, true).first end - def vms + def vms get_nodes("Vm") end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index 8352627..f2a4e30 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -60,16 +60,13 @@ def vm_tools get_nodes("VMWareTools").first["version"] end - def ip_address - #puts get_nodes("IpAddress").first.content - #puts get_nodes("NetworkConnection") + def ip_address ips = [] get_nodes("NetworkConnection").each do |ip| ips << ip.ip_address end - ips.pop if ips.length > 1 #elimina l'ultim element, que es un nil, sempre i quan tingui mes d'una ip + #ips.pop if ips.length > 1 #elimina l'ultim element, que es un nil, sempre i quan tingui mes d'una ip return ips - #get_nodes("IpAddress").first.content if !get_nodes("IpAddress").first.nil? end def reconfigure_link @@ -90,6 +87,10 @@ def install_vmtools_link true).first end + def guest_customization_link + get_nodes("GuestCustomizationSection").first["href"] + end + def def eject_media_link @@ -121,6 +122,10 @@ def product_section get_nodes("ProductSection", nil, true, OVF).first end + def guest_customization_section + get_nodes("GuestCustomizationSection").first + end + # hardware modification methods def add_hard_disk(capacity, bus_type, bus_sub_type) diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml index a23e18c..122b7f4 100644 --- a/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/CreateSnapshotParams.xml @@ -1,6 +1,6 @@ - Snapshot1 + name=""> + Snapshot falsefalsefalsefalsefalsefalsefalse \ No newline at end of file + + + + + Specifies Guest OS Customization Settings + false + false + + false + false + + + + false + true + + false + + + + \ No newline at end of file From d92b4b054454c862d9e169abf98c0fac2957942a Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Tue, 12 Jul 2016 11:30:01 +0200 Subject: [PATCH 31/37] vm customization added --- .../xml/wrapper_classes/customization.rb | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb new file mode 100644 index 0000000..c79c7a3 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb @@ -0,0 +1,49 @@ +module VCloudSdk + module Xml + class GuestCustomizationSection < Wrapper + def href=(value) + @root["href"] = value + end + + def type=(value) + @root["type"] = value + end + + def enable(uuid=nil) + get_nodes("Enabled").first.content = "true" + get_nodes("VirtualMachineId").first.content = uuid + end + + def computer_name=(value) + get_nodes("ComputerName").first.content = value + end + + def admin_pass=(value) + get_nodes("AdminPasswordEnabled").first.content = "true" + get_nodes("AdminPasswordAuto").first.content = "false" + + if get_nodes("AdminPassword").first.nil? + nm = @root.at_css "AdminPasswordAuto" + nm.add_next_sibling "#{value}" + else + get_nodes("AdminPassword").first.content = value + end + + end + + def reset_pass=(value) + get_nodes("ResetPasswordRequired").first.content = value + end + + def script=(value) + if get_nodes("CustomizationScript").first.nil? + nm = @root.at_css "ResetPasswordRequired" + nm.add_next_sibling "#{value}" + else + get_nodes("CustomizationScript").first.content = value + + end + end + end + end +end From 524a3026b2e4bbed827915e06d3ff75c4af278e9 Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Tue, 12 Jul 2016 13:07:48 +0200 Subject: [PATCH 32/37] working on gem --- lib/ruby_vcloud_sdk/client.rb | 2 +- lib/ruby_vcloud_sdk/infrastructure.rb | 4 ++++ ruby_vcloud_sdk.gemspec | 11 ++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/ruby_vcloud_sdk/client.rb b/lib/ruby_vcloud_sdk/client.rb index 28ea90f..c5ffc09 100644 --- a/lib/ruby_vcloud_sdk/client.rb +++ b/lib/ruby_vcloud_sdk/client.rb @@ -17,7 +17,7 @@ class Client public :find_vdc_by_name, :catalogs, :list_catalogs, :catalog_exists?, :find_catalog_by_name, - :vdc_exists? + :vdc_exists?, :vdcs ############################################################################## # Initializes the Client and creates a Session to vCloud API. diff --git a/lib/ruby_vcloud_sdk/infrastructure.rb b/lib/ruby_vcloud_sdk/infrastructure.rb index 98fe0fe..4142bd4 100644 --- a/lib/ruby_vcloud_sdk/infrastructure.rb +++ b/lib/ruby_vcloud_sdk/infrastructure.rb @@ -20,6 +20,10 @@ def vdc_exists?(name) end end + def vdcs + @session.org.vdcs + end + def find_network_by_name(name) @session.org.networks.each do |network_link| if network_link.name == name diff --git a/ruby_vcloud_sdk.gemspec b/ruby_vcloud_sdk.gemspec index 04b79df..16c6be8 100644 --- a/ruby_vcloud_sdk.gemspec +++ b/ruby_vcloud_sdk.gemspec @@ -1,16 +1,17 @@ # -*- encoding: utf-8 -*- # Copyright (c) 2009-2012 VMware, Inc. +#Copyright 2016-2016, vCloud Driver Project, CSUC Gem::Specification.new do |s| - s.name = "ruby_vcloud_sdk" - s.version = "0.7.3" + s.name = "vcloudSDK" + s.version = "0.7.4" s.platform = Gem::Platform::RUBY s.summary = "BOSH vCloud API client" s.description = "BOSH vCloud API client\n#{`git rev-parse HEAD`[0, 6]}" - s.author = "VMware" - s.homepage = 'https://github.com/vchs/ruby_vcloud_sdk' + s.author = "CSUC" + s.homepage = 'https://www.csuc.cat' s.license = 'Apache 2.0' - s.email = "support@cloudfoundry.com" + s.email = "ois@csuc.cat" s.required_ruby_version = Gem::Requirement.new(">= 1.9.3") s.files = `git ls-files -- lib/*`.split("\n") + %w(README.md) From 407ba7e65dcabb568f9069b99d89baed18269723 Mon Sep 17 00:00:00 2001 From: Arnau Colomins Date: Wed, 27 Jul 2016 09:19:14 +0200 Subject: [PATCH 33/37] working on edge_gateway --- lib/ruby_vcloud_sdk/catalog_item.rb | 1 + lib/ruby_vcloud_sdk/client.rb | 2 +- lib/ruby_vcloud_sdk/edge_gateway.rb | 15 +++ lib/ruby_vcloud_sdk/infrastructure.rb | 73 +++++++++++- lib/ruby_vcloud_sdk/network.rb | 1 + lib/ruby_vcloud_sdk/powerable.rb | 4 +- lib/ruby_vcloud_sdk/resources.rb | 7 +- lib/ruby_vcloud_sdk/vdc.rb | 107 ++++++++++++++++-- lib/ruby_vcloud_sdk/vm.rb | 9 +- lib/ruby_vcloud_sdk/xml/constants.rb | 1 + .../xml/wrapper_classes/edge_gateway.rb | 14 +++ .../xml/wrapper_classes/vdc.rb | 41 ++++--- lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 6 +- ruby_vcloud_sdk.gemspec | 9 +- 14 files changed, 252 insertions(+), 38 deletions(-) diff --git a/lib/ruby_vcloud_sdk/catalog_item.rb b/lib/ruby_vcloud_sdk/catalog_item.rb index aaeaca9..859e752 100644 --- a/lib/ruby_vcloud_sdk/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/catalog_item.rb @@ -78,4 +78,5 @@ def date entity_xml.date end end + ############################################################################## end diff --git a/lib/ruby_vcloud_sdk/client.rb b/lib/ruby_vcloud_sdk/client.rb index c5ffc09..606ecd8 100644 --- a/lib/ruby_vcloud_sdk/client.rb +++ b/lib/ruby_vcloud_sdk/client.rb @@ -78,5 +78,5 @@ def right_records end end end - + ################################################################################ end diff --git a/lib/ruby_vcloud_sdk/edge_gateway.rb b/lib/ruby_vcloud_sdk/edge_gateway.rb index a4725df..cd49bf5 100644 --- a/lib/ruby_vcloud_sdk/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/edge_gateway.rb @@ -14,6 +14,21 @@ def initialize(session, link) @link = link end + def add_fw_rule(rules) + link = entity_xml.configure_services_link + payload = entity_xml.add_rule(rules) + + #task = connection.post(link, + # payload, + # Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) + #monitor_task(task) + #self + end + + def ent + entity_xml + end + def public_ip_ranges uplink_gateway_interface = entity_xml .gateway_interfaces diff --git a/lib/ruby_vcloud_sdk/infrastructure.rb b/lib/ruby_vcloud_sdk/infrastructure.rb index 4142bd4..2643967 100644 --- a/lib/ruby_vcloud_sdk/infrastructure.rb +++ b/lib/ruby_vcloud_sdk/infrastructure.rb @@ -1,6 +1,9 @@ module VCloudSdk - # Shared functions by classes such as Client, Catalog and VDC - # Make sure instance variable @session is available + + ############################################################################################### + # This module defines the shared functions by classes such as Client, Catalog and VDC + # Make sure instance variable @session is available + ############################################################################################### module Infrastructure ERROR_STATUSES = [Xml::TASK_STATUS[:ABORTED], Xml::TASK_STATUS[:ERROR], Xml::TASK_STATUS[:CANCELED]] @@ -8,22 +11,42 @@ module Infrastructure private + ############################################################################################# + # Returns the Virtual Data Center identified by name. + # @return [VDC] The VDC. + ############################################################################################# def find_vdc_by_name(name) vdc_link = @session.org.vdc_link(name) fail ObjectNotFoundError, "VDC #{name} not found" unless vdc_link VCloudSdk::VDC.new(@session, vdc_link) end + ############################################################################################# + # Obtain if the VDC identified by name exists. + # @return [Boolean] If the VDC identified by name exists, returns "True". + ############################################################################################# def vdc_exists?(name) @session.org.vdcs.any? do |vdc| vdc.name == name end end + ############################################################################################# + # Returns the list of VDC existing. + # @return [VDC] The array of VDC. + ############################################################################################# def vdcs - @session.org.vdcs + #@session.org.vdcs + @session.org.vdcs.map do |vdc_link| + VCloudSdk::VDC.new(@session, vdc_link) + end + end + ############################################################################################# + # Returns the Network identified by name. + # @return [Network] The network returned. + ############################################################################################# def find_network_by_name(name) @session.org.networks.each do |network_link| if network_link.name == name @@ -34,30 +57,50 @@ def find_network_by_name(name) fail ObjectNotFoundError, "Network '#{name}' is not found" end + ############################################################################################# + # Obtain if the network identified by name exists. + # @return [Boolean] If the network identified by name exists, returns "True". + ############################################################################################# def network_exists?(name) @session.org.networks.any? do |network| network.name == name end end + ############################################################################################# + # Returns the list of catalogs. + # @return [Catalog] The array of existing catalogs. + ############################################################################################# def catalogs @session.org.catalogs.map do |catalog_link| VCloudSdk::Catalog.new(@session, catalog_link) end end + ############################################################################################# + # Returns the name's list of Networks created in the Virtual Data Center. + # @return [String] The array of Network's names. + ############################################################################################# def list_catalogs @session.org.catalogs.map do |catalog_link| catalog_link.name end end + ############################################################################################# + # Obtain if the catalog identified by name exists. + # @return [Boolean] If the catalog identified by name exists, returns "True". + ############################################################################################# def catalog_exists?(name) @session.org.catalogs.any? do |catalog| catalog.name == name end end + ############################################################################################# + # Returns the catalog identified by name. + # @return [Catalog] The catalog returned. + ############################################################################################# def find_catalog_by_name(name) @session.org.catalogs.each do |catalog_link| if catalog_link.name == name @@ -68,10 +111,17 @@ def find_catalog_by_name(name) fail ObjectNotFoundError, "Catalog '#{name}' is not found" end + ############################################################################################# + # Returns the object's connection. + # @return [Connection] The connection returned. + ############################################################################################# def connection @session.connection end + ############################################################################################# + # Monitores the task passed as a argument. + ############################################################################################# def monitor_task( task, time_limit = @session.time_limit[:default], @@ -128,23 +178,39 @@ def monitor_task( "Task #{task.operation} did not complete within limit of #{time_limit} seconds." end + ############################################################################################# + # Obtain if the task has progressed or not. + # @return [Boolean] If the task has progressed, returns "True". + ############################################################################################# def task_progressed?(current_task, prev_progress, prev_status) (current_task.progress && (current_task.progress != prev_progress)) || (current_task.status && (current_task.status != prev_status)) end + ############################################################################################# + # Obtain if the task has succeeded or not. + # @return [Boolean] If the task has succeeded, returns "True". + ############################################################################################# def task_is_success(current_task, success = SUCCESS_STATUS) success.find do |s| s.downcase == current_task.status.downcase end end + ############################################################################################# + # Obtain if the task has an error or not. + # @return [Boolean] If the task has an error, returns "True". + ############################################################################################# def task_has_error(current_task, error_statuses = ERROR_STATUSES) error_statuses.find do |s| s.downcase == current_task.status.downcase end end + ############################################################################################# + # Returns the object's XML representation. + # @return [String] The XML representation of the object. + ############################################################################################# def entity_xml connection.get(@link) end @@ -158,4 +224,5 @@ def wait_for_running_tasks(subject, subject_display) end end end + ############################################################################################### end diff --git a/lib/ruby_vcloud_sdk/network.rb b/lib/ruby_vcloud_sdk/network.rb index 0d94dcd..7d494b2 100644 --- a/lib/ruby_vcloud_sdk/network.rb +++ b/lib/ruby_vcloud_sdk/network.rb @@ -80,4 +80,5 @@ def allocated_ips end end end + ###################################################################################### end diff --git a/lib/ruby_vcloud_sdk/powerable.rb b/lib/ruby_vcloud_sdk/powerable.rb index 2a42709..07d0f15 100644 --- a/lib/ruby_vcloud_sdk/powerable.rb +++ b/lib/ruby_vcloud_sdk/powerable.rb @@ -197,11 +197,13 @@ def is_status?(target, status) end def undeploy(target, class_name) - params = Xml::WrapperFactory.create_instance("UndeployVAppParams") # Even for VM it's called UndeployVappParams + params = Xml::WrapperFactory.create_instance("UndeployVAppParams") + # Even for VM it's called UndeployVappParams task = connection.post(target.undeploy_link.href, params) task = monitor_task(task, @session.time_limit[:undeploy]) Config.logger.info "#{class_name} #{target.name} is undeployed." task end end + ############################################################################################### end diff --git a/lib/ruby_vcloud_sdk/resources.rb b/lib/ruby_vcloud_sdk/resources.rb index b630339..6e1fac0 100644 --- a/lib/ruby_vcloud_sdk/resources.rb +++ b/lib/ruby_vcloud_sdk/resources.rb @@ -2,14 +2,16 @@ module VCloudSdk ################################################################################ # This class represents the resource of the Virtual Data Center. + # CPU and MEMORY are quantified in MHZ and MB. ################################################################################ class Resources attr_reader :cpu_available, :cpu_limit, :cpu_used attr_reader :memory_available, :memory_limit, :memory_used + ############################################################################## # Initialize a Resource for the VDC. - # @param cpu [CPU] The CPU resource of the VDC. - # @param memory [Memory] The Memory resource of the VDC. + # @param cpu [CPU] The CPU resource in Mhz of the VDC. + # @param memory [Memory] The Memory resource in MB of the VDC. ############################################################################## def initialize(cpu,memory) @cpu_available = cpu.available_cores @@ -21,4 +23,5 @@ def initialize(cpu,memory) @memory_used = memory.limit_mb.to_i - memory.available_mb.to_i end end + ################################################################################ end diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb index 1a86ad2..668c14f 100644 --- a/lib/ruby_vcloud_sdk/vdc.rb +++ b/lib/ruby_vcloud_sdk/vdc.rb @@ -11,6 +11,10 @@ require_relative "edge_gateway" module VCloudSdk + + ############################################################################################### + # This class represents a Virtual Data Center in vCloud. + ############################################################################################### class VDC include Infrastructure @@ -21,23 +25,40 @@ class VDC public :find_network_by_name, :network_exists? + ############################################################################################# + # Initializes a VDC object associated with a vCloud Session and the VDC's link. + # @param session [Session] The client's session. + # @param link [String] The vCloud link of the vApp. + ############################################################################################# def initialize(session, link) @session = session @link = link end + ############################################################################################# + # Returns the storage profiles assoaciated with the Virtual Data Center. + # @return [VdcStorageProfile] The storafe profiles of de VDC. + ############################################################################################# def storage_profiles storage_profile_records.map do |storage_profile| VCloudSdk::VdcStorageProfile.new(storage_profile) end end + ############################################################################################# + # Returns the name's list of storage profiles assoaciated with the Virtual Data Center. + # @return [String] The array of storage profiles's names of de VDC. + ############################################################################################# def list_storage_profiles storage_profile_records.map do |storage_profile| storage_profile.name end end + ############################################################################################# + # Returns the storage profile identified by name. + # @return [VdcStorageProfile] The storafe profiles of the VDC. + ############################################################################################# def find_storage_profile_by_name(name) storage_profile_records.each do |storage_profile| if storage_profile.name == name @@ -48,24 +69,40 @@ def find_storage_profile_by_name(name) fail ObjectNotFoundError, "Storage profile '#{name}' is not found" end + ############################################################################################# + # Obtain if the storage profile identified by name exists. + # @return [Boolean] If the storage profile identified by name exists, returns "True". + ############################################################################################# def storage_profile_exists?(name) storage_profile_records.any? do |storage_profile| storage_profile.name == name end end + ############################################################################################# + # Returns the vApp's list hosted in the VDC. + # @return [VApp] The array of vApp hosted in the VDC. + ############################################################################################# def vapps entity_xml.vapps.map do |vapp_link| VCloudSdk::VApp.new(@session, vapp_link) end end + ############################################################################################# + # Returns the name's list of vApps hosted in the Virtual Data Center. + # @return [String] The array of vApps's names. + ############################################################################################# def list_vapps entity_xml.vapps.map do |vapp_link| vapp_link.name end end + ############################################################################################# + # Returns the vApp identified by name. + # @return [VApp] The vApp hosted in VDC. + ############################################################################################# def find_vapp_by_name(name) entity_xml.vapps.each do |vapp_link| if vapp_link.name == name @@ -76,6 +113,10 @@ def find_vapp_by_name(name) fail ObjectNotFoundError, "VApp '#{name}' is not found" end + ############################################################################################# + # Returns the vApp identified by uuid. + # @return [VApp] The vApp hosted in VDC. + ############################################################################################# def find_vapp_by_id(uuid) entity_xml.vapps.each do |vapp_link| if vapp_link.href.split("/")[5] == "vapp-#{uuid}" @@ -86,30 +127,50 @@ def find_vapp_by_id(uuid) fail ObjectNotFoundError, "VApp '#{uuid}' is not found" end + ############################################################################################# + # Obtain if the vApp identified by name exists. + # @return [Boolean] If the vApp identified by name exists, returns "True". + ############################################################################################# def vapp_exists?(name) entity_xml.vapps.any? do |vapp| vapp.name == name end end - + + ############################################################################################# + # Creates Resources object representing the CPU and Memory of the VDC. + # @return [Resouces] The Resource object of the VDC. + ############################################################################################# def resources - cpu = VCloudSdk::CPU.new(entity_xml.available_cpu_cores,entity_xml.limit_cpu_cores) + cpu = VCloudSdk::CPU.new(entity_xml.available_cpu_mhz,entity_xml.limit_cpu_mhz) memory = VCloudSdk::Memory.new(entity_xml.available_memory_mb,entity_xml.limit_memory_mb) VCloudSdk::Resources.new(cpu,memory) end + ############################################################################################# + # Returns the list of the Networks created in the VDC. + # @return [Network] The array of Networks created in the VDC. + ############################################################################################# def networks @session.org.networks.map do |network_link| VCloudSdk::Network.new(@session, network_link) end end + ############################################################################################# + # Returns the name's list of Networks created in the Virtual Data Center. + # @return [String] The array of Network's names. + ############################################################################################# def list_networks @session.org.networks.map do |network_link| network_link.name end end + ############################################################################################# + # Returns the list of Edge Gateways created in the VDC. + # @return [EdgeGateway] The array of Edge Gateways created in the VDC. + ############################################################################################# def edge_gateways connection .get(entity_xml.edge_gateways_link) @@ -119,18 +180,30 @@ def edge_gateways end end + ############################################################################################# + # Returns the list of Disks created in the VDC. + # @return [Disks] The array of Disk created in the VDC. + ############################################################################################# def disks entity_xml.disks.map do |disk_link| VCloudSdk::Disk.new(@session, disk_link) end end + ############################################################################################# + # Returns the name's list of Disks created in the Virtual Data Center. + # @return [String] The array of Disk's names. + ############################################################################################# def list_disks entity_xml.disks.map do |disk_link| disk_link.name end end + ############################################################################################# + # Returns the Disks identified by name. + # @return [Disk] The Disk or Disks created in VDC. + ############################################################################################# def find_disks_by_name(name) disks = entity_xml .disks @@ -144,18 +217,22 @@ def find_disks_by_name(name) disks end + ############################################################################################# + # Obtain if the Disk identified by name exists. + # @return [Boolean] If the vApp identified by name exists, returns "True". + ############################################################################################# def disk_exists?(name) list_disks.any? do |disk_name| disk_name == name end end - #################################################################################### - # Creates a disk. + ############################################################################################# + # Creates a Disk in the Virtual Data Center. # @param name [String] The disk's name. # @param capacity [Integer] The capacity in MB of the disk. - # @return [Disk] The object created.disk_create_param - #################################################################################### + # @return [Disk] The object created.disk_create_param. + ############################################################################################# def create_disk( name, capacity, @@ -187,6 +264,10 @@ def create_disk( VCloudSdk::Disk.new(@session, disk.href) end + ############################################################################################# + # Deletes the Disk identified by "name".. + # @return [VDC] The Virtual Data Center. + ############################################################################################# def delete_disk_by_name(name) disks = find_disks_by_name(name) fail CloudError, @@ -196,6 +277,10 @@ def delete_disk_by_name(name) self end + ############################################################################################# + # Deletes ALL the Disks identified by "name".. + # @return [VDC] The Virtual Data Center. + ############################################################################################# def delete_all_disks_by_name(name) disks = find_disks_by_name(name) success = true @@ -209,10 +294,15 @@ def delete_all_disks_by_name(name) end fail CloudError, - "Failed to delete one or more of the disks with name '#{name}'. Check logs for details." unless success + "Failed to delete one or more of the disks with name '#{name}'. + Check logs for details." unless success self end + ############################################################################################# + # Returns the storage profile identified by name in XML. + # @return [XML] The storafe profiles of de VDC. + ############################################################################################# def storage_profile_xml_node(name) return nil if name.nil? @@ -246,7 +336,8 @@ def disk_create_params(name, capacity, bus_type, bus_sub_type, vm) def delete_single_disk(disk) Config.logger.info "Deleting disk '#{disk.name}', link #{disk.href}" fail CloudError, - "Disk '#{disk.name}', link #{disk.href} is attached to VM '#{disk.vm.name}'" if disk.attached? + "Disk '#{disk.name}', link #{disk.href} is attached + to VM '#{disk.vm.name}'" if disk.attached? entity_xml = connection.get(disk.href) task = connection.delete(entity_xml.remove_link.href) diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index 775ff43..ff11b6a 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -153,8 +153,8 @@ def name=(name) ############################################################################################### def reconfigure(options) - payload = entity_xml - payload.name = options[:name] if !options[:name].nil? + payload = entity_xml + payload.name = options[:name] if !options[:name].nil? payload.description = options[:description] if !options[:name].nil? payload.change_cpu_count(options[:vcpu]) if !options[:name].nil? payload.change_memory(options[:memory]) if !options[:name].nil? @@ -431,13 +431,13 @@ def vmtools_version end def vmtools? - #puts entity_xml + puts entity_xml !entity_xml.vm_tools.nil? end def install_vmtools Config.logger.info( - "Installing VMware tools on #{name} ...") + "Mounting VMware tools on #{name} ...") task = connection.post(entity_xml.install_vmtools_link.href,nil) monitor_task(task) self @@ -650,4 +650,5 @@ def product_section_list_params(properties) BYTES_PER_MEGABYTE = 1_048_576 # 1048576 = 1024 * 1024 = 2^20 end + ################################################################################################# end diff --git a/lib/ruby_vcloud_sdk/xml/constants.rb b/lib/ruby_vcloud_sdk/xml/constants.rb index afc894f..1532584 100644 --- a/lib/ruby_vcloud_sdk/xml/constants.rb +++ b/lib/ruby_vcloud_sdk/xml/constants.rb @@ -207,6 +207,7 @@ module Xml :ADMIN_NETWORK => "application/vnd.vmware.admin.network+xml", :NETWORK => "application/vnd.vmware.vcloud.network+xml", :NETWORK_POOL => "application/vnd.vmware.admin.networkPool+xml", + :EDGE_SERVICES_CONFIG => "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml", :CATALOG_PUBLISH => "application/vnd.vmware.admin.publishCatalogParams+xml", :OWNER => "application/vnd.vmware.vcloud.owner+xml", diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb index d91cde8..0670776 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb @@ -1,6 +1,20 @@ module VCloudSdk module Xml class EdgeGateway < Wrapper + def configure_services_link + get_nodes(XML_TYPE[:LINK], + { rel: "edgeGateway:configureServices" }, + true).first + end + + def add_rule(options) + ###NEXT ID + id = get_nodes("FirewallRule").last + .get_nodes("Id").first + .content.to_i + 1 + + + end def gateway_interfaces get_nodes(:Configuration, nil, true) .first diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb index 100ec09..d63885e 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb @@ -73,30 +73,45 @@ def storage_profile(name) .first end - def limit_cpu_cores - cpu_limit = get_nodes("ComputeCapacity") - .first.get_nodes("Cpu").first.get_nodes("Limit").first.content + def limit_cpu_mhz + cpu_resource = get_nodes("ComputeCapacity") + .first.get_nodes("Cpu").first + + units = cpu_resource.get_nodes("Units").first.content + cpu_limit = cpu_resource.get_nodes("Limit").first.content + if units == "GHz" + cpu_limit = cpu_limit.to_i * 1000 + end + + cpu_limit end - def available_cpu_cores + def available_cpu_mhz cpu_resource = get_nodes("ComputeCapacity") .first.get_nodes("Cpu").first - available_cpu_clock_speed = get_available_resource(cpu_resource) -=begin + available_cpu = get_available_resource(cpu_resource) + # clock units can only be MHz or GHz units = cpu_resource.get_nodes("Units").first.content - if units == "MHz" - available_cpu_clock_speed = available_cpu_clock_speed / 1000 + if units == "GHz" + available_cpu = available_cpu * 1000 end -=end - # We assume 1 GHz is converted to 1 vCpu core - available_cpu_clock_speed + + available_cpu end def limit_memory_mb - memory_limit = get_nodes("ComputeCapacity") - .first.get_nodes("Memory").first.get_nodes("Limit").first.content + memory_resource = get_nodes("ComputeCapacity") + .first.get_nodes("Memory").first + + units = memory_resource.get_nodes("Units").first.content + memory_limit = memory_resource.get_nodes("Limit").first.content + if units == "GB" + memory_limit = memory_limit.to_i * 1024 + end + + memory_limit end def available_memory_mb diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index f2a4e30..d4853c0 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -56,8 +56,10 @@ def operating_system get_nodes("Description",nil,false,OVF).first.content end - def vm_tools - get_nodes("VMWareTools").first["version"] + def vm_tools + tools = get_nodes("VMWareTools") + return tools.first["version"] if !tools.empty? + return nil end def ip_address diff --git a/ruby_vcloud_sdk.gemspec b/ruby_vcloud_sdk.gemspec index 16c6be8..36e4443 100644 --- a/ruby_vcloud_sdk.gemspec +++ b/ruby_vcloud_sdk.gemspec @@ -1,10 +1,11 @@ # -*- encoding: utf-8 -*- # Copyright (c) 2009-2012 VMware, Inc. -#Copyright 2016-2016, vCloud Driver Project, CSUC +# Copyright 2016-2016, vCloud Driver Project, CSUC Gem::Specification.new do |s| - s.name = "vcloudSDK" - s.version = "0.7.4" + s.name = "ruby_vcloud_sdk" + s.version = "0.7.5" + s.date = Date.today.to_s s.platform = Gem::Platform::RUBY s.summary = "BOSH vCloud API client" s.description = "BOSH vCloud API client\n#{`git rev-parse HEAD`[0, 6]}" @@ -19,7 +20,7 @@ Gem::Specification.new do |s| s.add_dependency "builder", ">= 3.1" s.add_dependency "httpclient", ">= 2.4.0" - s.add_dependency "rest-client", ">= 1.6.7" + s.add_dependency "rest-client", "<= 1.8.0" s.add_dependency "nokogiri", ">= 1.5.6" s.add_dependency "netaddr" end From 5a7c226527bdd56f3fe90f7cf9e69378880fa5a1 Mon Sep 17 00:00:00 2001 From: CSUC Date: Tue, 13 Sep 2016 10:33:04 +0200 Subject: [PATCH 34/37] FirewallCapabilyAdded --- lib/ruby_vcloud_sdk/edge_gateway.rb | 63 ++++++++++++++++--- lib/ruby_vcloud_sdk/vdc.rb | 6 +- lib/ruby_vcloud_sdk/vm.rb | 20 ++---- lib/ruby_vcloud_sdk/xml/wrapper_classes.rb | 1 + .../xml/wrapper_classes/edge_gateway.rb | 36 +++++++++-- .../xml/wrapper_classes/fw_rules.rb | 50 +++++++++++++++ lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 4 +- .../xml/xml_templates/FirewallRule.xml | 18 ++++++ .../GuestCustomizationSection.xml | 59 +---------------- 9 files changed, 165 insertions(+), 92 deletions(-) create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/fw_rules.rb create mode 100644 lib/ruby_vcloud_sdk/xml/xml_templates/FirewallRule.xml diff --git a/lib/ruby_vcloud_sdk/edge_gateway.rb b/lib/ruby_vcloud_sdk/edge_gateway.rb index cd49bf5..f6b6b72 100644 --- a/lib/ruby_vcloud_sdk/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/edge_gateway.rb @@ -3,26 +3,69 @@ require_relative "ip_ranges" module VCloudSdk + + ############################################################################## + # This class represents a Edge Gateway in the Virtual Data Center. + ############################################################################## class EdgeGateway include Infrastructure extend Forwardable def_delegator :entity_xml, :name + ############################################################################ + # Initializes a EdgeGateway object associated with a vCloud Session and the + # the Edge Gateway's link + # @param session [Session] The client's session + # @param link [String] The xml representation of the Edge Gateway + ############################################################################ def initialize(session, link) - @session = session - @link = link + @session = session + @link = link end - def add_fw_rule(rules) - link = entity_xml.configure_services_link - payload = entity_xml.add_rule(rules) + ############################################################################ + # Add Firewall rules to the Edge Gateyay. + # @param rules [Array] Array of Hashes representing the rules to be added. + # :name [String] The name of the rule. + # :ip_src [String] The source IP or "Any". + # :ip_dest [String] The destination IP or "Any". + # :port_src [String] The source Port or "Any". + # :port_dest [String] The destination IP or "Any". + # :prot [String] "TCP","UDP", "TCP & UDP", "ICMP", + # "ANY" . + # :action [String] The action to be applied.It can be + # "allow" or "deny". + # :enabled [String] To enable or disable the rule. + # The options are "true" or "false". + # + # @return [EdgeGateway] The Edge Gateway object. + ############################################################################ + def add_fw_rules(rules) + link = entity_xml.configure_services_link + payload = entity_xml.add_rules(rules) + + task = connection.post(link, + payload.configure_services, + Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) + monitor_task(task) + self + end + + ############################################################################ + # Remove the Firewall rules with IPs destination passed as an argument + # @param ips [Array] Array of IPs destination addresses + # @return [EdgeGateway] The Edge Gateway object. + ############################################################################ + def remove_fw_rules(ips) + link = entity_xml.configure_services_link + payload = entity_xml.remove_rules(ips) - #task = connection.post(link, - # payload, - # Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) - #monitor_task(task) - #self + task = connection.post(link, + payload.configure_services, + Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) + monitor_task(task) + self end def ent diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb index 668c14f..b6c748b 100644 --- a/lib/ruby_vcloud_sdk/vdc.rb +++ b/lib/ruby_vcloud_sdk/vdc.rb @@ -117,9 +117,9 @@ def find_vapp_by_name(name) # Returns the vApp identified by uuid. # @return [VApp] The vApp hosted in VDC. ############################################################################################# - def find_vapp_by_id(uuid) - entity_xml.vapps.each do |vapp_link| - if vapp_link.href.split("/")[5] == "vapp-#{uuid}" + def find_vapp_by_id(uuid) + entity_xml.vapps.each do |vapp_link| + if vapp_link.href.split("/")[5] == "vapp-#{uuid}" return VCloudSdk::VApp.new(@session, vapp_link) end end diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index ff11b6a..c59050d 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -30,7 +30,8 @@ def initialize(session, link) # Returns the identifier of the VM (uuid) # @return [String] The identifier of the VM ############################################################################################### - def id + def id + puts entity_xml id = entity_xml.urn id.split(":")[3] end @@ -211,6 +212,10 @@ def reconfigure(options) self end + ############################################################################################### + # Returns the IP addresses assigned to the VM or nil. + # @return [Array or nil] The IP addresses or nil. + ############################################################################################### def ip_address entity_xml.ip_address end @@ -617,7 +622,6 @@ def network_connection_params(section, nic_index, network_name, addressing_mode, end def add_customization(section, customization) -#=begin section .tap do |params| params.enable @@ -626,18 +630,6 @@ def add_customization(section, customization) #params.reset_pass = customization[:reset_pass] unless customization[:reset_pass].nil? params.script = customization[:custom_script] unless customization[:custom_script].nil? end -#=end - -=begin - Xml::WrapperFactory.create_instance("GuestCustomizationSection", nil, section.doc_namespaces) - .tap do |params| - #params.href = section.href - params.enable(self.id) - params.computer_name = customization[:computer_name] - params.admin_pass = customization[:admin_pass] unless customization[:admin_pass].nil? - params.script = customization[:custom_script] unless customization[:custom_script].nil? - end -=end end def product_section_list_params(properties) diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb index 2ed6cfc..fca5494 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb @@ -11,6 +11,7 @@ require "ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway" require "ruby_vcloud_sdk/xml/wrapper_classes/entity" require "ruby_vcloud_sdk/xml/wrapper_classes/file" +require "ruby_vcloud_sdk/xml/wrapper_classes/fw_rules" require "ruby_vcloud_sdk/xml/wrapper_classes/gateway_interface" require "ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper" require "ruby_vcloud_sdk/xml/wrapper_classes/instantiate_vapp_template_params" diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb index 0670776..0398fe1 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb @@ -6,15 +6,41 @@ def configure_services_link { rel: "edgeGateway:configureServices" }, true).first end + def configure_services + get_nodes("EdgeGatewayServiceConfiguration").first + end - def add_rule(options) - ###NEXT ID + def add_rules(rules) + ###OBTAIN LAST ID id = get_nodes("FirewallRule").last .get_nodes("Id").first - .content.to_i + 1 - - + .content.to_i + rules.each do |rule| + id = id + 1 + fw_rule = Xml::WrapperFactory.create_instance("FirewallRule").tap do |params| + params.id = id.to_s + params.description = rule[:name] + params.ips(rule[:ip_src],rule[:ip_dest]) + params.ports(rule[:port_src],rule[:port_dest]) + params.action = rule[:action] + params.enabled = rule[:enabled] + end + nm = @root.at_css "FirewallRule" + nm.add_next_sibling "\n#{fw_rule}" + end + self end + + def remove_rules(ips) + rules = get_nodes("FirewallRule") + rules.each do |rule| + ips.each do |ip| + rule.node.remove if rule.ip_dest == ip + end + end + self + end + def gateway_interfaces get_nodes(:Configuration, nil, true) .first diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/fw_rules.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/fw_rules.rb new file mode 100644 index 0000000..876b38e --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/fw_rules.rb @@ -0,0 +1,50 @@ +module VCloudSdk + module Xml + class FirewallRule < Wrapper + def href=(value) + @root["href"] = value + end + + def type=(value) + @root["type"] = value + end + + def id=(id) + get_nodes("Id").first.content = id + end + + def ip_dest + get_nodes("DestinationIp").first.content + end + + def enabled=(opt) + get_nodes("IsEnabled").first.content = opt + end + + def description=(desc) + get_nodes("Description").first.content = desc + end + + def ips(src,dest) + get_nodes("SourceIp").first.content = src + get_nodes("DestinationIp").first.content = dest + end + + def ports(src,dest) + if dest == "Any" + get_nodes("Port").first.content = "-1" + else + get_nodes("Port").first.content = dest + end + get_nodes("SourcePort").first.content = "-1" if src == "Any" + get_nodes("SourcePortRange").first.content = src + get_nodes("DestinationPortRange").first.content = dest + end + + def action=(act) + get_nodes("Policy").first.content = act + end + + end + end +end \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index d4853c0..d6c383d 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -67,8 +67,8 @@ def ip_address get_nodes("NetworkConnection").each do |ip| ips << ip.ip_address end - #ips.pop if ips.length > 1 #elimina l'ultim element, que es un nil, sempre i quan tingui mes d'una ip - return ips + return ips if !ips.empty? + return nil end def reconfigure_link diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/FirewallRule.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/FirewallRule.xml new file mode 100644 index 0000000..5db7d88 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/FirewallRule.xml @@ -0,0 +1,18 @@ + + + + + false + + allow + + true + + + + + + + + false + \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/GuestCustomizationSection.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/GuestCustomizationSection.xml index 3be32ff..045bb1d 100644 --- a/lib/ruby_vcloud_sdk/xml/xml_templates/GuestCustomizationSection.xml +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/GuestCustomizationSection.xml @@ -1,26 +1,3 @@ - - false - - \ No newline at end of file + \ No newline at end of file From e6be472fc58abfe2f797615400b676f32928bd5d Mon Sep 17 00:00:00 2001 From: CSUC Date: Tue, 27 Sep 2016 11:38:02 +0200 Subject: [PATCH 35/37] bug fix: Adding multiple NIC --- lib/ruby_vcloud_sdk/vm.rb | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index c59050d..b147f47 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -30,8 +30,7 @@ def initialize(session, link) # Returns the identifier of the VM (uuid) # @return [String] The identifier of the VM ############################################################################################### - def id - puts entity_xml + def id id = entity_xml.urn id.split(":")[3] end @@ -146,6 +145,7 @@ def name=(name) # :nics [Array] Array of Hashes representing the nics # to attach to VM # :network_name [String] The network to attach nic + # :ip [String] Optional. The IP of the nic # :mac [String] Optional. The MAC of the nic # :disks [Array] Array of Hases representing the disks to # attach to VM @@ -159,6 +159,8 @@ def reconfigure(options) payload.description = options[:description] if !options[:name].nil? payload.change_cpu_count(options[:vcpu]) if !options[:name].nil? payload.change_memory(options[:memory]) if !options[:name].nil? + + nic_index = add_nic_index if options[:nics] !=[] #ADD NICS @@ -166,12 +168,18 @@ def reconfigure(options) mac_address = nic[:mac] - if !mac_address or (mac_address and !find_nic_by_mac(mac_address)) ###NOMES S'AFEGEIX NIC NI NO ESTÀ JA AFEGIDA + if !mac_address or (mac_address and !find_nic_by_mac(mac_address)) - nic_index = add_nic_index network_name = nic[:network_name] ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:POOL] - ip = "" + + ip = "" + + if !nic[:ip].nil? + ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:MANUAL] + ip = nic[:ip] + end + # Add Network to vapp vapp.add_network_by_name(network_name) if !vapp.list_networks.include? "#{network_name}" @@ -193,7 +201,8 @@ def reconfigure(options) .network_connection_section .network_connections.last .mac_address = mac_address - end + end + nic_index = nic_index + 1 end } end @@ -435,8 +444,7 @@ def vmtools_version entity_xml.vm_tools end - def vmtools? - puts entity_xml + def vmtools? !entity_xml.vm_tools.nil? end @@ -450,7 +458,6 @@ def install_vmtools def product_section_properties - #puts entity_xml product_section = entity_xml.product_section return [] if product_section.nil? @@ -538,10 +545,9 @@ def delete_internal_disk_by_name(name) def customization(customization) link = entity_xml.guest_customization_link payload = connection.get(link) - #puts payload + payload = add_customization(payload,customization) - #puts payload task = connection.put(link, payload, Xml::MEDIA_TYPE[:GUEST_CUSTOMIZATION_SECTION]) From 87c2a1576fb1b80623a1585ee8933ae3e6f2b726 Mon Sep 17 00:00:00 2001 From: Arnau Colominas Illa Date: Thu, 27 Oct 2016 12:04:16 +0200 Subject: [PATCH 36/37] Configure NAT rules capability added --- lib/ruby_vcloud_sdk/catalog_item.rb | 6 +- lib/ruby_vcloud_sdk/edge_gateway.rb | 48 +++++++++-- lib/ruby_vcloud_sdk/internal_disk.rb | 3 +- lib/ruby_vcloud_sdk/network.rb | 11 ++- lib/ruby_vcloud_sdk/vdc.rb | 2 +- lib/ruby_vcloud_sdk/vm.rb | 43 +++++++--- lib/ruby_vcloud_sdk/xml/wrapper.rb | 4 + lib/ruby_vcloud_sdk/xml/wrapper_classes.rb | 2 + .../xml/wrapper_classes/catalog_item.rb | 2 +- .../xml/wrapper_classes/dnat_rules.rb | 56 +++++++++++++ .../xml/wrapper_classes/edge_gateway.rb | 81 +++++++++++++++++-- .../xml/wrapper_classes/org_vdc_network.rb | 10 +++ .../xml/wrapper_classes/snat_rules.rb | 44 ++++++++++ lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 6 ++ .../xml/xml_templates/DNatRule.xml | 15 ++++ .../xml/xml_templates/SNatRule.xml | 12 +++ ruby_vcloud_sdk.gemspec | 4 +- 17 files changed, 315 insertions(+), 34 deletions(-) create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/dnat_rules.rb create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/snat_rules.rb create mode 100644 lib/ruby_vcloud_sdk/xml/xml_templates/DNatRule.xml create mode 100644 lib/ruby_vcloud_sdk/xml/xml_templates/SNatRule.xml diff --git a/lib/ruby_vcloud_sdk/catalog_item.rb b/lib/ruby_vcloud_sdk/catalog_item.rb index 859e752..bd32fd9 100644 --- a/lib/ruby_vcloud_sdk/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/catalog_item.rb @@ -58,10 +58,14 @@ def vapp_template_id # Return the type of the Catalog Item object. It can be: # @return [String] The type of the catalog item ############################################################################ - def type + def type entity_xml.entity[:type] end + def size + entity_xml.size + end + ############################################################################ # Return the vCloud href of the Catalog Item object. # @return [String] The href of the catalog item diff --git a/lib/ruby_vcloud_sdk/edge_gateway.rb b/lib/ruby_vcloud_sdk/edge_gateway.rb index f6b6b72..b5e2d26 100644 --- a/lib/ruby_vcloud_sdk/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/edge_gateway.rb @@ -43,8 +43,8 @@ def initialize(session, link) ############################################################################ def add_fw_rules(rules) link = entity_xml.configure_services_link - payload = entity_xml.add_rules(rules) - + payload = entity_xml.add_fw_rules(rules) + task = connection.post(link, payload.configure_services, Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) @@ -59,7 +59,7 @@ def add_fw_rules(rules) ############################################################################ def remove_fw_rules(ips) link = entity_xml.configure_services_link - payload = entity_xml.remove_rules(ips) + payload = entity_xml.remove_fw_rules(ips) task = connection.post(link, payload.configure_services, @@ -68,8 +68,46 @@ def remove_fw_rules(ips) self end - def ent - entity_xml + ############################################################################ + # Add Nat rules to the Edge Gateyay. + # @param rules [Array] Array of Hashes representing the rules to be added. + # :description [String] Description about the rule. + # :rule_type [String] "SNAT" or "DNAT". + # :enabled [String] "true" or "false". + # :interface [String] The name of the uplink network. + # :original_ip [String] The original IP or "Any". + # :original_port [String] The translated IP,"Any" or range ("startIP"-"finalIP"). + # :translated_ip [String] The destination IP or "Any". + # :translated_port [String] + # :protocol [String] + # + # @return [EdgeGateway] The Edge Gateway object. + ############################################################################ + def add_nat_rules(rules) + link = entity_xml.configure_services_link + payload = entity_xml.add_nat_rules(rules) + + task = connection.post(link, + payload.configure_services, + Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) + monitor_task(task) + self + end + + ############################################################################ + # Remove the Nat rules with the VM IPs passed as an argument + # @param ips [Array] Array of IPs addresses + # @return [EdgeGateway] The Edge Gateway object. + ############################################################################ + def remove_nat_rules(ips) + link = entity_xml.configure_services_link + payload = entity_xml.remove_nat_rules(ips) + + task = connection.post(link, + payload.configure_services, + Xml::ADMIN_MEDIA_TYPE[:EDGE_SERVICES_CONFIG]) + monitor_task(task) + self end def public_ip_ranges diff --git a/lib/ruby_vcloud_sdk/internal_disk.rb b/lib/ruby_vcloud_sdk/internal_disk.rb index a849782..9df4994 100644 --- a/lib/ruby_vcloud_sdk/internal_disk.rb +++ b/lib/ruby_vcloud_sdk/internal_disk.rb @@ -1,9 +1,10 @@ module VCloudSdk class InternalDisk - attr_reader :name, :capacity, :bus_type, :bus_sub_type + attr_reader :id, :name, :capacity, :bus_type, :bus_sub_type def initialize(entity_xml) + @id = entity_xml.disk_id @name = entity_xml.element_name @capacity = entity_xml.host_resource.attribute("capacity").to_s.to_i @bus_type = entity_xml.host_resource.attribute("busType").to_s diff --git a/lib/ruby_vcloud_sdk/network.rb b/lib/ruby_vcloud_sdk/network.rb index 7d494b2..bcec04b 100644 --- a/lib/ruby_vcloud_sdk/network.rb +++ b/lib/ruby_vcloud_sdk/network.rb @@ -37,7 +37,15 @@ def id def description entity_xml.description end - + + def gateway + entity_xml.gateway + end + + def netmask + entity_xml.netmask + end + #################################################################################### # Returns the fence mode of the Network. # @return [String] The fence mode of the Network. @@ -51,7 +59,6 @@ def fence_mode # @return [String] The vCloud link of the Network. #################################################################################### def href - #puts entity_xml @link end diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb index b6c748b..4510e9d 100644 --- a/lib/ruby_vcloud_sdk/vdc.rb +++ b/lib/ruby_vcloud_sdk/vdc.rb @@ -202,7 +202,7 @@ def list_disks ############################################################################################# # Returns the Disks identified by name. - # @return [Disk] The Disk or Disks created in VDC. + # @return [Array] The Disk or Disks created in VDC. ############################################################################################# def find_disks_by_name(name) disks = entity_xml diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index b147f47..a78c989 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -159,16 +159,15 @@ def reconfigure(options) payload.description = options[:description] if !options[:name].nil? payload.change_cpu_count(options[:vcpu]) if !options[:name].nil? payload.change_memory(options[:memory]) if !options[:name].nil? - nic_index = add_nic_index - + if options[:nics] !=[] #ADD NICS options[:nics].each { |nic| mac_address = nic[:mac] - if !mac_address or (mac_address and !find_nic_by_mac(mac_address)) + if !mac_address or (mac_address and !find_nic_by_mac(mac_address)) network_name = nic[:network_name] ip_addressing_mode = Xml::IP_ADDRESSING_MODE[:POOL] @@ -207,13 +206,22 @@ def reconfigure(options) } end - #DELETE NICS - nics.each{ |nc| - if options[:nic].nil? or !options[:nic][:mac].include? "#{nc.mac_address}" - payload.delete_nics(nc) + #DELETE NICS + macs = [] + options[:nics].each do |nic| + macs.push(nic[:mac]) + end + + if macs.empty? + payload.delete_nics(*nics) + else + nics.each do |nc| + options[:nics].each do |nic| + payload.delete_nics(nc) if !macs.include? "#{nc.mac_address}" end - } - + end + end + task = connection.post(payload.reconfigure_link.href, payload, Xml::MEDIA_TYPE[:VM]) @@ -291,7 +299,7 @@ def list_disks end ############################################################################################### - # Attaches a disk to VM. + # Attaches an independent disk to VM. # @param disk [Disk] The disk object to attach. # @throw ############################################################################################### @@ -448,6 +456,18 @@ def vmtools? !entity_xml.vm_tools.nil? end + def acquire_VMRC_ticket + + fail(CloudError, + "The VM must be powered on") if self.status != "POWERED_ON" + + Config.logger.info( + "Obtaining VMware VMware Remote Console Ticket on #{name} ...") + task = connection.post(entity_xml.vmrc_ticket_link.href,nil) + task = task.nil? ? nil : task.content + + end + def install_vmtools Config.logger.info( "Mounting VMware tools on #{name} ...") @@ -631,9 +651,8 @@ def add_customization(section, customization) section .tap do |params| params.enable - params.computer_name = customization[:computer_name] + params.computer_name = customization[:computer_name] unless customization[:computer_name].nil? params.admin_pass = customization[:admin_pass] unless customization[:admin_pass].nil? - #params.reset_pass = customization[:reset_pass] unless customization[:reset_pass].nil? params.script = customization[:custom_script] unless customization[:custom_script].nil? end end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper.rb b/lib/ruby_vcloud_sdk/xml/wrapper.rb index 08952cb..5966b9c 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper.rb @@ -122,6 +122,10 @@ def type def type=(type) @root["type"] = type end + + def size + @root["size"] + end def remove_link get_nodes(XML_TYPE[:LINK], diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb index fca5494..b6123e3 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb @@ -5,6 +5,7 @@ require "ruby_vcloud_sdk/xml/wrapper_classes/allocated_ip_addresses" require "ruby_vcloud_sdk/xml/wrapper_classes/catalog_item" require "ruby_vcloud_sdk/xml/wrapper_classes/customization" +require "ruby_vcloud_sdk/xml/wrapper_classes/dnat_rules" require "ruby_vcloud_sdk/xml/wrapper_classes/disk" require "ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params" require "ruby_vcloud_sdk/xml/wrapper_classes/disk_create_params" @@ -23,6 +24,7 @@ require "ruby_vcloud_sdk/xml/wrapper_classes/media" require "ruby_vcloud_sdk/xml/wrapper_classes/media_insert_or_eject_params" require "ruby_vcloud_sdk/xml/wrapper_classes/metadata_value" +require "ruby_vcloud_sdk/xml/wrapper_classes/snat_rules" require "ruby_vcloud_sdk/xml/wrapper_classes/network" require "ruby_vcloud_sdk/xml/wrapper_classes/network_config" require "ruby_vcloud_sdk/xml/wrapper_classes/network_config_section" diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb index 6ca176a..37e537c 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb @@ -13,7 +13,7 @@ def entity=(entity) def entity get_nodes(XML_TYPE[:ENTITY]).first end - + def description get_nodes("Description").first.content end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/dnat_rules.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/dnat_rules.rb new file mode 100644 index 0000000..bd53d78 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/dnat_rules.rb @@ -0,0 +1,56 @@ +module VCloudSdk + module Xml + class NatRule < Wrapper + + def description=(desc) + get_nodes("Description").first.content = desc + end + + def rule_type=(type) + get_nodes("RuleType").first.content = type + end + + def enabled=(opt) + get_nodes("IsEnabled").first.content = opt + end + + def id=(id) + get_nodes("Id").first.content = id + end + + def interface=(interface) + get_nodes("Interface").first["type"] = interface.get_nodes("Network").first["type"] + get_nodes("Interface").first["name"] = interface.get_nodes("Network").first["name"] + get_nodes("Interface").first["href"] = interface.get_nodes("Network").first["href"] + end + + def original_ip=(ip) + get_nodes("OriginalIp").first.content = ip + end + + def original_ip + get_nodes("OriginalIp").first.content + end + + def original_port=(port) + get_nodes("OriginalPort").first.content = port + end + + def translated_ip=(ip) + get_nodes("TranslatedIp").first.content = ip + end + + def translated_ip + get_nodes("TranslatedIp").first.content + end + + def translated_port=(port) + get_nodes("TranslatedPort").first.content = port + end + + def protocol=(protocol) + get_nodes("Protocol").first.content = protocol + end + end + end +end \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb index 0398fe1..3a12717 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb @@ -10,11 +10,8 @@ def configure_services get_nodes("EdgeGatewayServiceConfiguration").first end - def add_rules(rules) - ###OBTAIN LAST ID - id = get_nodes("FirewallRule").last - .get_nodes("Id").first - .content.to_i + def add_fw_rules(rules) + id = obtain_id("FirewallRule").nil? ? 1 : obtain_id("FirewallRule") rules.each do |rule| id = id + 1 fw_rule = Xml::WrapperFactory.create_instance("FirewallRule").tap do |params| @@ -25,13 +22,13 @@ def add_rules(rules) params.action = rule[:action] params.enabled = rule[:enabled] end - nm = @root.at_css "FirewallRule" - nm.add_next_sibling "\n#{fw_rule}" + nm = get_nodes("FirewallRule").last.node + nm.after(fw_rule.node) end self end - def remove_rules(ips) + def remove_fw_rules(ips) rules = get_nodes("FirewallRule") rules.each do |rule| ips.each do |ip| @@ -41,6 +38,53 @@ def remove_rules(ips) self end + def add_nat_rules(rules) + id = obtain_id("NatRule").nil? ? 65537 : obtain_id("NatRule") + rules.each do |rule| + id = id + 1 + if rule[:rule_type] == "SNAT" + snat_rule = Xml::WrapperFactory.create_instance("SNatRule").tap do |params| + params.id = id.to_s + params.description = rule[:description] + params.enabled = rule[:enabled] + params.rule_type = rule[:rule_type] + params.interface = gateway_interface_by_name(rule[:interface]) + params.original_ip = rule[:original_ip] + params.translated_ip = rule[:translated_ip] + end + nm = get_nodes("NatRule").last.node + nm.after(snat_rule.node) + + elsif rule[:rule_type] == "DNAT" + dnat_rule = Xml::WrapperFactory.create_instance("DNatRule").tap do |params| + params.id = id.to_s + params.description = rule[:description] + params.enabled = rule[:enabled] + params.rule_type = rule[:rule_type] + params.interface = gateway_interface_by_name(rule[:interface]) + params.original_ip = rule[:original_ip] + params.original_port = rule[:original_port] + params.translated_ip = rule[:translated_ip] + params.translated_port = rule[:translated_port] + params.protocol = rule[:protocol] + end + nm = get_nodes("NatRule").last.node + nm.after(dnat_rule.node) + end + end + self + end + + def remove_nat_rules(ips) + rules = get_nodes("NatRule") + rules.each do |rule| + ips.each do |ip| + rule.node.remove if rule.original_ip == ip or rule.translated_ip + end + end + self + end + def gateway_interfaces get_nodes(:Configuration, nil, true) .first @@ -48,6 +92,27 @@ def gateway_interfaces .first .get_nodes(:GatewayInterface, nil, true) end + + private + + def obtain_id(tag) + if get_nodes(tag).empty? + id = nil + else + id = get_nodes(tag).last + .get_nodes("Id").first + .content.to_i + end + return id + + end + + def gateway_interface_by_name(name) + gateway_interfaces.each do |gat_in| + return gat_in if gat_in.get_nodes("Name").first.content == name + end + end + end end end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb index bf2477b..6148659 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb @@ -15,6 +15,16 @@ def description get_nodes("Description").first.content end + def gateway + get_nodes(:IpScope).first. + get_nodes("Gateway").first.content + end + + def netmask + get_nodes(:IpScope).first. + get_nodes("Netmask").first.content + end + def fence_mode get_nodes("FenceMode").first.content end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/snat_rules.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/snat_rules.rb new file mode 100644 index 0000000..de4bcdf --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/snat_rules.rb @@ -0,0 +1,44 @@ +module VCloudSdk + module Xml + class NatRule < Wrapper + + def description=(desc) + get_nodes("Description").first.content = desc + end + + def rule_type=(type) + get_nodes("RuleType").first.content = type + end + + def enabled=(opt) + get_nodes("IsEnabled").first.content = opt + end + + def id=(id) + get_nodes("Id").first.content = id + end + + def interface=(interface) + get_nodes("Interface").first["type"] = interface.get_nodes("Network").first["type"] + get_nodes("Interface").first["name"] = interface.get_nodes("Network").first["name"] + get_nodes("Interface").first["href"] = interface.get_nodes("Network").first["href"] + end + + def original_ip=(ip) + get_nodes("OriginalIp").first.content = ip + end + + def original_ip + get_nodes("OriginalIp").first.content + end + + def translated_ip=(ip) + get_nodes("TranslatedIp").first.content = ip + end + + def translated_ip + get_nodes("TranslatedIp").first.content + end + end + end +end \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index d6c383d..f771120 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -62,6 +62,12 @@ def vm_tools return nil end + def vmrc_ticket_link + get_nodes(XML_TYPE[:LINK], + { rel: "screen:acquireTicket" }, + true).first + end + def ip_address ips = [] get_nodes("NetworkConnection").each do |ip| diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/DNatRule.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/DNatRule.xml new file mode 100644 index 0000000..1a39367 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/DNatRule.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/SNatRule.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/SNatRule.xml new file mode 100644 index 0000000..df28812 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/SNatRule.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/ruby_vcloud_sdk.gemspec b/ruby_vcloud_sdk.gemspec index 36e4443..fba41d6 100644 --- a/ruby_vcloud_sdk.gemspec +++ b/ruby_vcloud_sdk.gemspec @@ -1,10 +1,8 @@ # -*- encoding: utf-8 -*- -# Copyright (c) 2009-2012 VMware, Inc. -# Copyright 2016-2016, vCloud Driver Project, CSUC Gem::Specification.new do |s| s.name = "ruby_vcloud_sdk" - s.version = "0.7.5" + s.version = "0.7.7" s.date = Date.today.to_s s.platform = Gem::Platform::RUBY s.summary = "BOSH vCloud API client" From 1f03b3676137ee2915213cf55d154aedf4d4cdae Mon Sep 17 00:00:00 2001 From: CSUC Date: Thu, 5 Jan 2017 10:43:16 +0100 Subject: [PATCH 37/37] Added Disk resize capability during instanstiation --- README.md | 2 +- lib/ruby_vcloud_sdk/catalog.rb | 17 +++-- lib/ruby_vcloud_sdk/catalog_item.rb | 5 ++ lib/ruby_vcloud_sdk/edge_gateway.rb | 29 +++++++- lib/ruby_vcloud_sdk/envelope.rb | 45 +++++++++++ lib/ruby_vcloud_sdk/infrastructure.rb | 1 - lib/ruby_vcloud_sdk/network.rb | 4 + lib/ruby_vcloud_sdk/template_vapp.rb | 45 +++++++++++ lib/ruby_vcloud_sdk/vdc.rb | 2 +- lib/ruby_vcloud_sdk/vdc_storage_profile.rb | 2 +- lib/ruby_vcloud_sdk/vm.rb | 74 +++++++++++++++---- lib/ruby_vcloud_sdk/xml/constants.rb | 1 + lib/ruby_vcloud_sdk/xml/wrapper.rb | 19 ++--- lib/ruby_vcloud_sdk/xml/wrapper_classes.rb | 2 + .../xml/wrapper_classes/customization.rb | 23 ++++-- .../xml/wrapper_classes/edge_gateway.rb | 32 ++++++-- .../xml/wrapper_classes/envelope.rb | 14 ++++ .../wrapper_classes/hard_disk_item_wrapper.rb | 12 +++ .../instantiate_vapp_template_params.rb | 9 +++ .../sourced_vm_instatiation_params.rb | 17 +++++ .../xml/wrapper_classes/template_vapp.rb | 10 +++ .../xml/wrapper_classes/vapp_template.rb | 9 +++ lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb | 47 +++++++++++- .../InstantiateVAppTemplateParams.xml | 10 ++- .../SourcedVmInstantiationParams.xml | 9 +++ ruby_vcloud_sdk.gemspec | 2 +- 26 files changed, 386 insertions(+), 56 deletions(-) create mode 100644 lib/ruby_vcloud_sdk/envelope.rb create mode 100644 lib/ruby_vcloud_sdk/template_vapp.rb create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/envelope.rb create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/sourced_vm_instatiation_params.rb create mode 100644 lib/ruby_vcloud_sdk/xml/wrapper_classes/template_vapp.rb create mode 100644 lib/ruby_vcloud_sdk/xml/xml_templates/SourcedVmInstantiationParams.xml diff --git a/README.md b/README.md index 45dc98a..3f11a99 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Copyright (c) VMware, Inc. | | | |-> Vdc Storage Profile | - |-> Catalog |-> Catalog Item + |-> Catalog |-> Catalog Item |-> Template Vapp |-> Envelope | | | |-> OVF Directory | diff --git a/lib/ruby_vcloud_sdk/catalog.rb b/lib/ruby_vcloud_sdk/catalog.rb index a6daf6d..c009b6d 100644 --- a/lib/ruby_vcloud_sdk/catalog.rb +++ b/lib/ruby_vcloud_sdk/catalog.rb @@ -151,13 +151,15 @@ def find_vapp_template_by_name(name) end def instantiate_vapp_template(template_name, vdc_name, vapp_name, - description = nil, disk_locality = nil, network_config = nil) - + description = nil, disk_locality = nil, network_config = nil, vm_params = nil) + + catalog_item = find_vapp_template_by_name(template_name) + vm_link = catalog_item.vapp_template.vm_link + instantiate_vapp_params = create_instantiate_vapp_params( - template_name, vapp_name, description, disk_locality, network_config) - - vdc = find_vdc_by_name vdc_name + template_name, vapp_name, description, disk_locality, network_config,vm_params,vm_link) + vdc = find_vdc_by_name vdc_name vapp = connection.post(vdc.instantiate_vapp_template_link, instantiate_vapp_params) vapp.running_tasks.each do |task| @@ -344,7 +346,7 @@ def retrieve_vapp_template_xml_node(template_name) end def create_instantiate_vapp_params(template_name, - vapp_name, description, disk_locality, network_config) + vapp_name, description, disk_locality, network_config,vm_params,vm_link) source_vapp_template = retrieve_vapp_template_xml_node(template_name) @@ -360,6 +362,9 @@ def create_instantiate_vapp_params(template_name, instantiate_vapp_params.linked_clone = false instantiate_vapp_params.set_locality = locality_spec( source_vapp_template, disk_locality) + + disk = vm_params.first + instantiate_vapp_params.disk_size(disk[:id],disk[:size],vm_link) instantiate_vapp_params end diff --git a/lib/ruby_vcloud_sdk/catalog_item.rb b/lib/ruby_vcloud_sdk/catalog_item.rb index bd32fd9..70a7880 100644 --- a/lib/ruby_vcloud_sdk/catalog_item.rb +++ b/lib/ruby_vcloud_sdk/catalog_item.rb @@ -1,5 +1,6 @@ require_relative "session" require_relative "infrastructure" +require_relative "template_vapp" module VCloudSdk @@ -74,6 +75,10 @@ def href entity_xml.entity[:href] end + def vapp_template + VCloudSdk::TemplateVapp.new(@session, entity_xml.entity[:href]) + end + ############################################################################ # Return the date of creation of the Catalog Item object. # @return [String] The creation date of the catalog item diff --git a/lib/ruby_vcloud_sdk/edge_gateway.rb b/lib/ruby_vcloud_sdk/edge_gateway.rb index b5e2d26..9b96b7d 100644 --- a/lib/ruby_vcloud_sdk/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/edge_gateway.rb @@ -67,7 +67,9 @@ def remove_fw_rules(ips) monitor_task(task) self end - + def ent + entity_xml + end ############################################################################ # Add Nat rules to the Edge Gateyay. # @param rules [Array] Array of Hashes representing the rules to be added. @@ -110,6 +112,31 @@ def remove_nat_rules(ips) self end + def public_net_name + uplink_gateway_interface = entity_xml + .gateway_interfaces + .find { |g| g.interface_type == "uplink" } + return uplink_gateway_interface.get_nodes("Name").first.content + + end + + def public_ip_net + uplink_gateway_interface = entity_xml + .gateway_interfaces + .find { |g| g.interface_type == "uplink" } + + ip_address = uplink_gateway_interface.get_nodes("IpAddress").first.content.split(".") + netmask = uplink_gateway_interface.get_nodes("Netmask").first.content.split(".") + + ip_net = "" + ip_net << (ip_address[0].to_i & netmask[0].to_i).to_s << "." + ip_net << (ip_address[1].to_i & netmask[1].to_i).to_s << "." + ip_net << (ip_address[2].to_i & netmask[2].to_i).to_s << "." + ip_net << (ip_address[3].to_i & netmask[3].to_i).to_s + + return ip_net + end + def public_ip_ranges uplink_gateway_interface = entity_xml .gateway_interfaces diff --git a/lib/ruby_vcloud_sdk/envelope.rb b/lib/ruby_vcloud_sdk/envelope.rb new file mode 100644 index 0000000..c7ba785 --- /dev/null +++ b/lib/ruby_vcloud_sdk/envelope.rb @@ -0,0 +1,45 @@ +require_relative "infrastructure" + +module VCloudSdk + + ############################################################################## + # This class represents a catalog item in catalog. + # It can be a vApp Template or media&other, + ############################################################################## + class Envelope + include Infrastructure + + + ############################################################################ + # Initializes a Catalog Item object associated with a vCloud Session and the + # the catalog item's link + # @param session [Session] The client's session + # @param link [String] The xml representation of catalog item + ############################################################################ + def initialize(session, link) + @session = session + @link = link + end + + def ent + entity_xml + end + + def os + entity_xml.operating_system + end + + def disks + hardware_section = entity_xml.hardware_section + internal_disks = [] + hardware_section.hard_disks.each do |disk| + disk_link = disk.host_resource.attribute("disk") + if disk_link.nil? + internal_disks << VCloudSdk::InternalDisk.new(disk) + end + end + internal_disks + end + end + ############################################################################## +end diff --git a/lib/ruby_vcloud_sdk/infrastructure.rb b/lib/ruby_vcloud_sdk/infrastructure.rb index 2643967..cc69b26 100644 --- a/lib/ruby_vcloud_sdk/infrastructure.rb +++ b/lib/ruby_vcloud_sdk/infrastructure.rb @@ -36,7 +36,6 @@ def vdc_exists?(name) # @return [VDC] The array of VDC. ############################################################################################# def vdcs - #@session.org.vdcs @session.org.vdcs.map do |vdc_link| VCloudSdk::VDC.new(@session, vdc_link) end diff --git a/lib/ruby_vcloud_sdk/network.rb b/lib/ruby_vcloud_sdk/network.rb index bcec04b..f908b9e 100644 --- a/lib/ruby_vcloud_sdk/network.rb +++ b/lib/ruby_vcloud_sdk/network.rb @@ -29,6 +29,10 @@ def initialize(session, link) def id @link.href.split("/")[5] end + + def ent + entity_xml + end #################################################################################### # Returns the description of the Network. diff --git a/lib/ruby_vcloud_sdk/template_vapp.rb b/lib/ruby_vcloud_sdk/template_vapp.rb new file mode 100644 index 0000000..01eb76a --- /dev/null +++ b/lib/ruby_vcloud_sdk/template_vapp.rb @@ -0,0 +1,45 @@ +require_relative "session" +require_relative "infrastructure" +require_relative "envelope" + +module VCloudSdk + + ############################################################################## + # This class represents a catalog item in catalog. + # It can be a vApp Template or media&other, + ############################################################################## + class TemplateVapp + include Infrastructure + + ############################################################################ + # Initializes a Catalog Item object associated with a vCloud Session and the + # the catalog item's link + # @param session [Session] The client's session + # @param link [String] The xml representation of catalog item + ############################################################################ + def initialize(session, link) + @session = session + @link = link + end + + def ovf_descriptor + ovf = VCloudSdk::Envelope.new(@session, entity_xml.ovf_link) + ovf.ent + end + + def disks + ovf = VCloudSdk::Envelope.new(@session, entity_xml.ovf_link) + ovf.disks + end + + def operating_system + ovf = VCloudSdk::Envelope.new(@session, entity_xml.ovf_link) + ovf.os + end + + def vm_link + entity_xml.vm_link + end + end + ############################################################################## +end diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb index 4510e9d..cf56938 100644 --- a/lib/ruby_vcloud_sdk/vdc.rb +++ b/lib/ruby_vcloud_sdk/vdc.rb @@ -34,7 +34,7 @@ def initialize(session, link) @session = session @link = link end - + ############################################################################################# # Returns the storage profiles assoaciated with the Virtual Data Center. # @return [VdcStorageProfile] The storafe profiles of de VDC. diff --git a/lib/ruby_vcloud_sdk/vdc_storage_profile.rb b/lib/ruby_vcloud_sdk/vdc_storage_profile.rb index af1c27a..bf8776c 100644 --- a/lib/ruby_vcloud_sdk/vdc_storage_profile.rb +++ b/lib/ruby_vcloud_sdk/vdc_storage_profile.rb @@ -3,7 +3,7 @@ module VCloudSdk class VdcStorageProfile attr_reader :name, :storage_used_mb, :storage_limit_mb - def initialize(storage_profile_xml_obj) + def initialize(storage_profile_xml_obj) @storage_profile_xml_obj = storage_profile_xml_obj @name = @storage_profile_xml_obj[:name] @storage_used_mb = @storage_profile_xml_obj[:storageUsedMB].to_i diff --git a/lib/ruby_vcloud_sdk/vm.rb b/lib/ruby_vcloud_sdk/vm.rb index a78c989..aad3c20 100644 --- a/lib/ruby_vcloud_sdk/vm.rb +++ b/lib/ruby_vcloud_sdk/vm.rb @@ -25,7 +25,7 @@ def initialize(session, link) @session = session @link = link end - + ############################################################################################### # Returns the identifier of the VM (uuid) # @return [String] The identifier of the VM @@ -42,7 +42,9 @@ def id def href @link end - + def ent + entity_xml + end ############################################################################################### # Returns the memory of the VM # @return [String] The memory in MB of the VM @@ -148,12 +150,13 @@ def name=(name) # :ip [String] Optional. The IP of the nic # :mac [String] Optional. The MAC of the nic # :disks [Array] Array of Hases representing the disks to - # attach to VM + # attach to VM + # :id [String] Disk's identifier. + # :size [String] Size of disk in MB. # :vapp_name [String] The name of the vApp # @return [VM] ############################################################################################### - def reconfigure(options) - + def reconfigure(options) payload = entity_xml payload.name = options[:name] if !options[:name].nil? payload.description = options[:description] if !options[:name].nil? @@ -161,9 +164,10 @@ def reconfigure(options) payload.change_memory(options[:memory]) if !options[:name].nil? nic_index = add_nic_index + #NETWORK CONFIGURATION if options[:nics] !=[] #ADD NICS - options[:nics].each { |nic| + options[:nics].each do |nic| mac_address = nic[:mac] @@ -203,7 +207,7 @@ def reconfigure(options) end nic_index = nic_index + 1 end - } + end end #DELETE NICS @@ -222,6 +226,41 @@ def reconfigure(options) end end + #DISK CONFIGURATION + + if !options[:disks].empty? + + options[:disks].each do |disk| + + capacity = disk[:size].to_i + fail(CloudError,"Invalid size in MB #{capacity}") if capacity <= 0 + disk_id = disk[:id] + if !payload.hard_disk_exists?(disk_id) + bus_type = "scsi" + bus_type = Xml::BUS_TYPE_NAMES[bus_type.downcase] + fail(CloudError,"Invalid bus type!") unless bus_type + + bus_sub_type = "lsilogic" + bus_sub_type = Xml::BUS_SUB_TYPE_NAMES[bus_sub_type.downcase] + fail(CloudError,"Invalid bus sub type!") unless bus_sub_type + + payload.add_hard_disk(capacity.to_s, bus_type, bus_sub_type,disk_id) + end + end + + end + + #DELETE DISKS + + disks = [] + options[:disks].each do |disk| + disks.push(disk[:id]) + end + + internal_disks.each do |i_disk| + payload.delete_hard_disk_by_id(i_disk.id) if !disks.include?(i_disk.id) + end + task = connection.post(payload.reconfigure_link.href, payload, Xml::MEDIA_TYPE[:VM]) @@ -509,7 +548,8 @@ def internal_disks def create_internal_disk( capacity, bus_type = "scsi", - bus_sub_type = "lsilogic") + bus_sub_type = "lsilogic", + disk_id = nil) fail(CloudError, "Invalid size in MB #{capacity}") if capacity <= 0 @@ -527,15 +567,15 @@ def create_internal_disk( .info "Creating internal disk #{name} of #{capacity}MB." payload = entity_xml - payload.add_hard_disk(capacity, bus_type, bus_sub_type) + payload.add_hard_disk(capacity, bus_type, bus_sub_type,disk_id) task = connection.post(payload.reconfigure_link.href, payload, - Xml::MEDIA_TYPE[:VM]) + Xml::MEDIA_TYPE[:VM]) monitor_task(task) self end - + def delete_internal_disk_by_name(name) payload = entity_xml @@ -555,10 +595,12 @@ def delete_internal_disk_by_name(name) # All params are optional. # @param customization [Hash] The parameters of the guestOS customization. All parameters are # optional. - # :computer_name [String] The name of the computer - # :admin_pass [String] The password for the Administrator/root user - # :reset_pass [String] Values "true" or "false". To reset password. - # :custom_script [String] The customization script (Max 49,000 characters) + # :computer_name [String] The name of the computer + # :admin_pass [String] The password for the Administrator/root user + # :custom_script [String] The customization script (Max 49,000 characters) + # :sid [Boolean] Applicable for Windows VMs and will run Sysprep + # to change Windows SID. + # :auto_password [Boolean] Generates an automatic Administrator's password. # # @return [VM] ############################################################################################################ @@ -654,6 +696,8 @@ def add_customization(section, customization) params.computer_name = customization[:computer_name] unless customization[:computer_name].nil? params.admin_pass = customization[:admin_pass] unless customization[:admin_pass].nil? params.script = customization[:custom_script] unless customization[:custom_script].nil? + params.change_sid = customization[:sid] + params.auto_password = customization[:auto_password] unless customization[:auto_password].nil? or !customization[:admin_pass].nil? end end diff --git a/lib/ruby_vcloud_sdk/xml/constants.rb b/lib/ruby_vcloud_sdk/xml/constants.rb index 1532584..0fb1ef2 100644 --- a/lib/ruby_vcloud_sdk/xml/constants.rb +++ b/lib/ruby_vcloud_sdk/xml/constants.rb @@ -26,6 +26,7 @@ module Xml :CONNECTION => "Connection", :PARENT => "Parent", :ELEMENT_NAME => "ElementName", + :DESCRIPTION => "Description", :ALLOCATION_UNITS => "AllocationUnits", :VIRTUAL_QUANTITY => "VirtualQuantity" } diff --git a/lib/ruby_vcloud_sdk/xml/wrapper.rb b/lib/ruby_vcloud_sdk/xml/wrapper.rb index 5966b9c..f438d72 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper.rb @@ -7,14 +7,14 @@ class WrapperFactory class << self def wrap_document(xml, ns = nil, namespace_defintions = nil, *args) doc = Nokogiri::XML(xml) - type_name = doc.root.name - node_class = find_wrapper_class(type_name) + type_name = doc.root.name + node_class = find_wrapper_class(type_name) node_class.new(doc, ns, namespace_defintions, *args) end def wrap_node(node, ns, namespace_defintions = nil, *args) - type_name = node.node_name - node_class = find_wrapper_class(type_name) + type_name = node.node_name + node_class = find_wrapper_class(type_name) node_class.new(node, ns, namespace_defintions, *args) end @@ -29,10 +29,11 @@ def wrap_nodes(nodes, ns, namespace_defintions) # TODO: We might run into a bug later if there are ever XML node types # of the same name but different namespace def find_wrapper_class(type_name) - # for Ruby 1.9, we would need pass false in as the 2nd parameter - if Xml.constants.find { |c| c.to_sym == type_name.to_sym } - Xml.const_get(type_name.to_sym) - else + # for Ruby 1.9, we would need pass false in as the 2nd parameter + #Xml.constants.find { |c| puts "#{c.to_sym} . #{type_name.to_sym}"} + if Xml.constants.find { |c| c.to_sym == type_name.to_sym } + Xml.const_get(type_name.to_sym) + else Wrapper end end @@ -115,7 +116,7 @@ def urn @root["id"] end - def type + def type @root["type"] end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb index b6123e3..93443df 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb @@ -10,6 +10,7 @@ require "ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params" require "ruby_vcloud_sdk/xml/wrapper_classes/disk_create_params" require "ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway" +require "ruby_vcloud_sdk/xml/wrapper_classes/envelope" require "ruby_vcloud_sdk/xml/wrapper_classes/entity" require "ruby_vcloud_sdk/xml/wrapper_classes/file" require "ruby_vcloud_sdk/xml/wrapper_classes/fw_rules" @@ -39,6 +40,7 @@ require "ruby_vcloud_sdk/xml/wrapper_classes/query_result_records" require "ruby_vcloud_sdk/xml/wrapper_classes/recompose_vapp_params" require "ruby_vcloud_sdk/xml/wrapper_classes/session" +require "ruby_vcloud_sdk/xml/wrapper_classes/sourced_vm_instatiation_params" require "ruby_vcloud_sdk/xml/wrapper_classes/supported_versions" require "ruby_vcloud_sdk/xml/wrapper_classes/task" require "ruby_vcloud_sdk/xml/wrapper_classes/upload_vapp_template_params" diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb index c79c7a3..c9ac69d 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/customization.rb @@ -10,7 +10,7 @@ def type=(value) end def enable(uuid=nil) - get_nodes("Enabled").first.content = "true" + get_nodes("Enabled").first.content = true get_nodes("VirtualMachineId").first.content = uuid end @@ -18,27 +18,36 @@ def computer_name=(value) get_nodes("ComputerName").first.content = value end + def change_sid=(value) + get_nodes("ChangeSid").first.content = value + end + def admin_pass=(value) - get_nodes("AdminPasswordEnabled").first.content = "true" - get_nodes("AdminPasswordAuto").first.content = "false" + get_nodes("AdminPasswordEnabled").first.content = true + get_nodes("AdminPasswordAuto").first.content = false if get_nodes("AdminPassword").first.nil? - nm = @root.at_css "AdminPasswordAuto" - nm.add_next_sibling "#{value}" + nm = get_nodes("AdminPasswordAuto").last.node + nm.after("#{value}") else get_nodes("AdminPassword").first.content = value end end + def auto_password=(value) + get_nodes("AdminPasswordEnabled").first.content = true + get_nodes("AdminPasswordAuto").first.content = value + end + def reset_pass=(value) get_nodes("ResetPasswordRequired").first.content = value end def script=(value) if get_nodes("CustomizationScript").first.nil? - nm = @root.at_css "ResetPasswordRequired" - nm.add_next_sibling "#{value}" + nm = get_nodes("ResetPasswordRequired").last.node + nm.after("#{value}") else get_nodes("CustomizationScript").first.content = value diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb index 3a12717..0a66dc3 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb @@ -21,9 +21,14 @@ def add_fw_rules(rules) params.ports(rule[:port_src],rule[:port_dest]) params.action = rule[:action] params.enabled = rule[:enabled] - end - nm = get_nodes("FirewallRule").last.node - nm.after(fw_rule.node) + end + if (!get_nodes("FirewallRule").empty?) + nm = get_nodes("FirewallRule").last.node + nm.after(fw_rule.node) + else + nm = get_nodes("FirewallService").first.node + nm.add_child(fw_rule.node) + end end self end @@ -52,8 +57,13 @@ def add_nat_rules(rules) params.original_ip = rule[:original_ip] params.translated_ip = rule[:translated_ip] end - nm = get_nodes("NatRule").last.node - nm.after(snat_rule.node) + if (!get_nodes("NatRule").empty?) + nm = get_nodes("NatRule").last.node + nm.after(snat_rule.node) + else + nm = get_nodes("NatService").first.node + nm.add_child(snat_rule.node) + end elsif rule[:rule_type] == "DNAT" dnat_rule = Xml::WrapperFactory.create_instance("DNatRule").tap do |params| @@ -68,8 +78,14 @@ def add_nat_rules(rules) params.translated_port = rule[:translated_port] params.protocol = rule[:protocol] end - nm = get_nodes("NatRule").last.node - nm.after(dnat_rule.node) + if (!get_nodes("NatRule").empty?) + nm = get_nodes("NatRule").last.node + nm.after(dnat_rule.node) + else + nm = get_nodes("NatService").first.node + nm.add_child(dnat_rule.node) + end + end end self @@ -79,7 +95,7 @@ def remove_nat_rules(ips) rules = get_nodes("NatRule") rules.each do |rule| ips.each do |ip| - rule.node.remove if rule.original_ip == ip or rule.translated_ip + rule.node.remove if rule.original_ip == ip or rule.translated_ip == ip end end self diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/envelope.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/envelope.rb new file mode 100644 index 0000000..fc4d863 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/envelope.rb @@ -0,0 +1,14 @@ +module VCloudSdk + module Xml + class Envelope < Wrapper + def operating_system + get_nodes("OperatingSystemSection", nil, false, OVF).first. + get_nodes("Description",nil,false,OVF).first.content + end + + def hardware_section + get_nodes("VirtualHardwareSection",nil,false,OVF).first + end + end + end +end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb index 0d08af7..9a6ee41 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb @@ -17,11 +17,19 @@ def initialize(item) def capacity_mb host_resource[HOST_RESOURCE_ATTRIBUTE[:CAPACITY]] end + + def capacity_mb= new_capacity + host_resource[HOST_RESOURCE_ATTRIBUTE[:CAPACITY]] = new_capacity + end def disk_id get_rasd_content(RASD_TYPES[:ADDRESS_ON_PARENT]) end + def disk_id= new_id + set_rasd_content(new_id,RASD_TYPES[:ADDRESS_ON_PARENT]) + end + def instance_id get_rasd_content(RASD_TYPES[:INSTANCE_ID]) end @@ -42,6 +50,10 @@ def element_name get_rasd_content(RASD_TYPES[:ELEMENT_NAME]) end + def element_name= new_name + set_rasd_content(new_name,RASD_TYPES[:ELEMENT_NAME]) + end + def host_resource get_rasd(RASD_TYPES[:HOST_RESOURCE]) end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_vapp_template_params.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_vapp_template_params.rb index 33ca1ac..70b394a 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_vapp_template_params.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_vapp_template_params.rb @@ -27,6 +27,15 @@ def linked_clone=(value) @root["linkedClone"] = value.to_s end + def disk_size(id,size,vm_link) + return unless id + sourced = Xml::WrapperFactory + .create_instance("SourcedVmInstantiationParams", nil, nil) + sourced.resize_disk(id,size,vm_link) + nm = get_nodes("IsSourceDelete").first.node + nm.after(sourced.node) + end + def source=(src) source_node = get_nodes("Source").first source_node["href"] = src["href"] diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/sourced_vm_instatiation_params.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/sourced_vm_instatiation_params.rb new file mode 100644 index 0000000..8682143 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/sourced_vm_instatiation_params.rb @@ -0,0 +1,17 @@ +module VCloudSdk + module Xml + + class SourcedVmInstantiationParams < Wrapper + def name + @root["name"] + end + def resize_disk(id,size,vm_link) + disk_node = get_nodes("Source").first + disk_node["href"] = vm_link + disk_node = get_nodes("Disk").first + disk_node["instanceId"] = "200#{id}" + get_nodes("Size").first.content = size + end + end + end +end \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/template_vapp.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/template_vapp.rb new file mode 100644 index 0000000..c9de9e1 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/template_vapp.rb @@ -0,0 +1,10 @@ +module VCloudSdk + module Xml + class TemplateVapp < Wrapper + def vm_link + get_nodes("Vm").first["href"] + end + end + + end +end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb index 91e0e26..f5d4ecc 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb @@ -2,6 +2,15 @@ module VCloudSdk module Xml class VAppTemplate < VApp + + def vm_link + get_nodes("Vm").first["href"] + end + + def ovf_link + get_nodes("Link", {"rel" => "ovf"}, true).first["href"] + end + def files get_nodes("File") end diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb index f771120..260c1bc 100644 --- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb @@ -76,7 +76,7 @@ def ip_address return ips if !ips.empty? return nil end - + def reconfigure_link get_nodes(XML_TYPE[:LINK], { rel: "reconfigureVm" }, @@ -134,19 +134,37 @@ def guest_customization_section get_nodes("GuestCustomizationSection").first end + def hard_disk_exists?(disk_id) + hardware_section.hard_disks.each do |disk| + return true if disk.disk_id == disk_id + end + return false + end + # hardware modification methods - def add_hard_disk(capacity, bus_type, bus_sub_type) + def add_hard_disk(capacity, bus_type, bus_sub_type,disk_id=nil) section = hardware_section # Create a RASD item new_disk = WrapperFactory .create_instance("Item", nil, hardware_section.doc_namespaces) - section.add_item(new_disk) - # The order matters! + section.add_item(new_disk) + # The order matters! + if !disk_id.nil? + ap = RASD_TYPES[:ADDRESS_ON_PARENT] + new_disk.add_rasd(ap) + new_disk.set_rasd(ap,disk_id) + end new_disk.add_rasd(RASD_TYPES[:HOST_RESOURCE]) new_disk.add_rasd(RASD_TYPES[:INSTANCE_ID]) + if !disk_id.nil? + p = RASD_TYPES[:PARENT] + new_disk.add_rasd(p) + new_disk.set_rasd(RASD_TYPES[:PARENT],1) + end + rt = RASD_TYPES[:RESOURCE_TYPE] new_disk.add_rasd(rt) new_disk.set_rasd(rt, HARDWARE_TYPE[:HARD_DISK]) @@ -159,6 +177,18 @@ def add_hard_disk(capacity, bus_type, bus_sub_type) "busType", VCLOUD_NAMESPACE)] = bus_type end + def modify_hard_disk(name,new_capacity) + section = hardware_section + disks = section.hard_disks + disk = disks.find do |d| + d.element_name == name + end + host_resource = disk.get_rasd(RASD_TYPES[:HOST_RESOURCE]) + host_resource[disk.create_qualified_name( + "capacity", VCLOUD_NAMESPACE)] = new_capacity.to_s + end + + def delete_hard_disk?(disk_name) hardware_section.hard_disks.each do |disk| if disk.element_name == disk_name @@ -166,7 +196,16 @@ def delete_hard_disk?(disk_name) return true end end + false + end + def delete_hard_disk_by_id(disk_id) + hardware_section.hard_disks.each do |disk| + if disk.disk_id == disk_id + disk.node.remove + return true + end + end false end diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateVAppTemplateParams.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateVAppTemplateParams.xml index 95845f6..b6ff7ba 100644 --- a/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateVAppTemplateParams.xml +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateVAppTemplateParams.xml @@ -1 +1,9 @@ -falsefalse \ No newline at end of file + + + + + + + false + false + \ No newline at end of file diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/SourcedVmInstantiationParams.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/SourcedVmInstantiationParams.xml new file mode 100644 index 0000000..fe194c3 --- /dev/null +++ b/lib/ruby_vcloud_sdk/xml/xml_templates/SourcedVmInstantiationParams.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/ruby_vcloud_sdk.gemspec b/ruby_vcloud_sdk.gemspec index fba41d6..6d24cdd 100644 --- a/ruby_vcloud_sdk.gemspec +++ b/ruby_vcloud_sdk.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = "ruby_vcloud_sdk" - s.version = "0.7.7" + s.version = "0.7.8" s.date = Date.today.to_s s.platform = Gem::Platform::RUBY s.summary = "BOSH vCloud API client"