sshmenu 0.0.1
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 +7 -0
- data/bin/sshmenu +5 -0
- data/data/sshmenu/sampleconfig.yml +10 -0
- data/lib/sshmenu/actions.rb +43 -0
- data/lib/sshmenu/config.rb +72 -0
- data/lib/sshmenu/options.rb +41 -0
- data/lib/sshmenu/selector.rb +43 -0
- data/lib/sshmenu/version.rb +3 -0
- data/lib/sshmenu.rb +30 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 02b810d4fc98c9ed2f7108df1c914fd67923e1b9
|
4
|
+
data.tar.gz: 9384df5c89464f5f70b1fd6cdcd70babe478e491
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0d4733264a6047ea10cd3cbbafc295b0be1f180f9d290b14cb6415db608c19ab6c26b0ed546095e99fd9d204093e98edff3d4f94dcc6d51faf8878f3c811f64a
|
7
|
+
data.tar.gz: 9fd99d815020502f6499ed7b6d6fff5390de4300dc07f980a23d7bcfa353a6f0389017991d172f36fdf92bf8e44d987419e62e1e175b2e285767d3b39ba39688
|
data/bin/sshmenu
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
|
3
|
+
module SshMenu
|
4
|
+
class Actions
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@general = config.general
|
8
|
+
@connections = config.connections
|
9
|
+
@config_file = config.config_file
|
10
|
+
end
|
11
|
+
|
12
|
+
def edit
|
13
|
+
puts "Edit config file #{@config_file}"
|
14
|
+
exec("#{@general['editor']} #{@config_file}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def connect(index)
|
18
|
+
unless index.between?(0, @connections.length-1)
|
19
|
+
raise ArgumentError, 'invalid index'
|
20
|
+
end
|
21
|
+
|
22
|
+
conn = @connections[index]
|
23
|
+
|
24
|
+
opts = " #{@general['ssh_opts']} #{conn['ssh_opts']}"
|
25
|
+
cmd = "#{@general['ssh_exec']}"
|
26
|
+
cmd << opts
|
27
|
+
cmd << " #{conn['user_host']}"
|
28
|
+
|
29
|
+
puts "Connecting to #{conn['user_host']}"
|
30
|
+
exec(cmd)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.ask_edit_with_default_editor
|
34
|
+
editor = Config.default_editor
|
35
|
+
config = Config.default_config_file
|
36
|
+
print "Edit #{config} using default editor '#{editor}' [y/N]? "
|
37
|
+
if STDIN.getc =~ /\A[Yy]\z/
|
38
|
+
exec("#{editor} #{config}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module SshMenu
|
5
|
+
class ConfigException < Exception
|
6
|
+
end
|
7
|
+
|
8
|
+
class Config
|
9
|
+
attr_reader :general, :connections, :config_file
|
10
|
+
|
11
|
+
def initialize(cfg_file = nil)
|
12
|
+
@config_file = cfg_file || self.class.default_config_file
|
13
|
+
create_config_file(@config_file) unless File.exist? @config_file
|
14
|
+
|
15
|
+
config = YAML.load_file(@config_file)
|
16
|
+
config = {} unless config
|
17
|
+
|
18
|
+
merge_defaults config
|
19
|
+
validate_config config
|
20
|
+
gen_user_host config['connections']
|
21
|
+
|
22
|
+
@general = config['general']
|
23
|
+
@connections = config['connections']
|
24
|
+
|
25
|
+
puts "Config is #{config.inspect}" if ENV['SSHMENU_DEBUG'].eql?('true')
|
26
|
+
rescue Psych::SyntaxError => e
|
27
|
+
raise ConfigException, "YAML syntax error: #{e.message}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def merge_defaults(config)
|
31
|
+
config['general'] ||= {}
|
32
|
+
gen = config['general']
|
33
|
+
gen['ssh_exec'] ||= self.class.default_ssh_client
|
34
|
+
gen['ssh_opts'] ||= ''
|
35
|
+
gen['editor'] ||= self.class.default_editor
|
36
|
+
|
37
|
+
config['connections'] ||= []
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_config_file(cfg_file)
|
41
|
+
puts "Create sample config file #{cfg_file}"
|
42
|
+
project_dir = File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))
|
43
|
+
sample_cfg = File.join(project_dir, 'data', 'sshmenu', 'sampleconfig.yml');
|
44
|
+
FileUtils.mkdir_p(File.dirname(cfg_file))
|
45
|
+
FileUtils.cp(sample_cfg, cfg_file)
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate_config(config)
|
49
|
+
unless config['connections'].all? {|conn| conn['host']}
|
50
|
+
raise ConfigException, "invalid connection found in #{@config_file}: missing host"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def gen_user_host(conns)
|
55
|
+
conns.each do |conn|
|
56
|
+
conn['user_host'] = conn['user'] ? "#{conn['user']}@#{conn['host']}" : conn['host']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.default_ssh_client
|
61
|
+
'ssh'
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.default_editor
|
65
|
+
ENV['EDITOR'] || 'vi'
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.default_config_file
|
69
|
+
File.join(Dir.home, '.config', 'sshmenu', 'config.yml')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require_relative 'version'
|
3
|
+
|
4
|
+
module SshMenu
|
5
|
+
class Options
|
6
|
+
|
7
|
+
attr_reader :opts
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@opts = {}
|
11
|
+
opt_parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = "usage: sshmenu [options] [selected_index]\n"
|
13
|
+
opts.banner << "add no arguments to show a list of configured connections"
|
14
|
+
|
15
|
+
opts.on('-e', '--edit', 'edit configuration file') do |e|
|
16
|
+
@opts = @opts.merge({:action => :edit})
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on_tail('-v', '--version', 'print version') do
|
20
|
+
puts "sshmenu, version #{VERSION}"
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on_tail('-h', '--help', 'print this help') do
|
25
|
+
puts opts
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
opt_parser.parse!(args)
|
31
|
+
|
32
|
+
unless args.first.nil?
|
33
|
+
begin
|
34
|
+
@opts = @opts.merge({:index => Integer(args.first) - 1})
|
35
|
+
rescue ArgumentError
|
36
|
+
raise "'#{args[0]}' expected to be a preselected index"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SshMenu
|
2
|
+
class Selector
|
3
|
+
|
4
|
+
def initialize(connections)
|
5
|
+
@connections = connections
|
6
|
+
end
|
7
|
+
|
8
|
+
def select
|
9
|
+
selection = request_selection
|
10
|
+
|
11
|
+
case selection
|
12
|
+
when /\A[eE]\z/
|
13
|
+
{:action => :edit}
|
14
|
+
when /\A[1-9][0-9]*\z/
|
15
|
+
{:index => Integer(selection) - 1 }
|
16
|
+
when /\A\z/
|
17
|
+
{}
|
18
|
+
else
|
19
|
+
raise ArgumentError, "invalid selection '#{selection}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def request_selection
|
24
|
+
puts connection_list
|
25
|
+
print 'Pick a server (or e to edit connections): '
|
26
|
+
STDIN.gets.chomp
|
27
|
+
end
|
28
|
+
|
29
|
+
def connection_list
|
30
|
+
uh_length = @connections.map {|conn| conn['user_host'].length}.max
|
31
|
+
index_length = @connections.size.to_s.length
|
32
|
+
|
33
|
+
s = StringIO.new
|
34
|
+
@connections.each.with_index do |connection, index|
|
35
|
+
conn = connection['user_host']
|
36
|
+
desc = connection['description']
|
37
|
+
s << "%#{index_length}d) %-#{uh_length+3}s %s\n" % [ index+1, conn, desc]
|
38
|
+
end
|
39
|
+
s.string
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
data/lib/sshmenu.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sshmenu/options'
|
2
|
+
require 'sshmenu/config'
|
3
|
+
require 'sshmenu/actions'
|
4
|
+
require 'sshmenu/selector'
|
5
|
+
|
6
|
+
module SshMenu
|
7
|
+
class SshMenu
|
8
|
+
def self.run(args)
|
9
|
+
options = Options.new(args).opts
|
10
|
+
config = Config.new
|
11
|
+
actions = Actions.new(config)
|
12
|
+
|
13
|
+
selection = if options.empty?
|
14
|
+
selector = Selector.new(config.connections)
|
15
|
+
selector.select
|
16
|
+
else
|
17
|
+
options
|
18
|
+
end
|
19
|
+
|
20
|
+
actions.edit if selection[:action] == :edit
|
21
|
+
actions.connect selection[:index] if selection[:index]
|
22
|
+
|
23
|
+
rescue ConfigException => e
|
24
|
+
puts e.message
|
25
|
+
Actions.ask_edit_with_default_editor
|
26
|
+
rescue Exception => e
|
27
|
+
ENV['SSHMENU_DEBUG'].eql?('true') ? raise(e) : puts(e.message)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sshmenu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '11.2'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '11.2'
|
27
|
+
description: Simple ssh connection menu for the console
|
28
|
+
email:
|
29
|
+
- thefutureisunwritten@gmx.de
|
30
|
+
executables:
|
31
|
+
- sshmenu
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- bin/sshmenu
|
36
|
+
- data/sshmenu/sampleconfig.yml
|
37
|
+
- lib/sshmenu.rb
|
38
|
+
- lib/sshmenu/actions.rb
|
39
|
+
- lib/sshmenu/config.rb
|
40
|
+
- lib/sshmenu/options.rb
|
41
|
+
- lib/sshmenu/selector.rb
|
42
|
+
- lib/sshmenu/version.rb
|
43
|
+
homepage: http://rubygems.org/gems/sshmenu
|
44
|
+
licenses:
|
45
|
+
- GPL-2.0
|
46
|
+
metadata: {}
|
47
|
+
post_install_message: Type sshmenu -e to start editing you ssh connections
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.6.4
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: SSH menu
|
67
|
+
test_files: []
|