bosh_cli 1.3074.0 → 1.3087.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cli/base_command.rb +11 -4
- data/lib/cli/client/director.rb +34 -2
- data/lib/cli/commands/deployment.rb +3 -2
- data/lib/cli/commands/misc.rb +2 -2
- data/lib/cli/commands/ssh.rb +32 -47
- data/lib/cli/config.rb +3 -2
- data/lib/cli/ssh_session.rb +116 -0
- data/lib/cli/task_tracking/task_tracker.rb +2 -1
- data/lib/cli/version.rb +1 -1
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9baaebb2117962d1abb67eb395ba2511f70e2fab
|
4
|
+
data.tar.gz: a3d09e561bf02bc54b9d83862496ea116d1cce60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6e8bcec875f1365e972686cdb11f497f284022e7c94a1111be28c62e655ed9663e007d95082e5020afcde9698229d40ee7e6cc4f641aab17311b715d0e51cd5
|
7
|
+
data.tar.gz: 5590a84655a049ceca953160d4f73d17a218c0ec08179a1eed8ed517ef5834365b508efca9777fce84f8b12905e04a8c8d4f9e1210e1ae1e6949c040ab0fc705
|
data/lib/cli/base_command.rb
CHANGED
@@ -39,8 +39,14 @@ module Bosh::Cli
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def director
|
42
|
-
@director
|
43
|
-
|
42
|
+
return @director if @director
|
43
|
+
|
44
|
+
director_client_options = [:no_track, :ca_cert]
|
45
|
+
@director = Bosh::Cli::Client::Director.new(
|
46
|
+
target,
|
47
|
+
credentials,
|
48
|
+
@options.select { |k, _| director_client_options.include?(k) }
|
49
|
+
)
|
44
50
|
end
|
45
51
|
|
46
52
|
def release
|
@@ -134,8 +140,9 @@ module Bosh::Cli
|
|
134
140
|
|
135
141
|
def auth_info
|
136
142
|
@auth_info ||= begin
|
137
|
-
|
138
|
-
Client::
|
143
|
+
ca_cert = config.ca_cert(target)
|
144
|
+
director_client = Client::Director.new(target, nil, ca_cert: ca_cert)
|
145
|
+
Client::Uaa::AuthInfo.new(director_client, ENV, ca_cert)
|
139
146
|
end
|
140
147
|
end
|
141
148
|
|
data/lib/cli/client/director.rb
CHANGED
@@ -35,6 +35,7 @@ module Bosh
|
|
35
35
|
@track_tasks = !options.delete(:no_track)
|
36
36
|
@num_retries = options.fetch(:num_retries, 5)
|
37
37
|
@retry_wait_interval = options.fetch(:retry_wait_interval, 5)
|
38
|
+
@ca_cert = options[:ca_cert]
|
38
39
|
end
|
39
40
|
|
40
41
|
def uuid
|
@@ -292,6 +293,7 @@ module Bosh
|
|
292
293
|
|
293
294
|
options[:payload] = JSON.generate(payload)
|
294
295
|
options[:content_type] = 'application/json'
|
296
|
+
options[:task_success_state] = :queued
|
295
297
|
|
296
298
|
request_and_track(:post, url, options)
|
297
299
|
end
|
@@ -728,8 +730,34 @@ module Bosh
|
|
728
730
|
http_client.receive_timeout = API_TIMEOUT
|
729
731
|
http_client.connect_timeout = CONNECT_TIMEOUT
|
730
732
|
|
731
|
-
|
732
|
-
|
733
|
+
if @ca_cert.nil?
|
734
|
+
http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
735
|
+
http_client.ssl_config.verify_callback = Proc.new {}
|
736
|
+
else
|
737
|
+
unless File.exists?(@ca_cert)
|
738
|
+
err('Invalid ca certificate path')
|
739
|
+
end
|
740
|
+
|
741
|
+
parsed_url = nil
|
742
|
+
begin
|
743
|
+
parsed_url = URI.parse(uri)
|
744
|
+
rescue => e
|
745
|
+
err("Failed to parse director URL: #{e.message}")
|
746
|
+
end
|
747
|
+
|
748
|
+
unless parsed_url.instance_of?(URI::HTTPS)
|
749
|
+
err('CA certificate cannot be used with HTTP protocol')
|
750
|
+
end
|
751
|
+
|
752
|
+
# pass in client certificate
|
753
|
+
begin
|
754
|
+
cert_store = OpenSSL::X509::Store.new
|
755
|
+
cert_store.add_file(@ca_cert)
|
756
|
+
rescue OpenSSL::X509::StoreError
|
757
|
+
err('Invalid SSL Cert')
|
758
|
+
end
|
759
|
+
http_client.ssl_config.cert_store = cert_store
|
760
|
+
end
|
733
761
|
|
734
762
|
if @credentials
|
735
763
|
headers['Authorization'] = @credentials.authorization_header
|
@@ -750,6 +778,10 @@ module Bosh
|
|
750
778
|
HTTPClient::KeepAliveDisconnected,
|
751
779
|
OpenSSL::SSL::SSLError,
|
752
780
|
OpenSSL::X509::StoreError => e
|
781
|
+
|
782
|
+
if e.is_a?(OpenSSL::SSL::SSLError) && e.message.include?('certificate verify failed')
|
783
|
+
err('Invalid SSL Cert')
|
784
|
+
end
|
753
785
|
raise DirectorInaccessible, "cannot access director (#{e.message})"
|
754
786
|
|
755
787
|
rescue HTTPClient::BadResponseError => e
|
@@ -31,7 +31,7 @@ module Bosh::Cli::Command
|
|
31
31
|
end
|
32
32
|
|
33
33
|
if target
|
34
|
-
old_director = Bosh::Cli::Client::Director.new(target, credentials)
|
34
|
+
old_director = Bosh::Cli::Client::Director.new(target, credentials, ca_cert: config.ca_cert)
|
35
35
|
old_director_uuid = old_director.get_status["uuid"] rescue nil
|
36
36
|
else
|
37
37
|
old_director_uuid = nil
|
@@ -49,8 +49,9 @@ module Bosh::Cli::Command
|
|
49
49
|
"Please find your director IP or hostname and target it first.")
|
50
50
|
end
|
51
51
|
|
52
|
+
target_ca_cert = config.ca_cert(new_target_url)
|
52
53
|
new_director = Bosh::Cli::Client::Director.new(
|
53
|
-
new_target_url, credentials)
|
54
|
+
new_target_url, credentials, ca_cert: target_ca_cert)
|
54
55
|
|
55
56
|
status = new_director.get_status
|
56
57
|
|
data/lib/cli/commands/misc.rb
CHANGED
@@ -83,7 +83,7 @@ module Bosh::Cli::Command
|
|
83
83
|
end
|
84
84
|
|
85
85
|
director_url = normalize_url(director_url)
|
86
|
-
director = Bosh::Cli::Client::Director.new(director_url)
|
86
|
+
director = Bosh::Cli::Client::Director.new(director_url, nil, ca_cert: options[:ca_cert])
|
87
87
|
|
88
88
|
begin
|
89
89
|
status = director.get_status
|
@@ -237,7 +237,7 @@ module Bosh::Cli::Command
|
|
237
237
|
end
|
238
238
|
|
239
239
|
def get_director_status
|
240
|
-
Bosh::Cli::Client::Director.new(target, credentials).get_status
|
240
|
+
Bosh::Cli::Client::Director.new(target, credentials, ca_cert: config.ca_cert).get_status
|
241
241
|
end
|
242
242
|
end
|
243
243
|
end
|
data/lib/cli/commands/ssh.rb
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
require 'cli/job_command_args'
|
2
|
+
require 'cli/ssh_session'
|
2
3
|
|
3
4
|
module Bosh::Cli
|
4
5
|
module Command
|
5
6
|
class Ssh < Base
|
6
|
-
SSH_USER_PREFIX = 'bosh_'
|
7
|
-
SSH_DSA_PUB = File.expand_path('~/.ssh/id_dsa.pub')
|
8
|
-
SSH_RSA_PUB = File.expand_path('~/.ssh/id_rsa.pub')
|
9
7
|
|
10
8
|
# bosh ssh
|
11
9
|
usage 'ssh'
|
12
10
|
desc 'Execute command or start an interactive session'
|
13
|
-
option '--public_key FILE', 'Public key'
|
14
11
|
option '--gateway_host HOST', 'Gateway host'
|
15
12
|
option '--gateway_user USER', 'Gateway user'
|
16
13
|
option '--gateway_identity_file FILE', 'Gateway identity file'
|
@@ -46,7 +43,6 @@ module Bosh::Cli
|
|
46
43
|
'Note: for download /path/to/destination is a directory'
|
47
44
|
option '--download', 'Download file'
|
48
45
|
option '--upload', 'Upload file'
|
49
|
-
option '--public_key FILE', 'Public key'
|
50
46
|
option '--gateway_host HOST', 'Gateway host'
|
51
47
|
option '--gateway_user USER', 'Gateway user'
|
52
48
|
option '--gateway_identity_file FILE', 'Gateway identity file'
|
@@ -111,14 +107,16 @@ module Bosh::Cli
|
|
111
107
|
# @param [Integer] index
|
112
108
|
# @param [optional,String] password
|
113
109
|
def setup_ssh(deployment_name, job, index, password)
|
114
|
-
user = random_ssh_username
|
115
110
|
|
116
111
|
say("Target deployment is `#{deployment_name}'")
|
117
112
|
nl
|
118
113
|
say('Setting up ssh artifacts')
|
114
|
+
|
115
|
+
ssh_session = SSHSession.new
|
116
|
+
|
119
117
|
status, task_id = director.setup_ssh(
|
120
|
-
deployment_name, job, index, user,
|
121
|
-
public_key, encrypt_password(password))
|
118
|
+
deployment_name, job, index, ssh_session.user,
|
119
|
+
ssh_session.public_key, encrypt_password(password))
|
122
120
|
|
123
121
|
unless status == :done
|
124
122
|
err("Failed to set up SSH: see task #{task_id} log for details")
|
@@ -137,6 +135,8 @@ module Bosh::Cli
|
|
137
135
|
end
|
138
136
|
end
|
139
137
|
|
138
|
+
ssh_session.set_host_session(sessions.first)
|
139
|
+
|
140
140
|
begin
|
141
141
|
if options[:gateway_host]
|
142
142
|
require 'net/ssh/gateway'
|
@@ -153,20 +153,17 @@ module Bosh::Cli
|
|
153
153
|
gateway = nil
|
154
154
|
end
|
155
155
|
|
156
|
-
yield sessions,
|
156
|
+
yield sessions, gateway, ssh_session
|
157
157
|
ensure
|
158
158
|
nl
|
159
159
|
say('Cleaning up ssh artifacts')
|
160
|
+
ssh_session.cleanup
|
160
161
|
indices = sessions.map { |session| session['index'] }
|
161
|
-
director.cleanup_ssh(deployment_name, job, "^#{user}$", indices)
|
162
|
+
director.cleanup_ssh(deployment_name, job, "^#{ssh_session.user}$", indices)
|
162
163
|
gateway.shutdown! if gateway
|
163
164
|
end
|
164
165
|
end
|
165
166
|
|
166
|
-
def random_ssh_username
|
167
|
-
SSH_USER_PREFIX + rand(36**9).to_s(36)
|
168
|
-
end
|
169
|
-
|
170
167
|
# @param [String] job Job name
|
171
168
|
# @param [Integer] index Job index
|
172
169
|
def setup_interactive_shell(deployment_name, job, index)
|
@@ -180,7 +177,7 @@ module Bosh::Cli
|
|
180
177
|
err('Please provide ssh password') if password.blank?
|
181
178
|
end
|
182
179
|
|
183
|
-
setup_ssh(deployment_name, job, index, password) do |sessions,
|
180
|
+
setup_ssh(deployment_name, job, index, password) do |sessions, gateway, ssh_session|
|
184
181
|
session = sessions.first
|
185
182
|
|
186
183
|
unless session['status'] == 'success' && session['ip']
|
@@ -192,26 +189,30 @@ module Bosh::Cli
|
|
192
189
|
skip_strict_host_key_checking = options[:strict_host_key_checking] =~ (/(no|false)$/i) ?
|
193
190
|
'-o StrictHostKeyChecking=no' : '-o StrictHostKeyChecking=yes'
|
194
191
|
|
192
|
+
private_key_option = ssh_session.ssh_private_key_option
|
193
|
+
|
195
194
|
if gateway
|
196
195
|
port = gateway.open(session['ip'], 22)
|
197
|
-
|
198
|
-
Process.
|
196
|
+
known_host_option = ssh_session.ssh_known_host_option(port)
|
197
|
+
ssh_session_pid = Process.spawn('ssh', "#{ssh_session.user}@localhost", '-p', port.to_s, private_key_option, skip_strict_host_key_checking, known_host_option)
|
198
|
+
Process.waitpid(ssh_session_pid)
|
199
199
|
gateway.close(port)
|
200
200
|
else
|
201
|
-
|
202
|
-
Process.
|
201
|
+
known_host_option = ssh_session.ssh_known_host_option(nil)
|
202
|
+
ssh_session_pid = Process.spawn('ssh', "#{ssh_session.user}@#{session['ip']}", private_key_option, skip_strict_host_key_checking, known_host_option)
|
203
|
+
Process.waitpid(ssh_session_pid)
|
203
204
|
end
|
204
205
|
end
|
205
206
|
end
|
206
207
|
|
207
208
|
def perform_operation(operation, deployment_name, job, index, args)
|
208
|
-
setup_ssh(deployment_name, job, index, options[:default_password]) do |sessions,
|
209
|
+
setup_ssh(deployment_name, job, index, options[:default_password]) do |sessions, gateway, ssh_session|
|
209
210
|
sessions.each do |session|
|
210
211
|
unless session['status'] == 'success' && session['ip']
|
211
212
|
err("Failed to set up SSH on #{job}/#{index}: #{session.inspect}")
|
212
213
|
end
|
213
214
|
|
214
|
-
with_ssh(
|
215
|
+
with_ssh(session['ip'], ssh_session, gateway) do |ssh|
|
215
216
|
case operation
|
216
217
|
when :exec
|
217
218
|
nl
|
@@ -232,40 +233,24 @@ module Bosh::Cli
|
|
232
233
|
end
|
233
234
|
end
|
234
235
|
|
235
|
-
# @return [String] Public key
|
236
|
-
def public_key
|
237
|
-
public_key_path = options[:public_key]
|
238
|
-
|
239
|
-
if public_key_path
|
240
|
-
unless File.file?(public_key_path)
|
241
|
-
err("Can't find file `#{public_key_path}'")
|
242
|
-
end
|
243
|
-
return File.read(public_key_path)
|
244
|
-
else
|
245
|
-
%x[ssh-add -L 1>/dev/null 2>&1]
|
246
|
-
if $?.exitstatus == 0
|
247
|
-
return %x[ssh-add -L].split("\n").first
|
248
|
-
else
|
249
|
-
[SSH_DSA_PUB, SSH_RSA_PUB].each do |key_file|
|
250
|
-
return File.read(key_file) if File.file?(key_file)
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
err('Please specify a public key file')
|
256
|
-
end
|
257
|
-
|
258
236
|
# @param [String] user
|
259
237
|
# @param [String] ip
|
260
238
|
# @param [optional, Net::SSH::Gateway] gateway
|
261
239
|
# @yield [Net::SSH]
|
262
|
-
def with_ssh(
|
240
|
+
def with_ssh(ip, ssh_session, gateway = nil)
|
263
241
|
require 'net/scp'
|
242
|
+
options = { :keys => ssh_session.ssh_private_key_path }
|
264
243
|
if gateway
|
265
|
-
gateway.ssh(ip, user) { |ssh| yield ssh }
|
244
|
+
gateway.ssh(ip, ssh_session.user, options) { |ssh| yield ssh }
|
266
245
|
else
|
267
246
|
require 'net/ssh'
|
268
|
-
|
247
|
+
|
248
|
+
known_host_path = ssh_session.ssh_known_host_path(nil)
|
249
|
+
if known_host_path.length > 0
|
250
|
+
options[:user_known_hosts_file] = known_host_path
|
251
|
+
end
|
252
|
+
|
253
|
+
Net::SSH.start(ip, ssh_session.user, options) { |ssh| yield ssh }
|
269
254
|
end
|
270
255
|
end
|
271
256
|
end
|
data/lib/cli/config.rb
CHANGED
@@ -218,10 +218,11 @@ module Bosh::Cli
|
|
218
218
|
end
|
219
219
|
|
220
220
|
|
221
|
-
def save_ca_cert_path(cert_path)
|
221
|
+
def save_ca_cert_path(cert_path, for_target=nil)
|
222
222
|
expanded_path = cert_path ? File.expand_path(cert_path) : nil
|
223
|
+
cert_target = for_target || target
|
223
224
|
@config_file['ca_cert'] ||= {}
|
224
|
-
@config_file['ca_cert'][
|
225
|
+
@config_file['ca_cert'][cert_target] = expanded_path
|
225
226
|
|
226
227
|
expanded_path
|
227
228
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'sshkey'
|
2
|
+
|
3
|
+
module Bosh::Cli
|
4
|
+
class SSHSession
|
5
|
+
|
6
|
+
SSH_USER_PREFIX = 'bosh_'
|
7
|
+
|
8
|
+
attr_reader :public_key, :user
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@session_uuid = SecureRandom::uuid
|
12
|
+
@public_key = generate_rsa_key
|
13
|
+
@user = random_ssh_username
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_host_session(session)
|
17
|
+
@host_session = session
|
18
|
+
end
|
19
|
+
|
20
|
+
def ssh_known_host_option(port)
|
21
|
+
path = user_known_host_path(port)
|
22
|
+
if path.length > 0
|
23
|
+
path = "-o UserKnownHostsFile=#{path}"
|
24
|
+
end
|
25
|
+
return path
|
26
|
+
end
|
27
|
+
|
28
|
+
def ssh_known_host_path(port)
|
29
|
+
user_known_host_path(port)
|
30
|
+
end
|
31
|
+
|
32
|
+
def ssh_private_key_option
|
33
|
+
"-i#{ssh_private_key_path}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def ssh_private_key_path
|
37
|
+
File.join(ENV['HOME'], '.bosh', 'tmp', "#{@session_uuid}_key")
|
38
|
+
end
|
39
|
+
|
40
|
+
def cleanup
|
41
|
+
remove_private_key
|
42
|
+
remove_known_host_file
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def generate_rsa_key
|
48
|
+
key = SSHKey.generate(
|
49
|
+
type: "RSA",
|
50
|
+
bits: 2048,
|
51
|
+
comment: "bosh-ssh",
|
52
|
+
)
|
53
|
+
add_private_key(key.private_key)
|
54
|
+
return key.ssh_public_key
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove_private_key
|
58
|
+
file_name = private_key_file_name
|
59
|
+
FileUtils.rm_rf(file_name) if File.exist?(file_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def private_key_file_name
|
63
|
+
File.join(ENV['HOME'], '.bosh', 'tmp', "#{@session_uuid}_key")
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_private_key(private_key)
|
67
|
+
file_name = private_key_file_name
|
68
|
+
create_dir_for_file(file_name)
|
69
|
+
|
70
|
+
key_File = File.new(file_name, "w", 0400)
|
71
|
+
key_File.puts(private_key)
|
72
|
+
key_File.close
|
73
|
+
end
|
74
|
+
|
75
|
+
def random_ssh_username
|
76
|
+
SSH_USER_PREFIX + rand(36**9).to_s(36)
|
77
|
+
end
|
78
|
+
|
79
|
+
def user_known_host_path(gatewayPort)
|
80
|
+
if @host_session.include?('host_public_key')
|
81
|
+
hostEntryIP = if gatewayPort then "[localhost]:#{gatewayPort}" else @host_session['ip'] end
|
82
|
+
hostEntry = "#{hostEntryIP} #{@host_session['host_public_key']}"
|
83
|
+
add_known_host_file(hostEntry)
|
84
|
+
return known_host_file_path
|
85
|
+
else
|
86
|
+
return String.new
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def known_host_file_path
|
91
|
+
File.join(ENV['HOME'], '.bosh', 'tmp', "#{@session_uuid}_known_hosts")
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_known_host_file(hostEntry)
|
95
|
+
file_name = known_host_file_path
|
96
|
+
|
97
|
+
create_dir_for_file(file_name)
|
98
|
+
|
99
|
+
known_host_file = File.new(file_name, "w")
|
100
|
+
known_host_file.puts(hostEntry)
|
101
|
+
known_host_file.close
|
102
|
+
end
|
103
|
+
|
104
|
+
def remove_known_host_file
|
105
|
+
file_name = known_host_file_path
|
106
|
+
FileUtils.rm_rf(file_name) if File.exist?(file_name)
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_dir_for_file(file_name)
|
110
|
+
dirname = File.dirname(file_name)
|
111
|
+
unless File.directory?(dirname)
|
112
|
+
FileUtils.mkdir_p(dirname)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -13,6 +13,7 @@ module Bosh::Cli::TaskTracking
|
|
13
13
|
def initialize(director, task_id, options = {})
|
14
14
|
@director = director
|
15
15
|
@task_id = task_id
|
16
|
+
@task_success_state = options[:task_success_state] || :done
|
16
17
|
@options = options
|
17
18
|
|
18
19
|
@quiet = !!options[:quiet]
|
@@ -139,7 +140,7 @@ module Bosh::Cli::TaskTracking
|
|
139
140
|
end
|
140
141
|
|
141
142
|
def finished?(state)
|
142
|
-
|
143
|
+
"#{@task_success_state} error cancelled".include?(state)
|
143
144
|
end
|
144
145
|
|
145
146
|
def interactive?
|
data/lib/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3087.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- VMware
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bosh_common
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.3087.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.3087.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bosh-template
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.3087.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.3087.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: cf-uaa-lib
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 1.
|
131
|
+
version: 1.3087.0
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 1.
|
138
|
+
version: 1.3087.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: net-ssh
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,6 +206,20 @@ dependencies:
|
|
206
206
|
- - "~>"
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: 0.5.4
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: sshkey
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: 1.7.0
|
216
|
+
type: :runtime
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 1.7.0
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: rspec
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -412,6 +426,7 @@ files:
|
|
412
426
|
- lib/cli/resurrection.rb
|
413
427
|
- lib/cli/runner.rb
|
414
428
|
- lib/cli/source_control/git_ignore.rb
|
429
|
+
- lib/cli/ssh_session.rb
|
415
430
|
- lib/cli/stemcell.rb
|
416
431
|
- lib/cli/task_tracking.rb
|
417
432
|
- lib/cli/task_tracking/event_log_renderer.rb
|