ruby_vcloud_sdk 0.4.8 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +296 -0
  3. data/lib/ruby_vcloud_sdk.rb +0 -4
  4. data/lib/ruby_vcloud_sdk/catalog.rb +377 -0
  5. data/lib/ruby_vcloud_sdk/catalog_item.rb +26 -0
  6. data/lib/ruby_vcloud_sdk/client.rb +25 -882
  7. data/lib/ruby_vcloud_sdk/config.rb +1 -7
  8. data/lib/ruby_vcloud_sdk/connection/connection.rb +114 -54
  9. data/lib/ruby_vcloud_sdk/cpu.rb +11 -0
  10. data/lib/ruby_vcloud_sdk/disk.rb +55 -0
  11. data/lib/ruby_vcloud_sdk/edge_gateway.rb +32 -0
  12. data/lib/ruby_vcloud_sdk/infrastructure.rb +135 -0
  13. data/lib/ruby_vcloud_sdk/ip_ranges.rb +95 -0
  14. data/lib/ruby_vcloud_sdk/memory.rb +11 -0
  15. data/lib/ruby_vcloud_sdk/network.rb +32 -0
  16. data/lib/ruby_vcloud_sdk/powerable.rb +78 -0
  17. data/lib/ruby_vcloud_sdk/resources.rb +13 -0
  18. data/lib/ruby_vcloud_sdk/session.rb +46 -0
  19. data/lib/ruby_vcloud_sdk/vapp.rb +122 -0
  20. data/lib/ruby_vcloud_sdk/vdc.rb +210 -0
  21. data/lib/ruby_vcloud_sdk/vdc_storage_profile.rb +23 -0
  22. data/lib/ruby_vcloud_sdk/version.rb +1 -1
  23. data/lib/ruby_vcloud_sdk/vm.rb +132 -0
  24. data/lib/ruby_vcloud_sdk/xml/constants.rb +6 -4
  25. data/lib/ruby_vcloud_sdk/xml/wrapper.rb +109 -30
  26. data/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb +45 -2
  27. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/admin_catalog.rb +13 -4
  28. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/allocated_ip_addresses.rb +9 -0
  29. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog_item.rb +6 -14
  30. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk.rb +24 -14
  31. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params.rb +0 -2
  32. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/disk_create_params.rb +1 -3
  33. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/edge_gateway.rb +13 -0
  34. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/gateway_interface.rb +22 -0
  35. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper.rb +4 -4
  36. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_address.rb +10 -0
  37. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_range.rb +13 -0
  38. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_ranges.rb +9 -0
  39. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/ip_scope.rb +6 -32
  40. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/item.rb +1 -7
  41. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/link.rb +14 -0
  42. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/media.rb +4 -20
  43. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/media_insert_or_eject_params.rb +1 -3
  44. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/network_connection_section.rb +0 -4
  45. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/nic_item_wrapper.rb +0 -2
  46. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/org.rb +44 -0
  47. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/org_vdc_network.rb +11 -3
  48. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/query_result_records.rb +14 -0
  49. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/recompose_vapp_params.rb +42 -0
  50. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/session.rb +5 -5
  51. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/supported_versions.rb +19 -0
  52. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/task.rb +1 -1
  53. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/upload_vapp_template_params.rb +2 -4
  54. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb +13 -22
  55. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp_template.rb +0 -2
  56. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vcloud.rb +5 -3
  57. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb +72 -15
  58. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/virtual_hardware_section.rb +8 -6
  59. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vm.rb +29 -25
  60. data/lib/ruby_vcloud_sdk/xml/wrapper_classes/vms.rb +12 -0
  61. data/lib/ruby_vcloud_sdk/xml/xml_templates/AdminCatalog.xml +6 -1
  62. data/lib/ruby_vcloud_sdk/xml/xml_templates/RecomposeVAppParams.xml +16 -1
  63. metadata +116 -233
  64. data/README +0 -1
  65. data/Rakefile +0 -50
  66. data/lib/ruby_vcloud_sdk/util.rb +0 -21
  67. data/spec/assets/admin_org_response.xml +0 -75
  68. data/spec/assets/catalog_add_item_response.xml +0 -8
  69. data/spec/assets/catalog_add_vapp_request.xml +0 -5
  70. data/spec/assets/catalog_item_added_response.xml +0 -19
  71. data/spec/assets/catalog_response.xml +0 -19
  72. data/spec/assets/existing_media_busy_response.xml +0 -19
  73. data/spec/assets/existing_media_catalog_item.xml +0 -8
  74. data/spec/assets/existing_media_delete_task_done.xml +0 -6
  75. data/spec/assets/existing_media_done_response.xml +0 -11
  76. data/spec/assets/existing_vapp_resolver_response.xml +0 -3
  77. data/spec/assets/existing_vapp_template_catalog_resolver_response.xml +0 -3
  78. data/spec/assets/existing_vapp_template_instantiate_response.xml +0 -20
  79. data/spec/assets/existing_vapp_template_instantiate_task_error_response.xml +0 -7
  80. data/spec/assets/existing_vapp_template_instantiate_task_start_response.xml +0 -7
  81. data/spec/assets/existing_vapp_template_instantiate_task_success_response.xml +0 -7
  82. data/spec/assets/existing_vapp_template_item_response.xml +0 -8
  83. data/spec/assets/existing_vapp_template_ready_response.xml +0 -79
  84. data/spec/assets/finalize_upload_task_done_response.xml +0 -7
  85. data/spec/assets/finalize_upload_task_response.xml +0 -7
  86. data/spec/assets/indy_disk_attach_request.xml +0 -3
  87. data/spec/assets/indy_disk_attach_task.xml +0 -6
  88. data/spec/assets/indy_disk_attach_task_error.xml +0 -6
  89. data/spec/assets/indy_disk_create_error.xml +0 -1
  90. data/spec/assets/indy_disk_create_request.xml +0 -4
  91. data/spec/assets/indy_disk_create_response.xml +0 -19
  92. data/spec/assets/indy_disk_delete_task.xml +0 -6
  93. data/spec/assets/indy_disk_detach_request.xml +0 -3
  94. data/spec/assets/indy_disk_detach_task.xml +0 -6
  95. data/spec/assets/indy_disk_response.xml +0 -11
  96. data/spec/assets/instantiated_suspended_vapp_response.xml +0 -209
  97. data/spec/assets/instantiated_vapp_delelete_done_task.xml +0 -5
  98. data/spec/assets/instantiated_vapp_delelete_running_task.xml +0 -6
  99. data/spec/assets/instantiated_vapp_network_config_add_network_request.xml +0 -36
  100. data/spec/assets/instantiated_vapp_network_config_modify_network_task_success.xml +0 -6
  101. data/spec/assets/instantiated_vapp_network_config_remove_network_request.xml +0 -6
  102. data/spec/assets/instantiated_vapp_network_config_section_response.xml +0 -17
  103. data/spec/assets/instantiated_vapp_off_response.xml +0 -206
  104. data/spec/assets/instantiated_vapp_on_response.xml +0 -205
  105. data/spec/assets/instantiated_vapp_power_task_running.xml +0 -6
  106. data/spec/assets/instantiated_vapp_power_task_success.xml +0 -6
  107. data/spec/assets/instantiated_vapp_response.xml +0 -205
  108. data/spec/assets/instantiated_vm_change_task_running.xml +0 -6
  109. data/spec/assets/instantiated_vm_change_task_success.xml +0 -6
  110. data/spec/assets/instantiated_vm_cpu_response.xml +0 -11
  111. data/spec/assets/instantiated_vm_insert_media_task_done.xml +0 -6
  112. data/spec/assets/instantiated_vm_memory_response.xml +0 -11
  113. data/spec/assets/instantiated_vm_modify_task_running.xml +0 -6
  114. data/spec/assets/instantiated_vm_modify_task_success.xml +0 -5
  115. data/spec/assets/instantiated_vm_network_section_response.xml +0 -11
  116. data/spec/assets/instantiated_vm_response.xml +0 -149
  117. data/spec/assets/media_add_to_catalog_request.xml +0 -5
  118. data/spec/assets/media_add_to_catalog_response.xml +0 -8
  119. data/spec/assets/media_delete_task_done.xml +0 -6
  120. data/spec/assets/media_upload_pending_response.xml +0 -13
  121. data/spec/assets/media_upload_request.xml +0 -2
  122. data/spec/assets/metadata_set_request.xml +0 -3
  123. data/spec/assets/metadata_set_task_done.xml +0 -6
  124. data/spec/assets/org_network_response.xml +0 -22
  125. data/spec/assets/reconfigure_vm_request.xml +0 -133
  126. data/spec/assets/reconfigure_vm_task.xml +0 -8
  127. data/spec/assets/session.xml +0 -7
  128. data/spec/assets/test-config.yml +0 -38
  129. data/spec/assets/undeploy_params.xml +0 -1
  130. data/spec/assets/vapp_template_catalog_resolver_response.xml +0 -3
  131. data/spec/assets/vapp_template_delelete_done_task.xml +0 -5
  132. data/spec/assets/vapp_template_delelete_running_task.xml +0 -6
  133. data/spec/assets/vapp_template_instantiate_request.xml +0 -8
  134. data/spec/assets/vapp_template_instantiate_with_locality_request.xml +0 -14
  135. data/spec/assets/vapp_template_no_disk_response.xml +0 -27
  136. data/spec/assets/vapp_template_ready_response.xml +0 -79
  137. data/spec/assets/vapp_template_upload_complete.xml +0 -28
  138. data/spec/assets/vapp_template_upload_failed.xml +0 -28
  139. data/spec/assets/vapp_template_upload_request.xml +0 -4
  140. data/spec/assets/vapp_template_upload_response.xml +0 -25
  141. data/spec/assets/vcloud_response.xml +0 -56
  142. data/spec/assets/vdc_response.xml +0 -57
  143. data/spec/spec_helper.rb +0 -107
  144. data/spec/unit/client_response.rb +0 -700
  145. data/spec/unit/client_spec.rb +0 -1152
@@ -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["logger"] || @logger || Logger.new(STDOUT)
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
- SECURITY_CHECK = "/cloud/security_check"
9
- ACCEPT = "application/*+xml;version=5.1"
10
-
11
- def initialize(hostname_port, organization, request_timeout = nil,
12
- rest_client = nil, site = nil, file_uploader = nil)
13
- @organization = organization
14
- @logger = Config.logger
15
- @rest_logger = Config.rest_logger
16
- @rest_throttle = Config.rest_throttle
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.nil? ? rest_client::Resource.new(hostname_port,
21
- :timeout => request_timeout) : site
22
- @file_uploader = file_uploader.nil? ? FileUploader : file_uploader
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
- login = "#{username}@#{@organization}"
27
- login_password = "#{login}:#{password}"
33
+ login_password = "#{username}:#{password}"
28
34
  auth_header_value = "Basic #{Base64.encode64(login_password)}"
29
- response = @site["/api/sessions"].post(
30
- {:Authorization=>auth_header_value, :Accept=>ACCEPT})
31
- @logger.debug(response)
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
- @logger.debug("@cookies: #{@cookies.inspect}.")
40
+ Config.logger.debug("@cookies: #{@cookies.inspect}.")
35
41
  end
36
- VCloudSdk::Xml::WrapperFactory.wrap_document(response)
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
- :Accept=>ACCEPT,
46
- :cookies=>@cookies
47
- })
50
+ response = @site[get_nested_resource(destination)].get(
51
+ Accept: ACCEPT,
52
+ cookies: @cookies)
48
53
  @rest_logger.debug(response)
49
- Xml::WrapperFactory.wrap_document(response)
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
- :Accept=>ACCEPT,
63
- :cookies=>@cookies,
64
- :content_type=>content_type
67
+ Accept: ACCEPT,
68
+ cookies: @cookies,
69
+ content_type: content_type
65
70
  })
66
- raise ApiRequestError if http_error?(response)
71
+ fail ApiRequestError if http_error?(response)
67
72
  @rest_logger.debug(response)
68
- Xml::WrapperFactory.wrap_document(response)
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
- :Accept=>ACCEPT,
82
- :cookies=>@cookies,
83
- :content_type=>content_type
84
- })
85
- raise ApiRequestError if http_error?(response)
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
- Xml::WrapperFactory.wrap_document(response)
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
- :Accept=>ACCEPT,
101
- :cookies=>@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
- Xml::WrapperFactory.wrap_document(response)
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
- @logger.error("HTTP Code: #{e.http_code}")
126
- @logger.error("HTTP Body: #{e.http_body}")
127
- @logger.error("Message: #{e.message}")
128
- @logger.error("Response: #{e.response}")
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["min"] + rand(@rest_throttle["max"] -
134
- @rest_throttle["min"])
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).path
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
- raise ApiError,
143
- "href is not a string. href:#{href.inspect}, dst:#{destination}."
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,11 @@
1
+ module VCloudSdk
2
+
3
+ class CPU
4
+ attr_reader :available_cores
5
+
6
+ def initialize(available_cores)
7
+ @available_cores = available_cores
8
+ end
9
+ end
10
+
11
+ 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