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