opsmgr-cgfrost 0.35.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/LEGAL.txt +13 -0
  3. data/README.md +123 -0
  4. data/lib/opsmgr.rb +12 -0
  5. data/lib/opsmgr/api/client.rb +116 -0
  6. data/lib/opsmgr/api/http_client.rb +399 -0
  7. data/lib/opsmgr/api/results.rb +280 -0
  8. data/lib/opsmgr/api/version20/endpoints.rb +121 -0
  9. data/lib/opsmgr/bosh_command_runner.rb +84 -0
  10. data/lib/opsmgr/cmd/bosh_command.rb +189 -0
  11. data/lib/opsmgr/cmd/ops_manager.rb +142 -0
  12. data/lib/opsmgr/environments.rb +106 -0
  13. data/lib/opsmgr/errand_runner.rb +62 -0
  14. data/lib/opsmgr/log.rb +70 -0
  15. data/lib/opsmgr/product_upload_wrapper.rb +71 -0
  16. data/lib/opsmgr/renderer.rb +23 -0
  17. data/lib/opsmgr/renderer/aws.rb +148 -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 +56 -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 +90 -0
  24. data/lib/opsmgr/settings/microbosh/product_list.rb +27 -0
  25. data/lib/opsmgr/settings/microbosh/property.rb +33 -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 +104 -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 +205 -0
  32. data/lib/opsmgr/tasks/product.rake +82 -0
  33. data/lib/opsmgr/ui_helpers/add_first_user_spec.rb +25 -0
  34. data/lib/opsmgr/ui_helpers/config_helper.rb +38 -0
  35. data/lib/opsmgr/ui_helpers/delete_installation_spec.rb +41 -0
  36. data/lib/opsmgr/ui_helpers/delete_product_if_present_spec.rb +37 -0
  37. data/lib/opsmgr/ui_helpers/delete_product_spec.rb +39 -0
  38. data/lib/opsmgr/ui_helpers/export_installation_spec.rb +31 -0
  39. data/lib/opsmgr/ui_helpers/get_latest_install_log_spec.rb +29 -0
  40. data/lib/opsmgr/ui_helpers/import_stemcell_spec.rb +30 -0
  41. data/lib/opsmgr/ui_helpers/microbosh/configure_microbosh_spec.rb +32 -0
  42. data/lib/opsmgr/ui_helpers/post_import_configuration_spec.rb +31 -0
  43. data/lib/opsmgr/ui_helpers/revert_staged_changes_spec.rb +39 -0
  44. data/lib/opsmgr/ui_helpers/settings_helper.rb +132 -0
  45. data/lib/opsmgr/ui_helpers/trigger_install_spec.rb +35 -0
  46. data/lib/opsmgr/ui_helpers/ui_spec_runner.rb +122 -0
  47. data/lib/opsmgr/ui_helpers/uncheck_errands_spec.rb +29 -0
  48. data/lib/opsmgr/ui_helpers/upload_and_add_product_spec.rb +27 -0
  49. data/lib/opsmgr/ui_helpers/upload_and_upgrade_product_spec.rb +36 -0
  50. data/lib/opsmgr/version.rb +11 -0
  51. data/sample_env_files/aws.yml +95 -0
  52. data/sample_env_files/vsphere.yml +87 -0
  53. metadata +392 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f5da0a81ed7e7d3eeaa3c69f09af30df22a25a6
4
+ data.tar.gz: 474e43c4c2f42546df8537d11bb8d4d3f44f7381
5
+ SHA512:
6
+ metadata.gz: bd2269a6edd6809c4b143c1877902d06106186ad01174b5f75a3a2ac110408c07eb53b8045aaafdb43cedbe8df7b48a5fb1c4e6abb77e4eb80b00fe2a4e9de38
7
+ data.tar.gz: d873d303f5bc961eb1fd7867ea2aa20953c9c9ac567e32f4144316741aa43ace02629018404d47342040e9ad108180b69afa957b1598ddc4c27454c79a5babc8
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,123 @@
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
+ ## Prerequisites
6
+
7
+ ### Ruby
8
+ Install ruby on your machine. Two popular ways to install ruby and manage your ruby installations are:
9
+
10
+ - ruby-install (https://github.com/postmodern/ruby-install) / chruby (https://github.com/postmodern/chruby)
11
+ - rbenv (https://github.com/rbenv/rbenv)
12
+
13
+ The rest of these instructions assume you have already installed the correct ruby version and are familiar with its use.
14
+
15
+ ## Setup
16
+
17
+ ### Command-Line
18
+ Run:
19
+ ```shell
20
+ gem install opsmgr
21
+ ```
22
+
23
+ This will install the opsmgr Gem and all dependencies.
24
+
25
+ ### Within Ruby Code
26
+ To install, add this line to your Gemfile and run bundle install:
27
+ ```ruby
28
+ gem 'opsmgr'
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ### From the Command-Line
34
+ To see a list of all available rake tasks:
35
+
36
+ 1. Create a Rakefile:
37
+ ```ruby
38
+ require 'opsmgr/tasks'
39
+ ```
40
+
41
+ 1. Run:
42
+ ```shell
43
+ rake -T
44
+ ```
45
+
46
+ ### Within Ruby Code
47
+ Require the appropriate part of the opsmgr library. See below for the required files for each task.
48
+
49
+ ## Environment Configuration File
50
+ The expected location of the environment configuration file is `../environment/metadata`. If you need to specify an alternative location, you can use either the `ENV_CONFIG_FILE` or `ENV_DIRECTORY` environment variables. If you use the `ENV_DIRECTORY` environment variable to point to a directory of configuration files, the files inside that directory must be named according to the name of the environment, with the extension `.yml`.
51
+
52
+ Example AWS and vSphere environment files are included in the gem.
53
+
54
+ ## Basic Deployment of Ops Manager with Rake Tasks
55
+
56
+ ### Clean existing environment
57
+ If you want to start fresh, you can clear out your environment completely:
58
+
59
+ **WARNING: this destroys all VMs in the environment, including but not limited to Ops Manager, µBOSH and Runtime**
60
+
61
+ Note: If you used the old version of opsmgr tasks to create this environment, then you need to use that version to clean it. The new version does not correctly clean out deployments from the old version.
62
+
63
+ ```
64
+ bundle exec rake opsmgr:destroy[environment]
65
+ ```
66
+
67
+ ### Download an Ops Manager Image
68
+ Obtain the Ops Manager Image you need from [Pivotal Network](https://network.pivotal.io). If you need a newer version than is available there, consult the Ops Manager team.
69
+
70
+ ### Prepare The Environment (AWS-only)
71
+ This will spin up a cloudformation stack; because it provisions an RDS instance, it can take around half an hour.
72
+
73
+ ```
74
+ bundle exec rake opsmgr:prepare[environment]
75
+ ```
76
+
77
+ ### Deploy the Ops Manager
78
+ You need to specify the path to the Ops Manager image you want to use/have just downloaded.
79
+
80
+ ```
81
+ bundle exec rake opsmgr:install[environment,path_to_ops_manager_image]
82
+ ```
83
+
84
+ ### Configure and Deploy Microbosh
85
+ You need to specify the major and minor version of Ops Manager in these commands.
86
+
87
+ `<OM version>` is the Ops Manager version. Opsmgr supports Ops Manager `1.4`, `1.5`, and `1.6`.
88
+
89
+ `<wait time>` is number of minutes to wait for install, recommended wait time is `45`
90
+
91
+ ```
92
+ bundle exec rake opsmgr:add_first_user[environment,<OM version>]
93
+ bundle exec rake opsmgr:microbosh:configure[environment,<OM version>]
94
+ bundle exec rake opsmgr:trigger_install[environment,<OM version>,<wait time>]
95
+ ```
96
+
97
+ ## Advanced Tasks
98
+
99
+ ### Export the installation from Ops Manager
100
+ `<OM version>` is the Ops Manager version. Opsmgr supports Ops Manager `1.4`, `1.5`, and `1.6`.
101
+
102
+ `<file name>` local file name to save the exported installation file
103
+
104
+ ```
105
+ bundle exec rake opsmgr:export_installation[environment,<OM version>,<file name>]
106
+ ```
107
+
108
+ ### Import an installation to Ops Manager
109
+ `<OM version>` is the Ops Manager version. Opsmgr supports Ops Manager `1.4`, `1.5`, and `1.6`.
110
+
111
+ `<file name>` local file name of the installation file to import
112
+
113
+ ```
114
+ bundle exec rake opsmgr:import_installation[environment,<OM version>,<file name>]
115
+ ```
116
+
117
+ ### Destroy only the Ops Manager VM
118
+
119
+ Commonly done when testing export/import scenarios
120
+
121
+ ```
122
+ bundle exec rake opsmgr:destroy:opsmgr[environment]
123
+ ```
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,116 @@
1
+ require 'backport_refinements'
2
+ using OpsManagerUiDrivers::BackportRefinements
3
+
4
+ require 'json'
5
+ require 'opsmgr/api/http_client'
6
+ require 'opsmgr/api/results'
7
+ require 'opsmgr/settings/microbosh/product_list'
8
+
9
+ module Opsmgr
10
+ module Api
11
+ class Client
12
+ attr_reader :environment_name
13
+
14
+ def initialize(environment, om_version)
15
+ @http_client = HttpClient.build(environment, om_version)
16
+ @environment_name = environment.settings.dig('name').freeze
17
+ end
18
+
19
+ def installation_settings
20
+ response = http_client.installation_settings
21
+ if response.code == '200'
22
+ InstallationSettingsResult.new(JSON.parse(response.body))
23
+ else
24
+ Error.new('Error viewing current installation settings', response)
25
+ end
26
+ end
27
+
28
+ # .pivotal file is referred to as a "product" but the Tempest developers call it a "component"
29
+ def upload_component(path)
30
+ response = http_client.upload_component(path)
31
+ basic_success_or_error("Error uploading #{path}", response)
32
+ end
33
+
34
+ def add_product(product_name, version)
35
+ response = http_client.add_product(product_name, version)
36
+ basic_success_or_error("Error adding '#{product_name} #{version}'", response)
37
+ end
38
+
39
+ def root_ca_certificate
40
+ response = http_client.root_ca_certificate
41
+ if response.code == '200'
42
+ JSON.parse(response.body)['root_ca_certificate_pem']
43
+ else
44
+ Error.new('Error retrieving the root ca certificate', response)
45
+ end
46
+ end
47
+
48
+ def upgrade_product(product_guid, to_version)
49
+ response = http_client.upgrade_product(product_guid, to_version)
50
+ basic_success_or_error("Error upgrading '#{product_guid}' to '#{to_version}'", response)
51
+ end
52
+
53
+ def download_staged_manifest(product_guid)
54
+ response = http_client.download_staged_manifest(product_guid)
55
+ if response.code == '200'
56
+ StagedManifestResult.new(response.body)
57
+ else
58
+ Error.new("Error downloading staged manifest for '#{product_guid}'", response)
59
+ end
60
+ end
61
+
62
+ def list_products
63
+ response = http_client.list_products
64
+ if response.code == '200'
65
+ ListProductsResult.new(JSON.parse(response.body))
66
+ else
67
+ Error.new('Error listing products', response)
68
+ end
69
+ end
70
+
71
+ def installed_products
72
+ response = http_client.installed_products
73
+ if response.code == '200'
74
+ InstalledProductsResult.new(Opsmgr::Settings::Microbosh::ProductList.new(JSON.parse(response.body)))
75
+ else
76
+ Error.new('Error listing installed products', response)
77
+ end
78
+ end
79
+
80
+ def delete_unused_products
81
+ response = http_client.delete_unused_products
82
+ basic_success_or_error('There was an error deleting the unused products:', response)
83
+ end
84
+
85
+ def basic_success_or_error(message, response)
86
+ if response.code == '200'
87
+ Result.new
88
+ else
89
+ Error.new(message, response)
90
+ end
91
+ end
92
+
93
+ def import_installation(path, password)
94
+ response = http_client.import_installation(path, password)
95
+ basic_success_or_error("Error importing #{path}", response)
96
+ end
97
+
98
+ def import_stemcell(path)
99
+ response = http_client.import_stemcell(path)
100
+ basic_success_or_error("Error importing stemcell #{path}", response)
101
+ end
102
+
103
+ private
104
+
105
+ attr_reader :http_client
106
+ end
107
+ end
108
+ end
109
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
110
+ # All rights reserved.
111
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
112
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
113
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
114
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
115
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
116
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,399 @@
1
+ # rubocop:disable Metrics/ClassLength
2
+ require 'backport_refinements'
3
+ using OpsManagerUiDrivers::BackportRefinements
4
+
5
+ require 'net/http'
6
+ require 'net/http/post/multipart'
7
+ require 'json'
8
+ require 'open4'
9
+ require 'opsmgr/log'
10
+ require 'opsmgr/api/version20/endpoints'
11
+ require 'uaa'
12
+
13
+ # noinspection RubyResolve
14
+ module Opsmgr
15
+ module Api
16
+ class HttpClient
17
+ include Loggable
18
+ attr_reader :uri, :environment, :endpoints
19
+
20
+ def self.build(environment, om_version)
21
+ new(environment, Opsmgr::Api::Version20::Endpoints.new, om_version)
22
+ end
23
+
24
+ def initialize(environment, endpoints, om_version)
25
+ @environment = environment
26
+ @uri = URI.parse(environment.settings.dig('ops_manager', 'url'))
27
+ @endpoints = endpoints
28
+ @om_version = om_version
29
+ end
30
+
31
+ def upload_product_installation_settings(settings_file_path)
32
+ req = Net::HTTP::Post::Multipart.new(
33
+ endpoints.installation_settings_post_path,
34
+ 'installation[file]' =>
35
+ UploadIO.new(
36
+ settings_file_path,
37
+ 'application/octet-stream',
38
+ File.basename(settings_file_path)
39
+ )
40
+ )
41
+
42
+ add_auth_header(req)
43
+
44
+ http.request(req)
45
+ end
46
+
47
+ def upload_component(product_path)
48
+ # We ran into a possible Net::HTTP bug where Ruby would always drop the connection while waiting for the
49
+ # uploaded zip file to unzip. Curl behaved correctly, but curb (Ruby bindings for libcurl) did not behave
50
+ # well with WebMock, so here we are.
51
+ upload_component_command =
52
+ %W(
53
+ curl -k
54
+ --silent
55
+ --fail
56
+ #{uri}#{endpoints.upload_product_path}
57
+ -F #{endpoints.upload_product_form_key}[file]=@#{product_path}
58
+ -X POST
59
+ )
60
+
61
+ if Gem::Version.new(@om_version) >= Gem::Version.new('1.7')
62
+ log.info('using oauth')
63
+ token = get_oauth_token(web_auth_user)
64
+ upload_component_command.push("-H")
65
+ upload_component_command.push("Authorization: #{token}")
66
+ else
67
+ log.info('using basic auth')
68
+ upload_component_command.push("-u")
69
+ upload_component_command.push("#{web_auth_user}:#{web_auth_password}")
70
+ end
71
+
72
+ log.info('uploading product')
73
+
74
+ error = nil
75
+ status =
76
+ Open4.popen4(*upload_component_command) do |_, _, stdout, stderr|
77
+ log.info(stdout.read)
78
+ error = stderr.read
79
+ end
80
+
81
+ if status.success?
82
+ FakeResponse.new('200', '{}')
83
+ else
84
+ error_code = (error.match(/^\< HTTP\/.* (\d+) /) || [nil, '???'])[1]
85
+ FakeResponse.new(error_code, error)
86
+ end
87
+ end
88
+
89
+ def root_ca_certificate
90
+ req = Net::HTTP::Get.new(endpoints.root_ca_certificate_path)
91
+ add_auth_header(req)
92
+
93
+ http.request(req)
94
+ end
95
+
96
+ def add_product(product_name, version)
97
+ req = Net::HTTP::Post.new(endpoints.add_product_path)
98
+ req.set_form_data('name' => product_name, 'product_version' => version)
99
+ add_auth_header(req)
100
+
101
+ http.request(req)
102
+ end
103
+
104
+ def upgrade_product(product_guid, to_version)
105
+ req = Net::HTTP::Put.new(endpoints.upgrade_product_path(product_guid))
106
+ req.set_form_data('to_version' => to_version)
107
+ add_auth_header(req)
108
+
109
+ http.request(req)
110
+ end
111
+
112
+ def download_staged_manifest(product_guid)
113
+ req = Net::HTTP::Get.new(endpoints.download_staged_manifest(product_guid))
114
+ add_auth_header(req)
115
+
116
+ http.request(req)
117
+ end
118
+
119
+ def trigger_install
120
+ req = Net::HTTP::Post.new(endpoints.install_post_path)
121
+ req.body = ''
122
+ add_auth_header(req)
123
+
124
+ http.request(req)
125
+ end
126
+
127
+ # components are both uploaded AND configured AND deployed
128
+ def list_components
129
+ get_with_basic_auth(endpoints.list_components_path)
130
+ end
131
+
132
+ # products are uploaded but not necessarily configured or deployed
133
+ def list_products
134
+ get_with_basic_auth(endpoints.list_products_path)
135
+ end
136
+
137
+ # products that have been uploaded, configured, and installed
138
+ def installed_products
139
+ get_with_basic_auth(endpoints.installed_products_path)
140
+ end
141
+
142
+ def product_manifest(product_guid)
143
+ get_with_basic_auth(endpoints.product_manifest_path(product_guid))
144
+ end
145
+
146
+ def installation_settings
147
+ get_with_basic_auth(endpoints.installation_settings_get_path)
148
+ end
149
+
150
+ def installation_delete
151
+ req = Net::HTTP::Delete.new(endpoints.installation_path)
152
+ add_auth_header(req)
153
+
154
+ http.request(req)
155
+ end
156
+
157
+ def installation_deletion_status
158
+ get_with_basic_auth(endpoints.installation_deletion_status_path)
159
+ end
160
+
161
+ def create_the_first_user
162
+ if Gem::Version.new(@om_version) >= Gem::Version.new('1.6')
163
+ req = Net::HTTP::Post.new(endpoints.api_setup_path)
164
+ req.set_form_data(
165
+ 'setup[user_name]' => web_auth_user,
166
+ 'setup[password]' => web_auth_password,
167
+ 'setup[password_confirmation]' => web_auth_password,
168
+ 'setup[eula_accepted]' => true
169
+ )
170
+ else
171
+ req = Net::HTTP::Post.new(endpoints.api_user_path)
172
+ req.set_form_data(
173
+ 'user[user_name]' => web_auth_user,
174
+ 'user[password]' => web_auth_password,
175
+ 'user[password_confirmation]' => web_auth_password,
176
+ )
177
+ end
178
+
179
+ http.request(req)
180
+ end
181
+
182
+ def install_status(install_id)
183
+ get_with_basic_auth(endpoints.show_installation_status(install_id))
184
+ end
185
+
186
+ def install_log(install_id)
187
+ get_with_basic_auth(endpoints.installation_log_path(install_id))
188
+ end
189
+
190
+ def mark_product_for_deletion(product_guid)
191
+ req = Net::HTTP::Delete.new(endpoints.mark_for_deletion_path(product_guid))
192
+ add_auth_header(req)
193
+
194
+ http.request(req)
195
+ end
196
+
197
+ def delete_unused_products
198
+ req = Net::HTTP::Delete.new(endpoints.list_products_path)
199
+ add_auth_header(req)
200
+
201
+ http.request(req)
202
+ end
203
+
204
+ def version
205
+ endpoints.version
206
+ end
207
+
208
+ def import_installation(installation_file, password)
209
+ create_the_first_user unless Gem::Version.new(@om_version) >= Gem::Version.new('1.7')
210
+
211
+ log.info('uploading the installation file')
212
+ req = Net::HTTP::Post::Multipart.new(
213
+ endpoints.import_installation_path,
214
+ 'installation[file]' =>
215
+ UploadIO.new(
216
+ installation_file,
217
+ 'application/octet-stream',
218
+ File.basename(installation_file)
219
+ ),
220
+ import_secret_parameter_name => password
221
+ )
222
+
223
+ # The post-1.7 import happens before a user has been created so we cannot authenticate.
224
+ add_auth_header(req) unless Gem::Version.new(@om_version) >= Gem::Version.new('1.7')
225
+
226
+ response = http.request(req)
227
+
228
+ if Gem::Version.new(@om_version) == Gem::Version.new('1.7')
229
+ wait_for_uaa_to_be_available
230
+
231
+ ensure_env_admin_user_exists
232
+ end
233
+
234
+ response
235
+ end
236
+
237
+ def wait_for_uaa_to_be_available(sleep_interval = 10, max_retry_count = 24)
238
+ retry_count = 0
239
+
240
+ loop do
241
+ request = Net::HTTP::Get.new(
242
+ endpoints.login_ensure_availability
243
+ )
244
+
245
+ response = http.request(request)
246
+
247
+ http_location = response['location']
248
+
249
+ break if response.code == '302' && http_location == auth_redirect_location
250
+
251
+ retry_count += 1
252
+
253
+ if retry_count >= max_retry_count
254
+ retry_wait_time = sleep_interval * retry_count
255
+
256
+ raise("Timed out waiting for UAA to be available after #{retry_wait_time} seconds")
257
+ end
258
+
259
+ Kernel.sleep(sleep_interval)
260
+ end
261
+ end
262
+
263
+ def ensure_env_admin_user_exists
264
+ token = get_oauth_token('admin')
265
+
266
+ create_env_admin_user(token) unless verify_if_env_admin_user_exists?(token)
267
+ end
268
+
269
+ def verify_if_env_admin_user_exists?(token)
270
+ request = Net::HTTP::Get.new(
271
+ endpoints.uaa_get_user_by_username_path(web_auth_user)
272
+ )
273
+ request['Authorization'] = token
274
+
275
+ response = http.request(request)
276
+
277
+ if response.code != '200'
278
+ raise("Invalid response from UAA: #{response.code}")
279
+ end
280
+
281
+ reply = JSON.parse(response.body)
282
+
283
+ if reply['resources'].nil?
284
+ raise("Invalid response body from UAA: #{response.body}")
285
+ end
286
+
287
+ !reply['resources'].empty?
288
+ end
289
+
290
+ def create_env_admin_user(token)
291
+ request = Net::HTTP::Post.new(
292
+ endpoints.uaa_create_user
293
+ )
294
+ request['Content-Type'] = 'application/json'
295
+ request['Authorization'] = token
296
+ request.body = {
297
+ userName: web_auth_user,
298
+ password: web_auth_password,
299
+ emails: [
300
+ { value: web_auth_user }
301
+ ]
302
+ }.to_json
303
+
304
+ response = http.request(request)
305
+
306
+ if response.code != '201'
307
+ raise("Unexpected response from UAA: code #{response.code}, body: #{response.body}")
308
+ end
309
+ end
310
+
311
+ def import_secret_parameter_name
312
+ Gem::Version.new(@om_version) >= Gem::Version.new('1.7') ? 'passphrase' : 'password'
313
+ end
314
+
315
+ def import_stemcell(stemcell_file)
316
+ req = Net::HTTP::Post::Multipart.new(
317
+ endpoints.import_stemcell_path,
318
+ 'stemcell[file]' =>
319
+ UploadIO.new(
320
+ stemcell_file,
321
+ 'application/octet-stream',
322
+ File.basename(stemcell_file)
323
+ )
324
+ )
325
+
326
+ add_auth_header(req)
327
+
328
+ http.request(req)
329
+ end
330
+
331
+ def read_timeout
332
+ environment.settings.dig('iaas_type') != 'vcloud' ? 600 : 3600
333
+ end
334
+
335
+ def auth_redirect_location
336
+ host = environment.settings.dig('ops_manager', 'url')
337
+
338
+ host.concat('/') unless host.end_with? '/'
339
+
340
+ host+'auth/cloudfoundry'
341
+ end
342
+
343
+ private
344
+
345
+ def add_auth_header(request)
346
+ if Gem::Version.new(@om_version) >= Gem::Version.new('1.7')
347
+ log.info('using oauth')
348
+ token = get_oauth_token(web_auth_user)
349
+ request['Authorization'] = token
350
+ else
351
+ log.info('using basic auth')
352
+ request.basic_auth(web_auth_user, web_auth_password)
353
+ end
354
+ end
355
+
356
+ def get_oauth_token(user)
357
+ target_url = environment.settings.dig('ops_manager', 'url') + '/uaa'
358
+ token_issuer = CF::UAA::TokenIssuer.new(target_url, 'opsman', nil, skip_ssl_validation: true)
359
+ token_issuer.owner_password_grant(user, web_auth_password).auth_header
360
+ end
361
+
362
+ def web_auth_user
363
+ environment.settings.dig('ops_manager', 'username')
364
+ end
365
+
366
+ def web_auth_password
367
+ environment.settings.dig('ops_manager', 'password')
368
+ end
369
+
370
+ def http
371
+ http = Net::HTTP.new(uri.host, uri.port)
372
+ if uri.scheme == 'https'
373
+ http.use_ssl = true
374
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
375
+ end
376
+ http.read_timeout = read_timeout
377
+ http
378
+ end
379
+
380
+ def get_with_basic_auth(path)
381
+ req = Net::HTTP::Get.new(path)
382
+ add_auth_header(req)
383
+
384
+ http.request(req)
385
+ end
386
+
387
+ class FakeResponse < Struct.new(:code, :body)
388
+ end
389
+ end
390
+ end
391
+ end
392
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
393
+ # All rights reserved.
394
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
395
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
396
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
397
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
398
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
399
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.