Class: VCloudClient::Connection
- Inherits:
-
Object
- Object
- VCloudClient::Connection
- Defined in:
- lib/vcloud-rest/connection.rb,
lib/vcloud-rest/vcloud/vm.rb,
lib/vcloud-rest/vcloud/org.rb,
lib/vcloud-rest/vcloud/ovf.rb,
lib/vcloud-rest/vcloud/vdc.rb,
lib/vcloud-rest/vcloud/disk.rb,
lib/vcloud-rest/vcloud/vapp.rb,
lib/vcloud-rest/vcloud/media.rb,
lib/vcloud-rest/vcloud/catalog.rb,
lib/vcloud-rest/vcloud/network.rb,
lib/vcloud-rest/vcloud/extensibility.rb,
lib/vcloud-rest/vcloud/vapp_networking.rb
Overview
Main class to access vCloud rest APIs
Instance Attribute Summary collapse
-
#api_url ⇒ Object
readonly
Returns the value of attribute api_url.
-
#auth_key ⇒ Object
readonly
Returns the value of attribute auth_key.
-
#extensibility ⇒ Object
readonly
Returns the value of attribute extensibility.
Instance Method Summary collapse
-
#acquire_ticket_vm(vmId) ⇒ Object
Retrieve a screen ticket that you can use with the VMRC browser plug-in to gain access to the console of a running VM.
-
#add_internal_network_to_vapp(vAppId, network, config) ⇒ Object
Add an existing network (from Org) to vApp.
-
#add_org_network_to_vapp(vAppId, network, config) ⇒ Object
Add an existing network (from Org) to vApp.
-
#add_vm_network(vmId, network, config = {}) ⇒ Object
Add a new network to a VM.
-
#add_vm_to_vapp(vapp, vm, network_config = {}) ⇒ Object
Create a new virtual machine from a template in an existing vApp.
- #attach_disk_to_vm(disk_id, vm_id) ⇒ Object
-
#cancel_task(id) ⇒ Object
Cancel a given task.
-
#clone_vapp(vdc_id, source_vapp_id, name, deploy = "true", poweron = "false", linked = "false", delete_source = "false") ⇒ Object
Clone a vapp in a given VDC to a new Vapp.
-
#compose_vapp_from_vm(vdc, vapp_name, vapp_description, vm_list = {}, network_config = {}) ⇒ Object
Compose a vapp using existing virtual machines.
- #create_disk(name, size, vdc_id, description = "") ⇒ Object
-
#create_snapshot(vmId, description = "New Snapshot") ⇒ Object
Create a new vm snapshot (overwrites any existing) DEPRECATED - use create_vapp_snapshot instead.
-
#create_vapp_from_template(vdc, vapp_name, vapp_description, vapp_templateid, poweron = false) ⇒ Object
Create a vapp starting from a template.
-
#create_vapp_snapshot(vmId, description = "New Snapshot") ⇒ Object
Create a new vm snapshot (overwrites any existing).
-
#create_vm_snapshot(vmId, description = "New Snapshot") ⇒ Object
Create a new vm snapshot (overwrites any existing).
- #delete_disk(disk_id) ⇒ Object
-
#delete_vapp(vAppId) ⇒ Object
Delete a given vapp NOTE: It doesn’t verify that the vapp is shutdown.
-
#delete_vapp_network(vAppId, network) ⇒ Object
Remove an existing network.
-
#delete_vm_network(vmId, network) ⇒ Object
Remove an existing network.
- #detach_disk_from_vm(disk_id, vm_id) ⇒ Object
-
#discard_suspend_state_vapp(vAppId) ⇒ Object
Discard suspended state of a given vapp.
-
#discard_suspend_state_vm(vmId) ⇒ Object
Discard suspended state of a given vm.
-
#discard_vapp_snapshot(vmId) ⇒ Object
Discard all existing snapshots.
-
#discard_vm_snapshot(vmId) ⇒ Object
Discard all existing snapshots.
-
#edit_vm_network(vmId, network, config = {}) ⇒ Object
Edit VM Network Config.
-
#force_customization_vapp(vappId) ⇒ Object
Force a guest customization.
-
#force_customization_vm(vmId) ⇒ Object
Force a guest customization.
-
#get_catalog(catalogId) ⇒ Object
Fetch details about a given catalog.
-
#get_catalog_by_name(organization, catalogName) ⇒ Object
Friendly helper method to fetch an catalog by name - organization hash (from get_organization/get_organization_by_name) - catalog name.
-
#get_catalog_id_by_name(organization, catalogName) ⇒ Object
Friendly helper method to fetch an catalog id by name - organization hash (from get_organization/get_organization_by_name) - catalog name.
-
#get_catalog_item(catalogItemId) ⇒ Object
Fetch details about a given catalog item: - description - vApp templates.
-
#get_catalog_item_by_name(catalogId, catalogItemName) ⇒ Object
friendly helper method to fetch an catalogItem by name - catalogId (use get_catalog_name(org, name)) - catalagItemName.
- #get_disk(disk_id) ⇒ Object
- #get_disk_by_name(organization, vdcName, diskName) ⇒ Object
- #get_extensibility ⇒ Object
-
#get_network(networkId) ⇒ Object
Fetch details about a given Org VDC network.
-
#get_network_by_name(organization, networkName) ⇒ Object
Friendly helper method to fetch an network by name - organization hash (from get_organization/get_organization_by_name) - network name.
-
#get_network_id_by_name(organization, networkName) ⇒ Object
Friendly helper method to fetch an network id by name - organization hash (from get_organization/get_organization_by_name) - network name.
-
#get_organization(orgId) ⇒ Object
Fetch details about an organization: - catalogs - vdcs - networks - task lists.
-
#get_organization_by_name(name) ⇒ Object
friendly helper method to fetch an Organization by name - name (this isn’t case sensitive).
-
#get_organization_id_by_name(name) ⇒ Object
friendly helper method to fetch an Organization Id by name - name (this isn’t case sensitive).
-
#get_organizations ⇒ Object
Fetch existing organizations and their IDs.
-
#get_task(taskid) ⇒ Object
Fetch information for a given task.
-
#get_tasks_list(id) ⇒ Object
Fetch tasks from a given task list.
-
#get_vapp(vAppId) ⇒ Object
Fetch details about a given vapp: - name - description - status - IP - Children VMs: – IP addresses – status – ID.
-
#get_vapp_by_name(organization, vdcName, vAppName) ⇒ Object
Friendly helper method to fetch a vApp by name - Organization object - Organization VDC Name - vApp name.
-
#get_vapp_edge_public_ip(vAppId) ⇒ Object
get vApp edge public IP from the vApp ID Only works when: - vApp needs to be poweredOn - FenceMode is set to “natRouted” - NatType“ is set to ”portForwarding This will be required to know how to connect to VMs behind the Edge device.
-
#get_vapp_port_forwarding_rules(vAppId) ⇒ Object
Get vApp port forwarding rules.
-
#get_vapp_template(vAppId) ⇒ Object
Fetch details about a given vapp template: - name - description - Children VMs: – ID.
-
#get_vdc(vdcId) ⇒ Object
Fetch details about a given vdc: - description - vapps - templates - disks - networks.
-
#get_vdc_by_name(organization, vdcName) ⇒ Object
Friendly helper method to fetch a Organization VDC by name - Organization object - Organization VDC Name.
-
#get_vdc_id_by_name(organization, vdcName) ⇒ Object
Friendly helper method to fetch a Organization VDC Id by name - Organization object - Organization VDC Name.
-
#get_vm(vmId) ⇒ Object
Fetch details about a given VM.
-
#get_vm_by_name(organization, vdcName, vAppName, vmName) ⇒ Object
Friendly helper method to fetch a vApp by name - Organization object - Organization VDC Name - vApp Name - VM Name.
-
#get_vm_disk_info(vmid) ⇒ Object
Retrieve information about Disks.
-
#get_vm_info(vmid) ⇒ Object
Retrieve information (i.e., memory and CPUs).
-
#initialize(host, username, password, org_name, api_version) ⇒ Connection
constructor
A new instance of Connection.
-
#login ⇒ Object
Authenticate against the specified server.
-
#logout ⇒ Object
Destroy the current session.
-
#poweroff_vapp(vAppId) ⇒ Object
Shutdown a given vapp.
-
#poweroff_vm(vmId) ⇒ Object
Shutdown a given vm.
-
#poweron_vapp(vAppId) ⇒ Object
Boot a given vapp.
-
#poweron_vm(vmId) ⇒ Object
Boot a given vm.
-
#reboot_vapp(vAppId) ⇒ Object
reboot a given vapp This will basically initial a guest OS reboot, and will only work if VMware-tools are installed on the underlying VMs.
-
#reboot_vm(vmId) ⇒ Object
reboot a given vm This will basically initial a guest OS reboot, and will only work if VMware-tools are installed on the underlying VMs.
- #rename_vm(vmId, name) ⇒ Object
-
#reset_vapp(vAppId) ⇒ Object
reset a given vapp This will basically reset the VMs within the vApp vShield Edge devices are not affected.
-
#reset_vm(vmId) ⇒ Object
reset a given vm.
-
#revert_snapshot(vmId) ⇒ Object
Revert to an existing snapshot DEPRECATED - use revert_vapp_snapshot instead.
-
#revert_vapp_snapshot(vmId) ⇒ Object
Revert to an existing snapshot.
-
#revert_vm_snapshot(vmId) ⇒ Object
Revert to an existing snapshot.
-
#set_vapp_network_config(vappid, network, config = {}) ⇒ Object
Set vApp Network Config.
-
#set_vapp_port_forwarding_rules(vappid, network_name, config = {}) ⇒ Object
Set vApp port forwarding rules.
-
#set_vm_cpus(vmid, cpu_number) ⇒ Object
Set VM CPUs.
-
#set_vm_disk_info(vmid, disk_info = {}) ⇒ Object
Set information about Disks.
-
#set_vm_guest_customization(vmid, computer_name, config = {}) ⇒ Object
Set VM Guest Customization Config.
-
#set_vm_ram(vmid, memory_size) ⇒ Object
Set VM RAM.
-
#suspend_vapp(vAppId) ⇒ Object
Suspend a given vapp.
-
#suspend_vm(vmId) ⇒ Object
Suspend a given vm.
- #upload_media(vdcId, mediaName, mediaDescription, mediaFile, type, catalogId, uploadOptions = {}) ⇒ Object
-
#upload_ovf(vdcId, vappName, vappDescription, ovfFile, catalogId, uploadOptions = {}) ⇒ Object
Upload an OVF package - vdcId - vappName - vappDescription - ovfFile - catalogId - uploadOptions {}.
-
#wait_task_completion(taskid) ⇒ Object
Poll a given task until completion.
Constructor Details
#initialize(host, username, password, org_name, api_version) ⇒ Connection
Returns a new instance of Connection.
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/vcloud-rest/connection.rb', line 52 def initialize(host, username, password, org_name, api_version) @host = host @api_url = "#{host}/api" @host_url = "#{host}" @username = username @password = password @org_name = org_name @api_version = (api_version || "5.1") init_logger end |
Instance Attribute Details
#api_url ⇒ Object (readonly)
Returns the value of attribute api_url.
49 50 51 |
# File 'lib/vcloud-rest/connection.rb', line 49 def api_url @api_url end |
#auth_key ⇒ Object (readonly)
Returns the value of attribute auth_key.
49 50 51 |
# File 'lib/vcloud-rest/connection.rb', line 49 def auth_key @auth_key end |
#extensibility ⇒ Object (readonly)
Returns the value of attribute extensibility.
50 51 52 |
# File 'lib/vcloud-rest/connection.rb', line 50 def extensibility @extensibility end |
Instance Method Details
#acquire_ticket_vm(vmId) ⇒ Object
Retrieve a screen ticket that you can use with the VMRC browser plug-in to gain access to the console of a running VM.
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 478 def acquire_ticket_vm(vmId) params = { 'method' => :post, 'command' => "/vApp/vm-#{vmId}/screen/action/acquireTicket" } response, headers = send_request(params) screen_ticket = response.css("ScreenTicket").text result = {} if screen_ticket =~ /mks:\/\/([^\/]*)\/([^\?]*)\?ticket=(.*)/ result = { host: $1, moid: $2, token: $3 } result[:token] = URI.unescape result[:token] end result end |
#add_internal_network_to_vapp(vAppId, network, config) ⇒ Object
Add an existing network (from Org) to vApp
67 68 69 70 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 67 def add_internal_network_to_vapp(vAppId, network, config) network_section = generate_network_section(vAppId, network, config, :internal) add_network_to_vapp(vAppId, network_section) end |
#add_org_network_to_vapp(vAppId, network, config) ⇒ Object
Add an existing network (from Org) to vApp
60 61 62 63 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 60 def add_org_network_to_vapp(vAppId, network, config) network_section = generate_network_section(vAppId, network, config, :external) add_network_to_vapp(vAppId, network_section) end |
#add_vm_network(vmId, network, config = {}) ⇒ Object
Add a new network to a VM
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 176 def add_vm_network(vmId, network, config={}) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmId}/networkConnectionSection" } netconfig_response, headers = send_request(params) parent_section = netconfig_response.css('NetworkConnectionSection').first # For some reasons these elements must be removed netconfig_response.css("Link").each {|n| n.remove} # Delete placeholder network if present (since vcloud 5.5 has been removed) none_network = netconfig_response.css('NetworkConnection').find{|n| n.attribute('network').text == 'none'} none_network.remove if none_network networks_count = netconfig_response.css('NetworkConnection').count primary_index_node = netconfig_response.css('PrimaryNetworkConnectionIndex').first unless primary_index_node primary_index_node = Nokogiri::XML::Node.new "PrimaryNetworkConnectionIndex", parent_section parent_section.add_child(primary_index_node) end primary_index_node.content = config[:primary_index] || 0 new_network = Nokogiri::XML::Node.new "NetworkConnection", parent_section new_network["network"] = network[:name] new_network["needsCustomization"] = true idx_node = Nokogiri::XML::Node.new "NetworkConnectionIndex", new_network idx_node.content = config[:network_index] || networks_count new_network.add_child(idx_node) if config[:ip] ip_node = Nokogiri::XML::Node.new "IpAddress", new_network ip_node.content = config[:ip] new_network.add_child(ip_node) end is_connected_node = Nokogiri::XML::Node.new "IsConnected", new_network is_connected_node.content = config[:is_connected] || true new_network.add_child(is_connected_node) allocation_node = Nokogiri::XML::Node.new "IpAddressAllocationMode", new_network allocation_node.content = config[:ip_allocation_mode] || "POOL" new_network.add_child(allocation_node) parent_section.add_child(new_network) params = { 'method' => :put, 'command' => "/vApp/vm-#{vmId}/networkConnectionSection" } put_response, headers = send_request(params, netconfig_response.to_xml, "application/vnd.vmware.vcloud.networkConnectionSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#add_vm_to_vapp(vapp, vm, network_config = {}) ⇒ Object
Create a new virtual machine from a template in an existing vApp.
Params:
-
vapp: the target vapp
-
vm: hash with template ID and new VM name
-
network_config: hash of the network configuration for the VM
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 337 def add_vm_to_vapp(vapp, vm, network_config={}) builder = Nokogiri::XML::Builder.new do |xml| xml.RecomposeVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "name" => vapp[:name]) { xml.SourcedItem { xml.Source("href" => "#{@api_url}/vAppTemplate/vm-#{vm[:template_id]}", "name" => vm[:vm_name]) xml.InstantiationParams { xml.NetworkConnectionSection( "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "type" => "application/vnd.vmware.vcloud.networkConnectionSection+xml", "href" => "#{@api_url}/vAppTemplate/vm-#{vm[:template_id]}/networkConnectionSection/") { xml['ovf'].Info "Network config for sourced item" xml.PrimaryNetworkConnectionIndex "0" xml.NetworkConnection("network" => network_config[:name]) { xml.NetworkConnectionIndex "0" xml.IsConnected "true" xml.IpAddressAllocationMode(network_config[:ip_allocation_mode] || "POOL") } } } xml.NetworkAssignment("containerNetwork" => network_config[:name], "innerNetwork" => network_config[:name]) } xml.AllEULAsAccepted "true" } end params = { "method" => :post, "command" => "/vApp/vapp-#{vapp[:id]}/action/recomposeVApp" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.recomposeVAppParams+xml") task = response.css("Task[operationName='vdcRecomposeVapp']").first task_id = task["href"].gsub(/.*\/task\//, "") task_id end |
#attach_disk_to_vm(disk_id, vm_id) ⇒ Object
70 71 72 |
# File 'lib/vcloud-rest/vcloud/disk.rb', line 70 def attach_disk_to_vm(disk_id, vm_id) disk_attach_action(disk_id, vm_id, 'attach') end |
#cancel_task(id) ⇒ Object
Cancel a given task
The task will be marked for cancellation
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/vcloud-rest/vcloud/org.rb', line 133 def cancel_task(id) params = { 'method' => :post, 'command' => "/task/#{id}/action/cancel" } # Nothing useful is returned here # If return code is 20x return true send_request(params) true end |
#clone_vapp(vdc_id, source_vapp_id, name, deploy = "true", poweron = "false", linked = "false", delete_source = "false") ⇒ Object
Clone a vapp in a given VDC to a new Vapp
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 413 def clone_vapp(vdc_id, source_vapp_id, name, deploy="true", poweron="false", linked="false", delete_source="false") params = { "method" => :post, "command" => "/vdc/#{vdc_id}/action/cloneVApp" } builder = Nokogiri::XML::Builder.new do |xml| xml.CloneVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "name" => name, "deploy"=> deploy, "linkedClone"=> linked, "powerOn"=> poweron ) { xml.Source "href" => "#{@api_url}/vApp/vapp-#{source_vapp_id}" xml.IsSourceDelete delete_source } end response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.cloneVAppParams+xml") vapp_id = headers[:location].gsub(/.*\/vApp\/vapp\-/, "") task = response.css("VApp Task[operationName='vdcCopyVapp']").first task_id = task["href"].gsub(/.*\/task\//, "") {:vapp_id => vapp_id, :task_id => task_id} end |
#compose_vapp_from_vm(vdc, vapp_name, vapp_description, vm_list = {}, network_config = {}) ⇒ Object
Compose a vapp using existing virtual machines
Params:
-
vdc: the associated VDC
-
vapp_name: name of the target vapp
-
vapp_description: description of the target vapp
-
vm_list: hash with IDs of the VMs to be used in the composing process
-
network_config: hash of the network configuration for the vapp
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 244 def compose_vapp_from_vm(vdc, vapp_name, vapp_description, vm_list={}, network_config={}) builder = Nokogiri::XML::Builder.new do |xml| xml.ComposeVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "name" => vapp_name) { xml.Description vapp_description xml.InstantiationParams { xml.NetworkConfigSection { xml['ovf'].Info "Configuration parameters for logical networks" xml.NetworkConfig("networkName" => network_config[:name]) { xml.Configuration { xml.IpScopes { xml.IpScope { xml.IsInherited(network_config[:is_inherited] || "false") xml.Gateway network_config[:gateway] xml.Netmask network_config[:netmask] xml.Dns1 network_config[:dns1] if network_config[:dns1] xml.Dns2 network_config[:dns2] if network_config[:dns2] xml.DnsSuffix network_config[:dns_suffix] if network_config[:dns_suffix] xml.IpRanges { xml.IpRange { xml.StartAddress network_config[:start_address] xml.EndAddress network_config[:end_address] } } } } xml.ParentNetwork("href" => "#{@api_url}/network/#{network_config[:parent_network]}") xml.FenceMode network_config[:fence_mode] xml.Features { xml.FirewallService { xml.IsEnabled(network_config[:enable_firewall] || "false") } if network_config.has_key? :nat_type xml.NatService { xml.IsEnabled "true" xml.NatType network_config[:nat_type] xml.Policy(network_config[:nat_policy_type] || "allowTraffic") } end } } } } } vm_list.each do |vm_name, vm_id| xml.SourcedItem { xml.Source("href" => "#{@api_url}/vAppTemplate/vm-#{vm_id}", "name" => vm_name) xml.InstantiationParams { xml.NetworkConnectionSection( "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "type" => "application/vnd.vmware.vcloud.networkConnectionSection+xml", "href" => "#{@api_url}/vAppTemplate/vm-#{vm_id}/networkConnectionSection/") { xml['ovf'].Info "Network config for sourced item" xml.PrimaryNetworkConnectionIndex "0" xml.NetworkConnection("network" => network_config[:name]) { xml.NetworkConnectionIndex "0" xml.IsConnected "true" xml.IpAddressAllocationMode(network_config[:ip_allocation_mode] || "POOL") } } } xml.NetworkAssignment("containerNetwork" => network_config[:name], "innerNetwork" => network_config[:name]) } end xml.AllEULAsAccepted "true" } end params = { "method" => :post, "command" => "/vdc/#{vdc}/action/composeVApp" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.composeVAppParams+xml") vapp_id = headers[:location].gsub(/.*\/vApp\/vapp\-/, "") task = response.css("VApp Task[operationName='vdcComposeVapp']").first task_id = task["href"].gsub(/.*\/task\//, "") { :vapp_id => vapp_id, :task_id => task_id } end |
#create_disk(name, size, vdc_id, description = "") ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/vcloud-rest/vcloud/disk.rb', line 11 def create_disk(name, size, vdc_id, description="") builder = Nokogiri::XML::Builder.new do |xml| xml.DiskCreateParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5") { xml.Disk("name" => name, "size" => size) { xml.Description description } } end params = { 'method' => :post, 'command' => "/vdc/#{vdc_id}/disk" } @logger.debug "Creating independent disk #{name} in VDC #{vdc_id}" response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.diskCreateParams+xml") # Get the id of the new disk disk_url = response.css("Disk").first[:href] disk_id = disk_url.gsub(/.*\/disk\//, "") @logger.debug "Independent disk created = #{disk_id}" task = response.css("Task[operationName='vdcCreateDisk']").first task_id = task["href"].gsub(/.*\/task\//, "") { :disk_id => disk_id, :task_id => task_id } end |
#create_snapshot(vmId, description = "New Snapshot") ⇒ Object
Create a new vm snapshot (overwrites any existing) DEPRECATED - use create_vapp_snapshot instead.
380 381 382 383 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 380 def create_snapshot(vmId, description="New Snapshot") @logger.warn 'DEPRECATION WARNING: use [create,revert]_vapp_snapshot instead.' create_snapshot_action(vmId, description, :vapp) end |
#create_vapp_from_template(vdc, vapp_name, vapp_description, vapp_templateid, poweron = false) ⇒ Object
Create a vapp starting from a template
Params:
-
vdc: the associated VDC
-
vapp_name: name of the target vapp
-
vapp_description: description of the target vapp
-
vapp_templateid: ID of the vapp template
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 207 def create_vapp_from_template(vdc, vapp_name, vapp_description, vapp_templateid, poweron=false) builder = Nokogiri::XML::Builder.new do |xml| xml.InstantiateVAppTemplateParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "name" => vapp_name, "deploy" => "true", "powerOn" => poweron) { xml.Description vapp_description xml.Source("href" => "#{@api_url}/vAppTemplate/#{vapp_templateid}") } end params = { "method" => :post, "command" => "/vdc/#{vdc}/action/instantiateVAppTemplate" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml") vapp_id = headers[:location].gsub(/.*\/vApp\/vapp\-/, "") task = response.css("VApp Task[operationName='vdcInstantiateVapp']").first task_id = task["href"].gsub(/.*\/task\//, "") { :vapp_id => vapp_id, :task_id => task_id } end |
#create_vapp_snapshot(vmId, description = "New Snapshot") ⇒ Object
Create a new vm snapshot (overwrites any existing)
395 396 397 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 395 def create_vapp_snapshot(vmId, description="New Snapshot") create_snapshot_action(vmId, description, :vapp) end |
#create_vm_snapshot(vmId, description = "New Snapshot") ⇒ Object
Create a new vm snapshot (overwrites any existing)
459 460 461 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 459 def create_vm_snapshot(vmId, description="New Snapshot") create_snapshot_action(vmId, description, :vm) end |
#delete_disk(disk_id) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/vcloud-rest/vcloud/disk.rb', line 78 def delete_disk(disk_id) params = { 'method' => :delete, 'command' => "/disk/#{disk_id}" } @logger.debug "Deleting independent disk #{disk_id}" response, headers = send_request(params) task = response.css("Task").first task_id = task["href"].gsub(/.*\/task\//, "") end |
#delete_vapp(vAppId) ⇒ Object
Delete a given vapp NOTE: It doesn’t verify that the vapp is shutdown
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 132 def delete_vapp(vAppId) params = { 'method' => :delete, 'command' => "/vApp/vapp-#{vAppId}" } response, headers = send_request(params) task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#delete_vapp_network(vAppId, network) ⇒ Object
Remove an existing network
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 74 def delete_vapp_network(vAppId, network) params = { 'method' => :get, 'command' => "/vApp/vapp-#{vAppId}/networkConfigSection" } netconfig_response, headers = send_request(params) picked_network = netconfig_response.css("NetworkConfig").select do |net| net.attribute('networkName').text == network[:name] end.first raise WrongItemIDError, "Network #{network[:name]} not found on this vApp." unless picked_network picked_network.remove params = { 'method' => :put, 'command' => "/vApp/vapp-#{vAppId}/networkConfigSection" } put_response, headers = send_request(params, netconfig_response.to_xml, "application/vnd.vmware.vcloud.networkConfigSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#delete_vm_network(vmId, network) ⇒ Object
Remove an existing network
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 239 def delete_vm_network(vmId, network) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmId}/networkConnectionSection" } netconfig_response, headers = send_request(params) picked_network = netconfig_response.css("NetworkConnection").select do |net| net.attribute('network').text == network[:name] end.first raise WrongItemIDError, "Network #{network[:name]} not found on this VM." unless picked_network picked_network.remove params = { 'method' => :put, 'command' => "/vApp/vm-#{vmId}/networkConnectionSection" } put_response, headers = send_request(params, netconfig_response.to_xml, "application/vnd.vmware.vcloud.networkConnectionSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#detach_disk_from_vm(disk_id, vm_id) ⇒ Object
74 75 76 |
# File 'lib/vcloud-rest/vcloud/disk.rb', line 74 def detach_disk_from_vm(disk_id, vm_id) disk_attach_action(disk_id, vm_id, 'detach') end |
#discard_suspend_state_vapp(vAppId) ⇒ Object
Discard suspended state of a given vapp
172 173 174 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 172 def discard_suspend_state_vapp(vAppId) discard_suspended_state_action(vAppId, :vapp) end |
#discard_suspend_state_vm(vmId) ⇒ Object
Discard suspended state of a given vm
432 433 434 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 432 def discard_suspend_state_vm(vmId) discard_suspended_state_action(vmId, :vm) end |
#discard_vapp_snapshot(vmId) ⇒ Object
Discard all existing snapshots
407 408 409 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 407 def discard_vapp_snapshot(vmId) discard_snapshot_action(vmId, :vapp) end |
#discard_vm_snapshot(vmId) ⇒ Object
Discard all existing snapshots
471 472 473 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 471 def discard_vm_snapshot(vmId) discard_snapshot_action(vmId, :vm) end |
#edit_vm_network(vmId, network, config = {}) ⇒ Object
Edit VM Network Config
Retrieve the existing network config section and edit it to ensure settings are not lost
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 124 def edit_vm_network(vmId, network, config={}) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmId}/networkConnectionSection" } netconfig_response, headers = send_request(params) if config[:primary_index] node = netconfig_response.css('PrimaryNetworkConnectionIndex').first node.content = config[:primary_index] end picked_network = netconfig_response.css("NetworkConnection").select do |net| net.attribute('network').text == network[:name] end.first raise WrongItemIDError, "Network named #{network[:name]} not found." unless picked_network if config[:ip_allocation_mode] node = picked_network.css('IpAddressAllocationMode').first node.content = config[:ip_allocation_mode] end if config[:network_index] node = picked_network.css('NetworkConnectionIndex').first node.content = config[:network_index] end if config[:is_connected] node = picked_network.css('IsConnected').first node.content = config[:is_connected] end if config[:ip] node = picked_network.css('IpAddress').first node.content = config[:ip] end params = { 'method' => :put, 'command' => "/vApp/vm-#{vmId}/networkConnectionSection" } response, headers = send_request(params, netconfig_response.to_xml, "application/vnd.vmware.vcloud.networkConnectionSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#force_customization_vapp(vappId) ⇒ Object
Force a guest customization
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 479 def force_customization_vapp(vappId) builder = Nokogiri::XML::Builder.new do |xml| xml.DeployVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "forceCustomization" => "true") end params = { "method" => :post, "command" => "/vApp/vapp-#{vappId}/action/deploy" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.deployVAppParams+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#force_customization_vm(vmId) ⇒ Object
Force a guest customization
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 295 def force_customization_vm(vmId) builder = Nokogiri::XML::Builder.new do |xml| xml.DeployVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "forceCustomization" => "true") end params = { "method" => :post, "command" => "/vApp/vm-#{vmId}/action/deploy" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.deployVAppParams+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#get_catalog(catalogId) ⇒ Object
Fetch details about a given catalog
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/vcloud-rest/vcloud/catalog.rb', line 5 def get_catalog(catalogId) params = { 'method' => :get, 'command' => "/catalog/#{catalogId}" } response, headers = send_request(params) description = response.css("Description").first description = description.text unless description.nil? items = {} response.css("CatalogItem[type='application/vnd.vmware.vcloud.catalogItem+xml']").each do |item| items[item['name']] = item['href'].gsub(/.*\/catalogItem\//, "") end { :id => catalogId, :description => description, :items => items } end |
#get_catalog_by_name(organization, catalogName) ⇒ Object
Friendly helper method to fetch an catalog by name
-
organization hash (from get_organization/get_organization_by_name)
-
catalog name
42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/vcloud-rest/vcloud/catalog.rb', line 42 def get_catalog_by_name(organization, catalogName) result = nil organization[:catalogs].each do |catalog| if catalog[0].downcase == catalogName.downcase result = get_catalog(catalog[1]) end end result end |
#get_catalog_id_by_name(organization, catalogName) ⇒ Object
Friendly helper method to fetch an catalog id by name
-
organization hash (from get_organization/get_organization_by_name)
-
catalog name
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/vcloud-rest/vcloud/catalog.rb', line 26 def get_catalog_id_by_name(organization, catalogName) result = nil organization[:catalogs].each do |catalog| if catalog[0].downcase == catalogName.downcase result = catalog[1] end end result end |
#get_catalog_item(catalogItemId) ⇒ Object
Fetch details about a given catalog item:
-
description
-
vApp templates
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/vcloud-rest/vcloud/catalog.rb', line 58 def get_catalog_item(catalogItemId) params = { 'method' => :get, 'command' => "/catalogItem/#{catalogItemId}" } response, headers = send_request(params) description = response.css("Description").first description = description.text unless description.nil? items = [] # manage two different types of catalog items: vAppTemplate and media if response.css("Entity[type='application/vnd.vmware.vcloud.vAppTemplate+xml']").size > 0 response.css("Entity[type='application/vnd.vmware.vcloud.vAppTemplate+xml']").each do |item| itemId = item['href'].gsub(/.*\/vAppTemplate\/vappTemplate\-/, "") # Fetch the catalogItemId information params = { 'method' => :get, 'command' => "/vAppTemplate/vappTemplate-#{itemId}" } response, headers = send_request(params) # VMs Hash for all the vApp VM entities vms_hash = {} response.css("/VAppTemplate/Children/Vm").each do |vmElem| vmName = vmElem["name"] vmId = vmElem["href"].gsub(/.*\/vAppTemplate\/vm\-/, "") # Add the VM name/id to the VMs Hash vms_hash[vmName] = { :id => vmId } end items << { :id => itemId, :name => item['name'], :vms_hash => vms_hash } end { :id => catalogItemId, :description => description, :items => items, :type => 'vAppTemplate' } elsif response.css("Entity[type='application/vnd.vmware.vcloud.media+xml']").size > 0 name = response.css("Entity[type='application/vnd.vmware.vcloud.media+xml']").first['name'] { :id => catalogItemId, :description => description, :name => name, :type => 'media' } else @logger.warn 'WARNING: either this catalog item is empty or contains something not managed by vcloud-rest' { :id => catalogItemId, :description => description, :type => 'unknown' } end end |
#get_catalog_item_by_name(catalogId, catalogItemName) ⇒ Object
friendly helper method to fetch an catalogItem by name
-
catalogId (use get_catalog_name(org, name))
-
catalagItemName
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/vcloud-rest/vcloud/catalog.rb', line 110 def get_catalog_item_by_name(catalogId, catalogItemName) result = nil catalogElems = get_catalog(catalogId) catalogElems[:items].each do |k, v| if (k.downcase == catalogItemName.downcase) result = get_catalog_item(v) end end result end |
#get_disk(disk_id) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/vcloud-rest/vcloud/disk.rb', line 40 def get_disk(disk_id) params = { 'method' => :get, 'command' => "/disk/#{disk_id}" } @logger.debug "Fetching independent disk #{disk_id}" response, headers = send_request(params) name = response.css("Disk").attribute("name").text size = response.css("Disk").attribute("size").text description = response.css("Description").first description = description.text unless description.nil? storage_profile = response.css("StorageProfile").first[:name] owner = response.css("User").first[:name] { :id => disk_id, :name => name, :size => size, :description => description, :storage_profile => storage_profile, :owner => owner } end |
#get_disk_by_name(organization, vdcName, diskName) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/vcloud-rest/vcloud/disk.rb', line 58 def get_disk_by_name(organization, vdcName, diskName) result = nil get_vdc_by_name(organization, vdcName)[:disks].each do |disk| if disk[0].downcase == diskName.downcase result = get_disk(disk[1]) end end result end |
#get_extensibility ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/vcloud-rest/vcloud/extensibility.rb', line 3 def get_extensibility params = { 'method' => :get, 'command' => "/extensibility" } response, headers = send_request(params) down_service = response.css("Link[@rel='down:service']").first['href'] down_apidefinitions = response.css("Link[@rel='down:apidefinitions']").first['href'] down_files = response.css("Link[@rel='down:files']").first['href'] { :down_service => down_service, :down_apidefinitions => down_apidefinitions, :down_files => down_files, } end |
#get_network(networkId) ⇒ Object
Fetch details about a given Org VDC network
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/vcloud-rest/vcloud/network.rb', line 5 def get_network(networkId) response = get_base_network(networkId) name = response.css('OrgVdcNetwork').attribute('name').text description = response.css("Description").first description = description.text unless description.nil? gateway = response.css('Gateway') gateway = gateway.text unless gateway.nil? netmask = response.css('Netmask') netmask = netmask.text unless netmask.nil? fence_mode = response.css('FenceMode') fence_mode = fence_mode.text unless fence_mode.nil? start_address = response.css('StartAddress') start_address = start_address.text unless start_address.nil? end_address = response.css('EndAddress') end_address = end_address.text unless end_address.nil? { :id => networkId, :name => name, :description => description, :gateway => gateway, :netmask => netmask, :fence_mode => fence_mode, :start_address => start_address, :end_address => end_address } end |
#get_network_by_name(organization, networkName) ⇒ Object
Friendly helper method to fetch an network by name
-
organization hash (from get_organization/get_organization_by_name)
-
network name
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/vcloud-rest/vcloud/network.rb', line 54 def get_network_by_name(organization, networkName) result = nil organization[:networks].each do |network| if network[0].downcase == networkName.downcase result = get_network(network[1]) end end result end |
#get_network_id_by_name(organization, networkName) ⇒ Object
Friendly helper method to fetch an network id by name
-
organization hash (from get_organization/get_organization_by_name)
-
network name
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/vcloud-rest/vcloud/network.rb', line 38 def get_network_id_by_name(organization, networkName) result = nil organization[:networks].each do |network| if network[0].downcase == networkName.downcase result = network[1] end end result end |
#get_organization(orgId) ⇒ Object
Fetch details about an organization:
-
catalogs
-
vdcs
-
networks
-
task lists
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/vcloud-rest/vcloud/org.rb', line 62 def get_organization(orgId) params = { 'method' => :get, 'command' => "/org/#{orgId}" } response, headers = send_request(params) catalogs = {} response.css("Link[type='application/vnd.vmware.vcloud.catalog+xml']").each do |item| catalogs[item['name']] = item['href'].gsub(/.*\/catalog\//, "") end vdcs = {} response.css("Link[type='application/vnd.vmware.vcloud.vdc+xml']").each do |item| vdcs[item['name']] = item['href'].gsub(/.*\/vdc\//, "") end networks = {} response.css("Link[type='application/vnd.vmware.vcloud.orgNetwork+xml']").each do |item| networks[item['name']] = item['href'].gsub(/.*\/network\//, "") end tasklists = {} response.css("Link[type='application/vnd.vmware.vcloud.tasksList+xml']").each do |item| tasklists[item['name']] = item['href'].gsub(/.*\/tasksList\//, "") end { :catalogs => catalogs, :vdcs => vdcs, :networks => networks, :tasklists => tasklists } end |
#get_organization_by_name(name) ⇒ Object
friendly helper method to fetch an Organization by name
-
name (this isn’t case sensitive)
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/vcloud-rest/vcloud/org.rb', line 42 def get_organization_by_name(name) result = nil # Fetch all organizations organizations = get_organizations() organizations.each do |organization| if organization[0].downcase == name.downcase result = get_organization(organization[1]) end end result end |
#get_organization_id_by_name(name) ⇒ Object
friendly helper method to fetch an Organization Id by name
-
name (this isn’t case sensitive)
24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/vcloud-rest/vcloud/org.rb', line 24 def get_organization_id_by_name(name) result = nil # Fetch all organizations organizations = get_organizations() organizations.each do |organization| if organization[0].downcase == name.downcase result = organization[1] end end result end |
#get_organizations ⇒ Object
Fetch existing organizations and their IDs
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/vcloud-rest/vcloud/org.rb', line 5 def get_organizations params = { 'method' => :get, 'command' => '/org' } response, headers = send_request(params) orgs = response.css('OrgList Org') results = {} orgs.each do |org| results[org['name']] = org['href'].gsub(/.*\/org\//, "") end results end |
#get_task(taskid) ⇒ Object
Fetch information for a given task
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/vcloud-rest/connection.rb', line 100 def get_task(taskid) params = { 'method' => :get, 'command' => "/task/#{taskid}" } response, headers = send_request(params) task = response.css('Task').first status = task['status'] start_time = task['startTime'] end_time = task['endTime'] { :status => status, :start_time => start_time, :end_time => end_time, :response => response } end |
#get_tasks_list(id) ⇒ Object
Fetch tasks from a given task list
Note: id can be retrieved using get_organization
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/vcloud-rest/vcloud/org.rb', line 96 def get_tasks_list(id) params = { 'method' => :get, 'command' => "/tasksList/#{id}" } response, headers = send_request(params) tasks = [] response.css('Task').each do |task| id = task['href'].gsub(/.*\/task\//, "") operation = task['operationName'] status = task['status'] error = nil error = task.css('Error').first['message'] if task['status'] == 'error' start_time = task['startTime'] end_time = task['endTime'] user_canceled = task['cancelRequested'] == 'true' tasks << { :id => id, :operation => operation, :status => status, :error => error, :start_time => start_time, :end_time => end_time, :user_canceled => user_canceled } end tasks end |
#get_vapp(vAppId) ⇒ Object
Fetch details about a given vapp:
-
name
-
description
-
status
-
IP
-
Children VMs: – IP addresses – status – ID
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 15 def get_vapp(vAppId) params = { 'method' => :get, 'command' => "/vApp/vapp-#{vAppId}" } response, headers = send_request(params) vapp_node = response.css('VApp').first if vapp_node name = vapp_node['name'] status = convert_vapp_status(vapp_node['status']) end description = response.css("Description").first description = description.text unless description.nil? ip = response.css('IpAddress').first ip = ip.text unless ip.nil? networks = response.css('NetworkConfig').reject{|n| n.attribute('networkName').text == 'none'}. collect do |network| net_id = network.css('Link[rel="repair"]') net_id = net_id.attribute('href').text.gsub(/.*\/network\/(.*)\/action.*/, '\1') unless net_id.empty? net_name = network.attribute('networkName').text gateway = network.css('Gateway') gateway = gateway.text unless gateway.nil? netmask = network.css('Netmask') netmask = netmask.text unless netmask.nil? fence_mode = network.css('FenceMode') fence_mode = fence_mode.text unless fence_mode.nil? parent_network = network.css('ParentNetwork') parent_network = parent_network.attribute('name').text unless parent_network.empty? parent_network = nil if parent_network.empty? retain_network = network.css('RetainNetInfoAcrossDeployments') retain_network = retain_network.text unless retain_network.nil? # TODO: handle multiple scopes? ipscope = { :gateway => gateway, :netmask => netmask, :fence_mode => fence_mode, :parent_network => parent_network, :retain_network => retain_network } { :id => net_id, :name => net_name, :scope => ipscope } end vapp_snapshot = nil response.css('SnapshotSection').each do |snapshot_section| if snapshot_section['href'] =~ /.*\/vApp\/vapp\-/ snapshot = snapshot_section.css("Snapshot").first if snapshot vapp_snapshot = { :size => snapshot['size'], :creation_date => snapshot['created'] } end break end end vms = response.css('Children Vm') vms_hash = {} vms.each do |vm| vapp_local_id = vm.css('VAppScopedLocalId') addresses = vm.css('rasd|Connection').collect do |n| address = n.attribute('vcloud:ipAddress') address = n.attribute('ipAddress') unless address address = address.text if address end vms_hash[vm['name']] = { :addresses => addresses, :status => convert_vapp_status(vm['status']), :id => vm['href'].gsub(/.*\/vApp\/vm\-/, ""), :vapp_scoped_local_id => vapp_local_id.text } end { :id => vAppId, :name => name, :description => description, :status => status, :ip => ip, :networks => networks, :vapp_snapshot => vapp_snapshot, :vms_hash => vms_hash } end |
#get_vapp_by_name(organization, vdcName, vAppName) ⇒ Object
Friendly helper method to fetch a vApp by name
-
Organization object
-
Organization VDC Name
-
vApp name
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 117 def get_vapp_by_name(organization, vdcName, vAppName) result = nil get_vdc_by_name(organization, vdcName)[:vapps].each do |vapp| if vapp[0].downcase == vAppName.downcase result = get_vapp(vapp[1]) end end result end |
#get_vapp_edge_public_ip(vAppId) ⇒ Object
get vApp edge public IP from the vApp ID Only works when:
-
vApp needs to be poweredOn
-
FenceMode is set to “natRouted”
-
NatType“ is set to ”portForwarding
This will be required to know how to connect to VMs behind the Edge device.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 197 def get_vapp_edge_public_ip(vAppId) # Check the network configuration section params = { 'method' => :get, 'command' => "/vApp/vapp-#{vAppId}/networkConfigSection" } response, headers = send_request(params) # FIXME: this will return nil if the vApp uses multiple vApp Networks # with Edge devices in natRouted/portForwarding mode. config = response.css('NetworkConfigSection/NetworkConfig/Configuration') fenceMode = config.css('/FenceMode').text natType = config.css('/Features/NatService/NatType').text raise InvalidStateError, "Invalid request because FenceMode must be set to natRouted." unless fenceMode == "natRouted" raise InvalidStateError, "Invalid request because NatType must be set to portForwarding." unless natType == "portForwarding" # Check the routerInfo configuration where the global external IP is defined edgeIp = config.css('/RouterInfo/ExternalIp') edgeIp = edgeIp.text unless edgeIp.nil? end |
#get_vapp_port_forwarding_rules(vAppId) ⇒ Object
Get vApp port forwarding rules
-
vappid: id of the vApp
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 155 def get_vapp_port_forwarding_rules(vAppId) params = { 'method' => :get, 'command' => "/vApp/vapp-#{vAppId}/networkConfigSection" } response, headers = send_request(params) # FIXME: this will return nil if the vApp uses multiple vApp Networks # with Edge devices in natRouted/portForwarding mode. config = response.css('NetworkConfigSection/NetworkConfig/Configuration') fenceMode = config.css('/FenceMode').text natType = config.css('/Features/NatService/NatType').text raise InvalidStateError, "Invalid request because FenceMode must be set to natRouted." unless fenceMode == "natRouted" raise InvalidStateError, "Invalid request because NatType must be set to portForwarding." unless natType == "portForwarding" nat_rules = {} config.css('/Features/NatService/NatRule').each do |rule| # portforwarding rules information ruleId = rule.css('Id').text vmRule = rule.css('VmRule') nat_rules[rule.css('Id').text] = { :ExternalIpAddress => vmRule.css('ExternalIpAddress').text, :ExternalPort => vmRule.css('ExternalPort').text, :VAppScopedVmId => vmRule.css('VAppScopedVmId').text, :VmNicId => vmRule.css('VmNicId').text, :InternalPort => vmRule.css('InternalPort').text, :Protocol => vmRule.css('Protocol').text } end nat_rules end |
#get_vapp_template(vAppId) ⇒ Object
Fetch details about a given vapp template:
-
name
-
description
-
Children VMs: – ID
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 445 def get_vapp_template(vAppId) params = { 'method' => :get, 'command' => "/vAppTemplate/vappTemplate-#{vAppId}" } response, headers = send_request(params) vapp_node = response.css('VAppTemplate').first if vapp_node name = vapp_node['name'] status = convert_vapp_status(vapp_node['status']) end description = response.css("Description").first description = description.text unless description.nil? ip = response.css('IpAddress').first ip = ip.text unless ip.nil? vms = response.css('Children Vm') vms_hash = {} vms.each do |vm| vms_hash[vm['name']] = { :id => vm['href'].gsub(/.*\/vAppTemplate\/vm\-/, "") } end { :name => name, :description => description, :vms_hash => vms_hash } end |
#get_vdc(vdcId) ⇒ Object
Fetch details about a given vdc:
-
description
-
vapps
-
templates
-
disks
-
networks
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/vcloud-rest/vcloud/vdc.rb', line 10 def get_vdc(vdcId) params = { 'method' => :get, 'command' => "/vdc/#{vdcId}" } response, headers = send_request(params) name = response.css("Vdc").attribute("name") name = name.text unless name.nil? description = response.css("Description").first description = description.text unless description.nil? vapps = {} response.css("ResourceEntity[type='application/vnd.vmware.vcloud.vApp+xml']").each do |item| vapps[item['name']] = item['href'].gsub(/.*\/vApp\/vapp\-/, "") end templates = {} response.css("ResourceEntity[type='application/vnd.vmware.vcloud.vAppTemplate+xml']").each do |item| templates[item['name']] = item['href'].gsub(/.*\/vAppTemplate\/vappTemplate\-/, "") end disks = {} response.css("ResourceEntity[type='application/vnd.vmware.vcloud.disk+xml']").each do |item| disks[item['name']] = item['href'].gsub(/.*\/disk\//, "") end networks = {} response.css("Network[type='application/vnd.vmware.vcloud.network+xml']").each do |item| networks[item['name']] = item['href'].gsub(/.*\/network\//, "") end { :id => vdcId, :name => name, :description => description, :vapps => vapps, :templates => templates, :disks => disks, :networks => networks } end |
#get_vdc_by_name(organization, vdcName) ⇒ Object
Friendly helper method to fetch a Organization VDC by name
-
Organization object
-
Organization VDC Name
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/vcloud-rest/vcloud/vdc.rb', line 69 def get_vdc_by_name(organization, vdcName) result = nil organization[:vdcs].each do |vdc| if vdc[0].downcase == vdcName.downcase result = get_vdc(vdc[1]) end end result end |
#get_vdc_id_by_name(organization, vdcName) ⇒ Object
Friendly helper method to fetch a Organization VDC Id by name
-
Organization object
-
Organization VDC Name
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/vcloud-rest/vcloud/vdc.rb', line 53 def get_vdc_id_by_name(organization, vdcName) result = nil organization[:vdcs].each do |vdc| if vdc[0].downcase == vdcName.downcase result = vdc[1] end end result end |
#get_vm(vmId) ⇒ Object
Fetch details about a given VM
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 330 def get_vm(vmId) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmId}" } response, headers = send_request(params) vm_name = response.css('Vm').attribute("name") vm_name = vm_name.text unless vm_name.nil? status = convert_vapp_status(response.css('Vm').attribute("status").text) os_desc = response.css('ovf|OperatingSystemSection ovf|Description').first.text networks = {} response.css('NetworkConnection').each do |network| ip = network.css('IpAddress').first ip = ip.text if ip external_ip = network.css('ExternalIpAddress').first external_ip = external_ip.text if external_ip # Append NetworkConnectionIndex to network name to generate a unique hash key, # otherwise different interfaces on the same network would use the same hash key key = "#{network['network']}_#{network.css('NetworkConnectionIndex').first.text}" networks[key] = { :index => network.css('NetworkConnectionIndex').first.text, :ip => ip, :external_ip => external_ip, :is_connected => network.css('IsConnected').first.text, :mac_address => network.css('MACAddress').first.text, :ip_allocation_mode => network.css('IpAddressAllocationMode').first.text } end admin_password = response.css('GuestCustomizationSection AdminPassword').first admin_password = admin_password.text if admin_password guest_customizations = { :enabled => response.css('GuestCustomizationSection Enabled').first.text, :admin_passwd_enabled => response.css('GuestCustomizationSection AdminPasswordEnabled').first.text, :admin_passwd_auto => response.css('GuestCustomizationSection AdminPasswordAuto').first.text, :admin_passwd => admin_password, :reset_passwd_required => response.css('GuestCustomizationSection ResetPasswordRequired').first.text, :computer_name => response.css('GuestCustomizationSection ComputerName').first.text } { :id => vmId, :vm_name => vm_name, :os_desc => os_desc, :networks => networks, :guest_customizations => guest_customizations, :status => status } end |
#get_vm_by_name(organization, vdcName, vAppName, vmName) ⇒ Object
Friendly helper method to fetch a vApp by name
-
Organization object
-
Organization VDC Name
-
vApp Name
-
VM Name
391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 391 def get_vm_by_name(organization, vdcName, vAppName, vmName) result = nil get_vapp_by_name(organization, vdcName, vAppName)[:vms_hash].each do |key, values| if key.downcase == vmName.downcase result = get_vm(values[:id]) end end result end |
#get_vm_disk_info(vmid) ⇒ Object
Retrieve information about Disks
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 33 def get_vm_disk_info(vmid) response, headers = __get_disk_info(vmid) disks = [] response.css("Item").each do |entry| # Pick only entries with node "HostResource" resource = entry.css("rasd|HostResource").first next unless resource name = entry.css("rasd|ElementName").first name = name.text unless name.nil? capacity = resource.attribute("capacity").text disks << { :name => name, :capacity => "#{capacity} MB" } end disks end |
#get_vm_info(vmid) ⇒ Object
Retrieve information (i.e., memory and CPUs)
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 5 def get_vm_info(vmid) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmid}/virtualHardwareSection" } response, headers = send_request(params) result = {} response.css("ovf|Item[vcloud|href]").each do |item| item_name = item.attribute('href').text.gsub(/.*\/vApp\/vm\-(\w+(-?))+\/virtualHardwareSection\//, "") name = item.css("rasd|ElementName") name = name.text unless name.nil? description = item.css("rasd|Description") description = description.text unless description.nil? result[item_name] = { :name => name, :description => description } end result end |
#login ⇒ Object
Authenticate against the specified server
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/vcloud-rest/connection.rb', line 66 def login params = { 'method' => :post, 'command' => '/sessions' } response, headers = send_request(params) if !headers.has_key?(:x_vcloud_authorization) raise "Unable to authenticate: missing x_vcloud_authorization header" end extensibility_link = response.css("Link[rel='down:extensibility']") @extensibility = extensibility_link.first['href'] unless extensibility_link.empty? @auth_key = headers[:x_vcloud_authorization] end |
#logout ⇒ Object
Destroy the current session
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/vcloud-rest/connection.rb', line 86 def logout params = { 'method' => :delete, 'command' => '/session' } response, headers = send_request(params) ensure # reset auth key to nil @auth_key = nil end |
#poweroff_vapp(vAppId) ⇒ Object
Shutdown a given vapp
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 145 def poweroff_vapp(vAppId) builder = Nokogiri::XML::Builder.new do |xml| xml.UndeployVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5") { xml.UndeployPowerAction 'powerOff' } end params = { 'method' => :post, 'command' => "/vApp/vapp-#{vAppId}/action/undeploy" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.undeployVAppParams+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#poweroff_vm(vmId) ⇒ Object
Shutdown a given vm
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 405 def poweroff_vm(vmId) builder = Nokogiri::XML::Builder.new do |xml| xml.UndeployVAppParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5") { xml.UndeployPowerAction 'powerOff' } end params = { 'method' => :post, 'command' => "/vApp/vm-#{vmId}/action/undeploy" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.undeployVAppParams+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#poweron_vapp(vAppId) ⇒ Object
Boot a given vapp
195 196 197 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 195 def poweron_vapp(vAppId) power_action(vAppId, 'powerOn') end |
#poweron_vm(vmId) ⇒ Object
Boot a given vm
453 454 455 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 453 def poweron_vm(vmId) power_action(vmId, 'powerOn', :vm) end |
#reboot_vapp(vAppId) ⇒ Object
reboot a given vapp This will basically initial a guest OS reboot, and will only work if VMware-tools are installed on the underlying VMs. vShield Edge devices are not affected
181 182 183 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 181 def reboot_vapp(vAppId) power_action(vAppId, 'reboot') end |
#reboot_vm(vmId) ⇒ Object
reboot a given vm This will basically initial a guest OS reboot, and will only work if VMware-tools are installed on the underlying VMs. vShield Edge devices are not affected
441 442 443 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 441 def reboot_vm(vmId) power_action(vmId, 'reboot', :vm) end |
#rename_vm(vmId, name) ⇒ Object
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 312 def rename_vm(vmId, name) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmId}" } response, headers = send_request(params) response.css('Vm').attribute("name").content = name params['method'] = :put response, headers = send_request(params, response.to_xml, "application/vnd.vmware.vcloud.vm+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#reset_vapp(vAppId) ⇒ Object
reset a given vapp This will basically reset the VMs within the vApp vShield Edge devices are not affected.
189 190 191 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 189 def reset_vapp(vAppId) power_action(vAppId, 'reset') end |
#reset_vm(vmId) ⇒ Object
reset a given vm
447 448 449 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 447 def reset_vm(vmId) power_action(vmId, 'reset', :vm) end |
#revert_snapshot(vmId) ⇒ Object
Revert to an existing snapshot DEPRECATED - use revert_vapp_snapshot instead.
388 389 390 391 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 388 def revert_snapshot(vmId) @logger.warn 'DEPRECATION WARNING: use [create,revert]_vapp_snapshot instead.' revert_snapshot_action(vmId, :vapp) end |
#revert_vapp_snapshot(vmId) ⇒ Object
Revert to an existing snapshot
401 402 403 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 401 def revert_vapp_snapshot(vmId) revert_snapshot_action(vmId, :vapp) end |
#revert_vm_snapshot(vmId) ⇒ Object
Revert to an existing snapshot
465 466 467 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 465 def revert_vm_snapshot(vmId) revert_snapshot_action(vmId, :vm) end |
#set_vapp_network_config(vappid, network, config = {}) ⇒ Object
Set vApp Network Config
Retrieve the existing network config section and edit it to ensure settings are not lost
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 8 def set_vapp_network_config(vappid, network, config={}) params = { 'method' => :get, 'command' => "/vApp/vapp-#{vappid}/networkConfigSection" } netconfig_response, headers = send_request(params) picked_network = netconfig_response.css("NetworkConfig").select do |net| net.attribute('networkName').text == network[:name] end.first raise WrongItemIDError, "Network named #{network[:name]} not found." unless picked_network picked_network.css('FenceMode').first.content = config[:fence_mode] if config[:fence_mode] picked_network.css('IsInherited').first.content = "true" picked_network.css('RetainNetInfoAcrossDeployments').first.content = config[:retain_network] if config[:retain_network] if config[:parent_network] parent_network = picked_network.css('ParentNetwork').first new_parent = false unless parent_network new_parent = true ipscopes = picked_network.css('IpScopes').first parent_network = Nokogiri::XML::Node.new "ParentNetwork", ipscopes.parent end parent_network["name"] = "#{config[:parent_network][:name]}" parent_network["id"] = "#{config[:parent_network][:id]}" parent_network["href"] = "#{@api_url}/admin/network/#{config[:parent_network][:id]}" ipscopes.add_next_sibling(parent_network) if new_parent end data = netconfig_response.to_xml params = { 'method' => :put, 'command' => "/vApp/vapp-#{vappid}/networkConfigSection" } response, headers = send_request(params, data, "application/vnd.vmware.vcloud.networkConfigSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#set_vapp_port_forwarding_rules(vappid, network_name, config = {}) ⇒ Object
Set vApp port forwarding rules
-
vappid: id of the vapp to be modified
-
network_name: name of the vapp network to be modified
-
config: hash with network configuration specifications, must contain an array inside :nat_rules with the nat rules to be applied.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/vcloud-rest/vcloud/vapp_networking.rb', line 107 def set_vapp_port_forwarding_rules(vappid, network_name, config={}) builder = Nokogiri::XML::Builder.new do |xml| xml.NetworkConfigSection( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1") { xml['ovf'].Info "Network configuration" xml.NetworkConfig("networkName" => network_name) { xml.Configuration { xml.ParentNetwork("href" => "#{@api_url}/network/#{config[:parent_network]}") xml.FenceMode(config[:fence_mode] || 'isolated') xml.Features { xml.NatService { xml.IsEnabled "true" xml.NatType "portForwarding" xml.Policy(config[:nat_policy_type] || "allowTraffic") config[:nat_rules].each do |nat_rule| xml.NatRule { xml.VmRule { xml.ExternalPort nat_rule[:nat_external_port] xml.VAppScopedVmId nat_rule[:vm_scoped_local_id] xml.VmNicId(nat_rule[:nat_vmnic_id] || "0") xml.InternalPort nat_rule[:nat_internal_port] xml.Protocol(nat_rule[:nat_protocol] || "TCP") } } end } } } } } end params = { 'method' => :put, 'command' => "/vApp/vapp-#{vappid}/networkConfigSection" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.networkConfigSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#set_vm_cpus(vmid, cpu_number) ⇒ Object
Set VM CPUs
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 79 def set_vm_cpus(vmid, cpu_number) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmid}/virtualHardwareSection/cpu" } get_response, headers = send_request(params) # Change attributes from the previous invocation get_response.css("rasd|ElementName").first.content = "#{cpu_number} virtual CPU(s)" get_response.css("rasd|VirtualQuantity").first.content = cpu_number params['method'] = :put put_response, headers = send_request(params, get_response.to_xml, "application/vnd.vmware.vcloud.rasdItem+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#set_vm_disk_info(vmid, disk_info = {}) ⇒ Object
Set information about Disks
Disks can be added, deleted or modified
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 58 def set_vm_disk_info(vmid, disk_info={}) get_response, headers = __get_disk_info(vmid) if disk_info[:add] data = add_disk(get_response, disk_info) else data = edit_disk(get_response, disk_info) end params = { 'method' => :put, 'command' => "/vApp/vm-#{vmid}/virtualHardwareSection/disks" } put_response, headers = send_request(params, data, "application/vnd.vmware.vcloud.rasdItemsList+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#set_vm_guest_customization(vmid, computer_name, config = {}) ⇒ Object
Set VM Guest Customization Config
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 268 def set_vm_guest_customization(vmid, computer_name, config={}) builder = Nokogiri::XML::Builder.new do |xml| xml.GuestCustomizationSection( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1") { xml['ovf'].Info "VM Guest Customization configuration" xml.Enabled config[:enabled] if config[:enabled] xml.AdminPasswordEnabled config[:admin_passwd_enabled] if config[:admin_passwd_enabled] xml.AdminPassword config[:admin_passwd] if config[:admin_passwd] xml.CustomizationScript config[:customization_script] if config[:customization_script] xml.ComputerName computer_name } end params = { 'method' => :put, 'command' => "/vApp/vm-#{vmid}/guestCustomizationSection" } response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.guestCustomizationSection+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#set_vm_ram(vmid, memory_size) ⇒ Object
Set VM RAM
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 100 def set_vm_ram(vmid, memory_size) params = { 'method' => :get, 'command' => "/vApp/vm-#{vmid}/virtualHardwareSection/memory" } get_response, headers = send_request(params) # Change attributes from the previous invocation get_response.css("rasd|ElementName").first.content = "#{memory_size} MB of memory" get_response.css("rasd|VirtualQuantity").first.content = memory_size params['method'] = :put put_response, headers = send_request(params, get_response.to_xml, "application/vnd.vmware.vcloud.rasdItem+xml") task_id = headers[:location].gsub(/.*\/task\//, "") task_id end |
#suspend_vapp(vAppId) ⇒ Object
Suspend a given vapp
166 167 168 |
# File 'lib/vcloud-rest/vcloud/vapp.rb', line 166 def suspend_vapp(vAppId) power_action(vAppId, 'suspend') end |
#suspend_vm(vmId) ⇒ Object
Suspend a given vm
426 427 428 |
# File 'lib/vcloud-rest/vcloud/vm.rb', line 426 def suspend_vm(vmId) power_action(vmId, 'suspend', :vm) end |
#upload_media(vdcId, mediaName, mediaDescription, mediaFile, type, catalogId, uploadOptions = {}) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/vcloud-rest/vcloud/media.rb', line 4 def upload_media(vdcId, mediaName, mediaDescription, mediaFile, type, catalogId, uploadOptions={}) raise ::IOError, "File #{mediaFile} is missing." unless File.exists?(mediaFile) fileName = File.basename(mediaFile) mediaName = File.basename(fileName, ".*") if mediaName.nil? || mediaName.empty? type = File.extname(fileName).delete(".") if type.nil? || type.empty? size = File.size(mediaFile) builder = Nokogiri::XML::Builder.new do |xml| xml.Media( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "size" => size, "imageType" => type, "name" => mediaName) { xml.Description mediaDescription } end params = { 'method' => :post, 'command' => "/vdc/#{vdcId}/media" } @logger.debug "Creating Media item" response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.media+xml") # Get the new media id from response mediaUrl = response.css("Media").first[:href] mediaId = mediaUrl.gsub(/.*\/media\//, "") @logger.debug "Media item created - #{mediaId}" # Get File upload:default link from response uploadHref = response.css("Files Link [rel='upload:default']").first[:href] fileUpload = uploadHref.gsub(/(.*)(\/transfer\/.*)/, "\\2") begin @logger.debug "Uploading #{mediaFile}" upload_file(fileUpload, mediaFile, "/media/#{mediaId}", uploadOptions) # Add item to the catalog catalogId builder = Nokogiri::XML::Builder.new do |xml| xml.CatalogItem( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "type" => "application/vnd.vmware.vcloud.catalogItem+xml", "name" => mediaName) { xml.Description mediaDescription xml.Entity("href" => "#{@api_url}/media/#{mediaId}") } end params = { 'method' => :post, 'command' => "/catalog/#{catalogId}/catalogItems" } @logger.debug "Adding media item #{mediaName} to catalog." response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.catalogItem+xml") # TODO: the best thing would detect the real importing status. entity = response.css("Entity").first result = {} if entity result[:id] = entity['href'].gsub(/.*\/media\//, "") result[:name] = entity['name'] end result rescue Exception => e @logger.error "Exception detected: #{e.}." # Get Media Task params = { 'method' => :get, 'command' => "/media/#{mediaId}" } response, headers = send_request(params) # Cancel Task # Note that it might not exist (i.e., error for existing vdc entity) tasks = response.css("Tasks") unless tasks.empty? tasks.css("Task").each do |task| if task['status'] == 'error' @logger.error task.css('Error').first['message'] else id = task['href'].gsub(/.*\/task\//, "") @logger.error "Aborting task #{id}..." cancel_task(id) end end end raise e end end |
#upload_ovf(vdcId, vappName, vappDescription, ovfFile, catalogId, uploadOptions = {}) ⇒ Object
Upload an OVF package
-
vdcId
-
vappName
-
vappDescription
-
ovfFile
-
catalogId
-
uploadOptions {}
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/vcloud-rest/vcloud/ovf.rb', line 11 def upload_ovf(vdcId, vappName, vappDescription, ovfFile, catalogId, uploadOptions={}) raise ::IOError, "OVF #{ovfFile} is missing." unless File.exists?(ovfFile) raise ::IOError, "Only .ovf files are supported" unless File.extname(ovfFile) =~ /\.ovf/ # if send_manifest is not set, setting it true if uploadOptions[:send_manifest].nil? || uploadOptions[:send_manifest] uploadManifest = "true" else uploadManifest = "false" end builder = Nokogiri::XML::Builder.new do |xml| xml.UploadVAppTemplateParams( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1", "manifestRequired" => uploadManifest, "name" => vappName) { xml.Description vappDescription } end params = { 'method' => :post, 'command' => "/vdc/#{vdcId}/action/uploadVAppTemplate" } response, headers = send_request( params, builder.to_xml, "application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml" ) # Get vAppTemplate Link from location vAppTemplate = headers[:location].gsub(/.*\/vAppTemplate\/vappTemplate\-/, "") uploadHref = response.css("Files Link [rel='upload:default']").first[:href] descriptorUpload = uploadHref.gsub(/.*\/transfer\//, "") transferGUID = descriptorUpload.gsub("/descriptor.ovf", "") ovfFileBasename = File.basename(ovfFile, ".ovf") ovfDir = File.dirname(ovfFile) # Send OVF Descriptor uploadURL = "/transfer/#{descriptorUpload}" uploadFile = "#{ovfDir}/#{ovfFileBasename}.ovf" upload_file(uploadURL, uploadFile, "/vAppTemplate/vappTemplate-#{vAppTemplate}", uploadOptions) @logger.debug "OVF Descriptor uploaded." # Begin the catch for upload interruption begin params = { 'method' => :get, 'command' => "/vAppTemplate/vappTemplate-#{vAppTemplate}" } # Loop to wait for the upload links to show up in the vAppTemplate we just created while true response, headers = send_request(params) errored_task = response.css("Tasks Task [status='error']").first if errored_task error_msg = errored_task.css('Error').first['message'] raise OVFError, "OVF Upload failed: #{error_msg}" end break unless response.css("Files Link [rel='upload:default']").count == 1 sleep 1 end if uploadManifest == "true" uploadURL = "/transfer/#{transferGUID}/descriptor.mf" uploadFile = "#{ovfDir}/#{ovfFileBasename}.mf" upload_file(uploadURL, uploadFile, "/vAppTemplate/vappTemplate-#{vAppTemplate}", uploadOptions) @logger.debug "OVF Manifest uploaded." end # Start uploading OVF VMDK files params = { 'method' => :get, 'command' => "/vAppTemplate/vappTemplate-#{vAppTemplate}" } response, headers = send_request(params) response.css("Files File [bytesTransferred='0'] Link [rel='upload:default']").each do |file| fileName = file[:href].gsub(/.*\/transfer\/#{transferGUID}\//, "") uploadFile = "#{ovfDir}/#{fileName}" uploadURL = "/transfer/#{transferGUID}/#{fileName}" upload_file(uploadURL, uploadFile, "/vAppTemplate/vappTemplate-#{vAppTemplate}", uploadOptions) end # Add item to the catalog catalogId builder = Nokogiri::XML::Builder.new do |xml| xml.CatalogItem( "xmlns" => "http://www.vmware.com/vcloud/v1.5", "type" => "application/vnd.vmware.vcloud.catalogItem+xml", "name" => vappName) { xml.Description vappDescription xml.Entity( "href" => "#{@api_url}/vAppTemplate/vappTemplate-#{vAppTemplate}" ) } end params = { 'method' => :post, 'command' => "/catalog/#{catalogId}/catalogItems" } @logger.debug "Add item to catalog." response, headers = send_request(params, builder.to_xml, "application/vnd.vmware.vcloud.catalogItem+xml") entity = response.css("Entity").first # TODO: the best thing would detect the real importing status. result = {} if entity result[:id] = entity['href'].gsub(/.*\/vAppTemplate\/vappTemplate\-/, "") result[:name] = entity['name'] end result rescue Exception => e @logger.error "Exception detected: #{e.}." # Get vAppTemplate Task params = { 'method' => :get, 'command' => "/vAppTemplate/vappTemplate-#{vAppTemplate}" } response, headers = send_request(params) # Cancel Task # Note that it might not exist (i.e., error for existing vdc entity) tasks = response.css("Tasks") unless tasks.empty? tasks.css("Task").each do |task| if task['status'] == 'error' @logger.error task.css('Error').first['message'] else id = task['href'].gsub(/.*\/task\//, "") @logger.error "Aborting task #{id}..." cancel_task(id) end end end raise e end end |
#wait_task_completion(taskid) ⇒ Object
Poll a given task until completion
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/vcloud-rest/connection.rb', line 118 def wait_task_completion(taskid) errormsg = nil task = {} loop do task = get_task(taskid) break if task[:status] != 'running' sleep 1 end if task[:status] == 'error' errormsg = task[:response].css("Error").first errormsg = "Error code #{errormsg['majorErrorCode']} - #{errormsg['message']}" end { :status => task[:status], :errormsg => errormsg, :start_time => task[:start_time], :end_time => task[:end_time] } end |