ruby_vcloud_sdk 0.4.8 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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