ruby_vcloud_sdk 0.4.8 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +296 -0
  3. data/lib/ruby_vcloud_sdk.rb +0 -4
  4. data/lib/ruby_vcloud_sdk/catalog.rb +377 -0
  5. data/lib/ruby_vcloud_sdk/catalog_item.rb +26 -0
  6. data/lib/ruby_vcloud_sdk/client.rb +25 -882
  7. data/lib/ruby_vcloud_sdk/config.rb +1 -7
  8. data/lib/ruby_vcloud_sdk/connection/connection.rb +114 -54
  9. data/lib/ruby_vcloud_sdk/cpu.rb +11 -0
  10. data/lib/ruby_vcloud_sdk/disk.rb +55 -0
  11. data/lib/ruby_vcloud_sdk/edge_gateway.rb +32 -0
  12. data/lib/ruby_vcloud_sdk/infrastructure.rb +135 -0
  13. data/lib/ruby_vcloud_sdk/ip_ranges.rb +95 -0
  14. data/lib/ruby_vcloud_sdk/memory.rb +11 -0
  15. data/lib/ruby_vcloud_sdk/network.rb +32 -0
  16. data/lib/ruby_vcloud_sdk/powerable.rb +78 -0
  17. data/lib/ruby_vcloud_sdk/resources.rb +13 -0
  18. data/lib/ruby_vcloud_sdk/session.rb +46 -0
  19. data/lib/ruby_vcloud_sdk/vapp.rb +122 -0
  20. data/lib/ruby_vcloud_sdk/vdc.rb +210 -0
  21. data/lib/ruby_vcloud_sdk/vdc_storage_profile.rb +23 -0
  22. data/lib/ruby_vcloud_sdk/version.rb +1 -1
  23. data/lib/ruby_vcloud_sdk/vm.rb +132 -0
  24. data/lib/ruby_vcloud_sdk/xml/constants.rb +6 -4
  25. data/lib/ruby_vcloud_sdk/xml/wrapper.rb +109 -30
  26. data/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +45 -2
  27. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/admin_catalog.rb +13 -4
  28. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/allocated_ip_addresses.rb +9 -0
  29. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb +6 -14
  30. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk.rb +24 -14
  31. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params.rb +0 -2
  32. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk_create_params.rb +1 -3
  33. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +13 -0
  34. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/gateway_interface.rb +22 -0
  35. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb +4 -4
  36. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_address.rb +10 -0
  37. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_range.rb +13 -0
  38. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_ranges.rb +9 -0
  39. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_scope.rb +6 -32
  40. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/item.rb +1 -7
  41. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/link.rb +14 -0
  42. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/media.rb +4 -20
  43. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/media_insert_or_eject_params.rb +1 -3
  44. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/network_connection_section.rb +0 -4
  45. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/nic_item_wrapper.rb +0 -2
  46. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/org.rb +44 -0
  47. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb +11 -3
  48. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/query_result_records.rb +14 -0
  49. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/recompose_vapp_params.rb +42 -0
  50. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/session.rb +5 -5
  51. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/supported_versions.rb +19 -0
  52. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/task.rb +1 -1
  53. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/upload_vapp_template_params.rb +2 -4
  54. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb +13 -22
  55. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb +0 -2
  56. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vcloud.rb +5 -3
  57. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb +72 -15
  58. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/virtual_hardware_section.rb +8 -6
  59. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +29 -25
  60. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vms.rb +12 -0
  61. data/lib/ruby_vcloud_sdk/xml/xml_templates/AdminCatalog.xml +6 -1
  62. data/lib/ruby_vcloud_sdk/xml/xml_templates/RecomposeVAppParams.xml +16 -1
  63. metadata +116 -233
  64. data/README +0 -1
  65. data/Rakefile +0 -50
  66. data/lib/ruby_vcloud_sdk/util.rb +0 -21
  67. data/spec/assets/admin_org_response.xml +0 -75
  68. data/spec/assets/catalog_add_item_response.xml +0 -8
  69. data/spec/assets/catalog_add_vapp_request.xml +0 -5
  70. data/spec/assets/catalog_item_added_response.xml +0 -19
  71. data/spec/assets/catalog_response.xml +0 -19
  72. data/spec/assets/existing_media_busy_response.xml +0 -19
  73. data/spec/assets/existing_media_catalog_item.xml +0 -8
  74. data/spec/assets/existing_media_delete_task_done.xml +0 -6
  75. data/spec/assets/existing_media_done_response.xml +0 -11
  76. data/spec/assets/existing_vapp_resolver_response.xml +0 -3
  77. data/spec/assets/existing_vapp_template_catalog_resolver_response.xml +0 -3
  78. data/spec/assets/existing_vapp_template_instantiate_response.xml +0 -20
  79. data/spec/assets/existing_vapp_template_instantiate_task_error_response.xml +0 -7
  80. data/spec/assets/existing_vapp_template_instantiate_task_start_response.xml +0 -7
  81. data/spec/assets/existing_vapp_template_instantiate_task_success_response.xml +0 -7
  82. data/spec/assets/existing_vapp_template_item_response.xml +0 -8
  83. data/spec/assets/existing_vapp_template_ready_response.xml +0 -79
  84. data/spec/assets/finalize_upload_task_done_response.xml +0 -7
  85. data/spec/assets/finalize_upload_task_response.xml +0 -7
  86. data/spec/assets/indy_disk_attach_request.xml +0 -3
  87. data/spec/assets/indy_disk_attach_task.xml +0 -6
  88. data/spec/assets/indy_disk_attach_task_error.xml +0 -6
  89. data/spec/assets/indy_disk_create_error.xml +0 -1
  90. data/spec/assets/indy_disk_create_request.xml +0 -4
  91. data/spec/assets/indy_disk_create_response.xml +0 -19
  92. data/spec/assets/indy_disk_delete_task.xml +0 -6
  93. data/spec/assets/indy_disk_detach_request.xml +0 -3
  94. data/spec/assets/indy_disk_detach_task.xml +0 -6
  95. data/spec/assets/indy_disk_response.xml +0 -11
  96. data/spec/assets/instantiated_suspended_vapp_response.xml +0 -209
  97. data/spec/assets/instantiated_vapp_delelete_done_task.xml +0 -5
  98. data/spec/assets/instantiated_vapp_delelete_running_task.xml +0 -6
  99. data/spec/assets/instantiated_vapp_network_config_add_network_request.xml +0 -36
  100. data/spec/assets/instantiated_vapp_network_config_modify_network_task_success.xml +0 -6
  101. data/spec/assets/instantiated_vapp_network_config_remove_network_request.xml +0 -6
  102. data/spec/assets/instantiated_vapp_network_config_section_response.xml +0 -17
  103. data/spec/assets/instantiated_vapp_off_response.xml +0 -206
  104. data/spec/assets/instantiated_vapp_on_response.xml +0 -205
  105. data/spec/assets/instantiated_vapp_power_task_running.xml +0 -6
  106. data/spec/assets/instantiated_vapp_power_task_success.xml +0 -6
  107. data/spec/assets/instantiated_vapp_response.xml +0 -205
  108. data/spec/assets/instantiated_vm_change_task_running.xml +0 -6
  109. data/spec/assets/instantiated_vm_change_task_success.xml +0 -6
  110. data/spec/assets/instantiated_vm_cpu_response.xml +0 -11
  111. data/spec/assets/instantiated_vm_insert_media_task_done.xml +0 -6
  112. data/spec/assets/instantiated_vm_memory_response.xml +0 -11
  113. data/spec/assets/instantiated_vm_modify_task_running.xml +0 -6
  114. data/spec/assets/instantiated_vm_modify_task_success.xml +0 -5
  115. data/spec/assets/instantiated_vm_network_section_response.xml +0 -11
  116. data/spec/assets/instantiated_vm_response.xml +0 -149
  117. data/spec/assets/media_add_to_catalog_request.xml +0 -5
  118. data/spec/assets/media_add_to_catalog_response.xml +0 -8
  119. data/spec/assets/media_delete_task_done.xml +0 -6
  120. data/spec/assets/media_upload_pending_response.xml +0 -13
  121. data/spec/assets/media_upload_request.xml +0 -2
  122. data/spec/assets/metadata_set_request.xml +0 -3
  123. data/spec/assets/metadata_set_task_done.xml +0 -6
  124. data/spec/assets/org_network_response.xml +0 -22
  125. data/spec/assets/reconfigure_vm_request.xml +0 -133
  126. data/spec/assets/reconfigure_vm_task.xml +0 -8
  127. data/spec/assets/session.xml +0 -7
  128. data/spec/assets/test-config.yml +0 -38
  129. data/spec/assets/undeploy_params.xml +0 -1
  130. data/spec/assets/vapp_template_catalog_resolver_response.xml +0 -3
  131. data/spec/assets/vapp_template_delelete_done_task.xml +0 -5
  132. data/spec/assets/vapp_template_delelete_running_task.xml +0 -6
  133. data/spec/assets/vapp_template_instantiate_request.xml +0 -8
  134. data/spec/assets/vapp_template_instantiate_with_locality_request.xml +0 -14
  135. data/spec/assets/vapp_template_no_disk_response.xml +0 -27
  136. data/spec/assets/vapp_template_ready_response.xml +0 -79
  137. data/spec/assets/vapp_template_upload_complete.xml +0 -28
  138. data/spec/assets/vapp_template_upload_failed.xml +0 -28
  139. data/spec/assets/vapp_template_upload_request.xml +0 -4
  140. data/spec/assets/vapp_template_upload_response.xml +0 -25
  141. data/spec/assets/vcloud_response.xml +0 -56
  142. data/spec/assets/vdc_response.xml +0 -57
  143. data/spec/spec_helper.rb +0 -107
  144. data/spec/unit/client_response.rb +0 -700
  145. data/spec/unit/client_spec.rb +0 -1152
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e4a7a59af14ae30e7e385ec2d53140e95bbeea19
4
+ data.tar.gz: f9ea0599b374ae52a64d243754736534d45c6233
5
+ SHA512:
6
+ metadata.gz: ad8a5d9da2550b289ac57d6570a959ee26d28de8975e901d1b84666f61e14d5aeb5b3c2e1ae9000dfe334e60c3b7d267591d23e06ce062d814b74c91cc0a17c5
7
+ data.tar.gz: 098583e00f2b459ead4922fa101056a1c744e26ec16da444c0afb0ea0a684c55d1e2b09c380cd39623fdedde19d954c626472770dea51e803605da8b6d96c16b
@@ -0,0 +1,296 @@
1
+ ## Ruby VCloud SDK is a gem to simplify making vCloud Director API calls.
2
+ Copyright (c) VMware, Inc.
3
+
4
+ ## Object Model
5
+
6
+ Client
7
+
8
+ find_vdc_by_name
9
+ returns: VDC object matching name
10
+ throws:
11
+ 'ObjectNotFoundError' when VDC with the name does not exist
12
+ 'RestClient::BadRequest' for un-expected errors
13
+
14
+ catalogs
15
+ returns: array of catalog objects
16
+ throws:
17
+ 'RestClient::BadRequest' for un-expected errors
18
+
19
+ list_catalogs
20
+ returns: array of catalog names
21
+ throws:
22
+ 'RestClient::BadRequest' for un-expected errors
23
+
24
+ find_catalog_by_name
25
+ returns:
26
+ catalog object matching name
27
+ throws:
28
+ 'ObjectNotFoundError' when catalog with the name does not exist
29
+ 'RestClient::BadRequest' for un-expected errors
30
+
31
+ create_catalog
32
+ returns: catalog object created
33
+ throws:
34
+ 'RestClient::BadRequest' for un-expected errors
35
+
36
+ delete_catalog
37
+ returns: nil
38
+ throws:
39
+ 'ObjectNotFoundError' when catalog with the name does not exist
40
+ 'RestClient::BadRequest' for un-expected errors
41
+
42
+ VDC
43
+
44
+ storage_profiles
45
+ returns: array of storage profile objects
46
+ throws:
47
+ 'RestClient::BadRequest' for un-expected errors
48
+
49
+ list_storage_profiles
50
+ returns: array of storage profile names
51
+ throws:
52
+ 'RestClient::BadRequest' for un-expected errors
53
+
54
+ find_storage_profile_by_name
55
+ returns:
56
+ storage profile object matching name
57
+ throws:
58
+ 'ObjectNotFoundError' when storage profile with the name does not exist
59
+ 'RestClient::BadRequest' for un-expected errors
60
+
61
+ vapps
62
+ returns: array of vapp objects
63
+ throws:
64
+ 'RestClient::BadRequest' for un-expected errors
65
+
66
+ list_vapps
67
+ returns: array of vapp names
68
+ throws:
69
+ 'RestClient::BadRequest' for un-expected errors
70
+
71
+ find_vapp_by_name
72
+ returns:
73
+ vapp object matching name
74
+ throws:
75
+ 'ObjectNotFoundError' when vapp with the name does not exist
76
+ 'RestClient::BadRequest' for un-expected errors
77
+
78
+ resources
79
+
80
+ networks
81
+ returns: array of network objects
82
+ throws:
83
+ 'RestClient::BadRequest' for un-expected errors
84
+
85
+ list_networks
86
+ returns: array of network names
87
+ throws:
88
+ 'RestClient::BadRequest' for un-expected errors
89
+
90
+ find_network_by_name
91
+ returns:
92
+ network object matching name
93
+ throws:
94
+ 'ObjectNotFoundError' when network with the name does not exist
95
+ 'RestClient::BadRequest' for un-expected errors
96
+
97
+ disks
98
+ returns: array of disk objects
99
+ throws:
100
+ 'RestClient::BadRequest' for un-expected errors
101
+
102
+ list_disks
103
+ returns: array of disk names
104
+ throws:
105
+ 'RestClient::BadRequest' for un-expected errors
106
+
107
+ find_disks_by_name
108
+ returns:
109
+ array of disk objects matching name
110
+ throws:
111
+ 'ObjectNotFoundError' when disk with the name does not exist
112
+ 'RestClient::BadRequest' for un-expected errors
113
+
114
+ Catalog
115
+
116
+ items
117
+ returns: array of catalog item objects
118
+ throws:
119
+ 'RestClient::BadRequest' for un-expected errors
120
+
121
+ list_items
122
+ returns: array of catalog item names
123
+ throws:
124
+ 'RestClient::BadRequest' for un-expected errors
125
+
126
+ find_item
127
+ returns: catalog item matching name and type
128
+ throws:
129
+ 'ObjectNotFoundError' when an item matching the name and type is not found
130
+ 'RestClient::BadRequest' for un-expected errors
131
+
132
+ item_exists?
133
+ returns: boolean
134
+ throws:
135
+ 'RestClient::BadRequest' for un-expected errors
136
+
137
+ delete_item
138
+ returns: nil
139
+ throws:
140
+ 'ObjectNotFoundError' when an item matching the name and type is not found
141
+ 'RestClient::BadRequest' for un-expected errors
142
+
143
+ delete_all_items
144
+ returns: nil
145
+ throws:
146
+ 'RestClient::BadRequest' for un-expected errors
147
+
148
+ upload_media
149
+ returns: catalog item uploaded
150
+ throws:
151
+ 'CloudError' when media file matching name already exists
152
+ 'ObjectNotFoundError' when storage profile with the name does not exist
153
+ 'RestClient::BadRequest' for un-expected errors
154
+
155
+ upload_vapp_template
156
+
157
+ find_vapp_template_by_name
158
+
159
+ instantiate_vapp_template
160
+
161
+ Network
162
+
163
+ ip_ranges
164
+ returns: IpRanges object
165
+ throws:
166
+ 'RestClient::BadRequest' for un-expected errors
167
+
168
+ allocated_ips
169
+ returns: array of strings
170
+ throws:
171
+ 'RestClient::BadRequest' for un-expected errors
172
+
173
+ VApp
174
+
175
+ delete
176
+ returns: task object
177
+ throws:
178
+ 'CloudError' if VApp is powered on
179
+ 'RestClient::BadRequest' for un-expected errors
180
+
181
+ power_on
182
+ returns: task object
183
+ throws:
184
+ 'CloudError' if power_on_link of VApp is missing
185
+ 'RestClient::BadRequest' for un-expected errors
186
+
187
+ power_off
188
+ returns: task object
189
+ throws:
190
+ 'CloudError' if power_off_link of VApp is missing
191
+ 'VappSuspendedError' if VApp is suspended
192
+ 'RestClient::BadRequest' for un-expected errors
193
+
194
+ recompose_from_vapp_template
195
+ returns: recomposed vapp
196
+ throws:
197
+ 'CloudError' when vapp is powered on
198
+ 'ObjectNotFoundError' when catalog with the name does not exist
199
+ 'ObjectNotFoundError' when vapp template with the name does not exist
200
+ 'RestClient::BadRequest' for un-expected errors
201
+
202
+ vms
203
+ returns: array of vm objects
204
+ throws:
205
+ 'RestClient::BadRequest' for un-expected errors
206
+
207
+ list_vms
208
+ returns: array of vm names
209
+ throws:
210
+ 'RestClient::BadRequest' for un-expected errors
211
+
212
+ find_vm_by_name
213
+ returns: VM object
214
+ throws:
215
+ 'ObjectNotFoundError' when VM with the name does not exist
216
+ 'RestClient::BadRequest' for un-expected errors
217
+
218
+ remove_vm_by_name
219
+ returns: parent VApp object
220
+ throws:
221
+ 'ObjectNotFoundError' when VM with the name does not exist
222
+ 'CloudError' when VApp is in status of 'POWERED_ON' and can not be recomposed
223
+ 'RestClient::BadRequest' for un-expected errors
224
+
225
+ VM
226
+
227
+ independent_disks
228
+ returns: array of disk objects
229
+ throws:
230
+ 'RestClient::BadRequest' for un-expected errors
231
+
232
+ list_disks
233
+ returns: names of disks on vm (in parentheses it shows the name of independent disk)
234
+ throws:
235
+ 'RestClient::BadRequest' for un-expected errors
236
+
237
+ attach_disk
238
+ returns: task object
239
+ throws:
240
+ 'CloudError' if disk is already attached
241
+ 'RestClient::BadRequest' for un-expected errors
242
+
243
+ detach_disk
244
+ returns: task object
245
+ throws:
246
+ 'VmSuspendedError' if containing vApp is suspended
247
+ 'CloudError' if disk is not attached or attached to other VM
248
+ 'RestClient::BadRequest' for un-expected errors
249
+
250
+ status
251
+ returns: string object
252
+ throws:
253
+ 'CloudError' if status code is invalid
254
+ 'RestClient::BadRequest' for un-expected errors
255
+
256
+ power_on
257
+ returns: task object
258
+ throws:
259
+ 'CloudError' if power_on_link of VM is missing
260
+ 'RestClient::BadRequest' for un-expected errors
261
+
262
+ power_off
263
+ returns: task object
264
+ throws:
265
+ 'CloudError' if power_off_link of VM is missing
266
+ 'VmSuspendedError' if VM is suspended
267
+ 'RestClient::BadRequest' for un-expected errors
268
+
269
+ insert_media
270
+ returns: task object
271
+ throws:
272
+ 'ObjectNotFoundError' if when catalog with the name does not exist
273
+ 'ObjectNotFoundError' if when media with the name does not exist
274
+ 'RestClient::BadRequest' for un-expected errors
275
+
276
+ eject_media
277
+ returns: task object
278
+ throws:
279
+ 'ObjectNotFoundError' if when catalog with the name does not exist
280
+ 'ObjectNotFoundError' if when media with the name does not exist
281
+ 'RestClient::BadRequest' for un-expected errors
282
+
283
+ VdcStorageProfile
284
+
285
+ available_storage
286
+ returns:
287
+ integer number of available storage in MB, i.e. storageLimitMB - storageUsedMB
288
+ -1 if 'storageLimitMB' is 0
289
+
290
+ EdgeGateway
291
+
292
+ public_ips:
293
+ returns: IpRanges object
294
+ throws:
295
+ 'RestClient::BadRequest' for un-expected errors
296
+
@@ -1,6 +1,3 @@
1
- $:.unshift(File.expand_path("..", __FILE__))
2
-
3
- require "rubygems" # Needed for Ruby 1.8
4
1
  require "logger"
5
2
 
6
3
  module VCloudSdk; end
@@ -11,7 +8,6 @@ require "ruby_vcloud_sdk/xml/wrapper_classes"
11
8
 
12
9
  require "ruby_vcloud_sdk/config"
13
10
  require "ruby_vcloud_sdk/errors"
14
- require "ruby_vcloud_sdk/util"
15
11
  require "ruby_vcloud_sdk/client"
16
12
  require "ruby_vcloud_sdk/ovf_directory"
17
13
 
@@ -0,0 +1,377 @@
1
+ require_relative "vdc"
2
+ require_relative "session"
3
+ require_relative "infrastructure"
4
+ require_relative "catalog_item"
5
+
6
+ module VCloudSdk
7
+ class Catalog
8
+ include Infrastructure
9
+
10
+ def initialize(session, link)
11
+ @session = session
12
+ @link = link
13
+ end
14
+
15
+ def name
16
+ admin_xml.name
17
+ end
18
+
19
+ def id
20
+ @link.href_id
21
+ end
22
+
23
+ def items
24
+ admin_xml.catalog_items.map do |item|
25
+ VCloudSdk::CatalogItem.new(@session, item)
26
+ end
27
+ end
28
+
29
+ def list_items
30
+ admin_xml.catalog_items.map do |item_link|
31
+ item_link.name
32
+ end
33
+ end
34
+
35
+ # Find catalog item from catalog by name and type.
36
+ # If item_type is set to nil, returns catalog item as long as its name match.
37
+ # Raises an exception if catalog is not found.
38
+ # Raises ObjectNotFoundError if an item matching the name and type is not found.
39
+ # Otherwise, returns the catalog item.
40
+ def find_item(name, item_type = nil)
41
+ link = find_item_link(name)
42
+ item = VCloudSdk::CatalogItem.new(@session, link)
43
+ check_item_type(item, item_type)
44
+ item
45
+ end
46
+
47
+ def item_exists?(name, item_type = nil)
48
+ items.any? do |item|
49
+ item.name == name &&
50
+ (item_type.nil? || item.type == item_type)
51
+ end
52
+ end
53
+
54
+ def delete_item(name, item_type = nil)
55
+ link = find_item_link(name)
56
+ item = VCloudSdk::CatalogItem.new(@session, link)
57
+
58
+ check_item_type(item, item_type)
59
+ delete_item_by_link(link)
60
+ nil
61
+ end
62
+
63
+ def delete_all_items
64
+ admin_xml.catalog_items.map do |link|
65
+ Config.logger.info "Deleting catalog item \"#{link.name}\""
66
+ delete_item_by_link(link)
67
+ end
68
+ nil
69
+ end
70
+
71
+ def upload_media(
72
+ vdc_name,
73
+ media_name,
74
+ file,
75
+ storage_profile_name = nil,
76
+ image_type = "iso")
77
+
78
+ if item_exists?(media_name)
79
+ fail CloudError,
80
+ "Catalog Item '#{media_name}' already exists in catalog #{name}"
81
+ end
82
+
83
+ Config.logger.info %Q{
84
+ Uploading file #{file}
85
+ as media #{media_name} of type #{image_type}
86
+ to catalog #{name}, storage profile #{storage_profile_name}, vdc #{vdc_name}
87
+ }
88
+
89
+ media_file = file.is_a?(String) ? File.new(file, "rb") : file
90
+
91
+ vdc = find_vdc_by_name vdc_name
92
+
93
+ storage_profile = vdc.storage_profile_xml_node storage_profile_name
94
+
95
+ media = upload_media_params media_name, vdc, media_file, image_type, storage_profile
96
+
97
+ media = upload_media_file media, media_file
98
+
99
+ add_item(media)
100
+ end
101
+
102
+ def upload_vapp_template(
103
+ vdc_name,
104
+ template_name,
105
+ directory,
106
+ storage_profile_name = nil)
107
+ if item_exists?(template_name)
108
+ fail "vApp template '#{template_name}' already exists in catalog #{name}"
109
+ end
110
+
111
+ vdc = find_vdc_by_name vdc_name
112
+
113
+ storage_profile = vdc.storage_profile_xml_node storage_profile_name
114
+
115
+ Config.logger.info "Uploading vApp #{template_name} to #{vdc.name}"
116
+ vapp_template = upload_vapp_template_params(template_name, vdc, storage_profile)
117
+
118
+ vapp_template = upload_vapp_files(vapp_template, ovf_directory(directory))
119
+
120
+ validate_vapp_template_tasks vapp_template
121
+
122
+ Config.logger.info %Q{
123
+ Template #{template_name} uploaded, adding to catalog #{name}.
124
+ }
125
+ add_item(vapp_template)
126
+ end
127
+
128
+ def find_vapp_template_by_name(name)
129
+ find_item(name, Xml::MEDIA_TYPE[:VAPP_TEMPLATE])
130
+ end
131
+
132
+ def instantiate_vapp_template(template_name, vdc_name, vapp_name,
133
+ description = nil, disk_locality = nil)
134
+
135
+ instantiate_vapp_params = create_instantiate_vapp_params(
136
+ template_name, vapp_name, description, disk_locality)
137
+
138
+ vdc = find_vdc_by_name vdc_name
139
+
140
+ vapp = connection.post(vdc.instantiate_vapp_template_link,
141
+ instantiate_vapp_params)
142
+ vapp.running_tasks.each do |task|
143
+ begin
144
+ monitor_task(task, @session.time_limit[:instantiate_vapp_template])
145
+ rescue ApiError => e
146
+ Config.logger.error(e, "Instantiate vApp template #{vapp_name} " +
147
+ "failed. Task #{task.operation} did not complete successfully.")
148
+ raise e
149
+ end
150
+ end
151
+
152
+ vdc = find_vdc_by_name vdc_name # Refresh information about vdc
153
+ vdc.find_vapp_by_name vapp_name
154
+ end
155
+
156
+ private
157
+
158
+ def add_item(item)
159
+ catalog_item = create_catalog_item_payload(item)
160
+ catalog_name = name
161
+ catalog_item_name = catalog_item.name
162
+ Config.logger.info "Adding #{catalog_item_name} to catalog #{catalog_name}"
163
+ connection.post(admin_xml.add_item_link,
164
+ catalog_item,
165
+ Xml::ADMIN_MEDIA_TYPE[:CATALOG_ITEM])
166
+ Config.logger.info %Q{
167
+ catalog_item #{catalog_item_name} added to catalog #{catalog_name}:
168
+ #{catalog_item.to_s}
169
+ }
170
+ catalog_item
171
+ end
172
+
173
+ def delete_item_by_link(link)
174
+ entity_xml = connection.get(link)
175
+ delete_item_entity entity_xml.entity
176
+
177
+ connection.delete(entity_xml.remove_link)
178
+ end
179
+
180
+ def delete_item_entity(entity)
181
+ linked_obj = connection.get(entity)
182
+
183
+ wait_for_running_tasks(linked_obj, linked_obj.href)
184
+ Config.logger.info "Deleting #{linked_obj.href}."
185
+ monitor_task(connection.delete(linked_obj))
186
+ Config.logger.info "#{linked_obj.href} deleted."
187
+ end
188
+
189
+ def find_item_link(name)
190
+ fail ObjectNotFoundError, "Catalog item name cannot be nil" unless name
191
+
192
+ admin_xml.catalog_items.each do |item_link|
193
+ return item_link if name == item_link.name
194
+ end
195
+
196
+ fail ObjectNotFoundError, "Catalog Item '#{name}' is not found"
197
+ end
198
+
199
+ def check_item_type(item, item_type)
200
+ unless item_type.nil? || item.type == item_type
201
+ fail ObjectNotFoundError, "Catalog Item '#{item.name}' is not found"
202
+ end
203
+ end
204
+
205
+ def upload_vapp_template_params(template_name, vdc, storage_profile)
206
+ upload_params = Xml::WrapperFactory.create_instance(
207
+ "UploadVAppTemplateParams")
208
+ upload_params.name = template_name
209
+ upload_params.storage_profile = storage_profile
210
+ connection.post(vdc.upload_link, upload_params)
211
+ end
212
+
213
+ def ovf_directory(directory)
214
+ # if directory behaves like an OVFDirectory, then use it
215
+ is_ovf_directory = [:ovf_file, :ovf_file_path, :vmdk_file, :vmdk_file_path]
216
+ .reduce(true) do |present, name|
217
+ present && directory.respond_to?(name)
218
+ end
219
+
220
+ if is_ovf_directory
221
+ directory
222
+ else
223
+ OVFDirectory.new(directory)
224
+ end
225
+ end
226
+
227
+ def admin_xml
228
+ admin_catalog_link = "/api/admin/catalog/#{id}"
229
+ admin_catalog = connection.get(admin_catalog_link)
230
+
231
+ unless admin_catalog
232
+ fail ObjectNotFoundError,
233
+ "Catalog link #{admin_catalog_link} not available."
234
+ end
235
+
236
+ admin_catalog
237
+ end
238
+
239
+ def create_catalog_item_payload(item)
240
+ catalog_item = Xml::WrapperFactory.create_instance(Xml::XML_TYPE[:CATALOGITEM])
241
+ catalog_item.name = item.name
242
+ catalog_item.entity = item
243
+ catalog_item
244
+ end
245
+
246
+ def validate_vapp_template_tasks(vapp_template)
247
+ err_tasks = connection.get(vapp_template).tasks.select do |t|
248
+ t.status != Xml::TASK_STATUS[:SUCCESS]
249
+ end
250
+ unless err_tasks.empty?
251
+
252
+ Config.logger.error %Q{
253
+ Error uploading vApp template.
254
+ Non-successful tasks:
255
+ #{err_tasks}
256
+ }
257
+ fail CloudError, "Error uploading vApp template"
258
+ end
259
+ end
260
+
261
+ def upload_vapp_files(
262
+ vapp_template,
263
+ ovf_directory,
264
+ tries = @session.retries[:upload_vapp_files])
265
+ tries.times do |try|
266
+ current_vapp_template = connection.get(vapp_template)
267
+ if !current_vapp_template.files || current_vapp_template.files.empty?
268
+ Config.logger.info %Q{
269
+ #{current_vapp_template.name} has tasks in progress...
270
+ Waiting until done...
271
+ }
272
+ current_vapp_template.running_tasks.each do |task|
273
+ monitor_task(task,
274
+ @session.time_limit[:process_descriptor_vapp_template])
275
+ end
276
+
277
+ return current_vapp_template
278
+ end
279
+
280
+ Config.logger.debug "vapp files left to upload #{current_vapp_template.files}."
281
+ Config.logger.debug %Q{
282
+ vapp incomplete files left to upload:
283
+ #{current_vapp_template.incomplete_files}
284
+ }
285
+
286
+ current_vapp_template.incomplete_files.each do |f|
287
+ # switch on extension
288
+ case f.name.split(".")[-1].downcase
289
+ when "ovf"
290
+ Config.logger.info %Q{
291
+ Uploading OVF file:
292
+ #{ovf_directory.ovf_file_path} for #{vapp_template.name}
293
+ }
294
+ connection.put(f.upload_link, ovf_directory.ovf_file.read,
295
+ Xml::MEDIA_TYPE[:OVF])
296
+ when "vmdk"
297
+ Config.logger.info %Q{
298
+ Uploading VMDK file:
299
+ #{ovf_directory.vmdk_file_path(f.name)} for #{vapp_template.name}
300
+ }
301
+ connection.put_file(f.upload_link,
302
+ ovf_directory.vmdk_file(f.name))
303
+ end
304
+ end
305
+ # Repeat
306
+ sleep 2**try
307
+ end
308
+
309
+ fail ApiTimeoutError,
310
+ %Q{
311
+ Unable to finish uploading vApp after #{tries} tries.
312
+ current_vapp_template.files:
313
+ #{current_vapp_template.files}
314
+ }
315
+ end
316
+
317
+ def retrieve_vapp_template_xml_node(template_name)
318
+ vapp_template = find_vapp_template_by_name(template_name)
319
+ unless vapp_template
320
+ fail ObjectNotFoundError, "vapp_template #{template_name}" +
321
+ "cannot be found in catalog #{@name}."
322
+ end
323
+
324
+ connection.get(vapp_template.href)
325
+ end
326
+
327
+ def create_instantiate_vapp_params(template_name,
328
+ vapp_name, description, disk_locality)
329
+
330
+ source_vapp_template = retrieve_vapp_template_xml_node(template_name)
331
+
332
+ instantiate_vapp_params = Xml::WrapperFactory.create_instance(
333
+ "InstantiateVAppTemplateParams")
334
+ instantiate_vapp_params.name = vapp_name
335
+ instantiate_vapp_params.description = description
336
+ instantiate_vapp_params.source = source_vapp_template
337
+ instantiate_vapp_params.all_eulas_accepted = true
338
+ instantiate_vapp_params.linked_clone = false
339
+ instantiate_vapp_params.set_locality = locality_spec(
340
+ source_vapp_template, disk_locality)
341
+
342
+ instantiate_vapp_params
343
+ end
344
+
345
+ def locality_spec(vapp_template, disk_locality)
346
+ disk_locality ||= []
347
+ locality = {}
348
+ disk_locality.each do |disk|
349
+ current_disk = connection.get(disk)
350
+ unless current_disk
351
+ Config.logger.info "Disk #{disk.name} no longer exists."
352
+ next
353
+ end
354
+ vapp_template.vms.each do |vm|
355
+ locality[vm] = current_disk
356
+ end
357
+ end
358
+ locality
359
+ end
360
+
361
+ def upload_media_params(media_name, vdc, media_file, image_type, storage_profile)
362
+ upload_params = Xml::WrapperFactory.create_instance("Media")
363
+ upload_params.name = media_name
364
+ upload_params.size = media_file.stat.size
365
+ upload_params.image_type = image_type
366
+ upload_params.storage_profile = storage_profile
367
+
368
+ connection.post(vdc.upload_media_link, upload_params)
369
+ end
370
+
371
+ def upload_media_file(media, media_file)
372
+ incomplete_file = media.incomplete_files.pop
373
+ connection.put_file(incomplete_file.upload_link, media_file)
374
+ connection.get(media)
375
+ end
376
+ end
377
+ end