sshman 0.3.3 → 0.4.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/.gitattributes +2 -0
- data/.gitignore +71 -0
- data/Gemfile +8 -0
- data/LICENSE +674 -0
- data/README.md +93 -0
- data/exe/sshman +4 -6
- data/images/sshman.gif +0 -0
- data/lib/sshman/cli.rb +62 -85
- data/lib/sshman/connection.rb +30 -0
- data/lib/sshman/manager.rb +52 -0
- data/lib/sshman/tui.rb +136 -0
- data/lib/sshman/version.rb +2 -2
- data/lib/sshman.rb +9 -0
- data/sshman.gemspec +31 -0
- metadata +106 -19
- data/lib/sshman/constants.rb +0 -8
- data/lib/sshman/key_manager.rb +0 -38
- data/lib/sshman/server_manager.rb +0 -131
- data/lib/sshman/sshman.rb +0 -4
- data/lib/sshman/utils.rb +0 -28
metadata
CHANGED
@@ -1,39 +1,126 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sshman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Subnetmasked
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
11
|
+
date: 2024-10-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tty-table
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.12'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-prompt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.23'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.23'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '13.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '13.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: SSHMan is a command-line tool for managing SSH connections with a user-friendly
|
98
|
+
interface and a Text-based User Interface (TUI).
|
15
99
|
email:
|
16
|
-
-
|
100
|
+
- subnetmasked@cock.li
|
17
101
|
executables:
|
18
102
|
- sshman
|
19
103
|
extensions: []
|
20
104
|
extra_rdoc_files: []
|
21
105
|
files:
|
106
|
+
- ".gitattributes"
|
107
|
+
- ".gitignore"
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE
|
110
|
+
- README.md
|
22
111
|
- exe/sshman
|
112
|
+
- images/sshman.gif
|
113
|
+
- lib/sshman.rb
|
23
114
|
- lib/sshman/cli.rb
|
24
|
-
- lib/sshman/
|
25
|
-
- lib/sshman/
|
26
|
-
- lib/sshman/
|
27
|
-
- lib/sshman/sshman.rb
|
28
|
-
- lib/sshman/utils.rb
|
115
|
+
- lib/sshman/connection.rb
|
116
|
+
- lib/sshman/manager.rb
|
117
|
+
- lib/sshman/tui.rb
|
29
118
|
- lib/sshman/version.rb
|
119
|
+
- sshman.gemspec
|
30
120
|
homepage: https://github.com/subnetmasked/sshman
|
31
121
|
licenses:
|
32
|
-
- GPL-3.0-
|
33
|
-
metadata:
|
34
|
-
homepage_uri: https://github.com/subnetmasked/sshman
|
35
|
-
source_code_uri: https://github.com/subnetmasked/sshman
|
36
|
-
bug_tracker_uri: https://github.com/subnetmasked/sshman/issues
|
122
|
+
- GPL-3.0-OR-LATER
|
123
|
+
metadata: {}
|
37
124
|
post_install_message:
|
38
125
|
rdoc_options: []
|
39
126
|
require_paths:
|
@@ -42,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
129
|
requirements:
|
43
130
|
- - ">="
|
44
131
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
132
|
+
version: '0'
|
46
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
134
|
requirements:
|
48
135
|
- - ">="
|
@@ -52,5 +139,5 @@ requirements: []
|
|
52
139
|
rubygems_version: 3.5.21
|
53
140
|
signing_key:
|
54
141
|
specification_version: 4
|
55
|
-
summary: A
|
142
|
+
summary: A fancy SSH connection manager with TUI
|
56
143
|
test_files: []
|
data/lib/sshman/constants.rb
DELETED
data/lib/sshman/key_manager.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module Sshman
|
5
|
-
class KeyManager
|
6
|
-
SSH_DIR = File.expand_path("~/.ssh")
|
7
|
-
|
8
|
-
def self.generate_key
|
9
|
-
FileUtils.mkdir_p(SSH_DIR)
|
10
|
-
|
11
|
-
print "Enter bit size (default 2048): "
|
12
|
-
bit_size = gets.chomp.to_i
|
13
|
-
bit_size = 2048 if bit_size <= 0
|
14
|
-
|
15
|
-
print "Enter key name (default id_rsa): "
|
16
|
-
key_name = gets.chomp.strip
|
17
|
-
key_name = "id_rsa" if key_name.empty?
|
18
|
-
|
19
|
-
private_key_path = File.join(SSH_DIR, key_name)
|
20
|
-
public_key_path = "#{private_key_path}.pub"
|
21
|
-
|
22
|
-
print "Enter passphrase (leave blank for no passphrase): "
|
23
|
-
passphrase = gets.chomp.strip
|
24
|
-
|
25
|
-
key = OpenSSL::PKey::RSA.new(bit_size)
|
26
|
-
cipher = OpenSSL::Cipher.new('AES-128-CBC') if passphrase != ""
|
27
|
-
private_key = passphrase.empty? ? key.to_pem : key.export(cipher, passphrase)
|
28
|
-
public_key = "ssh-rsa #{[key.public_key.to_der].pack('m0')}"
|
29
|
-
|
30
|
-
File.write(private_key_path, private_key)
|
31
|
-
File.write(public_key_path, public_key)
|
32
|
-
File.chmod(0600, private_key_path)
|
33
|
-
File.chmod(0644, public_key_path)
|
34
|
-
|
35
|
-
puts "#{GREEN}SSH keys generated successfully! Private key: #{private_key_path}, Public key: #{public_key_path}#{RESET_COLOR}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,131 +0,0 @@
|
|
1
|
-
require 'csv'
|
2
|
-
require_relative 'constants'
|
3
|
-
|
4
|
-
module Sshman
|
5
|
-
class ServerManager
|
6
|
-
def self.list_servers
|
7
|
-
if File.zero?(SERVERS_CSV)
|
8
|
-
puts "#{YELLOW}No servers found. Add some using the 'add' option.#{RESET_COLOR}"
|
9
|
-
return
|
10
|
-
end
|
11
|
-
|
12
|
-
puts "#{CYAN}%-15s %-25s %-6s %-15s %-30s#{RESET_COLOR}" % ["Alias", "Hostname", "Port", "Username", "SSH Key"]
|
13
|
-
puts "-" * 95
|
14
|
-
|
15
|
-
CSV.foreach(SERVERS_CSV, headers: true) do |row|
|
16
|
-
puts "%-15s %-25s %-6s %-15s %-30s" % [row['alias'], row['hostname'], row['port'], row['username'], row['ssh_key']]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.add_server
|
21
|
-
puts "#{CYAN}Adding a new server...#{RESET_COLOR}"
|
22
|
-
print "Alias: "
|
23
|
-
alias_name = gets.chomp.strip
|
24
|
-
return puts "#{RED}Alias cannot be empty!#{RESET_COLOR}" if alias_name.empty?
|
25
|
-
|
26
|
-
print "Hostname or IP: "
|
27
|
-
hostname = gets.chomp.strip
|
28
|
-
return puts "#{RED}Hostname cannot be empty!#{RESET_COLOR}" if hostname.empty?
|
29
|
-
|
30
|
-
print "Port (default 22): "
|
31
|
-
port = gets.chomp.strip
|
32
|
-
port = '22' if port.empty?
|
33
|
-
|
34
|
-
print "Username: "
|
35
|
-
username = gets.chomp.strip
|
36
|
-
return puts "#{RED}Username cannot be empty!#{RESET_COLOR}" if username.empty?
|
37
|
-
|
38
|
-
print "Path to SSH key (leave blank if none): "
|
39
|
-
ssh_key = gets.chomp.strip
|
40
|
-
|
41
|
-
CSV.open(SERVERS_CSV, 'a+') do |csv|
|
42
|
-
csv << [alias_name, hostname, port, username, ssh_key]
|
43
|
-
end
|
44
|
-
|
45
|
-
puts "#{GREEN}Server '#{alias_name}' added successfully!#{RESET_COLOR}"
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.edit_server
|
49
|
-
print "Enter alias of the server to edit: "
|
50
|
-
alias_name = gets.chomp.strip
|
51
|
-
servers = CSV.table(SERVERS_CSV)
|
52
|
-
|
53
|
-
server = servers.find { |row| row[:alias] == alias_name }
|
54
|
-
unless server
|
55
|
-
puts "#{RED}No server found with alias '#{alias_name}'.#{RESET_COLOR}"
|
56
|
-
return
|
57
|
-
end
|
58
|
-
|
59
|
-
print "New Hostname (leave blank to keep current: #{server[:hostname]}): "
|
60
|
-
new_hostname = gets.chomp.strip
|
61
|
-
server[:hostname] = new_hostname unless new_hostname.empty?
|
62
|
-
|
63
|
-
print "New Port (leave blank to keep current: #{server[:port]}): "
|
64
|
-
new_port = gets.chomp.strip
|
65
|
-
server[:port] = new_port unless new_port.empty?
|
66
|
-
|
67
|
-
print "New Username (leave blank to keep current: #{server[:username]}): "
|
68
|
-
new_username = gets.chomp.strip
|
69
|
-
server[:username] = new_username unless new_username.empty?
|
70
|
-
|
71
|
-
print "New SSH Key Path (leave blank to keep current: #{server[:ssh_key]}): "
|
72
|
-
new_ssh_key = gets.chomp.strip
|
73
|
-
server[:ssh_key] = new_ssh_key unless new_ssh_key.empty?
|
74
|
-
|
75
|
-
CSV.open(SERVERS_CSV, 'w') do |csv|
|
76
|
-
csv << servers.headers
|
77
|
-
servers.each { |row| csv << row }
|
78
|
-
end
|
79
|
-
|
80
|
-
puts "#{GREEN}Server '#{alias_name}' updated successfully!#{RESET_COLOR}"
|
81
|
-
end
|
82
|
-
|
83
|
-
def self.delete_server
|
84
|
-
print "Enter alias of the server to delete: "
|
85
|
-
alias_name = gets.chomp.strip
|
86
|
-
servers = CSV.table(SERVERS_CSV)
|
87
|
-
|
88
|
-
if servers.delete_if { |row| row[:alias] == alias_name }
|
89
|
-
CSV.open(SERVERS_CSV, 'w') do |csv|
|
90
|
-
csv << servers.headers
|
91
|
-
servers.each { |row| csv << row }
|
92
|
-
end
|
93
|
-
puts "#{GREEN}Server '#{alias_name}' deleted successfully!#{RESET_COLOR}"
|
94
|
-
else
|
95
|
-
puts "#{RED}No server found with alias '#{alias_name}'.#{RESET_COLOR}"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def self.connect_to_server(alias_name = nil)
|
100
|
-
if alias_name.nil?
|
101
|
-
print "Enter alias of the server to connect: "
|
102
|
-
alias_name = gets.chomp.strip
|
103
|
-
end
|
104
|
-
|
105
|
-
server = nil
|
106
|
-
CSV.foreach(SERVERS_CSV, headers: true) do |row|
|
107
|
-
if row['alias'] == alias_name
|
108
|
-
server = row
|
109
|
-
break
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
unless server
|
114
|
-
CLI::LOGGER.error("Failed connection attempt to #{alias_name}: No server found")
|
115
|
-
puts "#{RED}No server found with alias '#{alias_name}'.#{RESET_COLOR}"
|
116
|
-
return
|
117
|
-
end
|
118
|
-
|
119
|
-
ssh_command = "ssh #{server['username']}@#{server['hostname']} -p #{server['port']}"
|
120
|
-
ssh_command += " -i #{server['ssh_key']}" unless server['ssh_key'].to_s.empty?
|
121
|
-
|
122
|
-
CLI::LOGGER.info("Connecting to #{alias_name}...")
|
123
|
-
|
124
|
-
if system(ssh_command)
|
125
|
-
CLI::LOGGER.info("Successfully connected to #{alias_name}")
|
126
|
-
else
|
127
|
-
CLI::LOGGER.error("Failed to connect to #{alias_name}")
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
data/lib/sshman/sshman.rb
DELETED
data/lib/sshman/utils.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'csv'
|
2
|
-
require_relative 'constants'
|
3
|
-
|
4
|
-
module Sshman
|
5
|
-
class Utils
|
6
|
-
def self.ensure_csv_file
|
7
|
-
unless File.exist?(SERVERS_CSV)
|
8
|
-
File.open(SERVERS_CSV, 'w') { |file| file.puts "alias,hostname,port,username,ssh_key" }
|
9
|
-
puts "#{GREEN}Created servers file at #{SERVERS_CSV}.#{RESET_COLOR}"
|
10
|
-
end
|
11
|
-
File.chmod(0600, SERVERS_CSV)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.display_help
|
15
|
-
puts <<-HELP
|
16
|
-
Usage: sshman [COMMAND]
|
17
|
-
Commands:
|
18
|
-
list List all saved servers
|
19
|
-
add Add a new server configuration
|
20
|
-
edit Edit an existing server
|
21
|
-
delete Delete a server by its alias
|
22
|
-
connect Connect to a server by its alias
|
23
|
-
version Display the current version
|
24
|
-
help Display this help information
|
25
|
-
HELP
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|