sshake 1.1.0 → 2.0.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.
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