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
@@ -0,0 +1,93 @@
1
+ module Opsmgr
2
+ module Api
3
+ module Version20
4
+ class Endpoints
5
+ VERSION = '2.0'.freeze
6
+
7
+ def version
8
+ VERSION
9
+ end
10
+
11
+ def installation_settings_post_path
12
+ '/api/installation_settings'
13
+ end
14
+
15
+ def installation_settings_get_path
16
+ '/api/installation_settings'
17
+ end
18
+
19
+ def install_post_path
20
+ '/api/installation?ignore_warnings=1'
21
+ end
22
+
23
+ def installation_path
24
+ '/api/installation'
25
+ end
26
+
27
+ def configure_user_path
28
+ '/api/users'
29
+ end
30
+
31
+ def show_installation_status(id)
32
+ "/api/installation/#{id}"
33
+ end
34
+
35
+ def installation_log_path(id)
36
+ "/api/installation/#{id}/logs"
37
+ end
38
+
39
+ def upload_product_path
40
+ '/api/products'
41
+ end
42
+
43
+ def add_product_path
44
+ '/api/installation_settings/products'
45
+ end
46
+
47
+ def upgrade_product_path(product_guid)
48
+ "/api/installation_settings/products/#{product_guid}"
49
+ end
50
+
51
+ def upload_product_form_key
52
+ 'product'
53
+ end
54
+
55
+ def list_components_path
56
+ '/api/components'
57
+ end
58
+
59
+ def list_products_path
60
+ '/api/products'
61
+ end
62
+
63
+ def installed_products_path
64
+ '/api/installation_settings/products'
65
+ end
66
+
67
+ def product_manifest_path(product_guid)
68
+ "/api/manifests/#{product_guid}"
69
+ end
70
+
71
+ def export_installation_path
72
+ '/api/installation_asset_collection'
73
+ end
74
+
75
+ def import_installation_path
76
+ '/api/installation_asset_collection'
77
+ end
78
+
79
+ def mark_for_deletion_path(product_guid)
80
+ "/api/installation_settings/products/#{product_guid}"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
87
+ # All rights reserved.
88
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
89
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
90
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
91
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
92
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
93
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,213 @@
1
+ require 'opsmgr/ui_helpers/ui_spec_runner'
2
+ require 'opsmgr/environments'
3
+ require 'ops_manager_ui_drivers'
4
+ require 'capybara'
5
+ require 'capybara/webkit'
6
+ require 'net/ssh/gateway'
7
+
8
+ module Opsmgr
9
+ module Cmd
10
+ class BoshCommand
11
+ include Capybara::DSL
12
+
13
+ def initialize(env_name:, om_version:)
14
+ @env_settings = Opsmgr::Environments.for(env_name).settings
15
+ configure_capybara
16
+
17
+ @env_name = env_name
18
+ @om_version = om_version
19
+ @current_ops_manager = setup_or_login
20
+ end
21
+
22
+ def command
23
+ ip = ENV['DIRECTOR_IP_OVERRIDE'] || director_ip
24
+
25
+ %W(
26
+ bosh
27
+ -t #{ip}
28
+ -u director
29
+ -p #{director_password}
30
+ ).join(' ')
31
+ end
32
+
33
+ def target
34
+ ip = ENV['DIRECTOR_IP_OVERRIDE'] || director_ip
35
+
36
+ %W(
37
+ bosh
38
+ -u director
39
+ -p #{director_password}
40
+ target #{ip}
41
+ ).join(' ')
42
+ end
43
+
44
+ def director_ip
45
+ status_page = current_ops_manager.product_status_for(director_tile_name)
46
+
47
+ partitioned_job_name = 'director-partition-null-az'
48
+ availability_zones = env_settings.ops_manager.availability_zones
49
+ if availability_zones
50
+ az_name = availability_zones.first.iaas_identifier || 'first-az'
51
+ partitioned_job_name = "director-partition-#{current_ops_manager.availability_zone_guid_for_name(az_name)}"
52
+ end
53
+
54
+ director_status = status_page.job_status(partitioned_job_name)
55
+
56
+ director_status.ips.first
57
+ end
58
+
59
+ private
60
+
61
+ def setup_or_login
62
+ driver = ops_manager_driver(om_version)
63
+
64
+ driver.setup_page.setup_or_login(
65
+ user: env_settings.ops_manager.username,
66
+ password: env_settings.ops_manager.password,
67
+ )
68
+ driver
69
+ end
70
+
71
+ def configure_capybara
72
+ Capybara.configure do |c|
73
+ c.default_driver = :webkit
74
+ c.run_server = false
75
+ c.app_host = env_settings.ops_manager.url
76
+ end
77
+
78
+ Capybara::Webkit.configure do |c|
79
+ c.ignore_ssl_errors = true
80
+ c.allow_url(env_settings.ops_manager.url)
81
+ end
82
+
83
+ page.current_window.resize_to(1024, 1600) # avoid overlapping footer spec failures
84
+ end
85
+
86
+ def director_password
87
+ browser = self
88
+
89
+ browser.visit '/'
90
+ browser.click_on "show-#{director_tile_name}-configure-action"
91
+ browser.click_on 'show-credentials-action'
92
+
93
+ credentials = ''
94
+
95
+ browser.within "#installations_credentials" do
96
+ credentials = browser.find(:xpath, ".//td[@class='with-table']/table[@class='table']/tbody/tr[4]/td[@class='value value-col']").text
97
+ end
98
+
99
+ credentials.split(' / ')[1]
100
+ end
101
+
102
+ def director_tile_name
103
+ (om_version.to_f >= 1.6) ? 'p-bosh' : 'microbosh'
104
+ end
105
+
106
+ def ops_manager_driver(om_version)
107
+ case om_version
108
+ when '1.4'
109
+ om_1_4
110
+ when '1.5'
111
+ om_1_5
112
+ when '1.6'
113
+ om_1_6
114
+ when '1.7'
115
+ om_1_7
116
+ else
117
+ fail "Unsupported Ops Manager Version #{om_version.inspect}"
118
+ end
119
+ end
120
+
121
+ def om_1_4
122
+ @om_1_4 ||= create_web_ui(OpsManagerUiDrivers::Version14)
123
+ end
124
+
125
+ def om_1_5
126
+ @om_1_5 ||= create_web_ui(OpsManagerUiDrivers::Version15)
127
+ end
128
+
129
+ def om_1_6
130
+ @om_1_6 ||= create_web_ui(OpsManagerUiDrivers::Version16)
131
+ end
132
+
133
+ def om_1_7
134
+ @om_1_7 ||= create_web_ui(OpsManagerUiDrivers::Version17)
135
+ end
136
+
137
+ def create_web_ui(version_module)
138
+ version_module::WebUi.new(browser: self)
139
+ end
140
+
141
+ attr_reader :env_settings, :om_version, :current_ops_manager
142
+ end
143
+
144
+ class IaasGateway
145
+ def initialize(bosh_command:, environment_name:, logger:)
146
+ @bosh_command = bosh_command
147
+ @environment = Opsmgr::Environments.for(environment_name)
148
+ @logger = logger
149
+ end
150
+
151
+ def gateway(&block)
152
+ case environment.settings.iaas_type
153
+ when 'vsphere'
154
+ block.call
155
+ when 'aws', 'openstack'
156
+ ssh_key_gateway(block)
157
+ when 'vcloud'
158
+ ssh_password_gateway(block)
159
+ end
160
+ end
161
+
162
+ private
163
+
164
+ attr_reader :bosh_command, :environment, :logger
165
+
166
+ def ssh_password_gateway(block)
167
+ ENV['DIRECTOR_IP_OVERRIDE'] = 'localhost'
168
+ uri = URI.parse(environment.settings.ops_manager.url)
169
+ director_ip = bosh_command.director_ip
170
+ logger.info("Setting up SSH gateway to OpsManager at #{uri.host}")
171
+ Net::SSH::Gateway.new(
172
+ uri.host,
173
+ 'ubuntu',
174
+ password: 'tempest'
175
+ ).open(director_ip, 25_555, 25_555) do |_|
176
+ logger.info("Opened tunnel to MicroBOSH at #{director_ip}")
177
+ block.call
178
+ end
179
+ end
180
+
181
+ def ssh_key_gateway(block)
182
+ ENV['DIRECTOR_IP_OVERRIDE'] = 'localhost'
183
+ uri = URI.parse(environment.settings.ops_manager.url)
184
+ director_ip = bosh_command.director_ip
185
+ Net::SSH::Gateway.new(
186
+ uri.host,
187
+ 'ubuntu',
188
+ key_data: [ssh_key]
189
+ ).open(director_ip, 25_555, 25_555) do |_|
190
+ logger.info("Opened tunnel to MicroBOSH at #{director_ip}")
191
+ block.call
192
+ end
193
+ end
194
+
195
+ def ssh_key
196
+ case environment.settings.iaas_type
197
+ when 'aws'
198
+ environment.settings.ops_manager.aws.ssh_key
199
+ when 'openstack'
200
+ environment.settings.ops_manager.openstack.ssh_private_key
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
207
+ # All rights reserved.
208
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
209
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
210
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
211
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
212
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
213
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ require 'opsmgr/log'
2
+
3
+ module Opsmgr
4
+ module Cmd
5
+ class OpsManager
6
+ include Loggable
7
+
8
+ def initialize(target_environment)
9
+ @environment = target_environment
10
+ end
11
+
12
+ def configure_microbosh_infrastructure(client)
13
+ result = client.installation_settings
14
+ return unless result.success?
15
+
16
+ result = result.as_hash
17
+ return if result.fetch('installation_version', '') != '1.4'
18
+ return if result['infrastructure']['type'] != 'vsphere'
19
+
20
+ result['infrastructure']['file_system'] = {
21
+ 'microbosh_vm_folder' => environment.settings.name,
22
+ 'microbosh_template_folder' => environment.settings.name,
23
+ 'microbosh_disk_path' => environment.settings.name,
24
+ }
25
+
26
+ file = Tempfile.new('om_install_settings')
27
+ file.write(YAML.dump(result))
28
+ file.close
29
+
30
+ client.upload_product_installation_settings(file.path)
31
+ end
32
+
33
+ def delete_unused_products(client)
34
+ result = client.delete_unused_products
35
+ if result.success?
36
+ log.info 'Successfully deleted unused products'
37
+ else
38
+ fail result.message
39
+ end
40
+ end
41
+
42
+ def upload_product(client, path)
43
+ result = client.upload_component(path)
44
+ if result.success?
45
+ log.info 'Successfully uploaded product'
46
+ else
47
+ fail result.message
48
+ end
49
+ end
50
+
51
+ def list_products(client)
52
+ result = client.list_products
53
+ if result.success?
54
+ result
55
+ else
56
+ fail result.message
57
+ end
58
+ end
59
+
60
+ def add_product(client, name, version)
61
+ result = client.add_product(name, version)
62
+ if result.success?
63
+ log.info 'Successfully added product'
64
+ else
65
+ fail result.message
66
+ end
67
+ end
68
+
69
+ def upgrade_product(client, guid, version)
70
+ result = client.upgrade_product(guid, version)
71
+ if result.success?
72
+ log.info 'Successfully upgraded product'
73
+ else
74
+ fail result.message
75
+ end
76
+ end
77
+
78
+ def installed_products(client)
79
+ result = client.installed_products
80
+ if result.success?
81
+ result
82
+ else
83
+ fail result.message
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ attr_reader :environment
90
+ end
91
+ end
92
+ end
93
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
94
+ # All rights reserved.
95
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
96
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
97
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
98
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
99
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
100
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,77 @@
1
+ require 'recursive-open-struct'
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+ require 'erb'
6
+ require 'yaml'
7
+ require 'opsmgr/renderer'
8
+
9
+ module Opsmgr
10
+ class Environments
11
+ def self.for(name = '')
12
+ env_config = config_file(directory, config_filename(name))
13
+ unless File.exist?(env_config)
14
+ raise "No environments config found in #{env_config}. Specify path using ENV_DIRECTORY or ENV_CONFIG_FILE."
15
+ end
16
+
17
+ new(env_config, name)
18
+ end
19
+
20
+ def self.list
21
+ Dir.glob(config_file(directory, '*')).map do |path|
22
+ fname = File.basename(path, '.*')
23
+ if fname == 'metadata'
24
+ string_keyed_hash = YAML.load(File.read(path))
25
+ string_keyed_hash['name'].to_sym
26
+ else
27
+ fname.to_sym
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.directory
33
+ ENV.fetch('ENV_DIRECTORY', File.join(Dir.pwd, '../environment/'))
34
+ end
35
+
36
+ def self.config_filename(name)
37
+ ENV.key?('ENV_DIRECTORY') ? "#{name}.yml" : 'metadata'
38
+ end
39
+
40
+ def self.config_file(dir, name)
41
+ ENV.fetch('ENV_CONFIG_FILE', File.join(dir, name))
42
+ end
43
+
44
+ def initialize(config_path, env_name = '')
45
+ @config_path = config_path
46
+ @env_name = env_name
47
+ end
48
+
49
+ def settings_with_merged_folders(installation_settings)
50
+ return settings unless installation_settings['infrastructure']['file_system']
51
+ file_system = installation_settings['infrastructure']['file_system']
52
+
53
+ settings_to_modify = settings
54
+ settings_to_modify.vm_shepherd.vm_configs[0].cleanup.datacenter_folders_to_clean << file_system['microbosh_vm_folder']
55
+ settings_to_modify.vm_shepherd.vm_configs[0].cleanup.datacenter_folders_to_clean << file_system['microbosh_template_folder']
56
+ settings_to_modify.vm_shepherd.vm_configs[0].cleanup.datastore_folders_to_clean << file_system['microbosh_disk_path']
57
+ settings_to_modify
58
+ end
59
+
60
+ def settings
61
+ string_keyed_hash = YAML.load(Renderer.for(File.read(@config_path)).rendered_settings)
62
+ unless @env_name == '' || string_keyed_hash['name'] == @env_name
63
+ raise "Specified name #{@env_name} does not match name in #{@config_path}"
64
+ end
65
+
66
+ RecursiveOpenStruct.new(string_keyed_hash, recurse_over_arrays: true)
67
+ end
68
+ end
69
+ end
70
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
71
+ # All rights reserved.
72
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
73
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
74
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
75
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
76
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
77
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.