ztk 1.9.1 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ztk/ansi.rb +0 -1
- data/lib/ztk/ssh.rb +8 -2
- data/lib/ztk/ssh/command.rb +2 -0
- data/lib/ztk/ssh/core.rb +60 -6
- data/lib/ztk/ssh/download.rb +50 -25
- data/lib/ztk/ssh/private.rb +64 -24
- data/lib/ztk/ssh/upload.rb +45 -17
- data/lib/ztk/version.rb +1 -1
- data/spec/ztk/ssh_spec.rb +97 -88
- data/ztk.gemspec +2 -0
- metadata +36 -4
data/lib/ztk/ansi.rb
CHANGED
@@ -97,7 +97,6 @@ module ZTK
|
|
97
97
|
# @return [String] The colored string.
|
98
98
|
|
99
99
|
# Defines a RegEx for stripping ANSI codes from strings
|
100
|
-
#ANSI_REGEX = /\e\[(?:(?:[349]|10)[0-7]|[0-9]|[34]8;5;\d{1,3})?m/
|
101
100
|
ANSI_REGEX = /\e\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/
|
102
101
|
|
103
102
|
# Build ANSI Methods
|
data/lib/ztk/ssh.rb
CHANGED
@@ -61,9 +61,12 @@ module ZTK
|
|
61
61
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
62
62
|
class SSH < ZTK::Base
|
63
63
|
require 'ostruct'
|
64
|
+
require 'tempfile'
|
64
65
|
require 'net/ssh'
|
66
|
+
require 'net/ssh/gateway'
|
65
67
|
require 'net/ssh/proxy/command'
|
66
68
|
require 'net/sftp'
|
69
|
+
require 'net/scp'
|
67
70
|
|
68
71
|
# Exit Signal Mappings
|
69
72
|
EXIT_SIGNALS = {
|
@@ -121,7 +124,8 @@ module ZTK
|
|
121
124
|
# @option configuration [String] :host_name Server hostname to connect to.
|
122
125
|
# @option configuration [String] :user Username to use for authentication.
|
123
126
|
# @option configuration [String, Array<String>] :keys A single or series of
|
124
|
-
# identity files to use for authentication.
|
127
|
+
# identity files to use for authentication. You can also supply keys as
|
128
|
+
# String blobs which will be rendered to temporary files automatically.
|
125
129
|
# @option configuration [String] :password Password to use for authentication.
|
126
130
|
# @option configuration [Integer] :timeout (60) SSH connection timeout in
|
127
131
|
# seconds to use.
|
@@ -160,7 +164,9 @@ module ZTK
|
|
160
164
|
:ignore_exit_status => false,
|
161
165
|
:request_pty => true,
|
162
166
|
:exit_code => 0,
|
163
|
-
:silence => false
|
167
|
+
:silence => false,
|
168
|
+
:keys => Array.new,
|
169
|
+
:proxy_keys => Array.new
|
164
170
|
}.merge(configuration))
|
165
171
|
|
166
172
|
config.ui.logger.debug { "config=#{config.send(:table).inspect}" }
|
data/lib/ztk/ssh/command.rb
CHANGED
@@ -6,6 +6,7 @@ module ZTK
|
|
6
6
|
|
7
7
|
# Builds our SSH console command.
|
8
8
|
def console_command
|
9
|
+
process_keys
|
9
10
|
verbosity = ((ENV['LOG_LEVEL'] == "DEBUG") ? '-vv' : '-q')
|
10
11
|
|
11
12
|
command = Array.new
|
@@ -34,6 +35,7 @@ module ZTK
|
|
34
35
|
!config.proxy_user and log_and_raise(SSHError, "You must specify an proxy user in order to SSH proxy.")
|
35
36
|
!config.proxy_host_name and log_and_raise(SSHError, "You must specify an proxy host_name in order to SSH proxy.")
|
36
37
|
|
38
|
+
process_keys
|
37
39
|
verbosity = ((ENV['LOG_LEVEL'] == "DEBUG") ? '-vv' : '-q')
|
38
40
|
|
39
41
|
command = Array.new
|
data/lib/ztk/ssh/core.rb
CHANGED
@@ -8,7 +8,11 @@ module ZTK
|
|
8
8
|
#
|
9
9
|
# Primarily used internally.
|
10
10
|
def ssh
|
11
|
-
|
11
|
+
if do_proxy?
|
12
|
+
@ssh ||= self.gateway.ssh(config.host_name, config.user, ssh_options)
|
13
|
+
else
|
14
|
+
@ssh ||= Net::SSH.start(config.host_name, config.user, ssh_options)
|
15
|
+
end
|
12
16
|
@ssh
|
13
17
|
end
|
14
18
|
|
@@ -20,10 +24,30 @@ module ZTK
|
|
20
24
|
@sftp
|
21
25
|
end
|
22
26
|
|
23
|
-
#
|
24
|
-
|
25
|
-
|
27
|
+
# Starts an SCP session. Can also be used to get the Net::SCP object.
|
28
|
+
#
|
29
|
+
# Primarily used internally.
|
30
|
+
def scp
|
31
|
+
@scp ||= self.ssh.scp
|
32
|
+
@scp
|
33
|
+
end
|
26
34
|
|
35
|
+
# Starts an SSH gateway session. Can also be used to get the
|
36
|
+
# Net::SSH::Gateway object.
|
37
|
+
#
|
38
|
+
# Primarily used internally.
|
39
|
+
def gateway
|
40
|
+
@gateway ||= Net::SSH::Gateway.new(config.proxy_host_name, config.proxy_user, gateway_options)
|
41
|
+
@gateway
|
42
|
+
end
|
43
|
+
|
44
|
+
# Should we run a proxy?
|
45
|
+
def do_proxy?
|
46
|
+
((!config.proxy_host_name.nil? && !config.proxy_host_name.empty?) && (!config.proxy_user.nil? && !config.proxy_user.empty?))
|
47
|
+
end
|
48
|
+
|
49
|
+
# Attempts to close the SSH session if it is valid.
|
50
|
+
def close_ssh
|
27
51
|
if (!@ssh.nil? && !@ssh.closed?)
|
28
52
|
config.ui.logger.debug { "SSH object is valid and not closed" }
|
29
53
|
|
@@ -39,11 +63,41 @@ module ZTK
|
|
39
63
|
else
|
40
64
|
config.ui.logger.debug { "SSH object is NIL!" }
|
41
65
|
end
|
66
|
+
end
|
42
67
|
|
43
|
-
|
44
|
-
|
68
|
+
# Attempts to close the gateway session if it is valid.
|
69
|
+
def close_gateway
|
70
|
+
if (!@gateway.nil? && !@gateway.closed?)
|
71
|
+
config.ui.logger.debug { "gateway object is valid and not shutdown" }
|
72
|
+
|
73
|
+
begin
|
74
|
+
config.ui.logger.debug { "attempting to shutdown" }
|
75
|
+
@gateway.shutdown!
|
76
|
+
config.ui.logger.debug { "shutdown" }
|
77
|
+
|
78
|
+
rescue Exception => e
|
79
|
+
config.ui.logger.fatal { "EXCEPTION: #{e.inspect}" }
|
80
|
+
end
|
81
|
+
|
82
|
+
else
|
83
|
+
config.ui.logger.debug { "gateway object is NIL!" }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Close our session gracefully.
|
88
|
+
def close
|
89
|
+
config.ui.logger.debug { "close" }
|
90
|
+
|
91
|
+
close_ssh
|
92
|
+
close_gateway
|
45
93
|
|
46
94
|
true
|
95
|
+
|
96
|
+
ensure
|
97
|
+
@ssh = nil
|
98
|
+
@gateway = nil
|
99
|
+
@sftp = nil
|
100
|
+
@scp = nil
|
47
101
|
end
|
48
102
|
|
49
103
|
# The on_retry method we'll use with the RescueRetry class.
|
data/lib/ztk/ssh/download.rb
CHANGED
@@ -6,14 +6,6 @@ module ZTK
|
|
6
6
|
|
7
7
|
# Downloads a remote file to the local host.
|
8
8
|
#
|
9
|
-
# @param [String] remote The remote file/path you with to download from.
|
10
|
-
# @param [String] local The local file/path you wish to download to.
|
11
|
-
# @param [Hash] options An optional hash of options.
|
12
|
-
# @option options [Boolean] :recursive Whether or not to recursively
|
13
|
-
# download files and directories. By default this looks at the local
|
14
|
-
# target and if it is a directory this is set to *true* otherwise it
|
15
|
-
# will default to *false*.
|
16
|
-
#
|
17
9
|
# @example Download a file:
|
18
10
|
# $logger = ZTK::Logger.new(STDOUT)
|
19
11
|
# ssh = ZTK::SSH.new
|
@@ -24,8 +16,24 @@ module ZTK
|
|
24
16
|
# local = File.expand_path(File.join(ZTK::Locator.root, "tmp", "id_rsa.pub"))
|
25
17
|
# remote = File.expand_path(File.join(ENV['HOME'], ".ssh", "id_rsa.pub"))
|
26
18
|
# ssh.download(remote, local)
|
19
|
+
#
|
20
|
+
# @param [String] remote The remote file/path you with to download from.
|
21
|
+
# @param [String] local The local file/path you wish to download to.
|
22
|
+
# @param [Hash] options An optional hash of options.
|
23
|
+
# @option options [Boolean] :recursive (false) Whether or not to
|
24
|
+
# recursively download files and directories. By default this looks at
|
25
|
+
# the local target and if it is a directory this is set to *true*
|
26
|
+
# otherwise it will default to *false*.
|
27
|
+
# @option options [Boolean] :use_scp (false) If set to true, the file will
|
28
|
+
# be transfered using SCP instead of SFTP. The default behaviour is to
|
29
|
+
# use SFTP. *WARNING: Recursive downloads are handled in differing
|
30
|
+
# manners between SCP and SFTP!*
|
31
|
+
# @return [Boolean] True if successful.
|
27
32
|
def download(remote, local, options={})
|
28
|
-
options = {
|
33
|
+
options = {
|
34
|
+
:recursive => ::File.directory?(local),
|
35
|
+
:use_scp => false
|
36
|
+
}.merge(options)
|
29
37
|
options = OpenStruct.new(config.send(:table).merge(options))
|
30
38
|
|
31
39
|
options.ui.logger.debug { "config=#{config.send(:table).inspect}" }
|
@@ -33,24 +41,41 @@ module ZTK
|
|
33
41
|
options.ui.logger.info { "download(#{remote.inspect}, #{local.inspect})" }
|
34
42
|
|
35
43
|
ZTK::RescueRetry.try(:ui => config.ui, :tries => ZTK::SSH::RESCUE_RETRY_ATTEMPTS, :on_retry => method(:on_retry)) do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
if (options.use_scp == false)
|
45
|
+
sftp.download!(remote.to_s, local.to_s, options.send(:table)) do |event, downloader, *args|
|
46
|
+
case event
|
47
|
+
when :open
|
48
|
+
options.ui.logger.debug { "download(#{args[0].remote} -> #{args[0].local})" }
|
49
|
+
options.on_progress.nil? or options.on_progress.call(:open, args)
|
50
|
+
when :close
|
51
|
+
options.ui.logger.debug { "close(#{args[0].local})" }
|
52
|
+
options.on_progress.nil? or options.on_progress.call(:close, args)
|
53
|
+
when :mkdir
|
54
|
+
options.ui.logger.debug { "mkdir(#{args[0]})" }
|
55
|
+
options.on_progress.nil? or options.on_progress.call(:mkdir, args)
|
56
|
+
when :get
|
57
|
+
options.ui.logger.debug { "get(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
|
58
|
+
options.on_progress.nil? or options.on_progress.call(:get, args)
|
59
|
+
when :finish
|
60
|
+
options.ui.logger.debug { "finish" }
|
61
|
+
options.on_progress.nil? or options.on_progress.call(:finish, args)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
else
|
65
|
+
opened = false
|
66
|
+
args = []
|
67
|
+
|
68
|
+
scp.download!(remote.to_s, local.to_s, options.send(:table)) do |ch, name, sent, total|
|
69
|
+
args = [ OpenStruct.new(:size => total, :local => name, :remote => name), sent, '' ]
|
70
|
+
|
71
|
+
opened or (options.on_progress.nil? or options.on_progress.call(:open, args) and (opened = true))
|
72
|
+
|
73
|
+
options.ui.logger.debug { "get(#{args[0].remote}, sent #{args[1]}, total #{args[0].size})" }
|
49
74
|
options.on_progress.nil? or options.on_progress.call(:get, args)
|
50
|
-
when :finish
|
51
|
-
options.ui.logger.debug { "finish" }
|
52
|
-
options.on_progress.nil? or options.on_progress.call(:finish, args)
|
53
75
|
end
|
76
|
+
|
77
|
+
options.ui.logger.debug { "finish" }
|
78
|
+
options.on_progress.nil? or options.on_progress.call(:finish, args)
|
54
79
|
end
|
55
80
|
end
|
56
81
|
|
data/lib/ztk/ssh/private.rb
CHANGED
@@ -4,37 +4,77 @@ module ZTK
|
|
4
4
|
# SSH Private Functionality
|
5
5
|
module Private
|
6
6
|
|
7
|
+
# Builds our core options
|
8
|
+
def base_options
|
9
|
+
options = Hash.new
|
10
|
+
|
11
|
+
config.encryption.nil? or options.merge!(:encryption => config.encryption)
|
12
|
+
config.compression.nil? or options.merge!(:compression => config.compression)
|
13
|
+
config.compression_level.nil? or options.merge!(:compression_level => config.compression_level)
|
14
|
+
config.timeout.nil? or options.merge!(:timeout => config.timeout)
|
15
|
+
config.forward_agent.nil? or options.merge!(:forward_agent => config.forward_agent)
|
16
|
+
config.global_known_hosts_file.nil? or options.merge!(:global_known_hosts_file => config.global_known_hosts_file)
|
17
|
+
config.auth_methods.nil? or options.merge!(:auth_methods => config.auth_methods)
|
18
|
+
config.host_key.nil? or options.merge!(:host_key => config.host_key)
|
19
|
+
config.host_key_alias.nil? or options.merge!(:host_key_alias => config.host_key_alias)
|
20
|
+
config.keys_only.nil? or options.merge!(:keys_only => config.keys_only)
|
21
|
+
config.hmac.nil? or options.merge!(:hmac => config.hmac)
|
22
|
+
config.rekey_limit.nil? or options.merge!(:rekey_limit => config.rekey_limit)
|
23
|
+
config.user_known_hosts_file.nil? or options.merge!(:user_known_hosts_file => config.user_known_hosts_file)
|
24
|
+
|
25
|
+
options
|
26
|
+
end
|
27
|
+
|
7
28
|
# Builds our SSH options hash.
|
8
29
|
def ssh_options
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
options.merge!(:
|
13
|
-
options.merge!(:
|
14
|
-
options.merge!(:
|
15
|
-
options.merge!(:timeout => config.timeout) if config.timeout
|
16
|
-
options.merge!(:forward_agent => config.forward_agent) if config.forward_agent
|
17
|
-
options.merge!(:global_known_hosts_file => config.global_known_hosts_file) if config.global_known_hosts_file
|
18
|
-
options.merge!(:auth_methods => config.auth_methods) if config.auth_methods
|
19
|
-
options.merge!(:host_key => config.host_key) if config.host_key
|
20
|
-
options.merge!(:host_key_alias => config.host_key_alias) if config.host_key_alias
|
21
|
-
options.merge!(:host_name => config.host_name) if config.host_name
|
22
|
-
options.merge!(:keys => config.keys) if config.keys
|
23
|
-
options.merge!(:keys_only => config.keys_only) if config.keys_only
|
24
|
-
options.merge!(:hmac => config.hmac) if config.hmac
|
25
|
-
options.merge!(:port => config.port) if config.port
|
26
|
-
options.merge!(:proxy => Net::SSH::Proxy::Command.new(proxy_command)) if config.proxy_host_name
|
27
|
-
options.merge!(:rekey_limit => config.rekey_limit) if config.rekey_limit
|
28
|
-
options.merge!(:user => config.user) if config.user
|
29
|
-
options.merge!(:user_known_hosts_file => config.user_known_hosts_file) if config.user_known_hosts_file
|
30
|
-
|
31
|
-
# This is not plainly documented on the Net::SSH config class.
|
32
|
-
options.merge!(:password => config.password) if config.password
|
30
|
+
process_keys
|
31
|
+
options = base_options
|
32
|
+
|
33
|
+
config.port.nil? or options.merge!(:port => config.port)
|
34
|
+
config.password.nil? or options.merge!(:password => config.password)
|
35
|
+
config.keys.nil? or options.merge!(:keys => config.keys)
|
33
36
|
|
34
37
|
config.ui.logger.debug { "ssh_options(#{options.inspect})" }
|
35
38
|
options
|
36
39
|
end
|
37
40
|
|
41
|
+
# Builds our SSH gateway options hash.
|
42
|
+
def gateway_options
|
43
|
+
process_keys
|
44
|
+
options = base_options
|
45
|
+
|
46
|
+
config.proxy_port.nil? or options.merge!(:port => config.proxy_port)
|
47
|
+
config.proxy_password.nil? or options.merge!(:password => config.proxy_password)
|
48
|
+
config.proxy_keys.nil? or options.merge!(:keys => config.proxy_keys)
|
49
|
+
|
50
|
+
config.ui.logger.debug { "gateway_options(#{options.inspect})" }
|
51
|
+
options
|
52
|
+
end
|
53
|
+
|
54
|
+
# Iterate the keys and proxy_keys, converting them as needed.
|
55
|
+
def process_keys
|
56
|
+
config.keys = config.keys.collect do |key|
|
57
|
+
process_key(key)
|
58
|
+
end
|
59
|
+
|
60
|
+
config.proxy_keys = config.proxy_keys.collect do |proxy_key|
|
61
|
+
process_key(proxy_key)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Process a individual key, rendering it to a temporary file if needed.
|
66
|
+
def process_key(key)
|
67
|
+
if ::File.exists?(key)
|
68
|
+
key
|
69
|
+
else
|
70
|
+
tempfile = ::Tempfile.new('key')
|
71
|
+
tempfile.write(key)
|
72
|
+
tempfile.flush
|
73
|
+
|
74
|
+
tempfile.path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
38
78
|
# Builds a human readable tag about our connection. Used for internal
|
39
79
|
# logging purposes.
|
40
80
|
def tag
|
data/lib/ztk/ssh/upload.rb
CHANGED
@@ -19,8 +19,19 @@ module ZTK
|
|
19
19
|
#
|
20
20
|
# @param [String] local The local file/path you wish to upload from.
|
21
21
|
# @param [String] remote The remote file/path you with to upload to.
|
22
|
+
# @param [Hash] options An optional hash of options.
|
23
|
+
# @option options [Boolean] :recursive (false) Whether or not to
|
24
|
+
# recursively download files and directories.
|
25
|
+
# @option options [Boolean] :use_scp (false) If set to true, the file will
|
26
|
+
# be transfered using SCP instead of SFTP. The default behaviour is to
|
27
|
+
# use SFTP. *WARNING: Recursive downloads are handled in differing
|
28
|
+
# manners between SCP and SFTP!*
|
22
29
|
# @return [Boolean] True if successful.
|
23
30
|
def upload(local, remote, options={})
|
31
|
+
options = {
|
32
|
+
:recursive => false,
|
33
|
+
:use_scp => false
|
34
|
+
}.merge(options)
|
24
35
|
options = OpenStruct.new(config.send(:table).merge(options))
|
25
36
|
|
26
37
|
options.ui.logger.debug { "config=#{config.send(:table).inspect}" }
|
@@ -28,24 +39,41 @@ module ZTK
|
|
28
39
|
config.ui.logger.info { "upload(#{local.inspect}, #{remote.inspect})" }
|
29
40
|
|
30
41
|
ZTK::RescueRetry.try(:ui => config.ui, :tries => ZTK::SSH::RESCUE_RETRY_ATTEMPTS, :on_retry => method(:on_retry)) do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
if (options.use_scp == false)
|
43
|
+
sftp.upload!(local.to_s, remote.to_s) do |event, uploader, *args|
|
44
|
+
case event
|
45
|
+
when :open
|
46
|
+
options.ui.logger.debug { "upload(#{args[0].local} -> #{args[0].remote})" }
|
47
|
+
options.on_progress.nil? or options.on_progress.call(:open, args)
|
48
|
+
when :close
|
49
|
+
options.ui.logger.debug { "close(#{args[0].remote})" }
|
50
|
+
options.on_progress.nil? or options.on_progress.call(:close, args)
|
51
|
+
when :mkdir
|
52
|
+
options.ui.logger.debug { "mkdir(#{args[0]})" }
|
53
|
+
options.on_progress.nil? or options.on_progress.call(:mkdir, args)
|
54
|
+
when :put
|
55
|
+
options.ui.logger.debug { "put(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
|
56
|
+
options.on_progress.nil? or options.on_progress.call(:put, args)
|
57
|
+
when :finish
|
58
|
+
options.ui.logger.debug { "finish" }
|
59
|
+
options.on_progress.nil? or options.on_progress.call(:finish, args)
|
60
|
+
end
|
48
61
|
end
|
62
|
+
else
|
63
|
+
opened = false
|
64
|
+
args = []
|
65
|
+
|
66
|
+
scp.upload!(local.to_s, remote.to_s, options.send(:table)) do |ch, name, sent, total|
|
67
|
+
args = [ OpenStruct.new(:size => total, :local => name, :remote => name), sent, '' ]
|
68
|
+
|
69
|
+
opened or (options.on_progress.nil? or options.on_progress.call(:open, args) and (opened = true))
|
70
|
+
|
71
|
+
options.ui.logger.debug { "put(#{args[0].remote}, sent #{args[1]}, total #{args[0].size})" }
|
72
|
+
options.on_progress.nil? or options.on_progress.call(:get, args)
|
73
|
+
end
|
74
|
+
|
75
|
+
options.ui.logger.debug { "finish" }
|
76
|
+
options.on_progress.nil? or options.on_progress.call(:finish, args)
|
49
77
|
end
|
50
78
|
end
|
51
79
|
|
data/lib/ztk/version.rb
CHANGED
data/spec/ztk/ssh_spec.rb
CHANGED
@@ -231,68 +231,73 @@ describe ZTK::SSH do
|
|
231
231
|
|
232
232
|
describe "upload" do
|
233
233
|
|
234
|
-
|
235
|
-
|
236
|
-
config
|
234
|
+
[true, false].each do |use_scp|
|
235
|
+
it "should be able to upload a file to 127.0.0.1 as the current user using #{use_scp ? 'scp' : 'sftp'} (your key must be in ssh-agent)" do
|
236
|
+
subject.config do |config|
|
237
|
+
config.ui = @ui
|
237
238
|
|
238
|
-
|
239
|
-
|
240
|
-
|
239
|
+
config.user = ENV["USER"]
|
240
|
+
config.host_name = "127.0.0.1"
|
241
|
+
end
|
241
242
|
|
242
|
-
|
243
|
+
data = "Hello World @ #{Time.now.utc}"
|
243
244
|
|
244
|
-
|
245
|
-
|
245
|
+
remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-remote")
|
246
|
+
File.exists?(remote_file) && File.delete(remote_file)
|
246
247
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
248
|
+
local_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-local")
|
249
|
+
if RUBY_VERSION < "1.9.3"
|
250
|
+
File.open(local_file, 'w') do |file|
|
251
|
+
file.puts(data)
|
252
|
+
end
|
253
|
+
else
|
254
|
+
IO.write(local_file, data)
|
251
255
|
end
|
252
|
-
else
|
253
|
-
IO.write(local_file, data)
|
254
|
-
end
|
255
256
|
|
256
|
-
|
257
|
-
|
258
|
-
|
257
|
+
File.exists?(remote_file).should == false
|
258
|
+
subject.upload(local_file, remote_file)
|
259
|
+
File.exists?(remote_file).should == true
|
259
260
|
|
260
|
-
|
261
|
-
|
261
|
+
File.exists?(remote_file) && File.delete(remote_file)
|
262
|
+
File.exists?(local_file) && File.delete(local_file)
|
263
|
+
end
|
262
264
|
end
|
263
265
|
|
264
266
|
end
|
265
267
|
|
266
268
|
describe "download" do
|
267
269
|
|
268
|
-
|
269
|
-
|
270
|
-
config
|
270
|
+
[true, false].each do |use_scp|
|
271
|
+
it "should be able to download a file from 127.0.0.1 as the current user using #{use_scp ? 'scp' : 'sftp'} (your key must be in ssh-agent)" do
|
272
|
+
subject.config do |config|
|
273
|
+
config.ui = @ui
|
271
274
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
+
config.user = ENV["USER"]
|
276
|
+
config.host_name = "127.0.0.1"
|
277
|
+
config.use_scp = use_scp
|
278
|
+
end
|
275
279
|
|
276
|
-
|
280
|
+
data = "Hello World @ #{Time.now.utc}"
|
277
281
|
|
278
|
-
|
279
|
-
|
282
|
+
local_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-local")
|
283
|
+
File.exists?(local_file) && File.delete(local_file)
|
280
284
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
+
remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-remote")
|
286
|
+
if RUBY_VERSION < "1.9.3"
|
287
|
+
File.open(remote_file, 'w') do |file|
|
288
|
+
file.puts(data)
|
289
|
+
end
|
290
|
+
else
|
291
|
+
IO.write(remote_file, data)
|
285
292
|
end
|
286
|
-
else
|
287
|
-
IO.write(remote_file, data)
|
288
|
-
end
|
289
293
|
|
290
|
-
|
291
|
-
|
292
|
-
|
294
|
+
File.exists?(local_file).should == false
|
295
|
+
subject.download(remote_file, local_file)
|
296
|
+
File.exists?(local_file).should == true
|
293
297
|
|
294
|
-
|
295
|
-
|
298
|
+
File.exists?(local_file) && File.delete(local_file)
|
299
|
+
File.exists?(remote_file) && File.delete(remote_file)
|
300
|
+
end
|
296
301
|
end
|
297
302
|
|
298
303
|
end
|
@@ -511,72 +516,76 @@ describe ZTK::SSH do
|
|
511
516
|
|
512
517
|
describe "upload" do
|
513
518
|
|
514
|
-
|
515
|
-
|
516
|
-
config
|
519
|
+
[true, false].each do |use_scp|
|
520
|
+
it "should be able to upload a file to 127.0.0.1 as the current user #{use_scp ? 'scp' : 'sftp'} (your key must be in ssh-agent)" do
|
521
|
+
subject.config do |config|
|
522
|
+
config.ui = @ui
|
517
523
|
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
524
|
+
config.user = ENV["USER"]
|
525
|
+
config.host_name = "127.0.0.1"
|
526
|
+
config.proxy_user = ENV["USER"]
|
527
|
+
config.proxy_host_name = "127.0.0.1"
|
528
|
+
end
|
523
529
|
|
524
|
-
|
530
|
+
data = "Hello World @ #{Time.now.utc}"
|
525
531
|
|
526
|
-
|
527
|
-
|
532
|
+
remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-remote")
|
533
|
+
File.exists?(remote_file) && File.delete(remote_file)
|
528
534
|
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
535
|
+
local_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-local")
|
536
|
+
if RUBY_VERSION < "1.9.3"
|
537
|
+
File.open(local_file, 'w') do |file|
|
538
|
+
file.puts(data)
|
539
|
+
end
|
540
|
+
else
|
541
|
+
IO.write(local_file, data)
|
533
542
|
end
|
534
|
-
else
|
535
|
-
IO.write(local_file, data)
|
536
|
-
end
|
537
543
|
|
538
|
-
|
539
|
-
|
540
|
-
|
544
|
+
File.exists?(remote_file).should == false
|
545
|
+
subject.upload(local_file, remote_file)
|
546
|
+
File.exists?(remote_file).should == true
|
541
547
|
|
542
|
-
|
543
|
-
|
548
|
+
File.exists?(remote_file) && File.delete(remote_file)
|
549
|
+
File.exists?(local_file) && File.delete(local_file)
|
550
|
+
end
|
544
551
|
end
|
545
552
|
|
546
553
|
end
|
547
554
|
|
548
555
|
describe "download" do
|
549
556
|
|
550
|
-
|
551
|
-
|
552
|
-
config
|
557
|
+
[true, false].each do |use_scp|
|
558
|
+
it "should be able to download a file from 127.0.0.1 as the current user using #{use_scp ? 'scp' : 'sftp'} (your key must be in ssh-agent)" do
|
559
|
+
subject.config do |config|
|
560
|
+
config.ui = @ui
|
553
561
|
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
562
|
+
config.user = ENV["USER"]
|
563
|
+
config.host_name = "127.0.0.1"
|
564
|
+
config.proxy_user = ENV["USER"]
|
565
|
+
config.proxy_host_name = "127.0.0.1"
|
566
|
+
end
|
559
567
|
|
560
|
-
|
568
|
+
data = "Hello World @ #{Time.now.utc}"
|
561
569
|
|
562
|
-
|
563
|
-
|
570
|
+
local_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-local")
|
571
|
+
File.exists?(local_file) && File.delete(local_file)
|
564
572
|
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
573
|
+
remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-remote")
|
574
|
+
if RUBY_VERSION < "1.9.3"
|
575
|
+
File.open(remote_file, 'w') do |file|
|
576
|
+
file.puts(data)
|
577
|
+
end
|
578
|
+
else
|
579
|
+
IO.write(remote_file, data)
|
569
580
|
end
|
570
|
-
else
|
571
|
-
IO.write(remote_file, data)
|
572
|
-
end
|
573
581
|
|
574
|
-
|
575
|
-
|
576
|
-
|
582
|
+
File.exists?(local_file).should == false
|
583
|
+
subject.download(remote_file, local_file)
|
584
|
+
File.exists?(local_file).should == true
|
577
585
|
|
578
|
-
|
579
|
-
|
586
|
+
File.exists?(local_file) && File.delete(local_file)
|
587
|
+
File.exists?(remote_file) && File.delete(remote_file)
|
588
|
+
end
|
580
589
|
end
|
581
590
|
|
582
591
|
end
|
data/ztk.gemspec
CHANGED
@@ -39,7 +39,9 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.add_dependency("activesupport")
|
40
40
|
spec.add_dependency("erubis")
|
41
41
|
spec.add_dependency("net-ssh")
|
42
|
+
spec.add_dependency("net-ssh-gateway")
|
42
43
|
spec.add_dependency("net-sftp")
|
44
|
+
spec.add_dependency("net-scp")
|
43
45
|
|
44
46
|
spec.add_development_dependency("pry")
|
45
47
|
spec.add_development_dependency("rake")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ztk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: net-ssh-gateway
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
62
78
|
- !ruby/object:Gem::Dependency
|
63
79
|
name: net-sftp
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +91,22 @@ dependencies:
|
|
75
91
|
- - ! '>='
|
76
92
|
- !ruby/object:Gem::Version
|
77
93
|
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: net-scp
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
78
110
|
- !ruby/object:Gem::Dependency
|
79
111
|
name: pry
|
80
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -275,7 +307,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
275
307
|
version: '0'
|
276
308
|
segments:
|
277
309
|
- 0
|
278
|
-
hash: -
|
310
|
+
hash: -3144121438206062484
|
279
311
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
280
312
|
none: false
|
281
313
|
requirements:
|
@@ -284,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
316
|
version: '0'
|
285
317
|
segments:
|
286
318
|
- 0
|
287
|
-
hash: -
|
319
|
+
hash: -3144121438206062484
|
288
320
|
requirements: []
|
289
321
|
rubyforge_project:
|
290
322
|
rubygems_version: 1.8.25
|