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.
- checksums.yaml +7 -0
- data/README.md +296 -0
- data/lib/ruby_vcloud_sdk.rb +0 -4
- data/lib/ruby_vcloud_sdk/catalog.rb +377 -0
- data/lib/ruby_vcloud_sdk/catalog_item.rb +26 -0
- data/lib/ruby_vcloud_sdk/client.rb +25 -882
- data/lib/ruby_vcloud_sdk/config.rb +1 -7
- data/lib/ruby_vcloud_sdk/connection/connection.rb +114 -54
- data/lib/ruby_vcloud_sdk/cpu.rb +11 -0
- data/lib/ruby_vcloud_sdk/disk.rb +55 -0
- data/lib/ruby_vcloud_sdk/edge_gateway.rb +32 -0
- data/lib/ruby_vcloud_sdk/infrastructure.rb +135 -0
- data/lib/ruby_vcloud_sdk/ip_ranges.rb +95 -0
- data/lib/ruby_vcloud_sdk/memory.rb +11 -0
- data/lib/ruby_vcloud_sdk/network.rb +32 -0
- data/lib/ruby_vcloud_sdk/powerable.rb +78 -0
- data/lib/ruby_vcloud_sdk/resources.rb +13 -0
- data/lib/ruby_vcloud_sdk/session.rb +46 -0
- data/lib/ruby_vcloud_sdk/vapp.rb +122 -0
- data/lib/ruby_vcloud_sdk/vdc.rb +210 -0
- data/lib/ruby_vcloud_sdk/vdc_storage_profile.rb +23 -0
- data/lib/ruby_vcloud_sdk/version.rb +1 -1
- data/lib/ruby_vcloud_sdk/vm.rb +132 -0
- data/lib/ruby_vcloud_sdk/xml/constants.rb +6 -4
- data/lib/ruby_vcloud_sdk/xml/wrapper.rb +109 -30
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +45 -2
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/admin_catalog.rb +13 -4
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/allocated_ip_addresses.rb +9 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb +6 -14
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk.rb +24 -14
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params.rb +0 -2
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk_create_params.rb +1 -3
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +13 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/gateway_interface.rb +22 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb +4 -4
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_address.rb +10 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_range.rb +13 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_ranges.rb +9 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_scope.rb +6 -32
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/item.rb +1 -7
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/link.rb +14 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/media.rb +4 -20
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/media_insert_or_eject_params.rb +1 -3
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/network_connection_section.rb +0 -4
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/nic_item_wrapper.rb +0 -2
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/org.rb +44 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb +11 -3
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/query_result_records.rb +14 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/recompose_vapp_params.rb +42 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/session.rb +5 -5
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/supported_versions.rb +19 -0
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/task.rb +1 -1
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/upload_vapp_template_params.rb +2 -4
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb +13 -22
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb +0 -2
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vcloud.rb +5 -3
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb +72 -15
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/virtual_hardware_section.rb +8 -6
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +29 -25
- data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vms.rb +12 -0
- data/lib/ruby_vcloud_sdk/xml/xml_templates/AdminCatalog.xml +6 -1
- data/lib/ruby_vcloud_sdk/xml/xml_templates/RecomposeVAppParams.xml +16 -1
- metadata +116 -233
- data/README +0 -1
- data/Rakefile +0 -50
- data/lib/ruby_vcloud_sdk/util.rb +0 -21
- data/spec/assets/admin_org_response.xml +0 -75
- data/spec/assets/catalog_add_item_response.xml +0 -8
- data/spec/assets/catalog_add_vapp_request.xml +0 -5
- data/spec/assets/catalog_item_added_response.xml +0 -19
- data/spec/assets/catalog_response.xml +0 -19
- data/spec/assets/existing_media_busy_response.xml +0 -19
- data/spec/assets/existing_media_catalog_item.xml +0 -8
- data/spec/assets/existing_media_delete_task_done.xml +0 -6
- data/spec/assets/existing_media_done_response.xml +0 -11
- data/spec/assets/existing_vapp_resolver_response.xml +0 -3
- data/spec/assets/existing_vapp_template_catalog_resolver_response.xml +0 -3
- data/spec/assets/existing_vapp_template_instantiate_response.xml +0 -20
- data/spec/assets/existing_vapp_template_instantiate_task_error_response.xml +0 -7
- data/spec/assets/existing_vapp_template_instantiate_task_start_response.xml +0 -7
- data/spec/assets/existing_vapp_template_instantiate_task_success_response.xml +0 -7
- data/spec/assets/existing_vapp_template_item_response.xml +0 -8
- data/spec/assets/existing_vapp_template_ready_response.xml +0 -79
- data/spec/assets/finalize_upload_task_done_response.xml +0 -7
- data/spec/assets/finalize_upload_task_response.xml +0 -7
- data/spec/assets/indy_disk_attach_request.xml +0 -3
- data/spec/assets/indy_disk_attach_task.xml +0 -6
- data/spec/assets/indy_disk_attach_task_error.xml +0 -6
- data/spec/assets/indy_disk_create_error.xml +0 -1
- data/spec/assets/indy_disk_create_request.xml +0 -4
- data/spec/assets/indy_disk_create_response.xml +0 -19
- data/spec/assets/indy_disk_delete_task.xml +0 -6
- data/spec/assets/indy_disk_detach_request.xml +0 -3
- data/spec/assets/indy_disk_detach_task.xml +0 -6
- data/spec/assets/indy_disk_response.xml +0 -11
- data/spec/assets/instantiated_suspended_vapp_response.xml +0 -209
- data/spec/assets/instantiated_vapp_delelete_done_task.xml +0 -5
- data/spec/assets/instantiated_vapp_delelete_running_task.xml +0 -6
- data/spec/assets/instantiated_vapp_network_config_add_network_request.xml +0 -36
- data/spec/assets/instantiated_vapp_network_config_modify_network_task_success.xml +0 -6
- data/spec/assets/instantiated_vapp_network_config_remove_network_request.xml +0 -6
- data/spec/assets/instantiated_vapp_network_config_section_response.xml +0 -17
- data/spec/assets/instantiated_vapp_off_response.xml +0 -206
- data/spec/assets/instantiated_vapp_on_response.xml +0 -205
- data/spec/assets/instantiated_vapp_power_task_running.xml +0 -6
- data/spec/assets/instantiated_vapp_power_task_success.xml +0 -6
- data/spec/assets/instantiated_vapp_response.xml +0 -205
- data/spec/assets/instantiated_vm_change_task_running.xml +0 -6
- data/spec/assets/instantiated_vm_change_task_success.xml +0 -6
- data/spec/assets/instantiated_vm_cpu_response.xml +0 -11
- data/spec/assets/instantiated_vm_insert_media_task_done.xml +0 -6
- data/spec/assets/instantiated_vm_memory_response.xml +0 -11
- data/spec/assets/instantiated_vm_modify_task_running.xml +0 -6
- data/spec/assets/instantiated_vm_modify_task_success.xml +0 -5
- data/spec/assets/instantiated_vm_network_section_response.xml +0 -11
- data/spec/assets/instantiated_vm_response.xml +0 -149
- data/spec/assets/media_add_to_catalog_request.xml +0 -5
- data/spec/assets/media_add_to_catalog_response.xml +0 -8
- data/spec/assets/media_delete_task_done.xml +0 -6
- data/spec/assets/media_upload_pending_response.xml +0 -13
- data/spec/assets/media_upload_request.xml +0 -2
- data/spec/assets/metadata_set_request.xml +0 -3
- data/spec/assets/metadata_set_task_done.xml +0 -6
- data/spec/assets/org_network_response.xml +0 -22
- data/spec/assets/reconfigure_vm_request.xml +0 -133
- data/spec/assets/reconfigure_vm_task.xml +0 -8
- data/spec/assets/session.xml +0 -7
- data/spec/assets/test-config.yml +0 -38
- data/spec/assets/undeploy_params.xml +0 -1
- data/spec/assets/vapp_template_catalog_resolver_response.xml +0 -3
- data/spec/assets/vapp_template_delelete_done_task.xml +0 -5
- data/spec/assets/vapp_template_delelete_running_task.xml +0 -6
- data/spec/assets/vapp_template_instantiate_request.xml +0 -8
- data/spec/assets/vapp_template_instantiate_with_locality_request.xml +0 -14
- data/spec/assets/vapp_template_no_disk_response.xml +0 -27
- data/spec/assets/vapp_template_ready_response.xml +0 -79
- data/spec/assets/vapp_template_upload_complete.xml +0 -28
- data/spec/assets/vapp_template_upload_failed.xml +0 -28
- data/spec/assets/vapp_template_upload_request.xml +0 -4
- data/spec/assets/vapp_template_upload_response.xml +0 -25
- data/spec/assets/vcloud_response.xml +0 -56
- data/spec/assets/vdc_response.xml +0 -57
- data/spec/spec_helper.rb +0 -107
- data/spec/unit/client_response.rb +0 -700
- data/spec/unit/client_spec.rb +0 -1152
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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
|
+
|
data/lib/ruby_vcloud_sdk.rb
CHANGED
@@ -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
|