prof 0.29.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LEGAL +13 -0
- data/lib/prof/cloud_foundry.rb +145 -0
- data/lib/prof/environment/cloud_foundry.rb +150 -0
- data/lib/prof/environment/pcf_drinks.rb +156 -0
- data/lib/prof/environment_manager.rb +93 -0
- data/lib/prof/external_spec/helpers/capybara.rb +58 -0
- data/lib/prof/external_spec/helpers/debug.rb +53 -0
- data/lib/prof/external_spec/helpers/file_helper.rb +35 -0
- data/lib/prof/external_spec/helpers/product_path.rb +23 -0
- data/lib/prof/external_spec/shared_examples/deployment.rb +23 -0
- data/lib/prof/external_spec/shared_examples/ops_manager_upgrade.rb +32 -0
- data/lib/prof/external_spec/shared_examples/service.rb +105 -0
- data/lib/prof/external_spec/shared_examples/service_broker.rb +25 -0
- data/lib/prof/external_spec/spec_helper.rb +35 -0
- data/lib/prof/marketplace_service.rb +20 -0
- data/lib/prof/matchers/metadata.rb +180 -0
- data/lib/prof/matchers/only_support_ssl_with_cipher_set.rb +102 -0
- data/lib/prof/matchers/ssl.rb +67 -0
- data/lib/prof/matchers/tile_configuration.rb +47 -0
- data/lib/prof/ops_manager/rails_500_error.rb +15 -0
- data/lib/prof/ops_manager/web_app_internals/page/checkbox_field.rb +38 -0
- data/lib/prof/ops_manager/web_app_internals/page/click_field.rb +40 -0
- data/lib/prof/ops_manager/web_app_internals/page/dashboard.rb +100 -0
- data/lib/prof/ops_manager/web_app_internals/page/flash_message.rb +53 -0
- data/lib/prof/ops_manager/web_app_internals/page/form.rb +130 -0
- data/lib/prof/ops_manager/web_app_internals/page/form_error.rb +43 -0
- data/lib/prof/ops_manager/web_app_internals/page/form_field.rb +51 -0
- data/lib/prof/ops_manager/web_app_internals/page/form_fields.rb +35 -0
- data/lib/prof/ops_manager/web_app_internals/page/installation_progress.rb +149 -0
- data/lib/prof/ops_manager/web_app_internals/page/login.rb +53 -0
- data/lib/prof/ops_manager/web_app_internals/page/modal.rb +85 -0
- data/lib/prof/ops_manager/web_app_internals/page/rails_500.rb +41 -0
- data/lib/prof/ops_manager/web_app_internals/page/select_field.rb +27 -0
- data/lib/prof/ops_manager/web_app_internals/page/tile_settings.rb +105 -0
- data/lib/prof/ops_manager/web_app_internals.rb +63 -0
- data/lib/prof/ops_manager.rb +141 -0
- data/lib/prof/ops_manager_log_fetcher.rb +30 -0
- data/lib/prof/product.rb +59 -0
- data/lib/prof/pushed_test_app.rb +40 -0
- data/lib/prof/service_instance.rb +21 -0
- data/lib/prof/ssh_gateway.rb +104 -0
- data/lib/prof/ssl/check.rb +79 -0
- data/lib/prof/ssl/cipher_set.rb +56 -0
- data/lib/prof/ssl/result.rb +27 -0
- data/lib/prof/ssl/results.rb +74 -0
- data/lib/prof/test_app.rb +19 -0
- data/lib/prof/tile.rb +25 -0
- data/lib/prof/uaa_client.rb +66 -0
- data/lib/prof/version.rb +13 -0
- metadata +403 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 40bcbedb4a82be8debb7fb4b120faa9ea9480d10
|
4
|
+
data.tar.gz: b3660e7602268aaa31f487c29e5b8820d85f4dab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 105928b4e69b0d47da3ae17a2e591bd09aa417899b2721297ae85d65387f755ed50e15252af1581bc8c0152d76242d25e0705797c9b1a2fb3167634432e26a92
|
7
|
+
data.tar.gz: 715dd614e05306fa15711845cfb03a54132e025211c5c1c0aceb87a38f4c0d8ec37cc7ced1bb02f4a6a177ab40463430bd700235a2d59a7ad4023be19d0d500e
|
data/LEGAL
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.
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Pivotal Software, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
4
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
5
|
+
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
6
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
8
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'forwardable'
|
12
|
+
require 'hula/cloud_foundry'
|
13
|
+
|
14
|
+
require 'prof/marketplace_service'
|
15
|
+
require 'prof/pushed_test_app'
|
16
|
+
require 'prof/service_instance'
|
17
|
+
|
18
|
+
module Prof
|
19
|
+
class CloudFoundry
|
20
|
+
extend Forwardable
|
21
|
+
|
22
|
+
attr_reader :api_url, :domain, :username, :password
|
23
|
+
|
24
|
+
def_delegators :hula_cloud_foundry,
|
25
|
+
:add_public_service_broker,
|
26
|
+
:app_env,
|
27
|
+
:create_org,
|
28
|
+
:target_org,
|
29
|
+
:create_space,
|
30
|
+
:target_space,
|
31
|
+
:create_and_target_org,
|
32
|
+
:create_and_target_space,
|
33
|
+
:create_service_instance,
|
34
|
+
:delete_org,
|
35
|
+
:delete_space,
|
36
|
+
:delete_service_instance_and_unbind,
|
37
|
+
:push_app_and_start,
|
38
|
+
:remove_service_broker,
|
39
|
+
:service_brokers,
|
40
|
+
:setup_permissive_security_group,
|
41
|
+
:app_vcap_services,
|
42
|
+
:marketplace
|
43
|
+
|
44
|
+
def initialize(opts = {})
|
45
|
+
@domain = opts.fetch(:domain)
|
46
|
+
@api_url = opts.fetch(:api_url) { "https://api.#{domain}" }
|
47
|
+
@username = opts.fetch(:username)
|
48
|
+
@password = opts.fetch(:password)
|
49
|
+
end
|
50
|
+
|
51
|
+
def push_app(app, &_block)
|
52
|
+
pushed_app_name = "cf-app-#{SecureRandom.hex(4)}"
|
53
|
+
deployed_app = PushedTestApp.new(name: pushed_app_name, url: hula_cloud_foundry.url_for_app(pushed_app_name))
|
54
|
+
|
55
|
+
hula_cloud_foundry.push_app(app.path, deployed_app.name)
|
56
|
+
|
57
|
+
yield deployed_app
|
58
|
+
ensure
|
59
|
+
hula_cloud_foundry.delete_app deployed_app.name
|
60
|
+
end
|
61
|
+
|
62
|
+
def enable_diego_and_start_app(app)
|
63
|
+
hula_cloud_foundry.enable_diego_for_app(app.name)
|
64
|
+
hula_cloud_foundry.start_app(app.name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def push_app_and_bind_with_service(app, service, &_block)
|
68
|
+
push_app(app) do |pushed_app|
|
69
|
+
provision_service(service) do |service_instance|
|
70
|
+
bind_service_and_run(pushed_app, service_instance) do
|
71
|
+
yield pushed_app, service_instance
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def push_app_and_bind_with_service_instance(app, service_instance, &_block)
|
78
|
+
push_app(app) do |pushed_app|
|
79
|
+
bind_service_and_run(pushed_app, service_instance) do
|
80
|
+
yield pushed_app, service_instance
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def bind_service_and_run(pushed_app, service_instance, &_block)
|
86
|
+
hula_cloud_foundry.bind_app_to_service(pushed_app.name, service_instance.name)
|
87
|
+
hula_cloud_foundry.start_app(pushed_app.name)
|
88
|
+
|
89
|
+
yield
|
90
|
+
|
91
|
+
hula_cloud_foundry.unbind_app_from_service(pushed_app.name, service_instance.name)
|
92
|
+
end
|
93
|
+
|
94
|
+
def provision_and_create_service_key(service, &_block)
|
95
|
+
provision_service(service) do |service_instance|
|
96
|
+
create_service_key(service_instance) do |service_key, service_key_data|
|
97
|
+
yield service_instance, service_key, service_key_data
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def list_service_keys(service_instance)
|
103
|
+
hula_cloud_foundry.list_service_keys(service_instance.name)
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_service_key(service_instance, &_block)
|
107
|
+
service_key_name = "#{service_instance.name}-#{SecureRandom.hex(4)}"
|
108
|
+
hula_cloud_foundry.create_service_key(service_instance.name, service_key_name)
|
109
|
+
service_key_raw = hula_cloud_foundry.service_key(service_instance.name, service_key_name)
|
110
|
+
service_key_data = JSON.parse(
|
111
|
+
service_key_raw.split("\n").slice(2..-1).join
|
112
|
+
)
|
113
|
+
|
114
|
+
yield service_key_name, service_key_data
|
115
|
+
|
116
|
+
hula_cloud_foundry.delete_service_key(service_instance.name, service_key_name)
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_service_key(service_instance, service_key)
|
120
|
+
hula_cloud_foundry.delete_service_key(service_instance.name, service_key)
|
121
|
+
end
|
122
|
+
|
123
|
+
def provision_service(service, &_block)
|
124
|
+
service_instance = ServiceInstance.new
|
125
|
+
|
126
|
+
hula_cloud_foundry.create_service_instance(service.name, service_instance.name, service.plan)
|
127
|
+
|
128
|
+
yield service_instance if block_given?
|
129
|
+
|
130
|
+
ensure
|
131
|
+
hula_cloud_foundry.delete_service_instance_and_unbind(service_instance.name)
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def hula_cloud_foundry
|
137
|
+
@hula_cloud_foundry ||= Hula::CloudFoundry.new(
|
138
|
+
api_url: api_url,
|
139
|
+
domain: domain,
|
140
|
+
username: username,
|
141
|
+
password: password
|
142
|
+
)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Pivotal Software, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
4
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
5
|
+
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
6
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
8
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'hula/bosh_director'
|
12
|
+
require 'hula/service_broker/client'
|
13
|
+
require 'hula/bosh_manifest'
|
14
|
+
require 'hula/socks4_proxy_ssh'
|
15
|
+
require 'hula/http_proxy_upstream_socks'
|
16
|
+
|
17
|
+
require 'prof/cloud_foundry'
|
18
|
+
require 'prof/ssh_gateway'
|
19
|
+
require 'prof/uaa_client'
|
20
|
+
|
21
|
+
module Prof
|
22
|
+
module Environment
|
23
|
+
class CloudFoundry
|
24
|
+
attr_reader :bosh_service_broker_job_name
|
25
|
+
|
26
|
+
def initialize(
|
27
|
+
cloud_foundry_domain: nil,
|
28
|
+
|
29
|
+
cloud_controller_identity: 'cloud_controller',
|
30
|
+
cloud_controller_password: 'cc-secret',
|
31
|
+
|
32
|
+
cloud_foundry_username: 'admin',
|
33
|
+
cloud_foundry_password: 'admin',
|
34
|
+
cloud_foundry_api_url: nil,
|
35
|
+
|
36
|
+
bosh_target: 'https://192.168.50.4:25555',
|
37
|
+
bosh_username: 'admin',
|
38
|
+
bosh_password: 'admin',
|
39
|
+
|
40
|
+
ssh_gateway_host: '192.168.50.4',
|
41
|
+
ssh_gateway_username: 'vagrant',
|
42
|
+
ssh_gateway_password: 'vagrant',
|
43
|
+
|
44
|
+
bosh_service_broker_job_name:,
|
45
|
+
bosh_manifest_path:,
|
46
|
+
|
47
|
+
use_proxy: true
|
48
|
+
)
|
49
|
+
@cloud_foundry_domain = cloud_foundry_domain
|
50
|
+
@cloud_controller_identity = cloud_controller_identity
|
51
|
+
@cloud_controller_password = cloud_controller_password
|
52
|
+
@cloud_foundry_username = cloud_foundry_username
|
53
|
+
@cloud_foundry_password = cloud_foundry_password
|
54
|
+
@bosh_target = bosh_target
|
55
|
+
@bosh_username = bosh_username
|
56
|
+
@bosh_password = bosh_password
|
57
|
+
@ssh_gateway_host = ssh_gateway_host
|
58
|
+
@ssh_gateway_username = ssh_gateway_username
|
59
|
+
@ssh_gateway_password = ssh_gateway_password
|
60
|
+
@bosh_service_broker_job_name = bosh_service_broker_job_name
|
61
|
+
@bosh_manifest_path = bosh_manifest_path
|
62
|
+
@cloud_foundry_api_url = cloud_foundry_api_url
|
63
|
+
@use_proxy = use_proxy
|
64
|
+
end
|
65
|
+
|
66
|
+
def cloud_foundry
|
67
|
+
@cloud_foundry ||= ::Prof::CloudFoundry.new(
|
68
|
+
domain: cloud_foundry_domain,
|
69
|
+
username: cloud_foundry_username,
|
70
|
+
password: cloud_foundry_password,
|
71
|
+
api_url: cloud_foundry_api_url
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def bosh_manifest
|
76
|
+
@bosh_manifest ||= Hula::BoshManifest.from_file(bosh_manifest_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
def cloud_foundry_domain
|
80
|
+
@cloud_foundry_domain ||= bosh_manifest.property('cf.domain')
|
81
|
+
end
|
82
|
+
|
83
|
+
def service_broker
|
84
|
+
@service_broker ||= Hula::ServiceBroker::Client.new(
|
85
|
+
url: URI::HTTPS.build(host: broker_registrar_properties.fetch('host')),
|
86
|
+
username: broker_registrar_properties.fetch('username'),
|
87
|
+
password: broker_registrar_properties.fetch('password'),
|
88
|
+
http_client: http_json_client(use_proxy: use_proxy)
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def service_broker_name
|
93
|
+
broker_registrar_properties.fetch('name')
|
94
|
+
end
|
95
|
+
|
96
|
+
def bosh_director
|
97
|
+
@bosh_director ||= Hula::BoshDirector.new(
|
98
|
+
target_url: bosh_target,
|
99
|
+
username: bosh_username,
|
100
|
+
password: bosh_password,
|
101
|
+
manifest_path: bosh_manifest_path
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
def ssh_gateway
|
106
|
+
@ssh_gateway ||= SshGateway.new(
|
107
|
+
gateway_host: ssh_gateway_host,
|
108
|
+
gateway_username: ssh_gateway_username,
|
109
|
+
gateway_password: ssh_gateway_password
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
def cloud_foundry_uaa
|
114
|
+
@cloud_foundry_uaa ||= UAAClient.new(
|
115
|
+
cloud_foundry_domain,
|
116
|
+
cloud_controller_identity,
|
117
|
+
cloud_controller_password
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
def socks4_proxy
|
122
|
+
@socks4_proxy ||= Hula::Socks4ProxySsh.new(
|
123
|
+
ssh_username: ssh_gateway_username,
|
124
|
+
ssh_password: ssh_gateway_password,
|
125
|
+
ssh_host: ssh_gateway_host
|
126
|
+
).tap(&:start)
|
127
|
+
end
|
128
|
+
|
129
|
+
def http_proxy
|
130
|
+
@http_proxy ||= Hula::HttpProxyUpstreamSocks.new(socks_proxy: socks4_proxy).tap(&:start)
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
attr_reader :cloud_controller_identity, :cloud_controller_password,
|
136
|
+
:cloud_foundry_username, :cloud_foundry_password, :bosh_target, :bosh_username, :bosh_password,
|
137
|
+
:ssh_gateway_host, :ssh_gateway_username, :ssh_gateway_password, :bosh_manifest_path,
|
138
|
+
:cloud_foundry_api_url, :use_proxy
|
139
|
+
|
140
|
+
def broker_registrar_properties
|
141
|
+
bosh_manifest.job('broker-registrar').properties.fetch('broker')
|
142
|
+
end
|
143
|
+
|
144
|
+
def http_json_client(use_proxy:)
|
145
|
+
proxy = use_proxy ? http_proxy : Hula::ServiceBroker::HttpProxyNull.new
|
146
|
+
@http_json_client ||= Hula::ServiceBroker::HttpJsonClient.new(http_proxy: proxy)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Pivotal Software, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
4
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
5
|
+
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
6
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
8
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'uri'
|
12
|
+
require 'hula/bosh_director'
|
13
|
+
require 'capybara'
|
14
|
+
|
15
|
+
require 'prof/cloud_foundry'
|
16
|
+
require 'prof/ops_manager'
|
17
|
+
require 'prof/ops_manager_log_fetcher'
|
18
|
+
require 'prof/ssh_gateway'
|
19
|
+
require 'prof/uaa_client'
|
20
|
+
|
21
|
+
module Prof
|
22
|
+
module Environment
|
23
|
+
class NoDirectorVm < StandardError; end
|
24
|
+
|
25
|
+
class PcfDrinks
|
26
|
+
def initialize(tempest_config, page: default_capybara_session)
|
27
|
+
@tempest_config = tempest_config
|
28
|
+
@page = page
|
29
|
+
end
|
30
|
+
|
31
|
+
def ops_manager
|
32
|
+
@ops_manager ||= OpsManager.new(ops_manager_config.merge(page: page))
|
33
|
+
end
|
34
|
+
|
35
|
+
def cloud_foundry
|
36
|
+
@cloud_foundry ||= CloudFoundry.new(
|
37
|
+
domain: cloud_foundry_domain,
|
38
|
+
username: cloud_foundry_credentials.username,
|
39
|
+
password: cloud_foundry_credentials.password
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def cloud_foundry_domain
|
44
|
+
tempest_config.fetch(:cloudfoundry).fetch(:domain)
|
45
|
+
end
|
46
|
+
|
47
|
+
def bosh_director
|
48
|
+
@bosh_director ||= Hula::BoshDirector.new(
|
49
|
+
target_url: bosh_director_url,
|
50
|
+
username: bosh_credentials.fetch('identity'),
|
51
|
+
password: bosh_credentials.fetch('password')
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def ssh_gateway
|
56
|
+
SshGateway.new(
|
57
|
+
gateway_host: ssh_gateway_config.fetch(:host),
|
58
|
+
gateway_username: ssh_gateway_config.fetch(:username),
|
59
|
+
gateway_password: ssh_gateway_config[:password],
|
60
|
+
ssh_key: ssh_gateway_config[:ssh_key]
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def cloud_foundry_uaa
|
65
|
+
@cloud_foundry_uaa ||= UAAClient.new(
|
66
|
+
cloud_foundry_domain,
|
67
|
+
cloud_controller_client_credentials.identity,
|
68
|
+
cloud_controller_client_credentials.password
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
attr_reader :tempest_config, :page
|
75
|
+
|
76
|
+
def default_capybara_session
|
77
|
+
Capybara::Session.new(Capybara.default_driver)
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_fetcher
|
81
|
+
OpsManagerLogFetcher.new(
|
82
|
+
ssh_gateway: ssh_gateway,
|
83
|
+
host: ops_manager_hostname,
|
84
|
+
username: ops_manager_vm_config.fetch(:username),
|
85
|
+
password: ops_manager_vm_config.fetch(:password)
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def cloud_controller_client_credentials
|
90
|
+
@cloud_controller_client_credentials ||= ops_manager.cc_client_credentials
|
91
|
+
end
|
92
|
+
|
93
|
+
def forwarded_bosh_port
|
94
|
+
@forwarded_bosh_port ||=
|
95
|
+
ssh_gateway.with_port_forwarded_to(
|
96
|
+
director.hostname,
|
97
|
+
25555
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
def director
|
102
|
+
director = ops_manager.vms_for_job_type('director').first
|
103
|
+
|
104
|
+
if director.nil?
|
105
|
+
raise NoDirectorVm, "No director VM found for #{ops_manager.url}"
|
106
|
+
else
|
107
|
+
director
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def ops_manager_hostname
|
112
|
+
URI.parse(ops_manager_config.fetch(:url)).hostname
|
113
|
+
end
|
114
|
+
|
115
|
+
def ops_manager_config
|
116
|
+
tempest_config.fetch(:tempest)
|
117
|
+
end
|
118
|
+
|
119
|
+
def ops_manager_vm_config
|
120
|
+
tempest_config.fetch(:tempest_vm)
|
121
|
+
end
|
122
|
+
|
123
|
+
def ssh_gateway_config
|
124
|
+
tempest_config.fetch(:proxy)
|
125
|
+
end
|
126
|
+
|
127
|
+
def bosh_director_url
|
128
|
+
return URI("https://127.0.0.1:#{forwarded_bosh_port}").to_s if !tempest_config[:proxy].nil?
|
129
|
+
return director.hostname
|
130
|
+
end
|
131
|
+
|
132
|
+
def bosh_product
|
133
|
+
# old versions of OpsMan (< v1.6 RC4)
|
134
|
+
@bosh_product ||= ops_manager
|
135
|
+
.send(:opsmanager_client)
|
136
|
+
.send(:product, 'microbosh')
|
137
|
+
|
138
|
+
# newer versions of OpsMan (>= v1.6 RC4)
|
139
|
+
@bosh_product ||= ops_manager
|
140
|
+
.send(:opsmanager_client)
|
141
|
+
.send(:product, 'p-bosh')
|
142
|
+
end
|
143
|
+
|
144
|
+
def bosh_credentials
|
145
|
+
# TODO: push this code into ops manager
|
146
|
+
@bosh_credentials ||= bosh_product
|
147
|
+
.job_of_type('director')
|
148
|
+
.properties.fetch('director_credentials')
|
149
|
+
end
|
150
|
+
|
151
|
+
def cloud_foundry_credentials
|
152
|
+
@cloud_foundry_credentials ||= ops_manager.cf_admin_credentials
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Pivotal Software, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
4
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
5
|
+
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
6
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
8
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
#
|
10
|
+
|
11
|
+
module Prof
|
12
|
+
class EnvironmentManager
|
13
|
+
class OpsManagerNotConfigured < StandardError; end
|
14
|
+
|
15
|
+
def initialize(pcf_environment)
|
16
|
+
@pcf_environment = pcf_environment
|
17
|
+
end
|
18
|
+
|
19
|
+
def isolate_cloud_foundry(&_block)
|
20
|
+
cloud_foundry.create_and_target_org(cf_org_name)
|
21
|
+
cloud_foundry.create_and_target_space(cf_space_name)
|
22
|
+
cloud_foundry.setup_permissive_security_group(cf_org_name, cf_space_name)
|
23
|
+
|
24
|
+
yield
|
25
|
+
|
26
|
+
cloud_foundry.delete_org(cf_org_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy_orphan_tiles
|
30
|
+
orphans = orphan_tiles
|
31
|
+
return unless orphans.any?
|
32
|
+
|
33
|
+
puts "Removing orphaned tile(s) #{orphans.map(&:name).join(', ')}"
|
34
|
+
ops_manager.uninstall_tiles(orphans)
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy_orphan_deployments
|
38
|
+
orphans = orphan_deployments
|
39
|
+
return unless orphans.any?
|
40
|
+
|
41
|
+
puts "Removing orphaned deployment(s) '#{orphans.join(', ')}'"
|
42
|
+
orphans.each do |deployment_name|
|
43
|
+
bosh_director.delete_deployment(deployment_name, force: true)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def uninstall_tiles
|
48
|
+
ops_manager.uninstall_tiles(ops_manager.product_tiles)
|
49
|
+
end
|
50
|
+
|
51
|
+
def reset
|
52
|
+
raise OpsManagerNotConfigured, "Please configure #{ops_manager.url}" unless ops_manager.cf_installed?
|
53
|
+
|
54
|
+
destroy_orphan_tiles
|
55
|
+
destroy_orphan_deployments
|
56
|
+
uninstall_tiles
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_reader :pcf_environment
|
62
|
+
|
63
|
+
def cf_org_name
|
64
|
+
@cf_org_name ||= "cf-org-#{SecureRandom.hex(4)}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def cf_space_name
|
68
|
+
@cf_space_name ||= "cf-space-#{SecureRandom.hex(4)}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def cloud_foundry
|
72
|
+
pcf_environment.cloud_foundry
|
73
|
+
end
|
74
|
+
|
75
|
+
def ops_manager
|
76
|
+
pcf_environment.ops_manager
|
77
|
+
end
|
78
|
+
|
79
|
+
def orphan_deployments
|
80
|
+
tile_guids = pcf_environment.ops_manager.tiles.map(&:guid)
|
81
|
+
pcf_environment.bosh_director.deployment_names.reject { |deployment_name| tile_guids.include?(deployment_name) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def orphan_tiles
|
85
|
+
bosh_deployment_names = pcf_environment.bosh_director.deployment_names
|
86
|
+
pcf_environment.ops_manager.product_tiles.reject { |tile| bosh_deployment_names.include?(tile.guid) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def bosh_director
|
90
|
+
pcf_environment.bosh_director
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Pivotal Software, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
4
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
5
|
+
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
6
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
8
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'capybara/rspec'
|
12
|
+
require 'capybara/query'
|
13
|
+
require 'capybara/poltergeist'
|
14
|
+
require 'capybara/webkit'
|
15
|
+
|
16
|
+
module Prof
|
17
|
+
module ExternalSpec
|
18
|
+
module Helpers
|
19
|
+
module Capybara
|
20
|
+
def setup_browser(driver = :poltergeist)
|
21
|
+
unless %i{poltergeist webkit}.include?(driver)
|
22
|
+
raise StandardError.new("invalid driver")
|
23
|
+
end
|
24
|
+
|
25
|
+
::Capybara.default_wait_time = 60
|
26
|
+
::Capybara.default_driver = driver
|
27
|
+
::Capybara.javascript_driver = driver
|
28
|
+
|
29
|
+
::Capybara.register_driver :poltergeist do |app|
|
30
|
+
::Capybara::Poltergeist::Driver.new(
|
31
|
+
app,
|
32
|
+
debug: ENV.key?('DEBUG'),
|
33
|
+
timeout: 240,
|
34
|
+
js_errors: false,
|
35
|
+
phantomjs_logger: null_io_object,
|
36
|
+
phantomjs_options: ['--ignore-ssl-errors=yes'],
|
37
|
+
window_size: [1300, 1000]
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
::Capybara.register_driver :webkit do |app|
|
42
|
+
::Capybara::Webkit::Driver.new(app).tap do |d|
|
43
|
+
d.browser.ignore_ssl_errors
|
44
|
+
d.browser.allow_url('*')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def null_io_object
|
50
|
+
f = File.open('/dev/null')
|
51
|
+
io = IO.for_fd(f.fileno)
|
52
|
+
io.autoclose = true
|
53
|
+
io
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright (c) 2014-2015 Pivotal Software, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
4
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
5
|
+
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
6
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
7
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
8
|
+
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
#
|
10
|
+
|
11
|
+
module Prof
|
12
|
+
module ExternalSpec
|
13
|
+
module Helpers
|
14
|
+
module Debug
|
15
|
+
|
16
|
+
def recording_exceptions
|
17
|
+
yield
|
18
|
+
rescue Exception => ex
|
19
|
+
@recorded_exception = ex
|
20
|
+
raise
|
21
|
+
end
|
22
|
+
|
23
|
+
def save_exceptions
|
24
|
+
yield
|
25
|
+
rescue Exception => ex
|
26
|
+
ops_manager.browser do |page|
|
27
|
+
name = "failure"
|
28
|
+
puts "Saving failure data for '#{name}'"
|
29
|
+
page.save_page("#{name}.html")
|
30
|
+
page.save_screenshot("#{name}.png")
|
31
|
+
end
|
32
|
+
raise
|
33
|
+
end
|
34
|
+
|
35
|
+
def save_exception_output(example)
|
36
|
+
unless @recorded_exception
|
37
|
+
return unless example.respond_to?(:exception)
|
38
|
+
return unless example.respond_to?(:full_description)
|
39
|
+
return unless respond_to?(:ops_manager)
|
40
|
+
return unless example.exception
|
41
|
+
end
|
42
|
+
|
43
|
+
ops_manager.browser do |page|
|
44
|
+
name = example.full_description.gsub(/\W/, '_')
|
45
|
+
puts "Saving failure data for '#{name}'"
|
46
|
+
page.save_page("#{name}.html")
|
47
|
+
page.save_screenshot("#{name}.png")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|