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