ruby_vcloud_sdk 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c8100349c1b50cb4fee66f496cd6c1ab4783addd
4
+ data.tar.gz: eb8dccf37fbec5841a64b0949216b2b595a2174b
5
+ SHA512:
6
+ metadata.gz: 4919e11c4041564202d38b4e1f2293e77b1df80cd5af8c8760acd25c158e16f6ec2cfef5bd9cfd8d8ba3d3ad720f3e292eb9005bda0250592f73bc282f7f595e
7
+ data.tar.gz: b7af07e1d38d9cb0e8198bf0d6ef1f7a45c7aa4e1b65826fe380031be0c89f2ba2285ea3394ea6adfd61c801ebd4dc25434b94d2d429ef242545ed592364d0a0
data/README.md CHANGED
@@ -6,11 +6,20 @@ Copyright (c) VMware, Inc.
6
6
  Client
7
7
 
8
8
  find_vdc_by_name
9
+ parameters:
10
+ name (String): name of VDC
9
11
  returns: VDC object matching name
10
12
  throws:
11
13
  'ObjectNotFoundError' when VDC with the name does not exist
12
14
  'RestClient::BadRequest' for un-expected errors
13
15
 
16
+ vdc_exists?
17
+ parameters:
18
+ name (String): name of VDC
19
+ returns: boolean
20
+ throws:
21
+ 'RestClient::BadRequest' for un-expected errors
22
+
14
23
  catalogs
15
24
  returns: array of catalog objects
16
25
  throws:
@@ -36,10 +45,15 @@ Copyright (c) VMware, Inc.
36
45
  delete_catalog_by_name
37
46
  parameters:
38
47
  name (String): name of catalog
39
- returns: nil
48
+ returns: Client object
40
49
  throws:
41
50
  'ObjectNotFoundError' when catalog with the name does not exist
42
51
  'RestClient::BadRequest' for un-expected errors
52
+
53
+ right_records
54
+ returns: array of RightRecord objects
55
+ throws:
56
+ 'RestClient::BadRequest' for un-expected errors
43
57
 
44
58
  VDC
45
59
 
@@ -54,11 +68,20 @@ Copyright (c) VMware, Inc.
54
68
  'RestClient::BadRequest' for un-expected errors
55
69
 
56
70
  find_storage_profile_by_name
71
+ parameters:
72
+ name (String): name of storage profile
57
73
  returns:
58
74
  storage profile object matching name
59
75
  throws:
60
76
  'ObjectNotFoundError' when storage profile with the name does not exist
61
77
  'RestClient::BadRequest' for un-expected errors
78
+
79
+ storage_profile_exists?
80
+ parameters:
81
+ name (String): name of storage profile
82
+ returns: boolean
83
+ throws:
84
+ 'RestClient::BadRequest' for un-expected errors
62
85
 
63
86
  vapps
64
87
  returns: array of vapp objects
@@ -71,13 +94,30 @@ Copyright (c) VMware, Inc.
71
94
  'RestClient::BadRequest' for un-expected errors
72
95
 
73
96
  find_vapp_by_name
97
+ parameters:
98
+ name (String): name of vapp
74
99
  returns:
75
100
  vapp object matching name
76
101
  throws:
77
102
  'ObjectNotFoundError' when vapp with the name does not exist
78
103
  'RestClient::BadRequest' for un-expected errors
79
104
 
105
+ vapp_exists?
106
+ parameters:
107
+ name (String): name of vapp
108
+ returns: boolean
109
+ throws:
110
+ 'RestClient::BadRequest' for un-expected errors
111
+
112
+ edge_gateways
113
+ returns: array of EdgeGateway objects
114
+ throws:
115
+ 'RestClient::BadRequest' for un-expected errors
116
+
80
117
  resources
118
+ returns: Resources object
119
+ throws:
120
+ 'RestClient::BadRequest' for un-expected errors
81
121
 
82
122
  networks
83
123
  returns: array of network objects
@@ -90,12 +130,21 @@ Copyright (c) VMware, Inc.
90
130
  'RestClient::BadRequest' for un-expected errors
91
131
 
92
132
  find_network_by_name
133
+ parameters:
134
+ name (String): name of network
93
135
  returns:
94
136
  network object matching name
95
137
  throws:
96
138
  'ObjectNotFoundError' when network with the name does not exist
97
139
  'RestClient::BadRequest' for un-expected errors
98
140
 
141
+ network_exists?
142
+ parameters:
143
+ name (String): name of network
144
+ returns: boolean
145
+ throws:
146
+ 'RestClient::BadRequest' for un-expected errors
147
+
99
148
  disks
100
149
  returns: array of disk objects
101
150
  throws:
@@ -107,12 +156,21 @@ Copyright (c) VMware, Inc.
107
156
  'RestClient::BadRequest' for un-expected errors
108
157
 
109
158
  find_disks_by_name
159
+ parameters:
160
+ name (String): name of disk
110
161
  returns:
111
162
  array of disk objects matching name
112
163
  throws:
113
164
  'ObjectNotFoundError' when disk with the name does not exist
114
165
  'RestClient::BadRequest' for un-expected errors
115
166
 
167
+ disk_exists?
168
+ parameters:
169
+ name (String): name of disk
170
+ returns: boolean
171
+ throws:
172
+ 'RestClient::BadRequest' for un-expected errors
173
+
116
174
  create_disk
117
175
  parameters:
118
176
  name (String): name of disk
@@ -130,7 +188,7 @@ Copyright (c) VMware, Inc.
130
188
  delete_disk_by_name
131
189
  parameters:
132
190
  name (String): name of disk
133
- returns: nil
191
+ returns: VDC object
134
192
  throws:
135
193
  'CloudError' when more than one disks matching the name exist
136
194
  'CloudError' when disk is attached to vm
@@ -139,7 +197,7 @@ Copyright (c) VMware, Inc.
139
197
  delete_all_disks_by_name
140
198
  parameters:
141
199
  name (String): name of disk
142
- returns: nil
200
+ returns: VDC object
143
201
  throws:
144
202
  'CloudError' when any disk deletion failure occurs
145
203
  'RestClient::BadRequest' for un-expected errors
@@ -156,37 +214,50 @@ Copyright (c) VMware, Inc.
156
214
  throws:
157
215
  'RestClient::BadRequest' for un-expected errors
158
216
 
159
- find_item
160
- returns: catalog item matching name and type
161
- throws:
162
- 'ObjectNotFoundError' when an item matching the name and type is not found
163
- 'RestClient::BadRequest' for un-expected errors
217
+ find_item
218
+ parameters:
219
+ name (String): name of item
220
+ type (String, optional): type of item - "application/vnd.vmware.vcloud.vAppTemplate+xml" or "application/vnd.vmware.vcloud.media+xml"
221
+ returns: catalog item matching name and type
222
+ throws:
223
+ 'ObjectNotFoundError' when an item matching the name and type is not found
224
+ 'RestClient::BadRequest' for un-expected errors
164
225
 
165
- item_exists?
166
- returns: boolean
167
- throws:
168
- 'RestClient::BadRequest' for un-expected errors
226
+ item_exists?
227
+ parameters:
228
+ name (String): name of item
229
+ type (String, optional): type of item - "application/vnd.vmware.vcloud.vAppTemplate+xml" or "application/vnd.vmware.vcloud.media+xml"
230
+
231
+ returns: boolean
232
+ throws:
233
+ 'RestClient::BadRequest' for un-expected errors
169
234
 
170
235
  delete_item_by_name_and_type
171
236
  parameters:
172
237
  name (String): name of item
173
238
  type (String, optional): type of item - "application/vnd.vmware.vcloud.vAppTemplate+xml" or "application/vnd.vmware.vcloud.media+xml"
174
- returns: nil
239
+ returns: Catalog object
175
240
  throws:
176
241
  'ObjectNotFoundError' when an item matching the name and type is not found
177
242
  'RestClient::BadRequest' for un-expected errors
178
243
 
179
244
  delete_all_items
180
- returns: nil
245
+ returns: Catalog object
181
246
  throws:
182
247
  'RestClient::BadRequest' for un-expected errors
183
248
 
184
- upload_media
185
- returns: catalog item uploaded
186
- throws:
187
- 'CloudError' when media file matching name already exists
188
- 'ObjectNotFoundError' when storage profile with the name does not exist
189
- 'RestClient::BadRequest' for un-expected errors
249
+ upload_media
250
+ parameters:
251
+ vdc_name (String): name of vdc
252
+ media_name (String): name of media
253
+ file (String): path of media file
254
+ storage_profile_name (String, optional): name of storage profile to upload vapp template to
255
+ image_type (String, optional): type of image file
256
+ returns: catalog item uploaded
257
+ throws:
258
+ 'CloudError' when media file matching name already exists
259
+ 'ObjectNotFoundError' when storage profile with the name does not exist
260
+ 'RestClient::BadRequest' for un-expected errors
190
261
 
191
262
  find_media_by_name
192
263
  parameters:
@@ -243,25 +314,28 @@ Copyright (c) VMware, Inc.
243
314
  VApp
244
315
 
245
316
  delete
246
- returns: task object
317
+ returns: nil
247
318
  throws:
248
319
  'CloudError' if VApp is powered on
249
320
  'RestClient::BadRequest' for un-expected errors
250
321
 
251
322
  power_on
252
- returns: task object
323
+ returns: VApp object
253
324
  throws:
254
325
  'CloudError' if power_on_link of VApp is missing
255
326
  'RestClient::BadRequest' for un-expected errors
256
327
 
257
328
  power_off
258
- returns: task object
329
+ returns: VApp object
259
330
  throws:
260
331
  'CloudError' if power_off_link of VApp is missing
261
332
  'VappSuspendedError' if VApp is suspended
262
333
  'RestClient::BadRequest' for un-expected errors
263
334
 
264
335
  recompose_from_vapp_template
336
+ parameters:
337
+ catalog_name (String): name of catalog
338
+ template_name (String): name of vapp template
265
339
  returns: recomposed vapp
266
340
  throws:
267
341
  'CloudError' when vapp is powered on
@@ -285,7 +359,16 @@ Copyright (c) VMware, Inc.
285
359
  'ObjectNotFoundError' when VM with the name does not exist
286
360
  'RestClient::BadRequest' for un-expected errors
287
361
 
362
+ vm_exists?
363
+ parameters:
364
+ name (String): name of vm
365
+ returns: boolean
366
+ throws:
367
+ 'RestClient::BadRequest' for un-expected errors
368
+
288
369
  remove_vm_by_name
370
+ parameters:
371
+ name (String): name of vm
289
372
  returns: parent VApp object
290
373
  throws:
291
374
  'ObjectNotFoundError' when VM with the name does not exist
@@ -306,7 +389,7 @@ Copyright (c) VMware, Inc.
306
389
  vApps to be powered on without conflict by isolating the MAC and IP addresses of the
307
390
  virtual machines. Available options are "bridged", "isolated" and "natRouted". Default
308
391
  to "bridged".
309
- returns: task object
392
+ returns: VApp object
310
393
  throws:
311
394
  'CloudError' when invalid fence mode is specified
312
395
  'ObjectNotFoundError' when network with the name does not exist
@@ -315,7 +398,7 @@ Copyright (c) VMware, Inc.
315
398
  delete_network_by_name
316
399
  parameters:
317
400
  name (String): name of network to delete
318
- returns: nil
401
+ returns: VApp object
319
402
  throws:
320
403
  'ObjectNotFoundError' when network with the name does not exist
321
404
  'RestClient::BadRequest' for un-expected errors
@@ -351,8 +434,8 @@ Copyright (c) VMware, Inc.
351
434
  'CloudError' when the memory size is less than or equal to 0
352
435
  'RestClient::BadRequest' for un-expected errors
353
436
 
354
- list_networks
355
- returns: array of network names
437
+ nics
438
+ returns: array of NIC objects
356
439
  throws:
357
440
  'RestClient::BadRequest' for un-expected errors
358
441
 
@@ -367,46 +450,50 @@ Copyright (c) VMware, Inc.
367
450
  'RestClient::BadRequest' for un-expected errors
368
451
 
369
452
  attach_disk
370
- returns: task object
453
+ parameters:
454
+ disk: The disk object.
455
+ returns: VM object
371
456
  throws:
372
457
  'CloudError' if disk is already attached
373
458
  'RestClient::BadRequest' for un-expected errors
374
459
 
375
460
  detach_disk
376
- returns: task object
461
+ parameters:
462
+ disk: The disk object.
463
+ returns: VM object
377
464
  throws:
378
465
  'VmSuspendedError' if containing vApp is suspended
379
466
  'CloudError' if disk is not attached or attached to other VM
380
467
  'RestClient::BadRequest' for un-expected errors
381
468
 
382
- status
383
- returns: string object
384
- throws:
385
- 'CloudError' if status code is invalid
386
- 'RestClient::BadRequest' for un-expected errors
387
-
388
469
  power_on
389
- returns: task object
470
+ returns: VM object
390
471
  throws:
391
472
  'CloudError' if power_on_link of VM is missing
392
473
  'RestClient::BadRequest' for un-expected errors
393
474
 
394
475
  power_off
395
- returns: task object
476
+ returns: VM object
396
477
  throws:
397
478
  'CloudError' if power_off_link of VM is missing
398
479
  'VmSuspendedError' if VM is suspended
399
480
  'RestClient::BadRequest' for un-expected errors
400
481
 
401
482
  insert_media
402
- returns: task object
483
+ parameters:
484
+ catalog_name (String): name of catalog
485
+ media_file_name (String): name of media file
486
+ returns: VM object
403
487
  throws:
404
488
  'ObjectNotFoundError' if when catalog with the name does not exist
405
489
  'ObjectNotFoundError' if when media with the name does not exist
406
490
  'RestClient::BadRequest' for un-expected errors
407
491
 
408
492
  eject_media
409
- returns: task object
493
+ parameters:
494
+ catalog_name (String): name of catalog
495
+ media_file_name (String): name of media file
496
+ returns: VM object
410
497
  throws:
411
498
  'ObjectNotFoundError' if when catalog with the name does not exist
412
499
  'ObjectNotFoundError' if when media with the name does not exist
@@ -418,7 +505,7 @@ Copyright (c) VMware, Inc.
418
505
  ip_addressing_mode (String, optional): available options are "NONE", "MANUAL",
419
506
  "POOL" and "DHCP". Default to "POOL"
420
507
  ip (String, optional): IP address for "MANUAL" IP Mode
421
- return: task object
508
+ return: VM object
422
509
  throws:
423
510
  'CloudError' if when ip_addressing_mode is invalid
424
511
  'CloudError' if ip is not specified in "MANUAL" ip_addressing_mode
@@ -426,6 +513,15 @@ Copyright (c) VMware, Inc.
426
513
  'ObjectNotFoundError' if network is not added to VM's parent VApp
427
514
  'RestClient::BadRequest' for un-expected errors
428
515
 
516
+ delete_nics
517
+ parameters:
518
+ nics (splat NIC objects): NICs to delete
519
+ return: VM object
520
+ throws:
521
+ 'CloudError' if vm is powered on
522
+ 'ObjectNotFoundError' if specified nic index does not exist
523
+ 'RestClient::BadRequest' for un-expected errors
524
+
429
525
  product_section_properties
430
526
  returns:
431
527
  array of hash values representing properties of product section of VM
@@ -452,13 +548,21 @@ Copyright (c) VMware, Inc.
452
548
  capcity (Integer): disk size in megabyte
453
549
  bus_type (String, optional): bus type of disk, defaults to "scsi"
454
550
  bus_sub_type (String, optional): bus sub type of disk, defaults to "lsilogic"
455
- returns: InternalDisk object created
551
+ returns: VM object
456
552
  throws:
457
553
  'CloudError' when capcity is less than or equal to 0
458
554
  'CloudError' when bus_type is invalid
459
555
  'CloudError' when bus_sub_type is invalid
460
556
  'RestClient::BadRequest' for un-expected errors
461
557
 
558
+ delete_internal_disk_by_name
559
+ parameters:
560
+ name (String): name of disk
561
+ returns: VM object
562
+ throws:
563
+ 'ObjectNotFoundError' if no disk matching the given name
564
+ 'RestClient::BadRequest' for un-expected errors
565
+
462
566
  VdcStorageProfile
463
567
 
464
568
  available_storage
@@ -472,4 +576,22 @@ Copyright (c) VMware, Inc.
472
576
  returns: IpRanges object
473
577
  throws:
474
578
  'RestClient::BadRequest' for un-expected errors
475
-
579
+
580
+
581
+ ## Example
582
+ VCloud_SDK is straightforward to use. Here is an example of creating vApp from vApp template.
583
+
584
+ 1. Create vCloud client object
585
+
586
+ client = VCloudSdk::Client.new(url, username, password)
587
+
588
+ Note that the parameter 'username' should be the VDC user_name@organization_name. For example,
589
+ the VDC user name is admin, the organization name is myorg, then the 'username' parameter
590
+ here should be admin@myorg.
591
+
592
+ 2. Find the catalog where the vapp template is stored
593
+ catalog = client.find_catalog_by_name(catalog_name)
594
+
595
+ 3. Create vApp from that vapp template
596
+ vapp = instantiate_vapp_template(vapp_template_name, vdc_name, vapp_name)
597
+
@@ -57,7 +57,7 @@ module VCloudSdk
57
57
 
58
58
  check_item_type(item, item_type)
59
59
  delete_item_by_link(link)
60
- nil
60
+ self
61
61
  end
62
62
 
63
63
  def delete_all_items
@@ -65,7 +65,7 @@ module VCloudSdk
65
65
  Config.logger.info "Deleting catalog item \"#{link.name}\""
66
66
  delete_item_by_link(link)
67
67
  end
68
- nil
68
+ self
69
69
  end
70
70
 
71
71
  def upload_media(
@@ -137,10 +137,10 @@ module VCloudSdk
137
137
  end
138
138
 
139
139
  def instantiate_vapp_template(template_name, vdc_name, vapp_name,
140
- description = nil, disk_locality = nil)
140
+ description = nil, disk_locality = nil, network_config = nil)
141
141
 
142
142
  instantiate_vapp_params = create_instantiate_vapp_params(
143
- template_name, vapp_name, description, disk_locality)
143
+ template_name, vapp_name, description, disk_locality, network_config)
144
144
 
145
145
  vdc = find_vdc_by_name vdc_name
146
146
 
@@ -179,7 +179,7 @@ module VCloudSdk
179
179
  entity_xml = connection.get(link)
180
180
  delete_item_entity entity_xml.entity
181
181
 
182
- connection.delete(entity_xml.remove_link)
182
+ connection.delete(entity_xml.remove_link.href)
183
183
  end
184
184
 
185
185
  def delete_item_entity(entity)
@@ -330,7 +330,7 @@ module VCloudSdk
330
330
  end
331
331
 
332
332
  def create_instantiate_vapp_params(template_name,
333
- vapp_name, description, disk_locality)
333
+ vapp_name, description, disk_locality, network_config)
334
334
 
335
335
  source_vapp_template = retrieve_vapp_template_xml_node(template_name)
336
336
 
@@ -338,6 +338,9 @@ module VCloudSdk
338
338
  "InstantiateVAppTemplateParams")
339
339
  instantiate_vapp_params.name = vapp_name
340
340
  instantiate_vapp_params.description = description
341
+
342
+ set_vapp_network_config_param(instantiate_vapp_params, network_config)
343
+
341
344
  instantiate_vapp_params.source = source_vapp_template
342
345
  instantiate_vapp_params.all_eulas_accepted = true
343
346
  instantiate_vapp_params.linked_clone = false
@@ -378,5 +381,19 @@ module VCloudSdk
378
381
  connection.put_file(incomplete_file.upload_link, media_file)
379
382
  connection.get(media)
380
383
  end
384
+
385
+ private
386
+
387
+ def set_vapp_network_config_param(instantiate_vapp_params, network_config)
388
+ return unless network_config
389
+
390
+ network = find_network_by_name(network_config.network_name)
391
+ target_vapp_net_name = network_config.vapp_net_name.nil? ?
392
+ network.name : network_config.vapp_net_name
393
+
394
+ instantiate_vapp_params.set_network_config(target_vapp_net_name,
395
+ network.href["href"].to_s,
396
+ network_config.fence_mode.to_s)
397
+ end
381
398
  end
382
399
  end
@@ -12,7 +12,8 @@ module VCloudSdk
12
12
  VCLOUD_VERSION_NUMBER = "5.1"
13
13
 
14
14
  public :find_vdc_by_name, :catalogs, :list_catalogs,
15
- :catalog_exists?, :find_catalog_by_name
15
+ :catalog_exists?, :find_catalog_by_name,
16
+ :vdc_exists?
16
17
 
17
18
  def initialize(url, username, password, options = {}, logger = nil)
18
19
  @url = url
@@ -36,7 +37,7 @@ module VCloudSdk
36
37
  catalog = find_catalog_by_name(name)
37
38
  catalog.delete_all_items
38
39
  connection.delete("/api/admin/catalog/#{catalog.id}")
39
- nil
40
+ self
40
41
  end
41
42
 
42
43
  def right_records
@@ -14,6 +14,12 @@ module VCloudSdk
14
14
  VCloudSdk::VDC.new(@session, vdc_link)
15
15
  end
16
16
 
17
+ def vdc_exists?(name)
18
+ @session.org.vdcs.any? do |vdc|
19
+ vdc.name == name
20
+ end
21
+ end
22
+
17
23
  def find_network_by_name(name)
18
24
  @session.org.networks.each do |network_link|
19
25
  if network_link.name == name
@@ -24,6 +30,12 @@ module VCloudSdk
24
30
  fail ObjectNotFoundError, "Network '#{name}' is not found"
25
31
  end
26
32
 
33
+ def network_exists?(name)
34
+ @session.org.networks.any? do |network|
35
+ network.name == name
36
+ end
37
+ end
38
+
27
39
  def catalogs
28
40
  @session.org.catalogs.map do |catalog_link|
29
41
  VCloudSdk::Catalog.new(@session, catalog_link)
@@ -1,9 +1,10 @@
1
1
  module VCloudSdk
2
2
 
3
3
  class InternalDisk
4
- attr_reader :capacity, :bus_type, :bus_sub_type
4
+ attr_reader :name, :capacity, :bus_type, :bus_sub_type
5
5
 
6
6
  def initialize(entity_xml)
7
+ @name = entity_xml.element_name
7
8
  @capacity = entity_xml.host_resource.attribute("capacity").to_s.to_i
8
9
  @bus_type = entity_xml.host_resource.attribute("busType").to_s
9
10
  @bus_sub_type = entity_xml.host_resource.attribute("busSubType").to_s
@@ -0,0 +1,16 @@
1
+ module VCloudSdk
2
+
3
+ class NetworkConfig
4
+ attr_reader :network_name, :vapp_net_name, :fence_mode
5
+
6
+ def initialize(
7
+ network_name,
8
+ vapp_net_name = nil,
9
+ fence_mode = Xml::FENCE_MODES[:BRIDGED])
10
+ @network_name = network_name
11
+ @vapp_net_name = vapp_net_name
12
+ @fence_mode = fence_mode
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,26 @@
1
+ module VCloudSdk
2
+ class NIC
3
+ extend Forwardable
4
+
5
+ def_delegators :@entity_xml,
6
+ :ip_address, :is_connected, :mac_address,
7
+ :ip_address_allocation_mode, :network
8
+
9
+ attr_reader :is_primary
10
+
11
+ def initialize(entity_xml, is_primary)
12
+ @entity_xml = entity_xml
13
+ @is_primary = is_primary
14
+ end
15
+
16
+ def network_connection_index
17
+ @entity_xml.network_connection_index.to_i
18
+ end
19
+
20
+ def is_connected
21
+ @entity_xml.is_connected == "true"
22
+ end
23
+
24
+ alias_method :nic_index, :network_connection_index
25
+ end
26
+ end
@@ -28,10 +28,10 @@ module VCloudSdk
28
28
  end
29
29
 
30
30
  Config.logger.info "Powering on #{class_name} #{target.name}."
31
- task = connection.post(power_on_link, nil)
31
+ task = connection.post(power_on_link.href, nil)
32
32
  task = monitor_task task, @session.time_limit[:power_on]
33
33
  Config.logger.info "#{class_name} #{target.name} is powered on."
34
- task
34
+ self
35
35
  end
36
36
 
37
37
  # Power off VApp or VM
@@ -54,11 +54,12 @@ module VCloudSdk
54
54
  fail CloudError, "#{class_name} #{target.name} is not in a state that could be powered off."
55
55
  end
56
56
 
57
- task = connection.post(power_off_link, nil)
57
+ task = connection.post(power_off_link.href, nil)
58
58
  monitor_task task, @session.time_limit[:power_off]
59
59
  Config.logger.info "#{class_name} #{target.name} is powered off."
60
60
 
61
61
  undeploy(target, class_name)
62
+ self
62
63
  end
63
64
 
64
65
  private
@@ -69,7 +70,7 @@ module VCloudSdk
69
70
 
70
71
  def undeploy(target, class_name)
71
72
  params = Xml::WrapperFactory.create_instance("UndeployVAppParams") # Even for VM it's called UndeployVappParams
72
- task = connection.post(target.undeploy_link, params)
73
+ task = connection.post(target.undeploy_link.href, params)
73
74
  task = monitor_task(task, @session.time_limit[:undeploy])
74
75
  Config.logger.info "#{class_name} #{target.name} is undeployed."
75
76
  task