hula 0.7.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.
- checksums.yaml +7 -0
- data/LEGAL +13 -0
- data/lib/hula/bosh_director.rb +246 -0
- data/lib/hula/bosh_manifest/job.rb +35 -0
- data/lib/hula/bosh_manifest.rb +102 -0
- data/lib/hula/cloud_foundry/service_broker.rb +36 -0
- data/lib/hula/cloud_foundry.rb +308 -0
- data/lib/hula/command_runner.rb +38 -0
- data/lib/hula/helpers/socket_tools.rb +44 -0
- data/lib/hula/helpers/timeout_tools.rb +27 -0
- data/lib/hula/http_proxy_upstream_socks.rb +72 -0
- data/lib/hula/service_broker/api.rb +123 -0
- data/lib/hula/service_broker/catalog.rb +43 -0
- data/lib/hula/service_broker/client.rb +69 -0
- data/lib/hula/service_broker/errors.rb +24 -0
- data/lib/hula/service_broker/http_json_client.rb +90 -0
- data/lib/hula/service_broker/instance_binding.rb +30 -0
- data/lib/hula/service_broker/plan.rb +32 -0
- data/lib/hula/service_broker/service.rb +47 -0
- data/lib/hula/service_broker/service_instance.rb +24 -0
- data/lib/hula/socks4_proxy_ssh.rb +118 -0
- data/lib/hula/version.rb +13 -0
- data/lib/hula.rb +16 -0
- metadata +235 -0
@@ -0,0 +1,69 @@
|
|
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/service_broker/api'
|
12
|
+
|
13
|
+
require 'forwardable'
|
14
|
+
|
15
|
+
module Hula
|
16
|
+
module ServiceBroker
|
17
|
+
class Client
|
18
|
+
|
19
|
+
extend Forwardable
|
20
|
+
def_delegators :api,
|
21
|
+
:catalog,
|
22
|
+
:debug,
|
23
|
+
:deprovision_instance,
|
24
|
+
:bind_instance,
|
25
|
+
:unbind_instance,
|
26
|
+
:url
|
27
|
+
|
28
|
+
def initialize(args = {})
|
29
|
+
api_args = args.reject { |k, _v| k == :api }
|
30
|
+
@api = args.fetch(:api) { Api.new(api_args) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def provision_and_bind(service_name, plan_name, &block)
|
34
|
+
raise Error, 'no block given' unless block_given?
|
35
|
+
provision_instance(service_name, plan_name) do |service_instance|
|
36
|
+
bind_instance(service_instance, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def provision_instance(service_name, plan_name, &block)
|
41
|
+
plan = catalog.service_plan(service_name, plan_name)
|
42
|
+
service_instance = api.provision_instance(plan)
|
43
|
+
return service_instance unless block
|
44
|
+
|
45
|
+
begin
|
46
|
+
block.call(service_instance)
|
47
|
+
ensure
|
48
|
+
api.deprovision_instance(service_instance)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def bind_instance(service_instance, &block)
|
53
|
+
binding = api.bind_instance(service_instance)
|
54
|
+
return binding unless block
|
55
|
+
|
56
|
+
begin
|
57
|
+
block.call(binding, service_instance)
|
58
|
+
ensure
|
59
|
+
api.unbind_instance(binding)
|
60
|
+
sleep 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
attr_reader :api
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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 Hula
|
12
|
+
module ServiceBroker
|
13
|
+
class Error < StandardError; end
|
14
|
+
|
15
|
+
class NotInCatalog < Error; end
|
16
|
+
class PlanNotFoundError < NotInCatalog; end
|
17
|
+
class ServiceNotFoundError < NotInCatalog; end
|
18
|
+
|
19
|
+
class JsonParseError < Error; end
|
20
|
+
class TimeoutError < Error; end
|
21
|
+
class HTTPError < Error; end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,90 @@
|
|
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 'net/http'
|
12
|
+
|
13
|
+
require 'hula/service_broker/errors'
|
14
|
+
|
15
|
+
module Hula
|
16
|
+
module ServiceBroker
|
17
|
+
|
18
|
+
class HttpProxyNull
|
19
|
+
def http_host
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
def http_port
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class HttpJsonClient
|
28
|
+
def initialize(http_proxy: HttpProxyNull.new)
|
29
|
+
@http_proxy = http_proxy
|
30
|
+
end
|
31
|
+
|
32
|
+
def get(uri, auth: nil)
|
33
|
+
request = Net::HTTP::Get.new(uri)
|
34
|
+
request.basic_auth auth.fetch(:username), auth.fetch(:password) unless auth.nil?
|
35
|
+
send_request(request)
|
36
|
+
end
|
37
|
+
|
38
|
+
def put(uri, body: nil, auth: nil)
|
39
|
+
request = Net::HTTP::Put.new(uri)
|
40
|
+
request.body = JSON.generate(body) if body
|
41
|
+
request.basic_auth auth.fetch(:username), auth.fetch(:password) unless auth.nil?
|
42
|
+
send_request(request)
|
43
|
+
end
|
44
|
+
|
45
|
+
def delete(uri, auth: nil)
|
46
|
+
request = Net::HTTP::Delete.new(uri)
|
47
|
+
request.basic_auth auth.fetch(:username), auth.fetch(:password) unless auth.nil?
|
48
|
+
send_request(request)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
attr_reader :http_proxy
|
54
|
+
|
55
|
+
def send_request(request)
|
56
|
+
uri = request.uri
|
57
|
+
make_request(uri.hostname, uri.port, uri.scheme, request)
|
58
|
+
end
|
59
|
+
|
60
|
+
def make_request(host, port, scheme, request)
|
61
|
+
response = Net::HTTP.start(
|
62
|
+
host,
|
63
|
+
port,
|
64
|
+
http_proxy.http_host,
|
65
|
+
http_proxy.http_port,
|
66
|
+
use_ssl: scheme == 'https',
|
67
|
+
verify_mode: OpenSSL::SSL::VERIFY_NONE
|
68
|
+
) { |http| http.request(request) }
|
69
|
+
|
70
|
+
handle(response)
|
71
|
+
rescue Timeout::Error => e
|
72
|
+
raise TimeoutError, e
|
73
|
+
end
|
74
|
+
|
75
|
+
def handle(response)
|
76
|
+
unless response.is_a?(Net::HTTPSuccess)
|
77
|
+
fail HTTPError, [
|
78
|
+
response.uri.to_s,
|
79
|
+
response.code,
|
80
|
+
response.body
|
81
|
+
].join("\n\n")
|
82
|
+
end
|
83
|
+
|
84
|
+
JSON.parse(response.body, symbolize_names: true)
|
85
|
+
rescue JSON::ParserError => e
|
86
|
+
raise JsonParseError, e
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 Hula
|
12
|
+
module ServiceBroker
|
13
|
+
class InstanceBinding
|
14
|
+
attr_reader :id, :credentials, :service_instance
|
15
|
+
|
16
|
+
def initialize(id:, credentials:, service_instance:)
|
17
|
+
@id = id
|
18
|
+
@credentials = credentials
|
19
|
+
@service_instance = service_instance
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
is_a?(other.class) &&
|
24
|
+
id == other.id &&
|
25
|
+
credentials == other.credentials &&
|
26
|
+
service_instance == other.service_instance
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
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 Hula
|
12
|
+
module ServiceBroker
|
13
|
+
class Plan
|
14
|
+
def initialize(args = {})
|
15
|
+
@id = args.fetch(:id)
|
16
|
+
@name = args.fetch(:name)
|
17
|
+
@description = args.fetch(:description)
|
18
|
+
@service_id = args.fetch(:service_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :id, :name, :description, :service_id
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
is_a?(other.class) &&
|
25
|
+
id == other.id &&
|
26
|
+
name == other.name &&
|
27
|
+
description == other.description &&
|
28
|
+
service_id == other.service_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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/service_broker/errors'
|
12
|
+
require 'hula/service_broker/plan'
|
13
|
+
|
14
|
+
module Hula
|
15
|
+
module ServiceBroker
|
16
|
+
class Service
|
17
|
+
def initialize(args = {})
|
18
|
+
@id = args.fetch(:id)
|
19
|
+
@name = args.fetch(:name)
|
20
|
+
@description = args.fetch(:description)
|
21
|
+
@bindable = !!args.fetch(:bindable)
|
22
|
+
@plans = args.fetch(:plans).map { |p| Plan.new(p.merge(service_id: self.id)) }
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :id, :name, :description, :bindable, :plans
|
26
|
+
|
27
|
+
def ==(other)
|
28
|
+
is_a?(other.class) &&
|
29
|
+
id == other.id &&
|
30
|
+
name == other.name &&
|
31
|
+
description == other.description &&
|
32
|
+
bindable == other.bindable &&
|
33
|
+
plans == other.plans
|
34
|
+
end
|
35
|
+
|
36
|
+
def plan(plan_name)
|
37
|
+
plans.find { |p| p.name == plan_name } or
|
38
|
+
fail(PlanNotFoundError, [
|
39
|
+
%{Unknown plan with name: #{plan_name.inspect}},
|
40
|
+
" Known plan names are: #{plans.map(&:name).inspect}"
|
41
|
+
].join("\n")
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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 Hula
|
12
|
+
module ServiceBroker
|
13
|
+
class ServiceInstance
|
14
|
+
def initialize(id:)
|
15
|
+
@id = id
|
16
|
+
end
|
17
|
+
attr_reader :id
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
is_a?(other.class) && id == other.id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,118 @@
|
|
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/helpers/socket_tools'
|
12
|
+
require 'pty'
|
13
|
+
require 'expect'
|
14
|
+
|
15
|
+
module Hula
|
16
|
+
class Socks4ProxySsh
|
17
|
+
class FailedToStart < StandardError; end
|
18
|
+
class DieSignal < StandardError; end
|
19
|
+
|
20
|
+
include Helpers::SocketTools
|
21
|
+
|
22
|
+
def initialize(
|
23
|
+
ssh_host:,
|
24
|
+
ssh_username:,
|
25
|
+
ssh_password:,
|
26
|
+
socks_host: 'localhost',
|
27
|
+
socks_port: free_port,
|
28
|
+
ssh_bin: 'ssh',
|
29
|
+
retry_count: 10
|
30
|
+
)
|
31
|
+
@ssh_bin = String(ssh_bin)
|
32
|
+
@ssh_host = String(ssh_host)
|
33
|
+
@ssh_username = String(ssh_username)
|
34
|
+
@ssh_password = String(ssh_password)
|
35
|
+
@socks_port = String(socks_port)
|
36
|
+
@socks_host = String(socks_host)
|
37
|
+
@retry_count = retry_count
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :socks_port, :socks_host
|
41
|
+
|
42
|
+
def stop
|
43
|
+
return unless @thread
|
44
|
+
@thread.raise(DieSignal)
|
45
|
+
@thread.join
|
46
|
+
@thread = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def start
|
50
|
+
@thread ||= begin
|
51
|
+
thread = start_ssh_socks_thread
|
52
|
+
wait_for_port(:host => socks_host, :port => socks_port, timeout_seconds: 30)
|
53
|
+
thread
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_reader :ssh_host, :ssh_username, :ssh_password, :ssh_bin
|
60
|
+
|
61
|
+
def start_ssh_socks_thread
|
62
|
+
# We need to shell out to ssh as this has a SOCKS proxy facility
|
63
|
+
# However, there's a problem. SSH does not provide an argument for passing in a password
|
64
|
+
# We don't have keys available so we need to use expect to feed the password into the prompt
|
65
|
+
Thread.new(
|
66
|
+
ssh_command,
|
67
|
+
ssh_password
|
68
|
+
) do |ssh_command, ssh_password|
|
69
|
+
tries_remaining = @retry_count
|
70
|
+
|
71
|
+
while true
|
72
|
+
puts "--- SSH Gateway attempt #{@retry_count + 1 - tries_remaining}"
|
73
|
+
sleep 1
|
74
|
+
|
75
|
+
begin
|
76
|
+
ssh_out, ssh_in, pid = PTY.spawn(*ssh_command)
|
77
|
+
# On BOSH lite a password is used, however on aws an identity is used
|
78
|
+
# The below statment will wait on a aws run and the pid is never returned
|
79
|
+
ssh_out.expect(/[Pp]assword\:/) { |r| ssh_in.print("#{ssh_password}\n") }
|
80
|
+
Process.wait(pid)
|
81
|
+
|
82
|
+
tries_remaining -= 1
|
83
|
+
if tries_remaining < 0
|
84
|
+
raise FailedToStart, "SSH finished early - SSH Socks Proxy could not be setup or failed"
|
85
|
+
end
|
86
|
+
rescue Errno::EIO
|
87
|
+
tries_remaining -= 1
|
88
|
+
# Can't read or write to dead process
|
89
|
+
|
90
|
+
if tries_remaining < 0
|
91
|
+
raise FailedToStart, "SSH finished early EIO - SSH Socks Proxy could not be setup or failed"
|
92
|
+
end
|
93
|
+
rescue DieSignal
|
94
|
+
Process.kill('KILL', pid) rescue Errno::ESRCH
|
95
|
+
Process.wait(pid) rescue Errno::ECHILD
|
96
|
+
break
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end.tap do |thread|
|
100
|
+
thread.abort_on_exception = true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def ssh_command
|
105
|
+
[
|
106
|
+
ssh_bin,
|
107
|
+
'-D', "#{socks_host}:#{socks_port}",
|
108
|
+
'-N',
|
109
|
+
"#{ssh_username}@#{ssh_host}",
|
110
|
+
'-o', 'UserKnownHostsFile=/dev/null',
|
111
|
+
'-o', 'StrictHostKeyChecking=no',
|
112
|
+
'-o', 'NumberOfPasswordPrompts=1',
|
113
|
+
'-o', 'StrictHostKeyChecking=no'
|
114
|
+
]
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
data/lib/hula/version.rb
ADDED
@@ -0,0 +1,13 @@
|
|
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 Hula
|
12
|
+
VERSION = '0.7.1'
|
13
|
+
end
|
data/lib/hula.rb
ADDED
@@ -0,0 +1,16 @@
|
|
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/version'
|
12
|
+
require 'hula/bosh_director'
|
13
|
+
require 'hula/cloud_foundry'
|
14
|
+
|
15
|
+
module Hula
|
16
|
+
end
|