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 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}" }
@@ -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
- @ssh ||= Net::SSH.start(config.host_name, config.user, ssh_options)
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
- # Close our session gracefully.
24
- def close
25
- config.ui.logger.debug { "close" }
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
- @ssh = nil
44
- @sftp = nil
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.
@@ -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 = {:recursive => ::File.directory?(local) }.merge(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
- sftp.download!(remote.to_s, local.to_s, options.send(:table)) do |event, downloader, *args|
37
- case event
38
- when :open
39
- options.ui.logger.debug { "download(#{args[0].remote} -> #{args[0].local})" }
40
- options.on_progress.nil? or options.on_progress.call(:open, args)
41
- when :close
42
- options.ui.logger.debug { "close(#{args[0].local})" }
43
- options.on_progress.nil? or options.on_progress.call(:close, args)
44
- when :mkdir
45
- options.ui.logger.debug { "mkdir(#{args[0]})" }
46
- options.on_progress.nil? or options.on_progress.call(:mkdir, args)
47
- when :get
48
- options.ui.logger.debug { "get(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
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
 
@@ -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
- options = {}
10
-
11
- # These are plainly documented on the Net::SSH config class.
12
- options.merge!(:encryption => config.encryption) if config.encryption
13
- options.merge!(:compression => config.compression) if config.compression
14
- options.merge!(:compression_level => config.compression_level) if config.compression_level
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
@@ -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
- sftp.upload!(local.to_s, remote.to_s) do |event, uploader, *args|
32
- case event
33
- when :open
34
- options.ui.logger.debug { "upload(#{args[0].local} -> #{args[0].remote})" }
35
- options.on_progress.nil? or options.on_progress.call(:open, args)
36
- when :close
37
- options.ui.logger.debug { "close(#{args[0].remote})" }
38
- options.on_progress.nil? or options.on_progress.call(:close, args)
39
- when :mkdir
40
- options.ui.logger.debug { "mkdir(#{args[0]})" }
41
- options.on_progress.nil? or options.on_progress.call(:mkdir, args)
42
- when :put
43
- options.ui.logger.debug { "put(#{args[0].remote}, size #{args[2].size} bytes, offset #{args[1]})" }
44
- options.on_progress.nil? or options.on_progress.call(:put, args)
45
- when :finish
46
- options.ui.logger.debug { "finish" }
47
- options.on_progress.nil? or options.on_progress.call(:finish, args)
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
@@ -1,6 +1,6 @@
1
1
  module ZTK
2
2
 
3
3
  # ZTK Version String
4
- VERSION = "1.9.1"
4
+ VERSION = "1.10.0"
5
5
 
6
6
  end
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
- it "should be able to upload a file to 127.0.0.1 as the current user (your key must be in ssh-agent)" do
235
- subject.config do |config|
236
- config.ui = @ui
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
- config.user = ENV["USER"]
239
- config.host_name = "127.0.0.1"
240
- end
239
+ config.user = ENV["USER"]
240
+ config.host_name = "127.0.0.1"
241
+ end
241
242
 
242
- data = "Hello World @ #{Time.now.utc}"
243
+ data = "Hello World @ #{Time.now.utc}"
243
244
 
244
- remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-remote")
245
- File.exists?(remote_file) && File.delete(remote_file)
245
+ remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-remote")
246
+ File.exists?(remote_file) && File.delete(remote_file)
246
247
 
247
- local_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-local")
248
- if RUBY_VERSION < "1.9.3"
249
- File.open(local_file, 'w') do |file|
250
- file.puts(data)
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
- File.exists?(remote_file).should == false
257
- subject.upload(local_file, remote_file)
258
- File.exists?(remote_file).should == true
257
+ File.exists?(remote_file).should == false
258
+ subject.upload(local_file, remote_file)
259
+ File.exists?(remote_file).should == true
259
260
 
260
- File.exists?(remote_file) && File.delete(remote_file)
261
- File.exists?(local_file) && File.delete(local_file)
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
- it "should be able to download a file from 127.0.0.1 as the current user (your key must be in ssh-agent)" do
269
- subject.config do |config|
270
- config.ui = @ui
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
- config.user = ENV["USER"]
273
- config.host_name = "127.0.0.1"
274
- end
275
+ config.user = ENV["USER"]
276
+ config.host_name = "127.0.0.1"
277
+ config.use_scp = use_scp
278
+ end
275
279
 
276
- data = "Hello World @ #{Time.now.utc}"
280
+ data = "Hello World @ #{Time.now.utc}"
277
281
 
278
- local_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-local")
279
- File.exists?(local_file) && File.delete(local_file)
282
+ local_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-local")
283
+ File.exists?(local_file) && File.delete(local_file)
280
284
 
281
- remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-remote")
282
- if RUBY_VERSION < "1.9.3"
283
- File.open(remote_file, 'w') do |file|
284
- file.puts(data)
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
- File.exists?(local_file).should == false
291
- subject.download(remote_file, local_file)
292
- File.exists?(local_file).should == true
294
+ File.exists?(local_file).should == false
295
+ subject.download(remote_file, local_file)
296
+ File.exists?(local_file).should == true
293
297
 
294
- File.exists?(local_file) && File.delete(local_file)
295
- File.exists?(remote_file) && File.delete(remote_file)
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
- it "should be able to upload a file to 127.0.0.1 as the current user (your key must be in ssh-agent)" do
515
- subject.config do |config|
516
- config.ui = @ui
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
- config.user = ENV["USER"]
519
- config.host_name = "127.0.0.1"
520
- config.proxy_user = ENV["USER"]
521
- config.proxy_host_name = "127.0.0.1"
522
- end
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
- data = "Hello World @ #{Time.now.utc}"
530
+ data = "Hello World @ #{Time.now.utc}"
525
531
 
526
- remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-remote")
527
- File.exists?(remote_file) && File.delete(remote_file)
532
+ remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-remote")
533
+ File.exists?(remote_file) && File.delete(remote_file)
528
534
 
529
- local_file = File.join(ZTK::Locator.root, "tmp", "ssh-upload-local")
530
- if RUBY_VERSION < "1.9.3"
531
- File.open(local_file, 'w') do |file|
532
- file.puts(data)
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
- File.exists?(remote_file).should == false
539
- subject.upload(local_file, remote_file)
540
- File.exists?(remote_file).should == true
544
+ File.exists?(remote_file).should == false
545
+ subject.upload(local_file, remote_file)
546
+ File.exists?(remote_file).should == true
541
547
 
542
- File.exists?(remote_file) && File.delete(remote_file)
543
- File.exists?(local_file) && File.delete(local_file)
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
- it "should be able to download a file from 127.0.0.1 as the current user (your key must be in ssh-agent)" do
551
- subject.config do |config|
552
- config.ui = @ui
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
- config.user = ENV["USER"]
555
- config.host_name = "127.0.0.1"
556
- config.proxy_user = ENV["USER"]
557
- config.proxy_host_name = "127.0.0.1"
558
- end
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
- data = "Hello World @ #{Time.now.utc}"
568
+ data = "Hello World @ #{Time.now.utc}"
561
569
 
562
- local_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-local")
563
- File.exists?(local_file) && File.delete(local_file)
570
+ local_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-local")
571
+ File.exists?(local_file) && File.delete(local_file)
564
572
 
565
- remote_file = File.join(ZTK::Locator.root, "tmp", "ssh-download-remote")
566
- if RUBY_VERSION < "1.9.3"
567
- File.open(remote_file, 'w') do |file|
568
- file.puts(data)
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
- File.exists?(local_file).should == false
575
- subject.download(remote_file, local_file)
576
- File.exists?(local_file).should == true
582
+ File.exists?(local_file).should == false
583
+ subject.download(remote_file, local_file)
584
+ File.exists?(local_file).should == true
577
585
 
578
- File.exists?(local_file) && File.delete(local_file)
579
- File.exists?(remote_file) && File.delete(remote_file)
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.9.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-05 00:00:00.000000000 Z
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: -4609495191496685449
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: -4609495191496685449
319
+ hash: -3144121438206062484
288
320
  requirements: []
289
321
  rubyforge_project:
290
322
  rubygems_version: 1.8.25