sshake 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f07fcd2695da038870ae9a7c15715524ed1cbd1912a38c9cbd4c3d3d9f39d96
4
- data.tar.gz: c941f1f5ae3dd0348da4c694f769fdad2fcaa026777cf0c8a5cd6278d179a87a
3
+ metadata.gz: 95a0f6a6db803ff62826997e18e0b5d5ec81977046833bc32c10e29ebdbfd883
4
+ data.tar.gz: 8a2c9aa526b96827b3d50d25cd8b479bf3310eb6857822790410e79a38ac8423
5
5
  SHA512:
6
- metadata.gz: 0c7636ffe034fc59aa89043bfb44d6e78d156567283f5a77b82eeb98df91f8977e561c2435f2512261166a0242fe0d75b5c7ca8369b9babd6f96729f29323dc5
7
- data.tar.gz: bc5eb231a03e4e207a9c478bdb4b3764366f48d82576d6d60b2daa3571cce7383c9f8d6d4d49d786b8c6fbf6582fee132cdb7039f7a40c9a90a44ffd5083856f
6
+ metadata.gz: dc53e93b8e027f96c6078acb1626a056512dbf932a5650a1e4e4dfa53d28d72c219cff4acb392ca3d46fcbd5cd136aa7114b3edca27884817f86ace0648ec0c5
7
+ data.tar.gz: 25e70b953ed507800fa3f1a0531c926023d383f8a73caf8de201e12db2b4dd4e864af0080bf657952ad00112528572368e6c9eced39adf254858897e9487a6e3
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'securerandom'
4
- require 'sshake/logger'
4
+ require 'klogger'
5
+ require 'sshake/klogger'
5
6
  require 'sshake/execution_options'
6
7
 
7
8
  module SSHake
@@ -9,8 +10,8 @@ module SSHake
9
10
 
10
11
  # A logger for this session
11
12
  #
12
- # @return [Logger, nil]
13
- attr_accessor :logger
13
+ # @return [Klogger, nil]
14
+ attr_accessor :klogger
14
15
 
15
16
  # An ID for this session
16
17
  #
@@ -22,8 +23,9 @@ module SSHake
22
23
  # @return [Boolean]
23
24
  attr_accessor :raise_on_error
24
25
 
25
- def initialize(*_args)
26
+ def initialize(*_args, klogger: nil)
26
27
  @id = SecureRandom.hex(4)
28
+ @klogger = klogger || SSHake.klogger
27
29
  end
28
30
 
29
31
  # Connect to the SSH server
@@ -88,17 +90,6 @@ module SSHake
88
90
  end
89
91
  end
90
92
 
91
- def log(type, text, _options = {})
92
- logger = @logger || SSHake.logger
93
- return unless logger
94
-
95
- prefix = "[#{@id}] [#{@host}] "
96
-
97
- text.split(/\n/).each do |line|
98
- logger.send(type, prefix + line)
99
- end
100
- end
101
-
102
93
  def prepare_commands(commands, execution_options, **options)
103
94
  commands = [commands] unless commands.is_a?(Array)
104
95
 
data/lib/sshake/error.rb CHANGED
@@ -19,7 +19,7 @@ module SSHake
19
19
 
20
20
  def message
21
21
  "Failed to execute command: #{@response.command} " \
22
- "(stderr: #{@response.stderr}) (exit code: #{@response.exit_code})"
22
+ "(stderr: #{@response.stderr}) (exit code: #{@response.exit_code})"
23
23
  end
24
24
 
25
25
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SSHake
4
+
5
+ class << self
6
+
7
+ def klogger
8
+ @klogger ||= Klogger.new(:ssh, destination: $stdout, formatter: :go)
9
+ end
10
+ attr_writer :klogger
11
+
12
+ end
13
+
14
+ end
@@ -12,11 +12,11 @@ module SSHake
12
12
  attr_accessor :command, :options, :captures
13
13
 
14
14
  def store
15
- @session ? @session.store : nil
15
+ @session&.store
16
16
  end
17
17
 
18
18
  def written_files
19
- @session ? @session.written_files : nil
19
+ @session&.written_files
20
20
  end
21
21
 
22
22
  end
@@ -23,23 +23,19 @@ module SSHake
23
23
  # Create a new SSH session
24
24
  #
25
25
  # @return [Sshake::Session]
26
- def initialize(host, username_or_options = {}, options_with_username = {})
26
+ def initialize(host, username = nil, **options)
27
27
  super
28
28
  @host = host
29
- if username_or_options.is_a?(String)
30
- @user = username_or_options
31
- @session_options = options_with_username
32
- else
33
- @user = username_or_options.delete(:user)
34
- @session_options = username_or_options
35
- end
29
+ @username = username
30
+ @session_options = options
31
+ @session_options.delete(:klogger)
36
32
  end
37
33
 
38
34
  # Return the username for the connection
39
35
  #
40
36
  # @return [String]
41
37
  def user
42
- @user || ENV['USER']
38
+ @user || ENV.fetch('USER', nil)
43
39
  end
44
40
 
45
41
  # Return the port that will be connected to
@@ -53,8 +49,7 @@ module SSHake
53
49
  #
54
50
  # @return [void]
55
51
  def connect
56
- log :debug, "Creating connection to #{@host}"
57
- log :debug, "Session options: #{@session_options.inspect}"
52
+ klogger.debug 'Connecting', id: @id, host: @host, user: @user, port: @session_options[:port] || 22
58
53
  @session = Net::SSH.start(@host, user, @session_options)
59
54
  true
60
55
  end
@@ -73,11 +68,11 @@ module SSHake
73
68
  return false if @session.nil?
74
69
 
75
70
  begin
76
- log :debug, 'Closing connectiong'
71
+ klogger.debug 'Closing connection', id: @id, host: @host
77
72
  @session.close
78
- log :debug, 'Connection closed successfully'
73
+ klogger.debug 'Connection closed', id: @id, host: @host
79
74
  rescue StandardError => e
80
- log :debug, "Connection not closed: #{e.message} (#{e.class})"
75
+ logger.exception(e, 'Connection not closed')
81
76
  nil
82
77
  end
83
78
  @session = nil
@@ -86,12 +81,13 @@ module SSHake
86
81
 
87
82
  # Kill the underlying connection
88
83
  def kill!
89
- log :debug, 'Attempting kill/shutdown of session'
84
+ klogger.debug 'Attemping to shutdown', id: @id, host: @host
90
85
  @session.shutdown!
91
- log :debug, 'Session shutdown success'
86
+ klogger.debug 'Shutdown success', id: @id, host: @host
92
87
  @session = nil
93
88
  end
94
89
 
90
+ # rubocop:disable Metrics/AbcSize
95
91
  def execute(commands, options = nil, &block)
96
92
  options = create_options(options, block)
97
93
  command_to_execute = prepare_commands(commands, options)
@@ -101,83 +97,86 @@ module SSHake
101
97
  response.command = command_to_execute
102
98
  connect unless connected?
103
99
 
104
- # Log the command
105
- log :info, "Executing: #{command_to_execute}"
106
- log :debug, "Timeout: #{options.timeout}"
100
+ klogger.group(id: @id, host: @host) do
101
+ klogger.info 'Executing command', command: command_to_execute, timeout: options.timeout
107
102
 
108
- begin
109
- channel = nil
110
- Timeout.timeout(options.timeout) do
111
- channel = @session.open_channel do |ch|
112
- response.start_time = Time.now
113
- channel.exec(command_to_execute) do |_, success|
114
- raise "Command \"#{command_to_execute}\" was unable to execute" unless success
115
-
116
- ch.send_data(options.stdin) if options.stdin
117
-
118
- if options.file_to_stream.nil? && options.sudo_password.nil?
119
- log :debug, 'Sending EOF to channel'
120
- ch.eof!
121
- end
103
+ begin
104
+ channel = nil
122
105
 
123
- ch.on_data do |_, data|
124
- response.stdout += data
125
- options.stdout&.call(data)
126
- log :debug, data.gsub(/\r/, '')
127
- end
106
+ Timeout.timeout(options.timeout) do
107
+ channel = @session.open_channel do |ch|
108
+ response.start_time = Time.now
128
109
 
129
- ch.on_extended_data do |_, _, data|
130
- response.stderr += data.delete("\r")
131
- options.stderr&.call(data)
132
- log :debug, data
133
- if options.sudo_password && data =~ /^\[sshake-sudo-password\]:\s\z/
134
- log :debug, 'Sending sudo password'
135
- ch.send_data "#{options.sudo_password}\n"
136
-
137
- if options.file_to_stream.nil?
138
- log :debug, 'Sending EOF after sudo password because no file'
139
- ch.eof!
140
- end
141
- end
142
- end
110
+ channel.exec(command_to_execute) do |_, success|
111
+ raise "Command \"#{command_to_execute}\" was unable to execute" unless success
143
112
 
144
- ch.on_request('exit-status') do |_, data|
145
- response.exit_code = data.read_long&.to_i
146
- log :debug, "Exit code: #{response.exit_code}"
147
- end
113
+ ch.send_data(options.stdin) if options.stdin
148
114
 
149
- ch.on_request('exit-signal') do |_, data|
150
- response.exit_signal = data.read_long
151
- end
115
+ if options.file_to_stream.nil? && options.sudo_password.nil?
116
+ klogger.debug 'Sending EOF to channel'
117
+ ch.eof!
118
+ end
152
119
 
153
- if options.file_to_stream
154
- ch.on_process do |_, data|
155
- next if ch.eof?
120
+ ch.on_data do |_, data|
121
+ response.stdout += data
122
+ options.stdout&.call(data)
123
+ klogger.debug "[stdout] #{data.gsub(/\r/, '').strip}"
124
+ end
125
+
126
+ ch.on_extended_data do |_, _, data|
127
+ response.stderr += data.delete("\r")
128
+ options.stderr&.call(data)
129
+ klogger.debug "[stderr] #{data.gsub(/\r/, '').strip}"
130
+ if options.sudo_password && data =~ /^\[sshake-sudo-password\]:\s\z/
131
+ klogger.debug 'Sending sudo password', length: options.sudo_password.length
132
+ ch.send_data "#{options.sudo_password}\n"
156
133
 
157
- if ch.output.length < 128 * 1024
158
- if data = options.file_to_stream.read(1024 * 1024)
159
- ch.send_data(data)
160
- response.bytes_streamed += data.bytesize
161
- else
134
+ if options.file_to_stream.nil?
135
+ klogger.debug 'Sending EOF after password'
162
136
  ch.eof!
163
137
  end
164
138
  end
165
139
  end
140
+
141
+ ch.on_request('exit-status') do |_, data|
142
+ response.exit_code = data.read_long&.to_i
143
+ klogger.info 'Exited', exit_code: response.exit_code
144
+ end
145
+
146
+ ch.on_request('exit-signal') do |_, data|
147
+ response.exit_signal = data.read_long
148
+ end
149
+
150
+ if options.file_to_stream
151
+ ch.on_process do |_, data|
152
+ next if ch.eof?
153
+
154
+ if ch.output.length < 128 * 1024
155
+ if data = options.file_to_stream.read(1024 * 1024)
156
+ ch.send_data(data)
157
+ response.bytes_streamed += data.bytesize
158
+ else
159
+ ch.eof!
160
+ end
161
+ end
162
+ end
163
+ end
166
164
  end
167
165
  end
166
+ channel.wait
168
167
  end
169
- channel.wait
168
+ rescue Timeout::Error
169
+ klogger.debug 'Command timed out'
170
+ kill!
171
+ response.timeout!
172
+ ensure
173
+ response.finish_time = Time.now
170
174
  end
171
- rescue Timeout::Error
172
- log :debug, 'Got timeout error while executing command'
173
- kill!
174
- response.timeout!
175
- ensure
176
- response.finish_time = Time.now
177
175
  end
178
176
 
179
177
  handle_response(response, options)
180
178
  end
179
+ # rubocop:enable Metrics/AbcSize
181
180
 
182
181
  def write_data(path, data, options = nil, &block)
183
182
  connect unless connected?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module SSHake
4
4
 
5
- VERSION = '1.1.0'
5
+ VERSION = '2.0.0'
6
6
 
7
7
  end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sshake
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Cooke
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-26 00:00:00.000000000 Z
11
+ date: 2023-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: klogger-logger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: net-sftp
15
35
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +70,7 @@ files:
50
70
  - lib/sshake/error.rb
51
71
  - lib/sshake/execution_options.rb
52
72
  - lib/sshake/execution_options_dsl.rb
53
- - lib/sshake/logger.rb
73
+ - lib/sshake/klogger.rb
54
74
  - lib/sshake/mock/command.rb
55
75
  - lib/sshake/mock/command_set.rb
56
76
  - lib/sshake/mock/environment.rb
@@ -66,8 +86,9 @@ files:
66
86
  homepage: https://github.com/adamcooke/sshake
67
87
  licenses:
68
88
  - MIT
69
- metadata: {}
70
- post_install_message:
89
+ metadata:
90
+ rubygems_mfa_required: 'true'
91
+ post_install_message:
71
92
  rdoc_options: []
72
93
  require_paths:
73
94
  - lib
@@ -82,8 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
103
  - !ruby/object:Gem::Version
83
104
  version: '0'
84
105
  requirements: []
85
- rubygems_version: 3.0.3
86
- signing_key:
106
+ rubygems_version: 3.2.32
107
+ signing_key:
87
108
  specification_version: 4
88
109
  summary: A wrapper for net/ssh to make running commands more fun
89
110
  test_files: []
data/lib/sshake/logger.rb DELETED
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SSHake
4
-
5
- class << self
6
-
7
- attr_accessor :logger
8
-
9
- end
10
-
11
- end