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.
- 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
|