ztk 1.9.1 → 1.10.0

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.
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