ssh_tunnels 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba405495fb6506f5a69ac1fb1e222ff0b471a6276914f82c46b6960c4fa3796c
4
- data.tar.gz: fe87c9476685c2d87d7843f098260875561399967c0f504081f92e844a58e4e4
3
+ metadata.gz: 4e4fe888d25ffab2361eb1978eab7e3c1a64e986388860c82a3aba981603afc1
4
+ data.tar.gz: a352882082070c6abd2faecbf0ca2b3e771cd88bd51107ee2d0d539853142561
5
5
  SHA512:
6
- metadata.gz: ded2e91fc8fce982c29a31a7da1e37e0ea3b009407c215dc6bfd4f0a6c451a22e639630a2acbf1f5776de3d8b20337857658e44ddb86554b61c67b86632b27e0
7
- data.tar.gz: 7827c2125fb9ea315d0e70629c01fde527bba7b027fa8c81b899caab12cb83c465fdaa937351272ded5e0a8b71c423deb3c8f455fda4aeff8c41eeaf44c0ae11
6
+ metadata.gz: 3899497544ac7e01a40605dcef63d9d3ddd0721eb36a0f1b4892f64769f39b185ee5aa70982123040c24e479366e830a04be416cf2edee0c2fb15a176bf121b9
7
+ data.tar.gz: 572f38e2af5076cec0604164ff59278296dec1ba7ce2e0e6d4635acc2ae122a3701f6fa86b86fb23590ed2d795858f5272e41835cc082f7386ce285ce9469197
data/Gemfile.lock CHANGED
@@ -1,42 +1,44 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ssh_tunnels (0.1.1)
4
+ ssh_tunnels (0.2.0)
5
5
  curses (~> 1.3)
6
6
  net-ssh-gateway (~> 2.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- ast (2.4.1)
12
- concurrent-ruby (1.1.6)
13
- curses (1.3.2)
14
- diff-lcs (1.4.2)
15
- i18n (1.8.3)
11
+ ast (2.4.2)
12
+ concurrent-ruby (1.2.3)
13
+ curses (1.4.4)
14
+ diff-lcs (1.5.1)
15
+ i18n (1.14.4)
16
16
  concurrent-ruby (~> 1.0)
17
- net-ssh (6.1.0)
17
+ net-ssh (7.2.3)
18
18
  net-ssh-gateway (2.0.0)
19
19
  net-ssh (>= 4.0.0)
20
- paint (2.2.0)
21
- parallel (1.19.2)
22
- parser (2.7.1.4)
20
+ paint (2.3.0)
21
+ parallel (1.24.0)
22
+ parser (3.3.0.5)
23
23
  ast (~> 2.4.1)
24
- rainbow (3.0.0)
25
- regexp_parser (1.7.1)
26
- rexml (3.2.4)
27
- rspec (3.9.0)
28
- rspec-core (~> 3.9.0)
29
- rspec-expectations (~> 3.9.0)
30
- rspec-mocks (~> 3.9.0)
31
- rspec-core (3.9.2)
32
- rspec-support (~> 3.9.3)
33
- rspec-expectations (3.9.2)
24
+ racc
25
+ racc (1.7.3)
26
+ rainbow (3.1.1)
27
+ regexp_parser (2.9.0)
28
+ rexml (3.2.6)
29
+ rspec (3.13.0)
30
+ rspec-core (~> 3.13.0)
31
+ rspec-expectations (~> 3.13.0)
32
+ rspec-mocks (~> 3.13.0)
33
+ rspec-core (3.13.0)
34
+ rspec-support (~> 3.13.0)
35
+ rspec-expectations (3.13.0)
34
36
  diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.9.0)
36
- rspec-mocks (3.9.1)
37
+ rspec-support (~> 3.13.0)
38
+ rspec-mocks (3.13.0)
37
39
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-support (3.9.3)
40
+ rspec-support (~> 3.13.0)
41
+ rspec-support (3.13.1)
40
42
  rubocop (0.86.0)
41
43
  parallel (~> 1.10)
42
44
  parser (>= 2.7.0.1)
@@ -46,13 +48,13 @@ GEM
46
48
  rubocop-ast (>= 0.0.3, < 1.0)
47
49
  ruby-progressbar (~> 1.7)
48
50
  unicode-display_width (>= 1.4.0, < 2.0)
49
- rubocop-ast (0.0.3)
50
- parser (>= 2.7.0.1)
51
- ruby-progressbar (1.10.1)
52
- strong_versions (0.4.4)
53
- i18n (>= 0.5.0)
51
+ rubocop-ast (0.8.0)
52
+ parser (>= 2.7.1.5)
53
+ ruby-progressbar (1.13.0)
54
+ strong_versions (0.4.5)
55
+ i18n (>= 0.5)
54
56
  paint (~> 2.0)
55
- unicode-display_width (1.7.0)
57
+ unicode-display_width (1.8.0)
56
58
 
57
59
  PLATFORMS
58
60
  ruby
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # SshTunnels
2
2
 
3
- Interactive _SSH_ tunnel management.
3
+ Interactive _SSH_ tunnel management. Console UI powered by [ncurses](https://invisible-island.net/ncurses/).
4
+
5
+ ![example](doc/demo.png)
4
6
 
5
7
  ## Installation
6
8
 
@@ -14,14 +16,64 @@ gem install ssh_tunnels
14
16
  ssh_tunnels -c config.yml
15
17
  ```
16
18
 
19
+ Alternatively, default to using `~/.ssh_tunnels.yml` for configuration:
20
+
21
+ ```bash
22
+ ssh_tunnels
23
+ ```
24
+
17
25
  ## Configuration
18
26
 
27
+ ### Gateways
28
+
29
+ There are two ways to configure an SSH gateway. Both can be used together, but at least one must be defined:
30
+
31
+ 1. Define a `default_gateway` section in your configuration file.
32
+ 1. Define a `gateways` section in your conifguration file.
33
+
34
+ The `default_gateway` is a map containing these keys:
35
+
36
+ * `host`: hostname or IP address of gateway (required).
37
+ * `port`: SSH port on gateway (default: `22`).
38
+ * `user`: Username on gateway to connect with (default: `$USER`).
39
+
40
+ The `gateways` section is also a map, but each key represents a named gateway, and each gateway is configured using the same parameters as `default_gateway`.
41
+
42
+ Each named gateway can be referred to in the `gateway` field for each tunnel.
43
+
19
44
  ```yaml
20
45
  # config.yml
21
46
 
22
- gateway:
47
+ default_gateway:
23
48
  host: gateway.example.com
24
- port: 22
49
+
50
+ gateways:
51
+ aws:
52
+ host: 111.111.111.111
53
+ user: ubuntu
54
+ azure:
55
+ host: 222.222.222.222
56
+ user: william
57
+ ```
58
+
59
+ ### Tunnels
60
+
61
+ The `tunnels` section is a map where each key represents a named tunnel. Each tunnel can be configured using the following parameters:
62
+
63
+ * `host`: The remote host to connect to from the gateway.
64
+ * `remote`: The remote port to use for forwarding.
65
+ * `local`: The local port to bind to (defaults to the `remote` port).
66
+
67
+ ```yaml
68
+ # config.yml
69
+
70
+ default_gateway:
71
+ host: gateway.example.com
72
+
73
+ gateways:
74
+ aws:
75
+ host: 111.111.111.111
76
+ user: ubuntu
25
77
 
26
78
  tunnels:
27
79
  my_host:
@@ -29,6 +81,7 @@ tunnels:
29
81
  host: my.host.example.com
30
82
  remote: 4567
31
83
  other_host:
84
+ gateway: aws
32
85
  local: 1111
33
86
  host: other.host.example.com
34
87
  remote: 5555
data/bin/ssh_tunnels CHANGED
@@ -20,24 +20,40 @@ OptionParser.new do |opts|
20
20
  end
21
21
  end.parse!
22
22
 
23
- unless options[:config_path]
24
- warn('Must provide configuration path. See --help')
25
- exit 1
26
- end
23
+ config_path = options.fetch(:config_path, File.expand_path('~/.ssh_tunnels.yml'))
27
24
 
28
- unless File.exist?(options[:config_path])
29
- warn("Unable to locate configuration file: #{options[:config_path]}")
25
+ unless File.exist?(config_path)
26
+ warn("Unable to locate configuration file: #{config_path}")
30
27
  exit 1
31
28
  end
32
29
 
33
- config = YAML.safe_load(File.read(options[:config_path]))
30
+ config = YAML.safe_load(File.read(config_path))
34
31
 
35
32
  begin
36
- gateway = config.fetch('gateway')
33
+ default_gateway = config.fetch('default_gateway', nil)
34
+ if !config.key?('tunnels')
35
+ warn('Configuration file must provide `tunnels` section. Exiting.')
36
+ exit 1
37
+ end
38
+
39
+ gateways = config.fetch('gateways', {})
40
+
37
41
  tunnels = config.fetch('tunnels')
38
- rescue KeyError
39
- warn('Configuration file must provide `gateway` and `tunnels` sections.')
40
- exit 1
42
+ error = false
43
+ tunnels.each do |key, tunnel|
44
+ if tunnel.key?('gateway') && !gateways.key?(tunnel.fetch('gateway'))
45
+ error = true
46
+ warn("Tunnel `#{key}` references unknown gateway `#{tunnel.fetch('gateway')}`")
47
+ elsif !tunnel.key?('gateway') && default_gateway.nil?
48
+ error = true
49
+ warn("Tunnel `#{key}` must provide `gateway` key or define a top-level `default_gateway` configuration.")
50
+ end
51
+ end
52
+
53
+ if error
54
+ warn("Configuration errors detected. Exiting.")
55
+ exit 1
56
+ end
41
57
  end
42
58
 
43
59
  user = ENV.fetch('USER')
@@ -47,6 +63,11 @@ puts
47
63
 
48
64
  begin
49
65
  tunnels = tunnels.map do |name, tunnel_config|
66
+ gateway = if tunnel_config.key?('gateway')
67
+ gateways.fetch(tunnel_config.fetch('gateway'))
68
+ else
69
+ default_gateway
70
+ end
50
71
  SshTunnels::Tunnel.new(name, user, tunnel_config, gateway, passphrase)
51
72
  end
52
73
  ui = SshTunnels::UI.new(tunnels)
data/doc/demo.png ADDED
Binary file
@@ -27,11 +27,11 @@ module SshTunnels
27
27
  end
28
28
 
29
29
  def open
30
- @connection = Net::SSH::Gateway.new(@gateway.fetch('host'), @user, options)
30
+ @connection = Net::SSH::Gateway.new(@gateway.fetch('host'), @gateway.fetch('user', @user), options)
31
31
  @connection.open(remote_host, remote_port, local_port)
32
- rescue Errno::EADDRINUSE => e
33
- @error = e.to_s
32
+ rescue StandardError => e
34
33
  shutdown
34
+ raise
35
35
  end
36
36
 
37
37
  def active?
@@ -41,7 +41,7 @@ module SshTunnels
41
41
  end
42
42
 
43
43
  def shutdown
44
- @connection.shutdown!
44
+ @connection&.shutdown!
45
45
  end
46
46
 
47
47
  private
@@ -55,14 +55,14 @@ module SshTunnels
55
55
  end
56
56
 
57
57
  def local_port
58
- @config.fetch('local_port')
58
+ @config.fetch('local_port', remote_port)
59
59
  end
60
60
 
61
61
  def options
62
62
  {
63
63
  keepalive: true,
64
64
  keepalive_interval: 5,
65
- port: @gateway.fetch('port'),
65
+ port: @gateway.fetch('port', 22),
66
66
  passphrase: @passphrase
67
67
  }
68
68
  end
@@ -96,7 +96,11 @@ module SshTunnels
96
96
  else
97
97
  status("Connecting: #{tunnel}")
98
98
  end
99
- tunnel.toggle
99
+ begin
100
+ tunnel.toggle
101
+ rescue StandardError => e
102
+ status("Error: #{e}")
103
+ end
100
104
  end
101
105
 
102
106
  def tunnel_color(tunnel)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SshTunnels
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssh_tunnels
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-08 00:00:00.000000000 Z
11
+ date: 2024-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -100,6 +100,7 @@ files:
100
100
  - bin/console
101
101
  - bin/setup
102
102
  - bin/ssh_tunnels
103
+ - doc/demo.png
103
104
  - lib/ssh_tunnels.rb
104
105
  - lib/ssh_tunnels/tunnel.rb
105
106
  - lib/ssh_tunnels/ui.rb