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
@@ -0,0 +1,189 @@
1
+ require 'backport_refinements'
2
+ using OpsManagerUiDrivers::BackportRefinements
3
+
4
+ require 'opsmgr/ui_helpers/ui_spec_runner'
5
+ require 'opsmgr/environments'
6
+ require 'opsmgr/api/client'
7
+ require 'ops_manager_ui_drivers'
8
+ require 'capybara'
9
+ require 'capybara/dsl'
10
+ require 'capybara/webkit'
11
+
12
+ module Opsmgr
13
+ module Cmd
14
+ class BoshCommand
15
+ include Capybara::DSL
16
+
17
+ def initialize(env_name:, om_version:)
18
+ @env_settings = Opsmgr::Environments.for(env_name).settings
19
+ configure_capybara
20
+
21
+ @env_name = env_name
22
+ @om_version = om_version
23
+ @current_ops_manager = setup_or_login
24
+
25
+ configure_client_credentials
26
+ end
27
+
28
+ def command
29
+ ip = ENV['DIRECTOR_IP_OVERRIDE'] || director_ip
30
+
31
+ if Gem::Version.new(om_version) >= Gem::Version.new('1.7')
32
+ return "BOSH_CLIENT=#{@bosh_client} BOSH_CLIENT_SECRET=#{@bosh_client_secret} bosh -t #{ip} --ca-cert #{root_cert_file}"
33
+ end
34
+
35
+ %W(
36
+ bosh
37
+ -t #{ip}
38
+ -u director
39
+ -p #{director_password}
40
+ ).join(' ')
41
+ end
42
+
43
+ def director_ip
44
+ status_page = current_ops_manager.product_status_for(director_tile_name)
45
+
46
+ partitioned_job_name = 'director-partition-null-az'
47
+ availability_zones = env_settings['ops_manager']['availability_zones']
48
+ if availability_zones
49
+ az_name = availability_zones.first['iaas_identifier'] || 'first-az'
50
+ partitioned_job_name = "director-partition-#{current_ops_manager.availability_zone_guid_for_name(az_name)}"
51
+ end
52
+
53
+ if Gem::Version.new(om_version) >= Gem::Version.new('1.8')
54
+ partitioned_job_name = 'director'
55
+ end
56
+
57
+ director_status = status_page.job_status(partitioned_job_name)
58
+
59
+ director_status.ips.first
60
+ end
61
+
62
+ private
63
+
64
+ def configure_client_credentials
65
+ return unless Gem::Version.new(om_version) >= Gem::Version.new('1.7')
66
+
67
+ installation_settings = api_client.installation_settings.as_hash
68
+ uaa_credentials = installation_settings['products'].find { |p| p['identifier'] == 'p-bosh' }['uaa_credentials']
69
+
70
+
71
+ @bosh_client = uaa_credentials['identity']
72
+ @bosh_client_secret = uaa_credentials['password']
73
+ end
74
+
75
+ def api_client
76
+ @api_client ||= Opsmgr::Api::Client.new(Opsmgr::Environments.for(@env_name), @om_version)
77
+ end
78
+
79
+ def root_cert_file
80
+ return @file_path if @file_path
81
+ tmp_dir = ENV.fetch('TMPDIR', '/tmp')
82
+ FileUtils.mkpath(tmp_dir)
83
+ @file_path = tmp_dir + '/root_ca_certificate'
84
+
85
+ result = api_client.root_ca_certificate
86
+ fail result.message if result.is_a?(Api::Error)
87
+ File.write(@file_path, result)
88
+
89
+ @file_path
90
+ end
91
+
92
+ def setup_or_login
93
+ driver = ops_manager_driver(om_version)
94
+
95
+ driver.setup_page.setup_or_login(
96
+ user: env_settings['ops_manager']['username'],
97
+ password: env_settings['ops_manager']['password'],
98
+ )
99
+ driver
100
+ end
101
+
102
+ def configure_capybara
103
+ Capybara.configure do |c|
104
+ c.default_driver = :webkit
105
+ c.run_server = false
106
+ c.app_host = env_settings['ops_manager']['url']
107
+ end
108
+
109
+ Capybara::Webkit.configure do |c|
110
+ c.ignore_ssl_errors = true
111
+ c.allow_url(env_settings['ops_manager']['url'])
112
+ end
113
+
114
+ page.current_window.resize_to(1024, 1600) # avoid overlapping footer spec failures
115
+ end
116
+
117
+ def director_password
118
+ browser = self
119
+
120
+ browser.visit '/'
121
+ browser.click_on "show-#{director_tile_name}-configure-action"
122
+ browser.click_on 'show-credentials-action'
123
+
124
+ credentials = ''
125
+
126
+ browser.within "#installations_credentials" do
127
+ credentials = browser.find(:xpath, ".//td[@class='with-table']/table[@class='table']/tbody/tr[4]/td[@class='value value-col']").text
128
+ end
129
+
130
+ credentials.split(' / ')[1]
131
+ end
132
+
133
+ def director_tile_name
134
+ om_version.to_f >= 1.6 ? 'p-bosh' : 'microbosh'
135
+ end
136
+
137
+ def ops_manager_driver(om_version)
138
+ case om_version
139
+ when '1.4'
140
+ om_1_4
141
+ when '1.5'
142
+ om_1_5
143
+ when '1.6'
144
+ om_1_6
145
+ when '1.7'
146
+ om_1_7
147
+ when '1.8'
148
+ om_1_8
149
+ else
150
+ fail "Unsupported Ops Manager Version #{om_version.inspect}"
151
+ end
152
+ end
153
+
154
+ def om_1_4
155
+ @om_1_4 ||= create_web_ui(OpsManagerUiDrivers::Version14)
156
+ end
157
+
158
+ def om_1_5
159
+ @om_1_5 ||= create_web_ui(OpsManagerUiDrivers::Version15)
160
+ end
161
+
162
+ def om_1_6
163
+ @om_1_6 ||= create_web_ui(OpsManagerUiDrivers::Version16)
164
+ end
165
+
166
+ def om_1_7
167
+ @om_1_7 ||= create_web_ui(OpsManagerUiDrivers::Version17)
168
+ end
169
+
170
+ def om_1_8
171
+ @om_1_8 ||= create_web_ui(OpsManagerUiDrivers::Version18)
172
+ end
173
+
174
+ def create_web_ui(version_module)
175
+ version_module::WebUi.new(browser: self)
176
+ end
177
+
178
+ attr_reader :env_settings, :om_version, :current_ops_manager
179
+ end
180
+ end
181
+ end
182
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
183
+ # All rights reserved.
184
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
185
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
186
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
187
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
188
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
189
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,142 @@
1
+ require 'backport_refinements'
2
+ using OpsManagerUiDrivers::BackportRefinements
3
+
4
+ require 'opsmgr/log'
5
+
6
+ module Opsmgr
7
+ module Cmd
8
+ class OpsManager
9
+ include Loggable
10
+
11
+ def initialize(target_environment)
12
+ @environment = target_environment
13
+ end
14
+
15
+ def configure_microbosh_infrastructure(client)
16
+ result = client.installation_settings
17
+ return unless result.success?
18
+
19
+ result = result.as_hash
20
+ return if result.fetch('installation_version', '') != '1.4'
21
+ return if result['infrastructure']['type'] != 'vsphere'
22
+
23
+ result['infrastructure']['file_system'] = {
24
+ 'microbosh_vm_folder' => environment.settings.dig('name'),
25
+ 'microbosh_template_folder' => environment.settings.dig('name'),
26
+ 'microbosh_disk_path' => environment.settings.dig('name'),
27
+ }
28
+
29
+ file = Tempfile.new('om_install_settings')
30
+ file.write(YAML.dump(result))
31
+ file.close
32
+
33
+ client.upload_product_installation_settings(file.path)
34
+ end
35
+
36
+ def delete_unused_products(client)
37
+ result = client.delete_unused_products
38
+ if result.success?
39
+ log.info 'Successfully deleted unused products'
40
+ else
41
+ fail result.message
42
+ end
43
+ end
44
+
45
+ def upload_product(client, path)
46
+ result = client.upload_component(path)
47
+ if result.success?
48
+ log.info 'Successfully uploaded product'
49
+ else
50
+ fail result.message
51
+ end
52
+ end
53
+
54
+ def list_products(client)
55
+ result = client.list_products
56
+ if result.success?
57
+ result
58
+ else
59
+ fail result.message
60
+ end
61
+ end
62
+
63
+ def add_product(client, name, version)
64
+ result = client.add_product(name, version)
65
+ if result.success?
66
+ log.info 'Successfully added product'
67
+ else
68
+ fail result.message
69
+ end
70
+ end
71
+
72
+ def upgrade_product(client, guid, version)
73
+ result = client.upgrade_product(guid, version)
74
+ if result.success?
75
+ log.info 'Successfully upgraded product'
76
+ else
77
+ fail result.message
78
+ end
79
+ end
80
+
81
+ def installed_products(client)
82
+ result = client.installed_products
83
+ if result.success?
84
+ result
85
+ else
86
+ fail result.message
87
+ end
88
+ end
89
+
90
+ def import_installation(client, path)
91
+ result = client.import_installation(path, environment.settings.dig('ops_manager', 'password'))
92
+ if result.success?
93
+ log.info 'Successfully imported installation'
94
+ else
95
+ fail result.message
96
+ end
97
+ end
98
+
99
+ def import_stemcell(client, path)
100
+ result = client.import_stemcell(path)
101
+ if result.success?
102
+ log.info 'Successfully imported stemcell'
103
+ else
104
+ fail result.message
105
+ end
106
+ end
107
+
108
+ def download_staged_manifest(client, guid, manifest_filepath)
109
+ result = client.download_staged_manifest(guid)
110
+ if result.success?
111
+ File.open(manifest_filepath, 'w') do |mf|
112
+ mf.write(result.manifest)
113
+ end
114
+ log.info 'Successfully downloaded staged manifest for product'
115
+ else
116
+ fail result.message
117
+ end
118
+ end
119
+
120
+ def revert_staged_changes(client)
121
+ result = client.revert_staged_changes
122
+ if result.success?
123
+ log.info 'Successfully reverted staged changes'
124
+ else
125
+ fail result.message
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ attr_reader :environment
132
+ end
133
+ end
134
+ end
135
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
136
+ # All rights reserved.
137
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
138
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
139
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
140
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
141
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
142
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,106 @@
1
+ require 'backport_refinements'
2
+ using OpsManagerUiDrivers::BackportRefinements
3
+
4
+ require 'active_support'
5
+ require 'active_support/core_ext'
6
+ require 'erb'
7
+ require 'yaml'
8
+ require 'opsmgr/renderer'
9
+
10
+ module Opsmgr
11
+ class Environments
12
+ def self.for(name = '')
13
+ env_config = config_file(directory, config_filename(name))
14
+ unless File.exist?(env_config)
15
+ raise "No environments config found in #{env_config}. Specify path using ENV_DIRECTORY or ENV_CONFIG_FILE."
16
+ end
17
+
18
+ new(env_config, name)
19
+ end
20
+
21
+ def self.list
22
+ Dir.glob(config_file(directory, '*')).map do |path|
23
+ fname = File.basename(path, '.*')
24
+ if fname == 'metadata'
25
+ string_keyed_hash = YAML.load(File.read(path))
26
+ string_keyed_hash['name'].to_sym
27
+ else
28
+ fname.to_sym
29
+ end
30
+ end
31
+ end
32
+
33
+ def self.directory
34
+ ENV.fetch('ENV_DIRECTORY', File.join(Dir.pwd, '../environment/'))
35
+ end
36
+
37
+ def self.config_filename(name)
38
+ ENV.key?('ENV_DIRECTORY') ? "#{name}.yml" : 'metadata'
39
+ end
40
+
41
+ def self.config_file(dir, name)
42
+ ENV.fetch('ENV_CONFIG_FILE', File.join(dir, name))
43
+ end
44
+
45
+ def initialize(config_path, env_name = '')
46
+ @config_path = config_path
47
+ @env_name = env_name
48
+ end
49
+
50
+ def settings_with_merged_folders(installation_settings)
51
+ return settings unless installation_settings['infrastructure']['file_system']
52
+ file_system = installation_settings['infrastructure']['file_system']
53
+
54
+ settings_to_modify = settings
55
+ settings_to_modify.dig('vm_shepherd', 'vm_configs', 0, 'cleanup', 'datacenter_folders_to_clean') << file_system['microbosh_vm_folder']
56
+ settings_to_modify.dig('vm_shepherd', 'vm_configs', 0, 'cleanup', 'datacenter_folders_to_clean') << file_system['microbosh_template_folder']
57
+ settings_to_modify.dig('vm_shepherd', 'vm_configs', 0, 'cleanup', 'datastore_folders_to_clean') << file_system['microbosh_disk_path']
58
+ settings_to_modify
59
+ end
60
+
61
+ def settings
62
+ string_keyed_hash = YAML.load(Renderer.for(File.read(@config_path)).rendered_settings)
63
+ unless @env_name == '' || string_keyed_hash['name'] == @env_name
64
+ raise "Specified name #{@env_name} does not match name in #{@config_path}"
65
+ end
66
+
67
+ fix_subnets(string_keyed_hash)
68
+ end
69
+
70
+ private
71
+
72
+ def fix_subnets(settings)
73
+ settings['ops_manager']['networks'].each do |n|
74
+ next if n['subnets']
75
+ availability_zones = settings['ops_manager']['availability_zones'] || []
76
+ n['subnets'] = [
77
+ {
78
+ 'identifier' => n['identifier'],
79
+ 'cidr' => n['subnet'],
80
+ 'dns' => n['dns'],
81
+ 'gateway' => n['gateway'],
82
+ 'reserved_ips' => n['reserved_ips'],
83
+ 'availability_zones' => availability_zones.map { |z| z['name'] }
84
+ }
85
+ ]
86
+ end
87
+
88
+ if settings['vm_shepherd']['env_config']
89
+ outputs = settings['vm_shepherd']['env_config']['outputs']
90
+ unless outputs['subnets']
91
+ outputs['subnets'] = [outputs['public_subnet_id'], outputs['private_subnet_id']]
92
+ end
93
+ end
94
+
95
+ settings
96
+ end
97
+ end
98
+ end
99
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
100
+ # All rights reserved.
101
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
102
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
103
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
104
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
105
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
106
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,62 @@
1
+ require 'opsmgr/bosh_command_runner'
2
+ require 'open3'
3
+
4
+ module Opsmgr
5
+ class ErrandRunner
6
+ def initialize(bosh_command:, environment_name:, logger:, product_name:, errand_name:, download_logs:)
7
+ @bosh_command = bosh_command
8
+ @environment_name = environment_name
9
+ @logger = logger
10
+ @product_name = product_name
11
+ @errand_name = errand_name
12
+ @download_logs = download_logs ? "--download-logs" : ""
13
+
14
+ @bosh_command_runner = Opsmgr::BoshCommandRunner.new(
15
+ bosh_command: @bosh_command,
16
+ logger: @logger
17
+ )
18
+ end
19
+
20
+ def run_errand
21
+ deployments_output = begin
22
+ @bosh_command_runner.run_and_capture_output('deployments')
23
+ rescue RuntimeError
24
+ raise 'bosh deployments failed'
25
+ end
26
+
27
+ bosh_deployment = deployments_output[/#{@product_name}-[0-9a-f]{8,}/]
28
+
29
+ fail 'Deployment not found' if bosh_deployment.nil?
30
+
31
+ deployment_file = "#{ENV.fetch('TMPDIR', '/tmp')}/#{environment_name}.yml"
32
+
33
+ begin
34
+ @bosh_command_runner.run(
35
+ "-n download manifest #{bosh_deployment} #{deployment_file}"
36
+ )
37
+ rescue RuntimeError
38
+ raise 'bosh download manifest failed'
39
+ end
40
+
41
+ begin
42
+ @bosh_command_runner.run(
43
+ "-d #{deployment_file} run errand #{@errand_name} #{@download_logs}"
44
+ )
45
+ rescue RuntimeError
46
+ raise "Errand #{@errand_name} failed"
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ attr_reader :bosh_command, :environment_name, :logger, :product_name, :errand_name, :download_logs
53
+ end
54
+ end
55
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
56
+ # All rights reserved.
57
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
58
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
59
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
60
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
61
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
62
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.