ssh_tunnels 0.1.1 → 0.2.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: 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