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
@@ -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.