sshkit 1.16.1 → 1.18.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 +4 -4
- data/CHANGELOG.md +11 -1
- data/Gemfile +0 -5
- data/README.md +34 -1
- data/lib/sshkit.rb +3 -0
- data/lib/sshkit/backends/abstract.rb +5 -1
- data/lib/sshkit/backends/local.rb +1 -7
- data/lib/sshkit/backends/netssh.rb +1 -1
- data/lib/sshkit/backends/printer.rb +1 -1
- data/lib/sshkit/command.rb +7 -0
- data/lib/sshkit/version.rb +1 -1
- data/sshkit.gemspec +1 -2
- data/test/functional/backends/test_netssh.rb +39 -4
- data/test/unit/backends/test_abstract.rb +9 -1
- metadata +11 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bebf3a96075e905b11a3f52b5e75064e49f5d710c375ae2c39c7bbd93b7d76bd
|
4
|
+
data.tar.gz: e8d9ab9ec716df400ce730ebc82c74a32c23c83e0edc52b778e74a5cba8055ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e91cf1cbcff6c0dfaef0f2a05a6843f5312f8091b6b55fbc24022cc4e688c29fce690ac09d3b6cb33a9e8c42ba6bcb1441479f5fdf40d111f862ff55bb3b9122
|
7
|
+
data.tar.gz: 3e50dc789ef3dff1ecd3041f89c332bc5883157c9ab2f007148e0c025f47f3a2941bab046661f45dcaa5f4880493674d34ff142df660f19a7eaf82b0c9e5da41
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,14 @@ appear at the top.
|
|
7
7
|
|
8
8
|
* Your contribution here!
|
9
9
|
|
10
|
+
## [1.18.0][] (2018-10-21)
|
11
|
+
|
12
|
+
* [#435](https://github.com/capistrano/sshkit/pull/435): Consistent verbosity configuration #capture and #test methods - [@NikolayRys](https://github.com/NikolayRys)
|
13
|
+
|
14
|
+
## [1.17.0][] (2018-07-07)
|
15
|
+
|
16
|
+
* [#430](https://github.com/capistrano/sshkit/pull/430): [Feature] Command Argument STDOUT/capistrano.log Hiding - [@NorseGaud](https://github.com/NorseGaud)
|
17
|
+
|
10
18
|
## [1.16.1][] (2018-05-20)
|
11
19
|
|
12
20
|
* [#425](https://github.com/capistrano/sshkit/pull/425): Command#group incorrectly escapes double quotes, resulting in a a syntax error when specifying the group execution using `as`. This issue manifested when user command quotes changed from double quotes to single quotes. This fix removes the double quote escaping - [@pblesi](https://github.com/pblesi).
|
@@ -742,7 +750,9 @@ version `0.0.5`.
|
|
742
750
|
|
743
751
|
First release.
|
744
752
|
|
745
|
-
[Unreleased]: https://github.com/capistrano/sshkit/compare/v1.
|
753
|
+
[Unreleased]: https://github.com/capistrano/sshkit/compare/v1.18.0...HEAD
|
754
|
+
[1.18.0]: https://github.com/capistrano/sshkit/compare/v1.17.0...v1.18.0
|
755
|
+
[1.17.0]: https://github.com/capistrano/sshkit/compare/v1.16.1...v1.17.0
|
746
756
|
[1.16.1]: https://github.com/capistrano/sshkit/compare/v1.16.0...v1.16.1
|
747
757
|
[1.16.0]: https://github.com/capistrano/sshkit/compare/v1.15.1...v1.16.0
|
748
758
|
[1.15.1]: https://github.com/capistrano/sshkit/compare/v1.15.0...v1.15.1
|
data/Gemfile
CHANGED
@@ -18,8 +18,3 @@ end
|
|
18
18
|
if Gem::Requirement.new('< 2.1').satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
19
19
|
gem 'public_suffix', '< 3'
|
20
20
|
end
|
21
|
-
|
22
|
-
# rbnacl-libsodium > 1.0.15.1 requires Ruby 2.2.6+
|
23
|
-
if Gem::Requirement.new('< 2.2.6').satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
24
|
-
gem 'rbnacl-libsodium', '<= 1.0.15.1'
|
25
|
-
end
|
data/README.md
CHANGED
@@ -5,7 +5,6 @@ more servers.
|
|
5
5
|
|
6
6
|
[](https://rubygems.org/gems/sshkit)
|
7
7
|
[](https://travis-ci.org/capistrano/sshkit)
|
8
|
-
[](https://gemnasium.com/capistrano/sshkit)
|
9
8
|
|
10
9
|
## How might it work?
|
11
10
|
|
@@ -444,6 +443,38 @@ SSHKit.config.output = SSHKit::Formatter::Pretty.new(output)
|
|
444
443
|
SSHKit.config.output = SSHKit::Formatter::SimpleText.new(File.open('log/deploy.log', 'wb'))
|
445
444
|
```
|
446
445
|
|
446
|
+
#### Output & Log Redaction
|
447
|
+
|
448
|
+
If necessary, `redact` can be used on a section of your `execute` arguments to hide it from both STDOUT and the capistrano.log. It supports the majority of data types.
|
449
|
+
|
450
|
+
```ruby
|
451
|
+
# Example from capistrano-postgresql gem
|
452
|
+
execute(:psql, fetch(:pg_system_db), '-c', %Q{"CREATE USER \\"#{fetch(:pg_username)}\\" PASSWORD}, redact("'#{fetch(:pg_password)}'"), %Q{;"})
|
453
|
+
```
|
454
|
+
Once wrapped, sshkit logging will replace the actual pg_password with a [REDACTED] value. The created database user will have the value from `fetch(:pg_password)`.
|
455
|
+
|
456
|
+
```
|
457
|
+
# STDOUT
|
458
|
+
00:00 postgresql:create_database_user
|
459
|
+
01 sudo -i -u postgres psql -d postgres -c "CREATE USER \"db_admin_user\" PASSWORD [REDACTED] ;"
|
460
|
+
01 CREATE ROLE
|
461
|
+
✔ 01 user@localhost 0.099s
|
462
|
+
|
463
|
+
# capistrano.log
|
464
|
+
INFO [59dbd2ba] Running /usr/bin/env sudo -i -u postgres psql -d postgres -c "CREATE USER \"db_admin_user\" PASSWORD [REDACTED] ;" as user@localhost
|
465
|
+
DEBUG [59dbd2ba] Command: ( export PATH="$HOME/.gem/ruby/2.5.0/bin:$PATH" ; /usr/bin/env sudo -i -u postgres psql -d postgres -c "CREATE USER \"db_admin_user\" PASSWORD [REDACTED] ;" )
|
466
|
+
DEBUG [529b623c] CREATE ROLE
|
467
|
+
|
468
|
+
```
|
469
|
+
|
470
|
+
Certain commands will require that no spaces exist between a string and what you want hidden. Because SSHKIT will include a whitespace between each argument of `execute`, this can be dealt with by wrapping both in redact:
|
471
|
+
|
472
|
+
```ruby
|
473
|
+
# lib/capistrano/tasks/systemd.rake
|
474
|
+
execute :sudo, :echo, redact("CONTENT_WEB_TOOLS_PASS='#{ENV['CONTENT_WEB_TOOLS_PASS']}'"), ">> /etc/systemd/system/#{fetch(:application)}_sidekiq.service.d/EnvironmentFile", '"'
|
475
|
+
|
476
|
+
```
|
477
|
+
|
447
478
|
#### Output Colors
|
448
479
|
|
449
480
|
By default, SSHKit will color the output using ANSI color escape sequences
|
@@ -489,6 +520,8 @@ produces a large amount of noise. They are tagged with a verbosity option on
|
|
489
520
|
the `Command` instances of `Logger::DEBUG`. The default configuration for
|
490
521
|
output verbosity is available to override with `SSHKit.config.output_verbosity=`,
|
491
522
|
and defaults to `Logger::INFO`.
|
523
|
+
Another way to is to provide a hash containing `{verbosity: Logger::INFO}` as
|
524
|
+
a last parameter for the method call.
|
492
525
|
|
493
526
|
At present the `Logger::WARN`, `ERROR` and `FATAL` are not used.
|
494
527
|
|
data/lib/sshkit.rb
CHANGED
@@ -42,6 +42,10 @@ module SSHKit
|
|
42
42
|
@group = nil
|
43
43
|
end
|
44
44
|
|
45
|
+
def redact(arg) # Used in execute_command to hide redact() args a user passes in
|
46
|
+
arg.to_s.extend(Redaction) # to_s due to our inability to extend Integer, etc
|
47
|
+
end
|
48
|
+
|
45
49
|
def make(commands=[])
|
46
50
|
execute :make, commands
|
47
51
|
end
|
@@ -51,7 +55,7 @@ module SSHKit
|
|
51
55
|
end
|
52
56
|
|
53
57
|
def test(*args)
|
54
|
-
options =
|
58
|
+
options = { verbosity: Logger::DEBUG, raise_on_non_zero_exit: false }.merge(args.extract_options!)
|
55
59
|
create_command_and_execute(args, options).success?
|
56
60
|
end
|
57
61
|
|
@@ -39,10 +39,8 @@ module SSHKit
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def execute_command(cmd)
|
42
|
-
output.log_command_start(cmd)
|
43
|
-
|
42
|
+
output.log_command_start(cmd.with_redaction)
|
44
43
|
cmd.started = Time.now
|
45
|
-
|
46
44
|
Open3.popen3(cmd.to_command) do |stdin, stdout, stderr, wait_thr|
|
47
45
|
stdout_thread = Thread.new do
|
48
46
|
while (line = stdout.gets) do
|
@@ -50,19 +48,15 @@ module SSHKit
|
|
50
48
|
output.log_command_data(cmd, :stdout, line)
|
51
49
|
end
|
52
50
|
end
|
53
|
-
|
54
51
|
stderr_thread = Thread.new do
|
55
52
|
while (line = stderr.gets) do
|
56
53
|
cmd.on_stderr(stdin, line)
|
57
54
|
output.log_command_data(cmd, :stderr, line)
|
58
55
|
end
|
59
56
|
end
|
60
|
-
|
61
57
|
stdout_thread.join
|
62
58
|
stderr_thread.join
|
63
|
-
|
64
59
|
cmd.exit_status = wait_thr.value.to_i
|
65
|
-
|
66
60
|
output.log_command_exit(cmd)
|
67
61
|
end
|
68
62
|
end
|
data/lib/sshkit/command.rb
CHANGED
@@ -204,6 +204,13 @@ module SSHKit
|
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
+
def with_redaction
|
208
|
+
new_args = args.map{|arg| arg.is_a?(Redaction) ? '[REDACTED]' : arg }
|
209
|
+
redacted_cmd = dup
|
210
|
+
redacted_cmd.instance_variable_set(:@args, new_args)
|
211
|
+
redacted_cmd
|
212
|
+
end
|
213
|
+
|
207
214
|
def to_s
|
208
215
|
if should_map?
|
209
216
|
[SSHKit.config.command_map[command.to_sym], *Array(args)].join(' ')
|
data/lib/sshkit/version.rb
CHANGED
data/sshkit.gemspec
CHANGED
@@ -29,6 +29,5 @@ Gem::Specification.new do |gem|
|
|
29
29
|
gem.add_development_dependency('mocha')
|
30
30
|
|
31
31
|
gem.add_development_dependency('bcrypt_pbkdf')
|
32
|
-
gem.add_development_dependency('
|
33
|
-
gem.add_development_dependency('rbnacl-libsodium')
|
32
|
+
gem.add_development_dependency('ed25519', '>= 1.2', '< 2.0')
|
34
33
|
end
|
@@ -42,13 +42,43 @@ module SSHKit
|
|
42
42
|
], command_lines
|
43
43
|
end
|
44
44
|
|
45
|
+
def test_redaction
|
46
|
+
# Be sure redaction in the logs is showing [REDACTED]
|
47
|
+
Netssh.new(a_host) do
|
48
|
+
execute :echo, 'password:', redact('PASSWORD')
|
49
|
+
execute :echo, 'password:', redact(10000)
|
50
|
+
execute :echo, 'password:', redact(['test1','test2'])
|
51
|
+
execute :echo, 'password:', redact({:test => 'test_value'})
|
52
|
+
end.run
|
53
|
+
command_lines = @output.lines.select { |line| line.start_with?('Command:') }
|
54
|
+
assert_equal [
|
55
|
+
"Command: /usr/bin/env echo password: [REDACTED]\n",
|
56
|
+
"Command: /usr/bin/env echo password: [REDACTED]\n",
|
57
|
+
"Command: /usr/bin/env echo password: [REDACTED]\n",
|
58
|
+
"Command: /usr/bin/env echo password: [REDACTED]\n"
|
59
|
+
], command_lines
|
60
|
+
# Be sure the actual command executed without *REDACTED*
|
61
|
+
Netssh.new(a_host) do
|
62
|
+
file_name = 'test.file'
|
63
|
+
execute :touch, redact("'#{file_name}'") # Test and be sure single quotes are included in actual command; expected /usr/bin/env touch 'test.file'
|
64
|
+
execute :ls, 'test.file'
|
65
|
+
end.run
|
66
|
+
ls_lines = @output.lines.select { |line| line.start_with?("\ttest.file") }
|
67
|
+
assert_equal [
|
68
|
+
"\ttest.file\n"
|
69
|
+
], ls_lines
|
70
|
+
# Cleanup
|
71
|
+
Netssh.new(a_host) do
|
72
|
+
execute :rm, ' -f test.file'
|
73
|
+
end.run
|
74
|
+
end
|
75
|
+
|
45
76
|
def test_group_netssh
|
46
77
|
Netssh.new(a_host) do
|
47
78
|
as user: :root, group: :admin do
|
48
79
|
execute :touch, 'restart.txt'
|
49
80
|
end
|
50
81
|
end.run
|
51
|
-
|
52
82
|
command_lines = @output.lines.select { |line| line.start_with?('Command:') }
|
53
83
|
assert_equal [
|
54
84
|
"Command: if ! sudo -u root whoami > /dev/null; then echo \"You cannot switch to user 'root' using sudo, please check the sudoers file\" 1>&2; false; fi\n",
|
@@ -66,16 +96,21 @@ module SSHKit
|
|
66
96
|
end
|
67
97
|
|
68
98
|
def test_ssh_option_merge
|
69
|
-
|
99
|
+
verify_host_opt = if Net::SSH::Version::MAJOR >= 5
|
100
|
+
{ verify_host_key: :always }
|
101
|
+
else
|
102
|
+
{ paranoid: true }
|
103
|
+
end
|
104
|
+
a_host.ssh_options = verify_host_opt
|
70
105
|
host_ssh_options = {}
|
71
106
|
SSHKit::Backend::Netssh.config.ssh_options = { forward_agent: false }
|
72
107
|
Netssh.new(a_host) do |host|
|
73
108
|
capture(:uname)
|
74
109
|
host_ssh_options = host.ssh_options
|
75
110
|
end.run
|
76
|
-
assert_equal [:forward_agent,
|
111
|
+
assert_equal [:forward_agent, *verify_host_opt.keys, :known_hosts, :logger, :password_prompt].sort, host_ssh_options.keys.sort
|
77
112
|
assert_equal false, host_ssh_options[:forward_agent]
|
78
|
-
assert_equal
|
113
|
+
assert_equal verify_host_opt.values.first, host_ssh_options[verify_host_opt.keys.first]
|
79
114
|
assert_instance_of SSHKit::Backend::Netssh::KnownHosts, host_ssh_options[:known_hosts]
|
80
115
|
end
|
81
116
|
|
@@ -40,7 +40,7 @@ module SSHKit
|
|
40
40
|
)
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
43
|
+
def test_test_creates_and_executes_command_with_false_raise_on_non_zero_exit
|
44
44
|
backend = ExampleBackend.new do
|
45
45
|
test '[ -d /some/file ]'
|
46
46
|
end
|
@@ -51,6 +51,14 @@ module SSHKit
|
|
51
51
|
assert_equal false, backend.executed_command.options[:raise_on_non_zero_exit], 'raise_on_non_zero_exit option'
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_test_allows_to_override_verbosity
|
55
|
+
backend = ExampleBackend.new do
|
56
|
+
test 'echo output', {verbosity: Logger::INFO}
|
57
|
+
end
|
58
|
+
backend.run
|
59
|
+
assert_equal(backend.executed_command.options[:verbosity], Logger::INFO)
|
60
|
+
end
|
61
|
+
|
54
62
|
def test_capture_creates_and_executes_command_and_returns_stripped_output
|
55
63
|
output = nil
|
56
64
|
backend = ExampleBackend.new do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sshkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Hambley
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-ssh
|
@@ -152,33 +152,25 @@ dependencies:
|
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
|
-
name:
|
156
|
-
requirement: !ruby/object:Gem::Requirement
|
157
|
-
requirements:
|
158
|
-
- - "~>"
|
159
|
-
- !ruby/object:Gem::Version
|
160
|
-
version: '3.4'
|
161
|
-
type: :development
|
162
|
-
prerelease: false
|
163
|
-
version_requirements: !ruby/object:Gem::Requirement
|
164
|
-
requirements:
|
165
|
-
- - "~>"
|
166
|
-
- !ruby/object:Gem::Version
|
167
|
-
version: '3.4'
|
168
|
-
- !ruby/object:Gem::Dependency
|
169
|
-
name: rbnacl-libsodium
|
155
|
+
name: ed25519
|
170
156
|
requirement: !ruby/object:Gem::Requirement
|
171
157
|
requirements:
|
172
158
|
- - ">="
|
173
159
|
- !ruby/object:Gem::Version
|
174
|
-
version: '
|
160
|
+
version: '1.2'
|
161
|
+
- - "<"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '2.0'
|
175
164
|
type: :development
|
176
165
|
prerelease: false
|
177
166
|
version_requirements: !ruby/object:Gem::Requirement
|
178
167
|
requirements:
|
179
168
|
- - ">="
|
180
169
|
- !ruby/object:Gem::Version
|
181
|
-
version: '
|
170
|
+
version: '1.2'
|
171
|
+
- - "<"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '2.0'
|
182
174
|
description: A comprehensive toolkit for remotely running commands in a structured
|
183
175
|
manner on groups of servers.
|
184
176
|
email:
|