kanrisuru 0.19.4 → 0.20.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 +4 -0
- data/kanrisuru.gemspec +1 -0
- data/lib/kanrisuru/core/system/commands/sysctl.rb +1 -1
- data/lib/kanrisuru/core/system/parsers/sysctl.rb +5 -5
- data/lib/kanrisuru/remote/cluster.rb +3 -9
- data/lib/kanrisuru/remote/host.rb +38 -1
- data/lib/kanrisuru/version.rb +1 -1
- data/spec/helper/hosts.json +9 -0
- data/spec/helper/test_hosts.rb +5 -0
- data/spec/support/shared_examples/integration/core/system.rb +1 -1
- data/spec/support/shared_examples/integration/remote/host.rb +41 -0
- data/spec/unit/remote/host_spec.rb +40 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 767ab1b59818ddd394ef7f4bb96435e5be43d2bf89c2c4469419f20a8a5f4a0c
|
4
|
+
data.tar.gz: 4c370eb4c60270ed707a78606976b391d098c1298de026558c80a543e28d8326
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cacf38cbfc427dfe1c3a1980a8c52e3c004f119b13473380f0eaeeb0eba39c5c495bed0a2a2be37add8b8d148505f6a34ff7f0455b6a6c4c6b71f2e80849c75
|
7
|
+
data.tar.gz: fbf05703912544955455f75af13ce799e0a039ee7269e7106bb3e2db9e1882cc2b2d90ee535c85e3bd0f259bffe4cfc4684ef49f97bf76884eaa61e1b8d3bc72
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## Kanrisuru 0.20.0 (February 21, 2022) ##
|
2
|
+
* Allow hosts to be connected via proxy host. This is much like using a bastion / jump server.
|
3
|
+
* Add integration test cases for proxy host connection.
|
4
|
+
|
1
5
|
## Kanrisuru 0.19.4 (February 19, 2022) ##
|
2
6
|
* Add additional family types to `ss` command.
|
3
7
|
|
data/kanrisuru.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_runtime_dependency 'net-ping', '~> 2.0'
|
28
28
|
gem.add_runtime_dependency 'net-scp', '~> 3.0'
|
29
29
|
gem.add_runtime_dependency 'net-ssh', '~> 6.1'
|
30
|
+
gem.add_runtime_dependency 'net-ssh-gateway', '~> 2.0'
|
30
31
|
|
31
32
|
gem.files = `git ls-files`.split("\n")
|
32
33
|
gem.require_paths = ['lib']
|
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'ostruct'
|
3
4
|
|
4
5
|
module Kanrisuru
|
5
6
|
module Core
|
6
7
|
module System
|
7
8
|
module Parser
|
8
|
-
class Sysctl
|
9
|
+
class Sysctl
|
9
10
|
class << self
|
10
11
|
def parse(command)
|
11
12
|
result = {}
|
12
13
|
|
13
14
|
lines = command.to_a
|
14
15
|
lines.each do |line|
|
15
|
-
next if line.include?(
|
16
|
+
next if line.include?('permission denied on key')
|
16
17
|
|
17
18
|
keys, value = parse_line(line)
|
18
19
|
next if Kanrisuru::Util.blank?(value)
|
@@ -27,7 +28,7 @@ module Kanrisuru
|
|
27
28
|
def build_struct(hash)
|
28
29
|
struct = Struct.new(*hash.keys).new
|
29
30
|
|
30
|
-
hash.
|
31
|
+
hash.each_key do |key|
|
31
32
|
struct[key] = hash[key].is_a?(Hash) ? build_struct(hash[key]) : hash[key]
|
32
33
|
end
|
33
34
|
|
@@ -35,7 +36,7 @@ module Kanrisuru
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def merge_recursively(h1, h2)
|
38
|
-
h1.merge(h2) do |
|
39
|
+
h1.merge(h2) do |_k, v1, v2|
|
39
40
|
if v1.is_a?(Hash) && v2.is_a?(Hash)
|
40
41
|
merge_recursively(v1, v2)
|
41
42
|
else
|
@@ -64,7 +65,6 @@ module Kanrisuru
|
|
64
65
|
|
65
66
|
[string.split('.').map(&:to_sym), value]
|
66
67
|
end
|
67
|
-
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -60,9 +60,7 @@ module Kanrisuru
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def su(user)
|
63
|
-
@hosts.each
|
64
|
-
host.su(user)
|
65
|
-
end
|
63
|
+
@hosts.each { |_, host| host.su(user) }
|
66
64
|
end
|
67
65
|
|
68
66
|
def chdir(path = '~')
|
@@ -70,15 +68,11 @@ module Kanrisuru
|
|
70
68
|
end
|
71
69
|
|
72
70
|
def cd(path = '~')
|
73
|
-
@hosts.each
|
74
|
-
host.cd(path)
|
75
|
-
end
|
71
|
+
@hosts.each { |_, host| host.cd(path) }
|
76
72
|
end
|
77
73
|
|
78
74
|
def disconnect
|
79
|
-
@hosts.each
|
80
|
-
host.disconnect
|
81
|
-
end
|
75
|
+
@hosts.each { |_, host| host.disconnect }
|
82
76
|
end
|
83
77
|
|
84
78
|
private
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'net/ssh'
|
4
|
+
require 'net/ssh/gateway'
|
4
5
|
require 'net/scp'
|
5
6
|
require 'net/ping'
|
6
7
|
|
@@ -12,6 +13,8 @@ module Kanrisuru
|
|
12
13
|
attr_reader :host, :username, :password, :port, :keys
|
13
14
|
|
14
15
|
def initialize(opts = {})
|
16
|
+
@opts = opts
|
17
|
+
|
15
18
|
@host = opts[:host]
|
16
19
|
@username = opts[:username]
|
17
20
|
@login_user = @username
|
@@ -84,7 +87,11 @@ module Kanrisuru
|
|
84
87
|
end
|
85
88
|
|
86
89
|
def ssh
|
87
|
-
@ssh ||=
|
90
|
+
@ssh ||= init_ssh
|
91
|
+
end
|
92
|
+
|
93
|
+
def proxy
|
94
|
+
@proxy ||= init_proxy
|
88
95
|
end
|
89
96
|
|
90
97
|
def ping?
|
@@ -110,6 +117,7 @@ module Kanrisuru
|
|
110
117
|
|
111
118
|
def disconnect
|
112
119
|
ssh.close
|
120
|
+
proxy&.close(ssh.transport.port)
|
113
121
|
end
|
114
122
|
|
115
123
|
private
|
@@ -158,6 +166,35 @@ module Kanrisuru
|
|
158
166
|
end
|
159
167
|
end
|
160
168
|
|
169
|
+
def init_ssh
|
170
|
+
if proxy&.active?
|
171
|
+
proxy.ssh(@host, @username,
|
172
|
+
keys: @keys, password: @password, port: @port)
|
173
|
+
else
|
174
|
+
Net::SSH.start(@host, @username,
|
175
|
+
keys: @keys, password: @password, port: @port)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def init_proxy
|
180
|
+
return unless @opts[:proxy]
|
181
|
+
|
182
|
+
proxy = @opts[:proxy]
|
183
|
+
|
184
|
+
case proxy
|
185
|
+
when Hash
|
186
|
+
Net::SSH::Gateway.new(proxy[:host], proxy[:username],
|
187
|
+
keys: proxy[:keys], password: proxy[:password], port: proxy[:port])
|
188
|
+
when Kanrisuru::Remote::Host
|
189
|
+
Net::SSH::Gateway.new(proxy.host, proxy.username,
|
190
|
+
keys: proxy.keys, password: proxy.password, port: proxy.port)
|
191
|
+
when Net::SSH::Gateway
|
192
|
+
proxy
|
193
|
+
else
|
194
|
+
raise ArgumentError, 'Invalid proxy type'
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
161
198
|
def init_hostname
|
162
199
|
command = Kanrisuru::Command.new('hostname')
|
163
200
|
execute(command)
|
data/lib/kanrisuru/version.rb
CHANGED
data/spec/helper/hosts.json
CHANGED
@@ -8,6 +8,15 @@
|
|
8
8
|
"kernel": "Linux",
|
9
9
|
"home": "/home/ubuntu"
|
10
10
|
},
|
11
|
+
{
|
12
|
+
"name": "proxy",
|
13
|
+
"port": 22,
|
14
|
+
"username": "ubuntu",
|
15
|
+
"ssh_key": "~/.ssh/id_rsa",
|
16
|
+
"hostname": "proxy-host",
|
17
|
+
"kernel": "Linux",
|
18
|
+
"home": "/home/ubuntu"
|
19
|
+
},
|
11
20
|
{
|
12
21
|
"name": "ubuntu",
|
13
22
|
"port": 22,
|
data/spec/helper/test_hosts.rb
CHANGED
@@ -20,6 +20,11 @@ class TestHosts
|
|
20
20
|
hosts(name)
|
21
21
|
end
|
22
22
|
|
23
|
+
def resolve(hostname)
|
24
|
+
s = Socket.getaddrinfo(hostname, nil)
|
25
|
+
s[0][2]
|
26
|
+
end
|
27
|
+
|
23
28
|
def spec_dir(host_json)
|
24
29
|
random_string = SecureRandom.hex
|
25
30
|
"#{host_json['home']}/.kanrisuru_spec_files_#{random_string[0..5]}"
|
@@ -103,7 +103,7 @@ RSpec.shared_examples 'system' do |os_name, host_json, _spec_dir|
|
|
103
103
|
it 'gets kernel sysctl info' do
|
104
104
|
result = host.sysctl
|
105
105
|
expect(result).to be_success
|
106
|
-
expect(result).to respond_to :net
|
106
|
+
expect(result).to respond_to :net
|
107
107
|
expect(result).to respond_to :kernel
|
108
108
|
expect(result).to respond_to :dev
|
109
109
|
|
@@ -24,6 +24,47 @@ RSpec.shared_examples 'host' do |os_name, host_json, _spec_dir|
|
|
24
24
|
expect(host.hostname).to eq(host_json['hostname'])
|
25
25
|
end
|
26
26
|
|
27
|
+
it 'connects with proxy host' do
|
28
|
+
config = TestHosts.host('proxy')
|
29
|
+
proxy = Kanrisuru::Remote::Host.new(
|
30
|
+
host: config['hostname'],
|
31
|
+
username: config['username'],
|
32
|
+
keys: [config['ssh_key']]
|
33
|
+
)
|
34
|
+
|
35
|
+
expect(proxy).to be_ping
|
36
|
+
|
37
|
+
host = Kanrisuru::Remote::Host.new(
|
38
|
+
host: TestHosts.resolve(host_json['hostname']),
|
39
|
+
username: host_json['username'],
|
40
|
+
keys: [host_json['ssh_key']],
|
41
|
+
proxy: proxy
|
42
|
+
)
|
43
|
+
|
44
|
+
## Test instiation
|
45
|
+
expect(host.proxy).to be_instance_of(Net::SSH::Gateway)
|
46
|
+
expect(host.ssh).to be_instance_of(Net::SSH::Connection::Session)
|
47
|
+
|
48
|
+
## Test basic commands
|
49
|
+
expect(host.hostname).to eq(host_json['hostname'])
|
50
|
+
|
51
|
+
host.cd('../')
|
52
|
+
expect(host.pwd.path).to eq('/home')
|
53
|
+
|
54
|
+
expect(host.whoami.user).to eq(host_json['username'])
|
55
|
+
host.su 'root'
|
56
|
+
expect(host.whoami.user).to eq('root')
|
57
|
+
|
58
|
+
## Test download
|
59
|
+
src_path = '/etc/hosts'
|
60
|
+
result = host.download(src_path)
|
61
|
+
expect(result).to be_instance_of(String)
|
62
|
+
lines = result.split("\n")
|
63
|
+
expect(lines.length).to be >= 1
|
64
|
+
|
65
|
+
## Test upload
|
66
|
+
end
|
67
|
+
|
27
68
|
it 'changes directories' do
|
28
69
|
expect(host.pwd.path).to eq(host_json['home'])
|
29
70
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Kanrisuru::Remote::Host do
|
4
|
+
before(:all) do
|
5
|
+
StubNetwork.stub!
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
StubNetwork.unstub!
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:host) do
|
13
|
+
described_class.new(
|
14
|
+
host: 'localhost',
|
15
|
+
username: 'ubuntu',
|
16
|
+
keys: ['id_rsa']
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'responds to methods' do
|
21
|
+
expect(host).to respond_to(:remote_user)
|
22
|
+
expect(host).to respond_to(:hostname)
|
23
|
+
expect(host).to respond_to(:os)
|
24
|
+
expect(host).to respond_to(:env)
|
25
|
+
expect(host).to respond_to(:template)
|
26
|
+
expect(host).to respond_to(:fstab)
|
27
|
+
expect(host).to respond_to(:chdir)
|
28
|
+
expect(host).to respond_to(:cd)
|
29
|
+
expect(host).to respond_to(:cpu)
|
30
|
+
expect(host).to respond_to(:memory)
|
31
|
+
expect(host).to respond_to(:su)
|
32
|
+
expect(host).to respond_to(:file)
|
33
|
+
expect(host).to respond_to(:ssh)
|
34
|
+
expect(host).to respond_to(:proxy)
|
35
|
+
expect(host).to respond_to(:ping?)
|
36
|
+
expect(host).to respond_to(:execute)
|
37
|
+
expect(host).to respond_to(:execute_shell)
|
38
|
+
expect(host).to respond_to(:disconnect)
|
39
|
+
end
|
40
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kanrisuru
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Mammina
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parallel_tests
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '6.1'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: net-ssh-gateway
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '2.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '2.0'
|
139
153
|
description: " Kanrisuru helps manage remote servers with objected oriented ruby.
|
140
154
|
\n Results come back as structured data, parsed, prepared and ready.\n"
|
141
155
|
email: ryan@avamia.com
|
@@ -687,6 +701,7 @@ files:
|
|
687
701
|
- spec/unit/remote/cpu_spec.rb
|
688
702
|
- spec/unit/remote/env_spec.rb
|
689
703
|
- spec/unit/remote/fstab_spec.rb
|
704
|
+
- spec/unit/remote/host_spec.rb
|
690
705
|
- spec/unit/template_spec.rb
|
691
706
|
- spec/unit/util_spec.rb
|
692
707
|
homepage: https://kanrisuru.com
|