remotus 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +5 -4
- data/.rubocop.yml +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +3 -1
- data/Gemfile.lock +25 -20
- data/README.md +9 -0
- data/docker/Dockerfile +16 -0
- data/docker/entrypoint.sh +3 -0
- data/docker/ssh_integration_script.sh +8 -0
- data/docker/ssh_integration_spec.rb +84 -0
- data/docker-compose.yml +10 -0
- data/lib/remotus/host_pool.rb +7 -0
- data/lib/remotus/result.rb +1 -1
- data/lib/remotus/ssh_connection.rb +97 -17
- data/lib/remotus/version.rb +1 -1
- data/remotus.gemspec +1 -0
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b375e9a93879a30b113991e9b653e602f30d970743925527af92a964298d7a27
|
4
|
+
data.tar.gz: 97bab3f384551a63e665d173e9b90330f03d3e8b56e6e89a9c216b18e37c2a66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b3ded8d0ceb3c4b36736e875ca9ed80a85d77d388d1fb26f5a9659350622230c4f17efaee017e7765ddc081cd0ba52e767af960514a54c4061f667b38f1933c
|
7
|
+
data.tar.gz: 53aaf5d724c91a5639ce5f7928c6049b5912c21a523f2d1e5697191fb2511611e384fa5ce14fe92a53affaa8e707e42f5a5539ce83c93a16549bc1ac0fb3e5e5
|
data/.github/workflows/main.yml
CHANGED
@@ -6,21 +6,22 @@ jobs:
|
|
6
6
|
build:
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
steps:
|
9
|
-
- uses: actions/checkout@
|
9
|
+
- uses: actions/checkout@v3
|
10
10
|
- name: Set up Ruby
|
11
11
|
uses: ruby/setup-ruby@v1
|
12
12
|
with:
|
13
|
-
ruby-version:
|
13
|
+
ruby-version: 3.0.4
|
14
14
|
- name: Run unit tests and code linting
|
15
15
|
run: |
|
16
|
-
gem install bundler -v 2.2.
|
16
|
+
gem install bundler -v 2.2.33
|
17
17
|
bundle install
|
18
18
|
bundle exec rake
|
19
|
+
bundle exec rspec docker
|
19
20
|
bundle exec yard
|
20
21
|
|
21
22
|
- name: Deploy documentation
|
22
23
|
if: github.ref == 'refs/heads/main'
|
23
|
-
uses: crazy-max/ghaction-github-pages@
|
24
|
+
uses: crazy-max/ghaction-github-pages@v3.0.0
|
24
25
|
with:
|
25
26
|
target_branch: gh-pages
|
26
27
|
build_dir: doc
|
data/.rubocop.yml
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.0.4
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
remotus (0.
|
4
|
+
remotus (0.5.0)
|
5
5
|
connection_pool (~> 2.2)
|
6
6
|
net-scp (~> 3.0)
|
7
7
|
net-ssh (~> 6.1)
|
8
|
+
net-ssh-gateway (~> 2.0)
|
8
9
|
winrm (~> 2.3)
|
9
10
|
winrm-elevated (~> 1.2)
|
10
11
|
winrm-fs (~> 1.3)
|
@@ -14,9 +15,9 @@ GEM
|
|
14
15
|
specs:
|
15
16
|
ast (2.4.2)
|
16
17
|
builder (3.2.4)
|
17
|
-
connection_pool (2.
|
18
|
+
connection_pool (2.3.0)
|
18
19
|
diff-lcs (1.5.0)
|
19
|
-
erubi (1.
|
20
|
+
erubi (1.11.0)
|
20
21
|
ffi (1.15.5)
|
21
22
|
gssapi (1.3.1)
|
22
23
|
ffi (>= 1.0.1)
|
@@ -24,6 +25,7 @@ GEM
|
|
24
25
|
builder (>= 2.1.2)
|
25
26
|
rexml (~> 3.0)
|
26
27
|
httpclient (2.8.3)
|
28
|
+
json (2.6.2)
|
27
29
|
little-plugger (1.1.4)
|
28
30
|
logging (2.3.1)
|
29
31
|
little-plugger (~> 1.1)
|
@@ -32,13 +34,15 @@ GEM
|
|
32
34
|
net-scp (3.0.0)
|
33
35
|
net-ssh (>= 2.6.5, < 7.0.0)
|
34
36
|
net-ssh (6.1.0)
|
37
|
+
net-ssh-gateway (2.0.0)
|
38
|
+
net-ssh (>= 4.0.0)
|
35
39
|
nori (2.6.0)
|
36
|
-
parallel (1.
|
37
|
-
parser (3.1.
|
40
|
+
parallel (1.22.1)
|
41
|
+
parser (3.1.2.1)
|
38
42
|
ast (~> 2.4.1)
|
39
43
|
rainbow (3.1.1)
|
40
44
|
rake (13.0.6)
|
41
|
-
regexp_parser (2.
|
45
|
+
regexp_parser (2.5.0)
|
42
46
|
rexml (3.2.5)
|
43
47
|
rspec (3.11.0)
|
44
48
|
rspec-core (~> 3.11.0)
|
@@ -46,32 +50,33 @@ GEM
|
|
46
50
|
rspec-mocks (~> 3.11.0)
|
47
51
|
rspec-core (3.11.0)
|
48
52
|
rspec-support (~> 3.11.0)
|
49
|
-
rspec-expectations (3.11.
|
53
|
+
rspec-expectations (3.11.1)
|
50
54
|
diff-lcs (>= 1.2.0, < 2.0)
|
51
55
|
rspec-support (~> 3.11.0)
|
52
|
-
rspec-mocks (3.11.
|
56
|
+
rspec-mocks (3.11.1)
|
53
57
|
diff-lcs (>= 1.2.0, < 2.0)
|
54
58
|
rspec-support (~> 3.11.0)
|
55
|
-
rspec-support (3.11.
|
56
|
-
rubocop (1.
|
59
|
+
rspec-support (3.11.1)
|
60
|
+
rubocop (1.36.0)
|
61
|
+
json (~> 2.3)
|
57
62
|
parallel (~> 1.10)
|
58
|
-
parser (>= 3.1.
|
63
|
+
parser (>= 3.1.2.1)
|
59
64
|
rainbow (>= 2.2.2, < 4.0)
|
60
65
|
regexp_parser (>= 1.8, < 3.0)
|
61
|
-
rexml
|
62
|
-
rubocop-ast (>= 1.
|
66
|
+
rexml (>= 3.2.5, < 4.0)
|
67
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
63
68
|
ruby-progressbar (~> 1.7)
|
64
69
|
unicode-display_width (>= 1.4.0, < 3.0)
|
65
|
-
rubocop-ast (1.
|
66
|
-
parser (>= 3.
|
70
|
+
rubocop-ast (1.21.0)
|
71
|
+
parser (>= 3.1.1.0)
|
67
72
|
rubocop-rake (0.6.0)
|
68
73
|
rubocop (~> 1.0)
|
69
|
-
rubocop-rspec (2.
|
70
|
-
rubocop (~> 1.
|
74
|
+
rubocop-rspec (2.13.1)
|
75
|
+
rubocop (~> 1.33)
|
71
76
|
ruby-progressbar (1.11.0)
|
72
77
|
rubyntlm (0.6.3)
|
73
78
|
rubyzip (2.3.2)
|
74
|
-
unicode-display_width (2.
|
79
|
+
unicode-display_width (2.3.0)
|
75
80
|
webrick (1.7.0)
|
76
81
|
winrm (2.3.6)
|
77
82
|
builder (>= 2.1.2)
|
@@ -91,7 +96,7 @@ GEM
|
|
91
96
|
logging (>= 1.6.1, < 3.0)
|
92
97
|
rubyzip (~> 2.0)
|
93
98
|
winrm (~> 2.0)
|
94
|
-
yard (0.9.
|
99
|
+
yard (0.9.28)
|
95
100
|
webrick (~> 1.7.0)
|
96
101
|
|
97
102
|
PLATFORMS
|
@@ -108,4 +113,4 @@ DEPENDENCIES
|
|
108
113
|
yard (~> 0.9)
|
109
114
|
|
110
115
|
BUNDLED WITH
|
111
|
-
2.2.
|
116
|
+
2.2.33
|
data/README.md
CHANGED
@@ -30,6 +30,15 @@ connection = Remotus.connect("remotehost.local", proto: :ssh, port: 2222)
|
|
30
30
|
# Initialize a new connection pool to remotehost.local with a defined protocol and port and arbitrary metadata
|
31
31
|
connection = Remotus.connect("remotehost.local", proto: :ssh, port: 2222, company: "Test Corp", location: "Oslo")
|
32
32
|
|
33
|
+
# Initialize a new connection pool to remotehost.local via a gateway host named gateway.local
|
34
|
+
connection = Remotus.connect("remotehost.local", gateway_host: "gateway.local")
|
35
|
+
|
36
|
+
# Initialize a new connection pool to remotehost.local via a gateway host named gateway.local with a defined protocol and port
|
37
|
+
connection = Remotus.connect("remotehost.local", proto: :ssh, port: 2222, gateway_host: "gateway.local", gateway_port: 2222)
|
38
|
+
|
39
|
+
# Initialize a new connection pool to remotehost.local via a gateway host named gateway.local with arbitrary metadata
|
40
|
+
connection = Remotus.connect("remotehost.local", company: "Test Corp", gateway_host: "gateway.local", gateway_metadata: { company: "Other Corp" })
|
41
|
+
|
33
42
|
# Create a credential for the new connection pool
|
34
43
|
connection.credential = Remotus::Auth::Credential.new("username", "password")
|
35
44
|
|
data/docker/Dockerfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
FROM alpine:latest
|
2
|
+
|
3
|
+
COPY entrypoint.sh /
|
4
|
+
|
5
|
+
RUN apk add --update --no-cache openssh && \
|
6
|
+
sed -i '/GatewayPorts.*/d' /etc/ssh/sshd_config && \
|
7
|
+
echo 'GatewayPorts yes' >> /etc/ssh/sshd_config && \
|
8
|
+
sed -i '/AllowTcpForwarding.*/d' /etc/ssh/sshd_config && \
|
9
|
+
echo 'AllowTcpForwarding yes' >> /etc/ssh/sshd_config && \
|
10
|
+
echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config && \
|
11
|
+
adduser -h /home/testuser -s /bin/sh -D testuser && \
|
12
|
+
echo 'testuser:testuser' | chpasswd
|
13
|
+
|
14
|
+
ENTRYPOINT ["/entrypoint.sh"]
|
15
|
+
|
16
|
+
EXPOSE 22
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Assumes docker-compose is available
|
4
|
+
|
5
|
+
RSpec.describe "Remotus::SshConnection Integration Tests" do
|
6
|
+
before(:all) do
|
7
|
+
# docker-compose startup
|
8
|
+
`docker-compose -f "docker-compose.yml" up -d --build`
|
9
|
+
|
10
|
+
# Set up Remotus credentials based on Dockerfile
|
11
|
+
Remotus::Auth.cache["localhost"] = Remotus::Auth::Credential.new("testuser", "testuser")
|
12
|
+
Remotus::Auth.cache["target"] = Remotus::Auth::Credential.new("testuser", "testuser")
|
13
|
+
|
14
|
+
# Allow time for sshd to start up
|
15
|
+
sleep 1
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:all) do
|
19
|
+
# docker-compose cleanup
|
20
|
+
`docker-compose -f "docker-compose.yml" down -v`
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:test_script) { ::File.join(__dir__, "ssh_integration_script.sh") }
|
24
|
+
let(:test_script_dest) { ::File.join("/home/testuser", ::File.basename(test_script)) }
|
25
|
+
|
26
|
+
context "when a gateway and inaccessible target host exist" do
|
27
|
+
let(:gateway_hostname) { `docker ps | grep remotus_gateway`.split.first }
|
28
|
+
let(:target_hostname) { `docker ps | grep remotus_target`.split.first }
|
29
|
+
let(:gateway_connection) { Remotus.connect("localhost", proto: :ssh, port: 2222) }
|
30
|
+
let(:target_connection) { Remotus.connect("target", proto: :ssh, port: 22, gateway_host: "localhost", gateway_port: 2222) }
|
31
|
+
|
32
|
+
it "Connects to the gateway host successfully" do
|
33
|
+
expect(gateway_connection.run("hostname").stdout.chomp).to eq(gateway_hostname)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "Can run a script against the gateway host successfully" do
|
37
|
+
result = gateway_connection.run_script(test_script, test_script_dest)
|
38
|
+
expect(result.stdout).to eq("success")
|
39
|
+
expect(result.success?).to eq(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "Can upload a file to the gateway host" do
|
43
|
+
result = gateway_connection.upload(test_script, "/home/testuser/upload_test")
|
44
|
+
expect(result).to eq("/home/testuser/upload_test")
|
45
|
+
expect(gateway_connection.file_exist?("/home/testuser/upload_test")).to eq(true)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "Can download a file from the gateway host" do
|
49
|
+
gateway_connection.run('echo -n "test" > /home/testuser/download_test')
|
50
|
+
result = gateway_connection.download("/home/testuser/download_test")
|
51
|
+
expect(result).to eq("test")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "Can check if a file exists on the gateway host" do
|
55
|
+
expect(gateway_connection.file_exist?("/home/testuser")).to eq(true)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "Connects to the target host successfully" do
|
59
|
+
expect(target_connection.run("hostname").stdout.chomp).to eq(target_hostname)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "Can run a script against the target host successfully" do
|
63
|
+
result = target_connection.run_script(test_script, test_script_dest)
|
64
|
+
expect(result.stdout).to eq("success")
|
65
|
+
expect(result.success?).to eq(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "Can upload a file to the target host" do
|
69
|
+
result = target_connection.upload(test_script, "/home/testuser/upload_test")
|
70
|
+
expect(result).to eq("/home/testuser/upload_test")
|
71
|
+
expect(target_connection.file_exist?("/home/testuser/upload_test")).to eq(true)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "Can download a file from the target host" do
|
75
|
+
target_connection.run('echo -n "test" > /home/testuser/download_test')
|
76
|
+
result = target_connection.download("/home/testuser/download_test")
|
77
|
+
expect(result).to eq("test")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "Can check if a file exists on the target host" do
|
81
|
+
expect(target_connection.file_exist?("/home/testuser")).to eq(true)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/docker-compose.yml
ADDED
data/lib/remotus/host_pool.rb
CHANGED
@@ -42,6 +42,13 @@ module Remotus
|
|
42
42
|
# @param [Hash] metadata metadata for this connection. Useful for providing additional information to various authentication stores
|
43
43
|
# should be specified using snake_case symbol keys. If keys are not snake_case, they will be converted.
|
44
44
|
#
|
45
|
+
# To configure a connection gateway, the following metadata entries can be provided to the host pool:
|
46
|
+
# :gateway_host
|
47
|
+
# :gateway_port
|
48
|
+
# :gateway_metadata
|
49
|
+
#
|
50
|
+
# These function similarly to the host, port, and host_pool metadata fields.
|
51
|
+
#
|
45
52
|
def initialize(host, size: DEFAULT_POOL_SIZE, timeout: DEFAULT_EXPIRATION_SECONDS, port: nil, proto: nil, **metadata)
|
46
53
|
Remotus.logger.debug { "Creating host pool for #{host}" }
|
47
54
|
|
data/lib/remotus/result.rb
CHANGED
@@ -65,7 +65,7 @@ module Remotus
|
|
65
65
|
def error!(accepted_exit_codes = [0])
|
66
66
|
return unless error?(accepted_exit_codes)
|
67
67
|
|
68
|
-
raise Remotus::ResultError, "Error encountered executing #{@command}! Exit code #{@exit_code} was returned "\
|
68
|
+
raise Remotus::ResultError, "Error encountered executing #{@command}! Exit code #{@exit_code} was returned " \
|
69
69
|
"while a value in #{accepted_exit_codes} was expected.\n#{output}"
|
70
70
|
end
|
71
71
|
|
@@ -6,6 +6,7 @@ require "remotus/result"
|
|
6
6
|
require "remotus/auth"
|
7
7
|
require "net/scp"
|
8
8
|
require "net/ssh"
|
9
|
+
require "net/ssh/gateway"
|
9
10
|
|
10
11
|
module Remotus
|
11
12
|
# Class representing an SSH connection to a host
|
@@ -21,6 +22,9 @@ module Remotus
|
|
21
22
|
# Number of default retries
|
22
23
|
DEFAULT_RETRIES = 2
|
23
24
|
|
25
|
+
# Base options for new SSH connections
|
26
|
+
BASE_CONNECT_OPTIONS = { non_interactive: true, keepalive: true, keepalive_interval: KEEPALIVE_INTERVAL }.freeze
|
27
|
+
|
24
28
|
# @return [Integer] Remote port
|
25
29
|
attr_reader :port
|
26
30
|
|
@@ -33,12 +37,50 @@ module Remotus
|
|
33
37
|
# Delegate metadata methods to associated host pool
|
34
38
|
def_delegators :@host_pool, :[], :[]=
|
35
39
|
|
40
|
+
# Internal gateway connection class to allow for the host and metadata to be pulled for the gateway
|
41
|
+
# by authentication credentials
|
42
|
+
class GatewayConnection
|
43
|
+
extend Forwardable
|
44
|
+
|
45
|
+
# @return [String] host gateway hostname
|
46
|
+
attr_reader :host
|
47
|
+
|
48
|
+
# @return [Integer] Remote port
|
49
|
+
attr_reader :port
|
50
|
+
|
51
|
+
# @return [Net::SSH::Gateway] connection gateway connection
|
52
|
+
attr_accessor :connection
|
53
|
+
|
54
|
+
# Delegate metadata methods to associated hash
|
55
|
+
def_delegators :@metadata, :[], :[]=
|
56
|
+
|
57
|
+
#
|
58
|
+
# Creates a GatewayConnection
|
59
|
+
#
|
60
|
+
# @param [String] host hostname
|
61
|
+
# @param [Integer] port remote port
|
62
|
+
# @param [Hash] metadata associated metadata for this gateway
|
63
|
+
#
|
64
|
+
def initialize(host, port = REMOTE_PORT, metadata = {})
|
65
|
+
@host = host
|
66
|
+
@port = port
|
67
|
+
@metadata = metadata
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
36
71
|
#
|
37
72
|
# Creates an SshConnection
|
38
73
|
#
|
39
74
|
# @param [String] host hostname
|
40
75
|
# @param [Integer] port remote port
|
41
76
|
# @param [Remotus::HostPool] host_pool associated host pool
|
77
|
+
# To configure the gateway, the following metadata
|
78
|
+
# entries can be provided to the host pool:
|
79
|
+
# :gateway_host
|
80
|
+
# :gateway_port
|
81
|
+
# :gateway_metadata
|
82
|
+
#
|
83
|
+
# These function similarly to the host, port, and host_pool metadata fields.
|
42
84
|
#
|
43
85
|
def initialize(host, port = REMOTE_PORT, host_pool: nil)
|
44
86
|
Remotus.logger.debug { "Creating SshConnection #{object_id} for #{host}" }
|
@@ -77,23 +119,32 @@ module Remotus
|
|
77
119
|
def connection
|
78
120
|
return @connection unless restart_connection?
|
79
121
|
|
80
|
-
|
122
|
+
target_cred = Remotus::Auth.credential(self)
|
123
|
+
|
124
|
+
Remotus.logger.debug { "Initializing SSH connection to #{target_cred.user}@#{@host}:#{@port}" }
|
81
125
|
|
82
|
-
|
126
|
+
target_options = BASE_CONNECT_OPTIONS.dup
|
127
|
+
target_options[:password] = target_cred.password if target_cred.password
|
128
|
+
target_options[:keys] = [target_cred.private_key] if target_cred.private_key
|
129
|
+
target_options[:key_data] = [target_cred.private_key_data] if target_cred.private_key_data
|
130
|
+
target_options[:port] = @port || REMOTE_PORT
|
83
131
|
|
84
|
-
|
85
|
-
|
86
|
-
|
132
|
+
if via_gateway?
|
133
|
+
@gateway = GatewayConnection.new(@host_pool[:gateway_host], @host_pool[:gateway_port], @host_pool[:gateway_metadata])
|
134
|
+
gateway_cred = Remotus::Auth.credential(@gateway)
|
135
|
+
gateway_options = BASE_CONNECT_OPTIONS.dup
|
136
|
+
gateway_options[:port] = @gateway.port || REMOTE_PORT
|
137
|
+
gateway_options[:password] = gateway_cred.password if gateway_cred.password
|
138
|
+
gateway_options[:keys] = [gateway_cred.private_key] if gateway_cred.private_key
|
139
|
+
gateway_options[:key_data] = [gateway_cred.private_key_data] if gateway_cred.private_key_data
|
87
140
|
|
88
|
-
|
89
|
-
options[:keys] = [private_key_path] if private_key_path
|
90
|
-
options[:key_data] = [private_key_data] if private_key_data
|
141
|
+
Remotus.logger.debug { "Initializing SSH gateway connection to #{gateway_cred.user}@#{@gateway.host}:#{gateway_options[:port]}" }
|
91
142
|
|
92
|
-
|
93
|
-
@host,
|
94
|
-
|
95
|
-
**
|
96
|
-
|
143
|
+
@gateway.connection = Net::SSH::Gateway.new(@gateway.host, gateway_cred.user, **gateway_options)
|
144
|
+
@gateway.connection.ssh(@host, target_cred.user, **target_options)
|
145
|
+
else
|
146
|
+
@connection = Net::SSH.start(@host, target_cred.user, **target_options)
|
147
|
+
end
|
97
148
|
end
|
98
149
|
|
99
150
|
#
|
@@ -392,10 +443,30 @@ module Remotus
|
|
392
443
|
return true unless @connection
|
393
444
|
return true if @connection.closed?
|
394
445
|
return true if @host != @connection.host
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
return true if
|
446
|
+
|
447
|
+
target_cred = Remotus::Auth.credential(self)
|
448
|
+
|
449
|
+
return true if target_cred.user != @connection.options[:user]
|
450
|
+
return true if target_cred.password != @connection.options[:password]
|
451
|
+
return true if Array(target_cred.private_key) != Array(@connection.options[:keys])
|
452
|
+
return true if Array(target_cred.private_key_data) != Array(@connection.options[:key_data])
|
453
|
+
|
454
|
+
# Perform gateway checks
|
455
|
+
if via_gateway?
|
456
|
+
return true unless @gateway&.connection&.active?
|
457
|
+
|
458
|
+
gateway_session = @gateway.connection.instance_variable_get(:@session)
|
459
|
+
|
460
|
+
return true if gateway_session.closed?
|
461
|
+
return true if @host_pool[:gateway_host] != gateway_session.host
|
462
|
+
|
463
|
+
gateway_cred = Remotus::Auth.credential(@gateway)
|
464
|
+
|
465
|
+
return true if gateway_cred.user != @connection.options[:user]
|
466
|
+
return true if gateway_cred.password != @connection.options[:password]
|
467
|
+
return true if Array(gateway_cred.private_key) != Array(@connection.options[:keys])
|
468
|
+
return true if Array(gateway_cred.private_key_data) != Array(@connection.options[:key_data])
|
469
|
+
end
|
399
470
|
|
400
471
|
false
|
401
472
|
end
|
@@ -469,5 +540,14 @@ module Remotus
|
|
469
540
|
Remotus.logger.debug { "Generated permission commands #{cmds}" }
|
470
541
|
cmds
|
471
542
|
end
|
543
|
+
|
544
|
+
#
|
545
|
+
# Whether connecting via an SSH gateway
|
546
|
+
#
|
547
|
+
# @return [Boolean] true if using a gateway, false otherwise
|
548
|
+
#
|
549
|
+
def via_gateway?
|
550
|
+
host_pool && host_pool[:gateway_host]
|
551
|
+
end
|
472
552
|
end
|
473
553
|
end
|
data/lib/remotus/version.rb
CHANGED
data/remotus.gemspec
CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_dependency "connection_pool", "~> 2.2"
|
33
33
|
spec.add_dependency "net-scp", "~> 3.0"
|
34
34
|
spec.add_dependency "net-ssh", "~> 6.1"
|
35
|
+
spec.add_dependency "net-ssh-gateway", "~> 2.0"
|
35
36
|
spec.add_dependency "winrm", "~> 2.3"
|
36
37
|
spec.add_dependency "winrm-elevated", "~> 1.2"
|
37
38
|
spec.add_dependency "winrm-fs", "~> 1.3"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remotus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Newell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: connection_pool
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '6.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: net-ssh-gateway
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: winrm
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -189,6 +203,7 @@ files:
|
|
189
203
|
- ".gitignore"
|
190
204
|
- ".rspec"
|
191
205
|
- ".rubocop.yml"
|
206
|
+
- ".ruby-version"
|
192
207
|
- CHANGELOG.md
|
193
208
|
- Gemfile
|
194
209
|
- Gemfile.lock
|
@@ -197,6 +212,11 @@ files:
|
|
197
212
|
- Rakefile
|
198
213
|
- bin/console
|
199
214
|
- bin/setup
|
215
|
+
- docker-compose.yml
|
216
|
+
- docker/Dockerfile
|
217
|
+
- docker/entrypoint.sh
|
218
|
+
- docker/ssh_integration_script.sh
|
219
|
+
- docker/ssh_integration_spec.rb
|
200
220
|
- lib/remotus.rb
|
201
221
|
- lib/remotus/auth.rb
|
202
222
|
- lib/remotus/auth/credential.rb
|
@@ -235,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
255
|
- !ruby/object:Gem::Version
|
236
256
|
version: '0'
|
237
257
|
requirements: []
|
238
|
-
rubygems_version: 3.
|
258
|
+
rubygems_version: 3.2.33
|
239
259
|
signing_key:
|
240
260
|
specification_version: 4
|
241
261
|
summary: Ruby gem for connecting to remote systems seamlessly via WinRM or SSH.
|