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
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
module VCloudSdk
|
|
2
|
-
|
|
3
2
|
class Config
|
|
4
3
|
class << self
|
|
5
4
|
attr_accessor :logger
|
|
6
|
-
attr_accessor :rest_logger
|
|
7
|
-
attr_accessor :rest_throttle
|
|
8
5
|
|
|
9
6
|
def configure(config)
|
|
10
|
-
@logger = config[
|
|
11
|
-
@rest_logger = config["rest_logger"] || @logger
|
|
12
|
-
@rest_throttle = config["rest_throttle"]
|
|
7
|
+
@logger = config[:logger] || @logger || Logger.new(STDOUT)
|
|
13
8
|
end
|
|
14
9
|
end
|
|
15
10
|
end
|
|
16
|
-
|
|
17
11
|
end
|
|
@@ -3,37 +3,43 @@ require "rest_client"
|
|
|
3
3
|
|
|
4
4
|
module VCloudSdk
|
|
5
5
|
module Connection
|
|
6
|
-
|
|
7
6
|
class Connection
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
ACCEPT = "application/*+xml;version=#{VCloudSdk::Client::VCLOUD_VERSION_NUMBER}"
|
|
8
|
+
|
|
9
|
+
REST_THROTTLE = {
|
|
10
|
+
min: 0,
|
|
11
|
+
max: 1,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private_constant :ACCEPT, :REST_THROTTLE
|
|
15
|
+
|
|
16
|
+
def initialize(url, request_timeout = nil,
|
|
17
|
+
rest_client = nil, site = nil, file_uploader = nil, rest_throttle = nil)
|
|
18
|
+
@rest_throttle = rest_throttle || REST_THROTTLE
|
|
19
|
+
|
|
20
|
+
construct_rest_logger
|
|
21
|
+
Config.configure(rest_logger: @rest_logger)
|
|
22
|
+
|
|
17
23
|
rest_client = RestClient unless rest_client
|
|
18
24
|
rest_client.log = @rest_logger
|
|
19
25
|
request_timeout = 60 unless request_timeout
|
|
20
|
-
@site = site
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
@site = site || rest_client::Resource.new(
|
|
27
|
+
url,
|
|
28
|
+
timeout: request_timeout)
|
|
29
|
+
@file_uploader = file_uploader || FileUploader
|
|
23
30
|
end
|
|
24
31
|
|
|
25
32
|
def connect(username, password)
|
|
26
|
-
|
|
27
|
-
login_password = "#{login}:#{password}"
|
|
33
|
+
login_password = "#{username}:#{password}"
|
|
28
34
|
auth_header_value = "Basic #{Base64.encode64(login_password)}"
|
|
29
|
-
response = @site[
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
response = @site[login_url].post(
|
|
36
|
+
Authorization: auth_header_value, Accept: ACCEPT)
|
|
37
|
+
Config.logger.debug(response)
|
|
32
38
|
@cookies = response.cookies
|
|
33
39
|
unless @cookies["vcloud-token"].gsub!("+", "%2B").nil?
|
|
34
|
-
|
|
40
|
+
Config.logger.debug("@cookies: #{@cookies.inspect}.")
|
|
35
41
|
end
|
|
36
|
-
|
|
42
|
+
wrap_response(response)
|
|
37
43
|
end
|
|
38
44
|
|
|
39
45
|
# GET an object from REST and return the unmarshalled object
|
|
@@ -41,15 +47,14 @@ module VCloudSdk
|
|
|
41
47
|
@rest_logger.info "#{__method__.to_s.upcase} #{delay}\t " +
|
|
42
48
|
"#{self.class.get_href(destination)}"
|
|
43
49
|
sleep(delay)
|
|
44
|
-
response = @site[get_nested_resource(destination)].get(
|
|
45
|
-
:
|
|
46
|
-
:cookies
|
|
47
|
-
})
|
|
50
|
+
response = @site[get_nested_resource(destination)].get(
|
|
51
|
+
Accept: ACCEPT,
|
|
52
|
+
cookies: @cookies)
|
|
48
53
|
@rest_logger.debug(response)
|
|
49
|
-
|
|
54
|
+
wrap_response(response)
|
|
50
55
|
end
|
|
51
56
|
|
|
52
|
-
def post(destination, data, content_type =
|
|
57
|
+
def post(destination, data, content_type = "*/*")
|
|
53
58
|
@rest_logger.info "#{__method__.to_s.upcase} #{delay}\t " +
|
|
54
59
|
"#{self.class.get_href(destination)}"
|
|
55
60
|
sleep(delay)
|
|
@@ -59,13 +64,13 @@ module VCloudSdk
|
|
|
59
64
|
end
|
|
60
65
|
@rest_logger.info("#{__method__.to_s.upcase} data:#{data.to_s}")
|
|
61
66
|
response = @site[get_nested_resource(destination)].post(data.to_s, {
|
|
62
|
-
:
|
|
63
|
-
:cookies
|
|
64
|
-
:content_type
|
|
67
|
+
Accept: ACCEPT,
|
|
68
|
+
cookies: @cookies,
|
|
69
|
+
content_type: content_type
|
|
65
70
|
})
|
|
66
|
-
|
|
71
|
+
fail ApiRequestError if http_error?(response)
|
|
67
72
|
@rest_logger.debug(response)
|
|
68
|
-
|
|
73
|
+
wrap_response(response)
|
|
69
74
|
end
|
|
70
75
|
|
|
71
76
|
def put(destination, data, content_type = "*/*")
|
|
@@ -77,16 +82,16 @@ module VCloudSdk
|
|
|
77
82
|
"Warning: content type not specified. Default to '*/*'")
|
|
78
83
|
end
|
|
79
84
|
@rest_logger.info("#{__method__.to_s.upcase} data:#{data.to_s}")
|
|
80
|
-
response = @site[get_nested_resource(destination)].put(data.to_s,
|
|
81
|
-
:
|
|
82
|
-
:cookies
|
|
83
|
-
:content_type
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
response = @site[get_nested_resource(destination)].put(data.to_s,
|
|
86
|
+
Accept: ACCEPT,
|
|
87
|
+
cookies: @cookies,
|
|
88
|
+
content_type: content_type
|
|
89
|
+
)
|
|
90
|
+
fail ApiRequestError if http_error?(response)
|
|
86
91
|
@rest_logger.debug((response && !response.strip.empty?) ?
|
|
87
92
|
response : "Received empty response.")
|
|
88
93
|
if response && !response.strip.empty?
|
|
89
|
-
|
|
94
|
+
wrap_response(response)
|
|
90
95
|
else
|
|
91
96
|
nil
|
|
92
97
|
end
|
|
@@ -96,13 +101,13 @@ module VCloudSdk
|
|
|
96
101
|
@rest_logger.info "#{__method__.to_s.upcase} #{delay}\t " +
|
|
97
102
|
"#{self.class.get_href(destination)}"
|
|
98
103
|
sleep(delay)
|
|
99
|
-
response = @site[get_nested_resource(destination)].delete(
|
|
100
|
-
:
|
|
101
|
-
:cookies
|
|
102
|
-
|
|
104
|
+
response = @site[get_nested_resource(destination)].delete(
|
|
105
|
+
Accept: ACCEPT,
|
|
106
|
+
cookies: @cookies
|
|
107
|
+
)
|
|
103
108
|
@rest_logger.debug(response)
|
|
104
109
|
if response && !response.strip.empty?
|
|
105
|
-
|
|
110
|
+
wrap_response(response)
|
|
106
111
|
else
|
|
107
112
|
nil
|
|
108
113
|
end
|
|
@@ -120,27 +125,83 @@ module VCloudSdk
|
|
|
120
125
|
end
|
|
121
126
|
|
|
122
127
|
private
|
|
128
|
+
|
|
129
|
+
def wrap_response(response)
|
|
130
|
+
VCloudSdk::Xml::WrapperFactory.wrap_document response
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def login_url
|
|
134
|
+
return @login_url if @login_url
|
|
135
|
+
default_login_url = "/api/sessions"
|
|
136
|
+
|
|
137
|
+
begin
|
|
138
|
+
url_node = get("/api/versions")
|
|
139
|
+
if url_node.nil?
|
|
140
|
+
Config.logger.warn %Q{
|
|
141
|
+
Unable to find version=#{VCLOUD_VERSION_NUMBER}. Default to #{default_login_url}
|
|
142
|
+
}
|
|
143
|
+
@login_url = default_login_url
|
|
144
|
+
else
|
|
145
|
+
# Typically url_content is the full URL such as "https://10.146.21.135/api/sessions"
|
|
146
|
+
# In this case we need to trim the beginning of the url string
|
|
147
|
+
@login_url = get_nested_resource(url_node.login_url.content)
|
|
148
|
+
end
|
|
149
|
+
rescue => ex
|
|
150
|
+
Config.logger.warn %Q{
|
|
151
|
+
Caught exception when retrieving login url:
|
|
152
|
+
#{ex.to_s}"
|
|
153
|
+
|
|
154
|
+
Default to #{default_login_url}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@login_url = default_login_url
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def construct_rest_logger
|
|
162
|
+
Config.logger.debug("constructing rest_logger")
|
|
163
|
+
|
|
164
|
+
config_logger_dev = Config.logger.instance_eval { @logdev }.dev
|
|
165
|
+
if config_logger_dev.respond_to?(:path)
|
|
166
|
+
rest_log_filename = File.join(
|
|
167
|
+
File.dirname(config_logger_dev.path),
|
|
168
|
+
"rest")
|
|
169
|
+
log_file = File.open(rest_log_filename, "w")
|
|
170
|
+
log_file.sync = true
|
|
171
|
+
@rest_logger = Logger.new(log_file)
|
|
172
|
+
@rest_logger.level = Config.logger.level
|
|
173
|
+
@rest_logger.formatter = Config.logger.formatter
|
|
174
|
+
else
|
|
175
|
+
@rest_logger = Config.logger
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
123
179
|
def log_exceptions(e)
|
|
124
180
|
if e.is_a? RestClient::Exception
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
181
|
+
Config.logger.error("HTTP Code: #{e.http_code}")
|
|
182
|
+
Config.logger.error("HTTP Body: #{e.http_body}")
|
|
183
|
+
Config.logger.error("Message: #{e.message}")
|
|
184
|
+
Config.logger.error("Response: #{e.response}")
|
|
129
185
|
end
|
|
130
186
|
end
|
|
131
187
|
|
|
132
|
-
def delay
|
|
133
|
-
@rest_throttle[
|
|
134
|
-
@rest_throttle[
|
|
188
|
+
def delay
|
|
189
|
+
@rest_throttle[:min] + rand(@rest_throttle[:max] -
|
|
190
|
+
@rest_throttle[:min])
|
|
135
191
|
end
|
|
136
192
|
|
|
137
193
|
def get_nested_resource(destination)
|
|
138
194
|
href = self.class.get_href(destination)
|
|
139
195
|
if href.is_a?(String)
|
|
140
|
-
URI.parse(href)
|
|
196
|
+
uri = URI.parse(href)
|
|
197
|
+
if uri.query.nil?
|
|
198
|
+
uri.path
|
|
199
|
+
else
|
|
200
|
+
"#{uri.path}?#{uri.query}"
|
|
201
|
+
end
|
|
141
202
|
else
|
|
142
|
-
|
|
143
|
-
|
|
203
|
+
fail ApiError,
|
|
204
|
+
"href is not a string. href:#{href.inspect}, dst:#{destination}."
|
|
144
205
|
end
|
|
145
206
|
end
|
|
146
207
|
|
|
@@ -158,6 +219,5 @@ module VCloudSdk
|
|
|
158
219
|
end
|
|
159
220
|
end
|
|
160
221
|
end
|
|
161
|
-
|
|
162
222
|
end
|
|
163
223
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
require_relative "session"
|
|
3
|
+
require_relative "infrastructure"
|
|
4
|
+
|
|
5
|
+
module VCloudSdk
|
|
6
|
+
class Disk
|
|
7
|
+
include Infrastructure
|
|
8
|
+
|
|
9
|
+
extend Forwardable
|
|
10
|
+
def_delegators :entity_xml,
|
|
11
|
+
:name, :bus_type, :bus_sub_type,
|
|
12
|
+
:size_mb, :status
|
|
13
|
+
|
|
14
|
+
def initialize(session, link)
|
|
15
|
+
@session = session
|
|
16
|
+
@link = link
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def href
|
|
20
|
+
@link
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def attached?
|
|
24
|
+
!vm_reference.nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def vm
|
|
28
|
+
vm_link = vm_reference
|
|
29
|
+
fail ObjectNotFoundError,
|
|
30
|
+
"No vm is attached to disk '#{name}'" if vm_link.nil?
|
|
31
|
+
|
|
32
|
+
VCloudSdk::VM.new(@session, vm_link.href)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def delete
|
|
36
|
+
fail CloudError,
|
|
37
|
+
"Disk '#{name}' of link #{href} is attached to VM '#{vm.name}'" if attached?
|
|
38
|
+
|
|
39
|
+
disk_name = name
|
|
40
|
+
task = connection.delete(entity_xml.remove_link.href)
|
|
41
|
+
task = monitor_task(task)
|
|
42
|
+
|
|
43
|
+
Config.logger.info "Disk '#{disk_name}' of link #{@link} is deleted successfully"
|
|
44
|
+
task
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def vm_reference
|
|
50
|
+
connection
|
|
51
|
+
.get(entity_xml.vms_link)
|
|
52
|
+
.vm_reference
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
require_relative "infrastructure"
|
|
3
|
+
require_relative "ip_ranges"
|
|
4
|
+
|
|
5
|
+
module VCloudSdk
|
|
6
|
+
class EdgeGateway
|
|
7
|
+
include Infrastructure
|
|
8
|
+
|
|
9
|
+
extend Forwardable
|
|
10
|
+
def_delegator :entity_xml, :name
|
|
11
|
+
|
|
12
|
+
def initialize(session, link)
|
|
13
|
+
@session = session
|
|
14
|
+
@link = link
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def public_ip_ranges
|
|
18
|
+
uplink_gateway_interface = entity_xml
|
|
19
|
+
.gateway_interfaces
|
|
20
|
+
.find { |g| g.interface_type == "uplink" }
|
|
21
|
+
|
|
22
|
+
ip_ranges = uplink_gateway_interface.ip_ranges
|
|
23
|
+
return IpRanges.new unless ip_ranges
|
|
24
|
+
|
|
25
|
+
ip_ranges
|
|
26
|
+
.ranges
|
|
27
|
+
.reduce(IpRanges.new) do |result, i|
|
|
28
|
+
result + IpRanges.new("#{i.start_address}-#{i.end_address}")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
module VCloudSdk
|
|
2
|
+
# Shared functions by classes such as Client, Catalog and VDC
|
|
3
|
+
# Make sure instance variable @session is available
|
|
4
|
+
module Infrastructure
|
|
5
|
+
ERROR_STATUSES = [Xml::TASK_STATUS[:ABORTED], Xml::TASK_STATUS[:ERROR],
|
|
6
|
+
Xml::TASK_STATUS[:CANCELED]]
|
|
7
|
+
SUCCESS_STATUS = [Xml::TASK_STATUS[:SUCCESS]]
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def find_vdc_by_name(name)
|
|
12
|
+
vdc_link = @session.org.vdc_link(name)
|
|
13
|
+
fail ObjectNotFoundError, "VDC #{name} not found" unless vdc_link
|
|
14
|
+
VCloudSdk::VDC.new(@session, connection.get(vdc_link))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def catalogs
|
|
18
|
+
@session.org.catalogs.map do |catalog_link|
|
|
19
|
+
VCloudSdk::Catalog.new(@session, catalog_link)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def list_catalogs
|
|
24
|
+
@session.org.catalogs.map do |catalog_link|
|
|
25
|
+
catalog_link.name
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def catalog_exists?(name)
|
|
30
|
+
@session.org.catalogs.any? do |catalog|
|
|
31
|
+
catalog.name == name
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def find_catalog_by_name(name)
|
|
36
|
+
@session.org.catalogs.each do |catalog_link|
|
|
37
|
+
if catalog_link.name == name
|
|
38
|
+
return VCloudSdk::Catalog.new(@session, catalog_link)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
fail ObjectNotFoundError, "Catalog '#{name}' is not found"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def connection
|
|
46
|
+
@session.connection
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def monitor_task(
|
|
50
|
+
task,
|
|
51
|
+
time_limit = @session.time_limit[:default],
|
|
52
|
+
error_statuses = ERROR_STATUSES,
|
|
53
|
+
success = SUCCESS_STATUS,
|
|
54
|
+
delay = @session.delay,
|
|
55
|
+
&b)
|
|
56
|
+
|
|
57
|
+
iterations = time_limit / delay
|
|
58
|
+
i = 0
|
|
59
|
+
prev_progress = task.progress
|
|
60
|
+
prev_status = task.status
|
|
61
|
+
current_task = task
|
|
62
|
+
while i < iterations
|
|
63
|
+
Config.logger.debug %Q{
|
|
64
|
+
#{current_task.urn} #{current_task.operation} is #{current_task.status}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if task_is_success(current_task, success)
|
|
68
|
+
if b
|
|
69
|
+
return b.call(current_task)
|
|
70
|
+
else
|
|
71
|
+
return current_task
|
|
72
|
+
end
|
|
73
|
+
elsif task_has_error(current_task, error_statuses)
|
|
74
|
+
fail ApiRequestError,
|
|
75
|
+
"Task #{task.urn} #{task.operation} did not complete successfully."
|
|
76
|
+
elsif task_progressed?(current_task, prev_progress, prev_status)
|
|
77
|
+
Config.logger.debug %Q{
|
|
78
|
+
task status #{prev_status} =>
|
|
79
|
+
#{current_task.status}, progress #{prev_progress}% =>
|
|
80
|
+
#{current_task.progress}%, timer #{i} reset.
|
|
81
|
+
}
|
|
82
|
+
prev_progress = current_task.progress
|
|
83
|
+
prev_status = current_task.status
|
|
84
|
+
i = 0 # Reset clock if status changes or running task makes progress
|
|
85
|
+
sleep(delay)
|
|
86
|
+
else
|
|
87
|
+
Config.logger.debug %Q{
|
|
88
|
+
Approximately #{i * delay}s elapsed waiting for #{current_task.operation} to
|
|
89
|
+
reach #{success.join("/")}/#{error_statuses.join("/")}.
|
|
90
|
+
Checking again in #{delay} seconds.
|
|
91
|
+
}
|
|
92
|
+
if current_task.progress
|
|
93
|
+
Config.logger.debug(
|
|
94
|
+
"Task #{task.urn} progress: #{current_task.progress} %.")
|
|
95
|
+
end
|
|
96
|
+
sleep(delay)
|
|
97
|
+
end
|
|
98
|
+
current_task = connection.get(task)
|
|
99
|
+
i += 1
|
|
100
|
+
end
|
|
101
|
+
fail ApiTimeoutError,
|
|
102
|
+
"Task #{task.operation} did not complete within limit of #{time_limit} seconds."
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def task_progressed?(current_task, prev_progress, prev_status)
|
|
106
|
+
(current_task.progress && (current_task.progress != prev_progress)) ||
|
|
107
|
+
(current_task.status && (current_task.status != prev_status))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def task_is_success(current_task, success = SUCCESS_STATUS)
|
|
111
|
+
success.find do |s|
|
|
112
|
+
s.downcase == current_task.status.downcase
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def task_has_error(current_task, error_statuses = ERROR_STATUSES)
|
|
117
|
+
error_statuses.find do |s|
|
|
118
|
+
s.downcase == current_task.status.downcase
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def entity_xml
|
|
123
|
+
connection.get(@link)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def wait_for_running_tasks(subject, subject_display)
|
|
127
|
+
unless subject.running_tasks.empty?
|
|
128
|
+
Config.logger.info "#{subject_display} has tasks in progress, wait until done."
|
|
129
|
+
subject.running_tasks.each do |task|
|
|
130
|
+
monitor_task(task)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|