opsmgr 0.26.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 (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.