spectre-ssh 1.2.3 → 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 +4 -4
- data/lib/spectre/ssh.rb +70 -84
- metadata +14 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f13557c403d5bcd207fba8935bce62e99aed681a9383253563d8a211d0c8dc0d
|
4
|
+
data.tar.gz: f5493676adda1f6e8d3c765d38e410ba2b04a23549a871826afdeb356ec9594e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 625cdd34e6be526409fe86b25ea7859581d8625bc3497a88a6cfc25843b65da06e43a0b9b2d2b15b75105f9fa93622a88b5abfc082d971da75448c0ae5b1fd86
|
7
|
+
data.tar.gz: 4726e468350db0b4bcb7f506e749a0e12f6f3f02310fbad19f0c71eac7d484771875de7df5fa8c46d1a6884339b61e091b6d8addbd70a1b1c517b50b6257a6de
|
data/lib/spectre/ssh.rb
CHANGED
@@ -1,50 +1,52 @@
|
|
1
1
|
require 'net/ssh'
|
2
|
-
require 'logger'
|
3
|
-
require 'spectre'
|
4
|
-
require 'spectre/logging'
|
5
2
|
require 'net/ssh/proxy/http'
|
3
|
+
require 'logger'
|
6
4
|
|
7
5
|
module Spectre
|
8
6
|
module SSH
|
9
7
|
@@cfg = {}
|
10
8
|
|
11
|
-
class
|
9
|
+
class SshError < StandardError
|
12
10
|
end
|
13
11
|
|
14
|
-
class
|
12
|
+
class SshConnection
|
13
|
+
include Spectre::Delegate if defined? Spectre::Delegate
|
14
|
+
|
15
|
+
attr_reader :exit_code, :output
|
16
|
+
|
15
17
|
def initialize host, username, opts, logger
|
16
18
|
opts[:non_interactive] = true
|
17
19
|
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
20
|
+
@logger = logger
|
21
|
+
@host = host
|
22
|
+
@username = username
|
23
|
+
@opts = opts
|
24
|
+
@session = nil
|
25
|
+
@exit_code = nil
|
26
|
+
@output = ''
|
25
27
|
end
|
26
28
|
|
27
29
|
def username user
|
28
|
-
@
|
30
|
+
@username = user
|
29
31
|
end
|
30
32
|
|
31
33
|
def password pass
|
32
|
-
@
|
33
|
-
@
|
34
|
+
@opts[:password] = pass
|
35
|
+
@opts[:auth_methods].push('password') unless @opts[:auth_methods].include? 'password'
|
34
36
|
end
|
35
37
|
|
36
38
|
def private_key file_path
|
37
|
-
@
|
38
|
-
@
|
39
|
+
@opts[:keys] = [file_path]
|
40
|
+
@opts[:auth_methods].push('publickey') unless @opts[:auth_methods].include? 'publickey'
|
39
41
|
end
|
40
42
|
|
41
43
|
def passphrase phrase
|
42
|
-
@
|
44
|
+
@opts[:passphrase] = phrase
|
43
45
|
end
|
44
46
|
|
45
47
|
def file_exists path
|
46
48
|
exec "ls #{path}"
|
47
|
-
exit_code
|
49
|
+
@exit_code.nil? || @exit_code.zero?
|
48
50
|
end
|
49
51
|
|
50
52
|
def owner_of path
|
@@ -53,90 +55,87 @@ module Spectre
|
|
53
55
|
end
|
54
56
|
|
55
57
|
def connect!
|
56
|
-
return unless @
|
58
|
+
return unless @session.nil? or @session.closed?
|
57
59
|
|
58
60
|
begin
|
59
|
-
@
|
61
|
+
@session = Net::SSH.start(@host, @username, @opts)
|
60
62
|
rescue SocketError
|
61
|
-
raise
|
63
|
+
raise SshError, "Unable to connect to #{@host} with user #{@username}"
|
62
64
|
rescue Net::SSH::AuthenticationFailed
|
63
|
-
raise
|
65
|
+
raise SshError, "Authentication failed for #{@username}@#{@host}. \
|
66
|
+
Please check password, SSH keys and passphrases."
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
67
70
|
def close
|
68
|
-
return unless @
|
71
|
+
return unless @session and !@session.closed?
|
69
72
|
|
70
|
-
@
|
73
|
+
@session.close
|
71
74
|
end
|
72
75
|
|
73
76
|
def can_connect?
|
74
|
-
@
|
77
|
+
@output = nil
|
75
78
|
|
76
79
|
begin
|
77
80
|
connect!
|
78
|
-
@
|
79
|
-
@
|
80
|
-
@
|
81
|
+
@session.open_channel.close
|
82
|
+
@output = "successfully connected to #{@host} with user #{@username}"
|
83
|
+
@exit_code = 0
|
81
84
|
return true
|
82
|
-
rescue
|
83
|
-
@
|
84
|
-
@
|
85
|
-
@
|
85
|
+
rescue StandardError => e
|
86
|
+
@logger.error e.message
|
87
|
+
@output = "unable to connect to #{@host} with user #{@username}"
|
88
|
+
@exit_code = 1
|
86
89
|
end
|
87
90
|
|
88
|
-
|
91
|
+
false
|
89
92
|
end
|
90
93
|
|
91
94
|
def exec command
|
92
95
|
connect!
|
93
96
|
|
94
|
-
log_str = "#{@
|
97
|
+
log_str = "ssh #{@username}@#{@session.host} -p #{@session.options[:port]} #{command}"
|
95
98
|
|
96
|
-
@
|
99
|
+
@session.open_channel do |channel|
|
97
100
|
channel.exec(command) do |_ch, success|
|
98
|
-
abort "could not execute #{command} on #{@
|
101
|
+
abort "could not execute #{command} on #{@session.host}" unless success
|
99
102
|
|
100
|
-
@
|
103
|
+
@output = ''
|
101
104
|
|
102
|
-
channel.on_data do |
|
103
|
-
@
|
105
|
+
channel.on_data do |_ch, data|
|
106
|
+
@output += data
|
104
107
|
end
|
105
108
|
|
106
|
-
channel.on_extended_data do |
|
107
|
-
@
|
109
|
+
channel.on_extended_data do |_ch, _type, data|
|
110
|
+
@output += data
|
108
111
|
end
|
109
112
|
|
110
|
-
channel.on_request('exit-status') do |
|
111
|
-
@
|
113
|
+
channel.on_request('exit-status') do |_ch, data|
|
114
|
+
@exit_code = data.read_long
|
112
115
|
end
|
113
116
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
+
channel.on_request('exit-signal') do |_ch, data|
|
118
|
+
@exit_code = data.read_long
|
119
|
+
end
|
117
120
|
end
|
118
|
-
end
|
119
|
-
|
120
|
-
@channel.wait
|
121
|
-
@__session.loop
|
121
|
+
end.wait
|
122
122
|
|
123
|
-
|
124
|
-
@__logger.info log_str
|
125
|
-
end
|
126
|
-
|
127
|
-
def output
|
128
|
-
@__output
|
129
|
-
end
|
123
|
+
@session.loop
|
130
124
|
|
131
|
-
|
132
|
-
@
|
125
|
+
log_str += "\n" + @output
|
126
|
+
@logger.info(log_str)
|
133
127
|
end
|
134
128
|
end
|
135
129
|
|
130
|
+
class Client
|
131
|
+
def initialize config, logger
|
132
|
+
@config = config['ssh']
|
133
|
+
@logger = logger
|
134
|
+
@debug = config['debug']
|
135
|
+
end
|
136
136
|
|
137
|
-
|
138
|
-
|
139
|
-
cfg = @@cfg[name] || {}
|
137
|
+
def ssh(name, options = {}, &)
|
138
|
+
cfg = @config[name] || {}
|
140
139
|
|
141
140
|
host = cfg['host'] || name
|
142
141
|
username = options[:username] || cfg['username']
|
@@ -151,41 +150,28 @@ module Spectre
|
|
151
150
|
opts[:passphrase] = options[:passphrase] || cfg['passphrase']
|
152
151
|
|
153
152
|
opts[:auth_methods] = []
|
154
|
-
opts[:auth_methods].push
|
155
|
-
opts[:auth_methods].push
|
153
|
+
opts[:auth_methods].push('publickey') unless opts[:keys].nil? or opts[:keys].empty?
|
154
|
+
opts[:auth_methods].push('password') unless opts[:password].nil?
|
156
155
|
|
157
156
|
proxy_host = options[:proxy_host] || cfg['proxy_host']
|
158
157
|
proxy_port = options[:proxy_port] || cfg['proxy_port']
|
159
158
|
opts[:proxy] = Net::SSH::Proxy::HTTP.new(proxy_host, proxy_port) unless proxy_host.nil?
|
160
159
|
|
161
|
-
if
|
162
|
-
opts[:logger] = @@logger.logger
|
160
|
+
if @debug
|
163
161
|
opts[:verbose] = Logger::DEBUG
|
162
|
+
opts[:logger] = @logger
|
164
163
|
end
|
165
164
|
|
166
|
-
ssh_con =
|
165
|
+
ssh_con = SshConnection.new(host, username, opts, @logger)
|
167
166
|
|
168
167
|
begin
|
169
|
-
ssh_con.instance_eval
|
168
|
+
ssh_con.instance_eval(&)
|
170
169
|
ensure
|
171
170
|
ssh_con.close
|
172
171
|
end
|
173
172
|
end
|
174
173
|
end
|
175
|
-
|
176
|
-
Spectre.register do |config|
|
177
|
-
@@logger = Spectre::Logging::ModuleLogger.new(config, 'spectre/ssh')
|
178
|
-
@@debug = config['debug']
|
179
|
-
|
180
|
-
if config.key? 'ssh'
|
181
|
-
@@debug = config['ssh'].delete('debug') if config['ssh'].key? 'debug'
|
182
|
-
|
183
|
-
config['ssh'].each do |name, cfg|
|
184
|
-
@@cfg[name] = cfg
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
Spectre.delegate :ssh, to: self
|
190
174
|
end
|
175
|
+
|
176
|
+
Engine.register(SSH::Client, :ssh) if defined? Engine
|
191
177
|
end
|
metadata
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spectre-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Neubauer
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-03-21 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
13
|
+
name: bcrypt_pbkdf
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
@@ -25,7 +24,7 @@ dependencies:
|
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: '0'
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
27
|
+
name: ed25519
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
30
|
- - ">="
|
@@ -39,21 +38,21 @@ dependencies:
|
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: '0'
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
41
|
+
name: net-ssh
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - ">="
|
46
45
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
46
|
+
version: '0'
|
48
47
|
type: :runtime
|
49
48
|
prerelease: false
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
51
50
|
requirements:
|
52
51
|
- - ">="
|
53
52
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
53
|
+
version: '0'
|
55
54
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
55
|
+
name: openssl
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
58
|
- - ">="
|
@@ -67,7 +66,7 @@ dependencies:
|
|
67
66
|
- !ruby/object:Gem::Version
|
68
67
|
version: '0'
|
69
68
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
69
|
+
name: stringio
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
72
71
|
requirements:
|
73
72
|
- - ">="
|
@@ -80,7 +79,7 @@ dependencies:
|
|
80
79
|
- - ">="
|
81
80
|
- !ruby/object:Gem::Version
|
82
81
|
version: '0'
|
83
|
-
description:
|
82
|
+
description: A SSH wrapper for nice readability. Is compatible with spectre-core.
|
84
83
|
email:
|
85
84
|
- christian.neubauer@ionos.com
|
86
85
|
executables: []
|
@@ -90,12 +89,11 @@ files:
|
|
90
89
|
- lib/spectre/ssh.rb
|
91
90
|
homepage: https://github.com/ionos-spectre/spectre-ssh
|
92
91
|
licenses:
|
93
|
-
-
|
92
|
+
- GPL-3.0-or-later
|
94
93
|
metadata:
|
95
94
|
homepage_uri: https://github.com/ionos-spectre/spectre-ssh
|
96
95
|
source_code_uri: https://github.com/ionos-spectre/spectre-ssh
|
97
96
|
changelog_uri: https://github.com/ionos-spectre/spectre-ssh/blob/master/CHANGELOG.md
|
98
|
-
post_install_message:
|
99
97
|
rdoc_options: []
|
100
98
|
require_paths:
|
101
99
|
- lib
|
@@ -103,15 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
101
|
requirements:
|
104
102
|
- - ">="
|
105
103
|
- !ruby/object:Gem::Version
|
106
|
-
version: 3.
|
104
|
+
version: '3.4'
|
107
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
106
|
requirements:
|
109
107
|
- - ">="
|
110
108
|
- !ruby/object:Gem::Version
|
111
109
|
version: '0'
|
112
110
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
114
|
-
signing_key:
|
111
|
+
rubygems_version: 3.6.6
|
115
112
|
specification_version: 4
|
116
|
-
summary: SSH
|
113
|
+
summary: Standalone SSH wrapper compatible with spectre
|
117
114
|
test_files: []
|