kanrisuru 0.19.4 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef72387ee3392fab30d54254e7226e066d943757b686bd1e66fea0fc1bd58181
4
- data.tar.gz: eb829fe3e5d90968c17cfa9922161505f4fbdce4a44da5524f35ad23967c7335
3
+ metadata.gz: 767ab1b59818ddd394ef7f4bb96435e5be43d2bf89c2c4469419f20a8a5f4a0c
4
+ data.tar.gz: 4c370eb4c60270ed707a78606976b391d098c1298de026558c80a543e28d8326
5
5
  SHA512:
6
- metadata.gz: 9e6b315320713f79f5693b6a21269dcadbf6327efae5ab8dc4287165ebfd6f0c05cc221cb351911f669f71b1812ac3a43884ed978ef64422f07a3beab835ec4a
7
- data.tar.gz: 21e425b548076e932aa9770f4a0827e3252b6dba3869e90d219bbf3e70d983fadb87f14b7ed1747f3c4c569c109901e4da708211816573c963c96bd3977bee24
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']
@@ -14,7 +14,7 @@ module Kanrisuru
14
14
  else
15
15
  command.append_flag('--all')
16
16
  end
17
-
17
+
18
18
  execute_shell(command)
19
19
 
20
20
  Kanrisuru::Result.new(command) do |cmd|
@@ -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?("permission denied on key")
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.keys.each do |key|
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 |k, v1, v2|
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 do |_host_addr, host|
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 do |_host_addr, host|
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 do |_host_addr, host|
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 ||= Net::SSH.start(@host, @username, keys: @keys, password: @password, port: @port)
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kanrisuru
4
- VERSION = '0.19.4'
4
+ VERSION = '0.20.0'
5
5
  end
@@ -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,
@@ -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.19.4
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-19 00:00:00.000000000 Z
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