opsmgr 0.26.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/LEGAL.txt +13 -0
  3. data/README.md +21 -0
  4. data/lib/opsmgr.rb +12 -0
  5. data/lib/opsmgr/api/client.rb +85 -0
  6. data/lib/opsmgr/api/endpoints_factory.rb +39 -0
  7. data/lib/opsmgr/api/http_client.rb +204 -0
  8. data/lib/opsmgr/api/results.rb +257 -0
  9. data/lib/opsmgr/api/version20/endpoints.rb +93 -0
  10. data/lib/opsmgr/cmd/bosh_command.rb +213 -0
  11. data/lib/opsmgr/cmd/ops_manager.rb +100 -0
  12. data/lib/opsmgr/environments.rb +77 -0
  13. data/lib/opsmgr/errand_runner.rb +75 -0
  14. data/lib/opsmgr/log.rb +70 -0
  15. data/lib/opsmgr/product_upload_wrapper.rb +69 -0
  16. data/lib/opsmgr/renderer.rb +23 -0
  17. data/lib/opsmgr/renderer/aws.rb +147 -0
  18. data/lib/opsmgr/renderer/noop.rb +21 -0
  19. data/lib/opsmgr/settings/microbosh/installation_settings.rb +84 -0
  20. data/lib/opsmgr/settings/microbosh/job.rb +54 -0
  21. data/lib/opsmgr/settings/microbosh/job_list.rb +27 -0
  22. data/lib/opsmgr/settings/microbosh/network.rb +21 -0
  23. data/lib/opsmgr/settings/microbosh/product.rb +88 -0
  24. data/lib/opsmgr/settings/microbosh/product_list.rb +27 -0
  25. data/lib/opsmgr/settings/microbosh/property.rb +31 -0
  26. data/lib/opsmgr/settings/microbosh/property_list.rb +27 -0
  27. data/lib/opsmgr/tasks.rb +16 -0
  28. data/lib/opsmgr/tasks/bosh.rake +70 -0
  29. data/lib/opsmgr/tasks/destroy.rake +42 -0
  30. data/lib/opsmgr/tasks/info.rake +19 -0
  31. data/lib/opsmgr/tasks/opsmgr.rake +179 -0
  32. data/lib/opsmgr/tasks/product.rake +53 -0
  33. data/lib/opsmgr/teapot.rb +51 -0
  34. data/lib/opsmgr/teapot/app.rb +50 -0
  35. data/lib/opsmgr/teapot/spec_helper.rb +33 -0
  36. data/lib/opsmgr/ui_helpers/add_first_user_spec.rb +25 -0
  37. data/lib/opsmgr/ui_helpers/config_helper.rb +151 -0
  38. data/lib/opsmgr/ui_helpers/delete_installation_spec.rb +41 -0
  39. data/lib/opsmgr/ui_helpers/delete_product_if_present_spec.rb +43 -0
  40. data/lib/opsmgr/ui_helpers/delete_product_spec.rb +39 -0
  41. data/lib/opsmgr/ui_helpers/export_installation_spec.rb +31 -0
  42. data/lib/opsmgr/ui_helpers/get_latest_install_log_spec.rb +29 -0
  43. data/lib/opsmgr/ui_helpers/import_installation_spec.rb +29 -0
  44. data/lib/opsmgr/ui_helpers/import_stemcell_spec.rb +30 -0
  45. data/lib/opsmgr/ui_helpers/microbosh/configure_microbosh_spec.rb +31 -0
  46. data/lib/opsmgr/ui_helpers/trigger_install_spec.rb +35 -0
  47. data/lib/opsmgr/ui_helpers/ui_spec_runner.rb +117 -0
  48. data/lib/opsmgr/ui_helpers/uncheck_errands_spec.rb +29 -0
  49. data/lib/opsmgr/ui_helpers/upload_and_add_product_spec.rb +27 -0
  50. data/lib/opsmgr/ui_helpers/upload_and_upgrade_product_spec.rb +36 -0
  51. data/lib/opsmgr/version.rb +11 -0
  52. metadata +360 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 864044e4d3a84e015296758b804e25971447ada0
4
+ data.tar.gz: b6e953028634614943d4ae23af5e8f86640b8a34
5
+ SHA512:
6
+ metadata.gz: 33132d5940ceaf71d8b3f0c2bfa4ceb9f253824cf72cbbc52ebf722665610343e464371925a1677792b3bda65467e0a860804eac37cab1ebc0d14952cc55ade9
7
+ data.tar.gz: 32fab1f041920f74a0ecaa4db3c6c8023b839b4638bba54c2583dea13dd5afde3d0997e6fe0fd57bd9ec0f7190a8231053519ff41299b714cf38f34f36da1b27
data/LEGAL.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2014-2015 Pivotal Software, Inc. All rights reserved.
2
+
3
+ Unauthorized use, copying or distribution of this source code via any
4
+ medium is strictly prohibited without the express written consent of
5
+ Pivotal Software, Inc.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
8
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
10
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
11
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
12
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
13
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # opsmgr
2
+
3
+ A ruby client for opsmanager and related tools. Extracted from RelEng's [release-engineeering-automation](https://github.com/pivotal-cf/release-engineering-automation/).
4
+
5
+ ## Usage
6
+
7
+ ### Gemfile
8
+
9
+ ```ruby
10
+ gem 'opsmgr', git: 'git@github.com:pivotal-cf/opsmgr.git'
11
+ ```
12
+
13
+ ### Rakefile
14
+
15
+ ```ruby
16
+ require 'opsmgr/tasks'
17
+ ```
18
+
19
+ ### Teapot
20
+
21
+ TODO
data/lib/opsmgr.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'opsmgr/version'
2
+
3
+ module Opsmgr
4
+ end
5
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
6
+ # All rights reserved.
7
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
8
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
9
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
10
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
11
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
12
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ require 'json'
2
+ require 'opsmgr/api/http_client'
3
+ require 'opsmgr/api/results'
4
+ require 'opsmgr/settings/microbosh/product_list'
5
+
6
+ module Opsmgr
7
+ module Api
8
+ class Client
9
+ attr_reader :environment_name
10
+
11
+ def initialize(environment)
12
+ @http_client = HttpClient.build(environment)
13
+ @environment_name = environment.settings.name.freeze
14
+ end
15
+
16
+ def installation_settings
17
+ response = http_client.installation_settings
18
+ if response.code == '200'
19
+ InstallationSettingsResult.new(JSON.parse(response.body))
20
+ else
21
+ Error.new('Error viewing current installation settings', response)
22
+ end
23
+ end
24
+
25
+ # .pivotal file is referred to as a "product" but the Tempest developers call it a "component"
26
+ def upload_component(path)
27
+ response = http_client.upload_component(path)
28
+ basic_success_or_error("Error uploading #{path}", response)
29
+ end
30
+
31
+ def add_product(product_name, version)
32
+ response = http_client.add_product(product_name, version)
33
+ basic_success_or_error("Error adding '#{product_name} #{version}'", response)
34
+ end
35
+
36
+ def upgrade_product(product_guid, to_version)
37
+ response = http_client.upgrade_product(product_guid, to_version)
38
+ basic_success_or_error("Error upgrading '#{product_guid}' to '#{to_version}'", response)
39
+ end
40
+
41
+ def list_products
42
+ response = http_client.list_products
43
+ if response.code == '200'
44
+ ListProductsResult.new(JSON.parse(response.body))
45
+ else
46
+ Error.new('Error listing products', response)
47
+ end
48
+ end
49
+
50
+ def installed_products
51
+ response = http_client.installed_products
52
+ if response.code == '200'
53
+ InstalledProductsResult.new(Opsmgr::Settings::Microbosh::ProductList.new(JSON.parse(response.body)))
54
+ else
55
+ Error.new('Error listing installed products', response)
56
+ end
57
+ end
58
+
59
+ def delete_unused_products
60
+ response = http_client.delete_unused_products
61
+ basic_success_or_error('There was an error deleting the unused products:', response)
62
+ end
63
+
64
+ def basic_success_or_error(message, response)
65
+ if response.code == '200'
66
+ Result.new
67
+ else
68
+ Error.new(message, response)
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ attr_reader :http_client
75
+ end
76
+ end
77
+ end
78
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
79
+ # All rights reserved.
80
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
81
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
82
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
83
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
84
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
85
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ require 'net/http'
2
+ require 'opsmgr/api/version20/endpoints'
3
+
4
+ module Opsmgr
5
+ module Api
6
+ class EndpointsFactory
7
+ def self.create(environment)
8
+ req = Net::HTTP::Get.new('/api/api_version')
9
+ uri = URI.parse(environment.settings.ops_manager.url)
10
+ req.basic_auth(environment.settings.ops_manager.username, environment.settings.ops_manager.password)
11
+
12
+ response = http(uri).request(req)
13
+
14
+ api_version = JSON.parse(response.body).fetch('version')
15
+ case api_version
16
+ when '2.0'
17
+ return Opsmgr::Api::Version20::Endpoints.new
18
+ end
19
+ end
20
+
21
+ def self.http(uri)
22
+ http = Net::HTTP.new(uri.host, uri.port)
23
+ if uri.scheme == 'https'
24
+ http.use_ssl = true
25
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
26
+ end
27
+ http
28
+ end
29
+ end
30
+ end
31
+ end
32
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
33
+ # All rights reserved.
34
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
35
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
37
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
38
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
39
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,204 @@
1
+ require 'net/http'
2
+ require 'net/http/post/multipart'
3
+ require 'json'
4
+ require 'open4'
5
+ require 'opsmgr/api/endpoints_factory'
6
+ require 'opsmgr/log'
7
+
8
+ # noinspection RubyResolve
9
+ module Opsmgr
10
+ module Api
11
+ class HttpClient
12
+ include Loggable
13
+ attr_reader :uri, :environment, :endpoints
14
+
15
+ def self.build(environment)
16
+ new(environment, Opsmgr::Api::EndpointsFactory.create(environment))
17
+ end
18
+
19
+ def initialize(environment, endpoints)
20
+ @environment = environment
21
+ @uri = URI.parse(environment.settings.ops_manager.url)
22
+ @endpoints = endpoints
23
+ end
24
+
25
+ def upload_product_installation_settings(settings_file_path)
26
+ req = Net::HTTP::Post::Multipart.new(
27
+ endpoints.installation_settings_post_path,
28
+ 'installation[file]' =>
29
+ UploadIO.new(
30
+ settings_file_path,
31
+ 'application/octet-stream',
32
+ File.basename(settings_file_path)
33
+ )
34
+ )
35
+
36
+ req.basic_auth(web_auth_user, web_auth_password)
37
+
38
+ http.request(req)
39
+ end
40
+
41
+ def upload_component(product_path)
42
+ # We ran into a possible Net::HTTP bug where Ruby would always drop the connection while waiting for the
43
+ # uploaded zip file to unzip. Curl behaved correctly, but curb (Ruby bindings for libcurl) did not behave
44
+ # well with WebMock, so here we are.
45
+ upload_component_command =
46
+ %W(
47
+ curl -k
48
+ --silent
49
+ --fail
50
+ #{uri}#{endpoints.upload_product_path}
51
+ -F #{endpoints.upload_product_form_key}[file]=@#{product_path}
52
+ -X POST
53
+ -u #{web_auth_user}:#{web_auth_password}
54
+ )
55
+ log.info('uploading product')
56
+
57
+ error = nil
58
+ status =
59
+ Open4.popen4(*upload_component_command) do |_, _, stdout, stderr|
60
+ log.info(stdout.read)
61
+ error = stderr.read
62
+ end
63
+
64
+ if status.success?
65
+ FakeResponse.new('200', '{}')
66
+ else
67
+ error_code = (error.match(/^\< HTTP\/.* (\d+) /) || [nil, '???'])[1]
68
+ FakeResponse.new(error_code, error)
69
+ end
70
+ end
71
+
72
+ def add_product(product_name, version)
73
+ req = Net::HTTP::Post.new(endpoints.add_product_path)
74
+ req.set_form_data('name' => product_name, 'product_version' => version)
75
+ req.basic_auth(web_auth_user, web_auth_password)
76
+
77
+ http.request(req)
78
+ end
79
+
80
+ def upgrade_product(product_guid, to_version)
81
+ req = Net::HTTP::Put.new(endpoints.upgrade_product_path(product_guid))
82
+ req.set_form_data('to_version' => to_version)
83
+ req.basic_auth(web_auth_user, web_auth_password)
84
+
85
+ http.request(req)
86
+ end
87
+
88
+ def trigger_install
89
+ req = Net::HTTP::Post.new(endpoints.install_post_path)
90
+ req.body = ''
91
+ req.basic_auth(web_auth_user, web_auth_password)
92
+
93
+ http.request(req)
94
+ end
95
+
96
+ # components are both uploaded AND configured AND deployed
97
+ def list_components
98
+ get_with_basic_auth(endpoints.list_components_path)
99
+ end
100
+
101
+ # products are uploaded but not necessarily configured or deployed
102
+ def list_products
103
+ get_with_basic_auth(endpoints.list_products_path)
104
+ end
105
+
106
+ # products that have been uploaded, configured, and installed
107
+ def installed_products
108
+ get_with_basic_auth(endpoints.installed_products_path)
109
+ end
110
+
111
+ def product_manifest(product_guid)
112
+ get_with_basic_auth(endpoints.product_manifest_path(product_guid))
113
+ end
114
+
115
+ def installation_settings
116
+ get_with_basic_auth(endpoints.installation_settings_get_path)
117
+ end
118
+
119
+ def installation_delete
120
+ req = Net::HTTP::Delete.new(endpoints.installation_path)
121
+ req.basic_auth(web_auth_user, web_auth_password)
122
+
123
+ http.request(req)
124
+ end
125
+
126
+ def installation_deletion_status
127
+ get_with_basic_auth(endpoints.installation_deletion_status_path)
128
+ end
129
+
130
+ def create_the_first_user
131
+ req = Net::HTTP::Post.new(endpoints.configure_user_path)
132
+ req.set_form_data(
133
+ 'user[user_name]' => web_auth_user,
134
+ 'user[password]' => web_auth_password,
135
+ 'user[password_confirmation]' => web_auth_password)
136
+ http.request(req)
137
+ end
138
+
139
+ def install_status(install_id)
140
+ get_with_basic_auth(endpoints.show_installation_status(install_id))
141
+ end
142
+
143
+ def install_log(install_id)
144
+ get_with_basic_auth(endpoints.installation_log_path(install_id))
145
+ end
146
+
147
+ def mark_product_for_deletion(product_guid)
148
+ req = Net::HTTP::Delete.new(endpoints.mark_for_deletion_path(product_guid))
149
+ req.basic_auth(web_auth_user, web_auth_password)
150
+
151
+ http.request(req)
152
+ end
153
+
154
+ def delete_unused_products
155
+ req = Net::HTTP::Delete.new(endpoints.list_products_path)
156
+ req.basic_auth(web_auth_user, web_auth_password)
157
+
158
+ http.request(req)
159
+ end
160
+
161
+ def version
162
+ endpoints.version
163
+ end
164
+
165
+ private
166
+
167
+ def web_auth_user
168
+ environment.settings.ops_manager.username
169
+ end
170
+
171
+ def web_auth_password
172
+ environment.settings.ops_manager.password
173
+ end
174
+
175
+ def http
176
+ http = Net::HTTP.new(uri.host, uri.port)
177
+ if uri.scheme == 'https'
178
+ http.use_ssl = true
179
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
180
+ end
181
+ http.read_timeout = 240
182
+ http
183
+ end
184
+
185
+ def get_with_basic_auth(path)
186
+ req = Net::HTTP::Get.new(path)
187
+ req.basic_auth(web_auth_user, web_auth_password)
188
+
189
+ http.request(req)
190
+ end
191
+
192
+ class FakeResponse < Struct.new(:code, :body)
193
+ end
194
+ end
195
+ end
196
+ end
197
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
198
+ # All rights reserved.
199
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
200
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
201
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
202
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
203
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
204
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,257 @@
1
+ require 'opsmgr/settings/microbosh/installation_settings'
2
+ require 'opsmgr/settings/microbosh/product_list'
3
+ require 'opsmgr/settings/microbosh/job_list'
4
+ require 'opsmgr/settings/microbosh/property_list'
5
+
6
+ module Opsmgr
7
+ module Api
8
+ class Result
9
+ attr_reader :message
10
+
11
+ def success?
12
+ true
13
+ end
14
+ end
15
+
16
+ class InstallStatusResult < Result
17
+ attr_reader :status
18
+
19
+ def initialize(status_hash)
20
+ @status = status_hash['status']
21
+ status.freeze
22
+
23
+ fail(ArgumentError, "Unrecognized status: #{status}") unless %w(failed success running).include?(status)
24
+ end
25
+
26
+ def failed?
27
+ @status == 'failed'
28
+ end
29
+
30
+ def pending?
31
+ @status == 'running'
32
+ end
33
+
34
+ def finished_successfully?
35
+ @status == 'success'
36
+ end
37
+
38
+ def finished?
39
+ failed? || finished_successfully?
40
+ end
41
+ end
42
+
43
+ class InstallationDeletionStatusResult < Result
44
+ NO_INSTALLATION = 'There is no installation.'.freeze
45
+ DELETE_IN_PROGRESS = 'Delete in progress'.freeze
46
+
47
+ attr_reader :status
48
+
49
+ def initialize(status_hash)
50
+ @status = status_hash['status']
51
+ end
52
+
53
+ def in_progress?
54
+ status == DELETE_IN_PROGRESS
55
+ end
56
+ end
57
+
58
+ class InstallLogResult < Result
59
+ attr_reader :log
60
+
61
+ def initialize(log_hash)
62
+ @log = log_hash['logs'].dup.freeze
63
+ end
64
+ end
65
+
66
+ class TriggerInstallResult < Result
67
+ attr_reader :install_id
68
+
69
+ def initialize(install_hash)
70
+ @install_id = install_hash['install']['id']
71
+ end
72
+ end
73
+
74
+ class ListProductsResult < Result
75
+ Product = Struct.new(:name, :product_version)
76
+
77
+ attr_reader :products
78
+
79
+ def initialize(product_hash_array)
80
+ @products = product_hash_array.map { |p| Product.new(p.fetch('name'), p.fetch('product_version')) }
81
+ end
82
+ end
83
+
84
+ class InstalledProductsResult < Result
85
+ def initialize(installed_products)
86
+ @installed_products = installed_products
87
+ end
88
+
89
+ def guid_for(product_type)
90
+ product_result = installed_products.find { |h| h.name == product_type }
91
+ product_result ? product_result.fetch('guid') : nil
92
+ end
93
+
94
+ private
95
+
96
+ attr_reader :installed_products
97
+ end
98
+
99
+ class InstallationSettingsResult < Result
100
+ def initialize(install_hash)
101
+ @install_hash = install_hash
102
+ end
103
+
104
+ def director_ip
105
+ ips = microbosh_settings.fetch('ips')
106
+ _, director_ips = ips.each_pair.find { |ip_key, _| ip_key =~ /^director-/ }
107
+ director_ips.first
108
+ end
109
+
110
+ def director_password
111
+ microbosh_jobs = microbosh_settings.fetch('jobs')
112
+ microbosh_job_list = Opsmgr::Settings::Microbosh::JobList.new(microbosh_jobs)
113
+ director_job = microbosh_job_list.find { |job| job.name == 'director' }
114
+ properties = director_job.fetch('properties')
115
+ property_list = Opsmgr::Settings::Microbosh::PropertyList.new(properties)
116
+ credential_property = property_list.find { |property| property.name == 'director_credentials' }
117
+ credential_property.fetch('value').fetch('password')
118
+ end
119
+
120
+ def uaa_admin_password
121
+ jobs = cf_settings.fetch('jobs')
122
+ job_list = Opsmgr::Settings::Microbosh::JobList.new(jobs)
123
+ uaa_job = job_list.find { |job| job.name == 'uaa' }
124
+ properties = uaa_job.fetch('properties')
125
+ property_list = Opsmgr::Settings::Microbosh::PropertyList.new(properties)
126
+ credential_property = property_list.find { |property| property.name == 'admin_credentials' }
127
+ credential_property.fetch('value').fetch('password')
128
+ end
129
+
130
+ def system_domain
131
+ properties = cc_job.fetch('properties')
132
+ property_list = Opsmgr::Settings::Microbosh::PropertyList.new(properties)
133
+ credential_property = property_list.find { |property| property.name == 'system_domain' }
134
+ credential_property.fetch('value')
135
+ end
136
+
137
+ def apps_domain
138
+ properties = cc_job.fetch('properties')
139
+ property_list = Opsmgr::Settings::Microbosh::PropertyList.new(properties)
140
+ credential_property = property_list.find { |property| property.name == 'apps_domain' }
141
+ credential_property.fetch('value')
142
+ end
143
+
144
+ def product_version(product_guid)
145
+ product = products.find { |p| p.guid == product_guid }
146
+ return nil if product.nil?
147
+ product.fetch('product_version')
148
+ end
149
+
150
+ def product_version_by_name(product_name)
151
+ product = products.find { |p| p.name == product_name }
152
+ return nil if product.nil?
153
+ product.fetch('product_version')
154
+ end
155
+
156
+ def ops_manager_installation_settings
157
+ Opsmgr::Settings::Microbosh::InstallationSettings.from_api_result(self)
158
+ end
159
+
160
+ def as_hash
161
+ install_hash
162
+ end
163
+
164
+ private
165
+
166
+ attr_reader :install_hash
167
+
168
+ def microbosh_settings
169
+ products.find { |product| product.name == 'microbosh' } || fail('microbosh not found')
170
+ end
171
+
172
+ def cf_settings
173
+ products.find { |product| product.name == 'cf' } || fail('cf not found')
174
+ end
175
+
176
+ def products
177
+ if install_hash.key?('products')
178
+ Opsmgr::Settings::Microbosh::ProductList.new(install_hash.fetch('products'))
179
+ elsif install_hash.key?('components')
180
+ Opsmgr::Settings::Microbosh::ProductList.new(install_hash.fetch('components'))
181
+ else
182
+ fail "Unable to find products in OpsManager response. Check installation schema: #{install_hash.inspect}."
183
+ end
184
+ end
185
+
186
+ def cc_job
187
+ cf_settings.fetch('jobs')
188
+ cf_jobs = cf_settings.fetch('jobs')
189
+ cf_job_list = Opsmgr::Settings::Microbosh::JobList.new(cf_jobs)
190
+ cf_job_list.find { |job| job.name == 'cloud_controller' }
191
+ end
192
+ end
193
+
194
+ class ProductManifestResult < Result
195
+ Product = Struct.new(:name, :version)
196
+ Stemcell = Struct.new(:name, :version)
197
+
198
+ def initialize(manifest_hash)
199
+ @manifest_hash = manifest_hash
200
+ end
201
+
202
+ def releases
203
+ manifest_hash.fetch('releases').map { |h| Product.new(h.fetch('name'), h.fetch('version')) }
204
+ end
205
+
206
+ def stemcell
207
+ stemcell_hash = manifest_hash.fetch('resource_pools').first.fetch('stemcell')
208
+ Stemcell.new(stemcell_hash.fetch('name'), stemcell_hash.fetch('version'))
209
+ end
210
+
211
+ private
212
+
213
+ attr_reader :manifest_hash
214
+ end
215
+
216
+ class CreateFirstUserResult < Result
217
+ attr_reader :user_id
218
+
219
+ def initialize(user_hash)
220
+ @user_id = user_hash['user']['id']
221
+ end
222
+
223
+ def user_already_existed?
224
+ false
225
+ end
226
+ end
227
+
228
+ class Error < Result
229
+ def initialize(message, response)
230
+ @message = "#{message}:\n#{response.body}"
231
+ @response = response
232
+ end
233
+
234
+ def success?
235
+ false
236
+ end
237
+
238
+ private
239
+
240
+ attr_reader :response
241
+ end
242
+
243
+ class CreateFirstUserError < Error
244
+ def user_already_existed?
245
+ response.code == '401'
246
+ end
247
+ end
248
+ end
249
+ end
250
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
251
+ # All rights reserved.
252
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
253
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
254
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
255
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
256
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
257
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.