sshman 0.2.4 → 0.3.1

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: 247fe150bd53e1caf0e599d074cce532df14da4c2055af26a94de4baf74e9cc1
4
- data.tar.gz: 3889aac5b2b664ff32146a625a48fbca2d702b8e8163c20f99ff0c367753d9f4
3
+ metadata.gz: ae2c4874869f063e6d243cc2cff2134a4ae0dc2f56fe1419cf9a6558ee489277
4
+ data.tar.gz: 6c399292b20e2f0bfedbfeae112e16a7c751b0148ecef8237736d5a74676afb8
5
5
  SHA512:
6
- metadata.gz: 470ebb35db7788190c13a9f5cd4c78c454a43fdbd9333899e6efe5c1ea40263e16277911af3498772790bea5ad273ec2d6334e2d167dd2188a8ddb47a804c4f2
7
- data.tar.gz: b1a23ef51b01000ca5642b04c2d22910d7c03dd2d29b13aef9cd4678acd348a479b74862249560888da4068085ae48224938d019622b7ec3e9ab2663c53f6bc1
6
+ metadata.gz: 6bbb1afeaf07a02d056b92af75c1fcaf4cc6c95020f84094dba20a4b511a0f7d91989d54452ac1cb801d96e863d102d367ea9762b1b60631976b840066fbb2fe
7
+ data.tar.gz: 39c60c4351a973e5452a605cf1aac17f2d83a0e6cc72f3f24a43edf64e3321753b6728c24321f35f9b2f20db7c99ede47700c05dbca635fc936915db09be2fdb
data/lib/sshman/cli.rb ADDED
@@ -0,0 +1,98 @@
1
+ require 'logger'
2
+ require_relative 'constants'
3
+ require_relative 'version'
4
+ require_relative 'server_manager'
5
+ require_relative 'utils'
6
+
7
+ module Sshman
8
+ class CLI
9
+ LOGGER = Logger.new(File.expand_path('~/.sshman.log'))
10
+
11
+ def self.start(argv)
12
+ case argv[0]
13
+ when 'list'
14
+ new.list_servers
15
+ when 'add'
16
+ new.add_server
17
+ when 'edit'
18
+ new.edit_server
19
+ when 'delete'
20
+ new.delete_server
21
+ when 'connect'
22
+ new.connect_to_server(argv[1])
23
+ when 'help'
24
+ new.display_help
25
+ when 'version'
26
+ new.version
27
+ else
28
+ puts "Unknown command: #{argv[0]}. Use 'sshman help' for a list of commands."
29
+ end
30
+ end
31
+
32
+ def version
33
+ puts "sshman version #{Sshman::VERSION}"
34
+ end
35
+
36
+ def self.start_interactive
37
+ new.main
38
+ end
39
+
40
+ def main
41
+ ensure_csv_file
42
+
43
+ loop do
44
+ puts "\n#{YELLOW}Options:#{RESET_COLOR} list, add, edit, delete, connect, help, quit"
45
+ print "#{CYAN}Choose an option: #{RESET_COLOR}"
46
+ option = gets.chomp.downcase.strip
47
+
48
+ case option
49
+ when 'list'
50
+ list_servers
51
+ when 'add'
52
+ add_server
53
+ when 'edit'
54
+ edit_server
55
+ when 'delete'
56
+ delete_server
57
+ when 'connect'
58
+ connect_to_server
59
+ when 'help'
60
+ display_help
61
+ when 'quit'
62
+ puts "#{GREEN}Goodbye!#{RESET_COLOR}"
63
+ break
64
+ else
65
+ puts "#{RED}Unknown option '#{option}'. Type 'help' for usage instructions.#{RESET_COLOR}"
66
+ end
67
+ end
68
+ end
69
+
70
+ def ensure_csv_file
71
+ Sshman::Utils.ensure_csv_file
72
+ end
73
+
74
+ def display_help
75
+ Sshman::Utils.display_help
76
+ end
77
+
78
+ def list_servers
79
+ Sshman::ServerManager.list_servers
80
+ end
81
+
82
+ def add_server
83
+ Sshman::ServerManager.add_server
84
+ end
85
+
86
+ def edit_server
87
+ Sshman::ServerManager.edit_server
88
+ end
89
+
90
+ def delete_server
91
+ Sshman::ServerManager.delete_server
92
+ end
93
+
94
+ def connect_to_server(alias_name = nil)
95
+ Sshman::ServerManager.connect_to_server(alias_name)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,8 @@
1
+ module Sshman
2
+ RESET_COLOR = "\033[0m"
3
+ RED = "\033[31m"
4
+ GREEN = "\033[32m"
5
+ YELLOW = "\033[33m"
6
+ CYAN = "\033[36m"
7
+ SERVERS_CSV = File.expand_path("~/.sshman_servers.csv")
8
+ end
@@ -0,0 +1,131 @@
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 CHANGED
@@ -1,237 +1,4 @@
1
- require 'csv'
2
- require 'io/console'
3
- require 'logger'
4
- require_relative 'version'
5
-
6
- module Sshman
7
- RESET_COLOR = "\033[0m"
8
- RED = "\033[31m"
9
- GREEN = "\033[32m"
10
- YELLOW = "\033[33m"
11
- CYAN = "\033[36m"
12
- SERVERS_CSV = File.expand_path("~/.sshman_servers.csv")
13
-
14
- class CLI
15
- LOGGER = Logger.new(File.expand_path('~/.sshman.log'))
16
-
17
- # This method handles inline commands
18
- def self.start(argv)
19
- case argv[0]
20
- when 'list'
21
- new.list_servers
22
- when 'add'
23
- new.add_server
24
- when 'edit'
25
- new.edit_server
26
- when 'delete'
27
- new.delete_server
28
- when 'connect'
29
- new.connect_to_server(argv[1])
30
- when 'help'
31
- new.display_help
32
- when 'version'
33
- new.version
34
- else
35
- puts "Unknown command: #{argv[0]}. Use 'sshman help' for a list of commands."
36
- end
37
- end
38
-
39
- # Display the current version
40
- def version
41
- puts "sshman version #{Sshman::VERSION}"
42
- end
43
-
44
- # This method starts the interactive menu (default)
45
- def self.start_interactive
46
- new.main
47
- end
48
-
49
- # Main interactive loop
50
- def main
51
- ensure_csv_file
52
-
53
- loop do
54
- puts "\n#{YELLOW}Options:#{RESET_COLOR} list, add, edit, delete, connect, help, quit"
55
- print "#{CYAN}Choose an option: #{RESET_COLOR}"
56
- option = gets.chomp.downcase.strip
57
-
58
- case option
59
- when 'list'
60
- list_servers
61
- when 'add'
62
- add_server
63
- when 'edit'
64
- edit_server
65
- when 'delete'
66
- delete_server
67
- when 'connect'
68
- connect_to_server
69
- when 'help'
70
- display_help
71
- when 'quit'
72
- puts "#{GREEN}Goodbye!#{RESET_COLOR}"
73
- break
74
- else
75
- puts "#{RED}Unknown option '#{option}'. Type 'help' for usage instructions.#{RESET_COLOR}"
76
- end
77
- end
78
- end
79
-
80
- # Ensure the CSV file exists and is secure
81
- def ensure_csv_file
82
- unless File.exist?(SERVERS_CSV)
83
- File.open(SERVERS_CSV, 'w') { |file| file.puts "alias,hostname,port,username,ssh_key" }
84
- puts "#{GREEN}Created servers file at #{SERVERS_CSV}.#{RESET_COLOR}"
85
- end
86
- File.chmod(0600, SERVERS_CSV) # Restrict file permissions for security
87
- end
88
-
89
- # Display help information
90
- def display_help
91
- puts <<-HELP
92
- Usage: sshman [COMMAND]
93
- Commands:
94
- list List all saved servers
95
- add Add a new server configuration
96
- edit Edit an existing server
97
- delete Delete a server by its alias
98
- connect Connect to a server by its alias
99
- version Display the current version
100
- help Display this help information
101
- HELP
102
- end
103
-
104
- # List all servers in a formatted table with colors
105
- def list_servers
106
- if File.zero?(SERVERS_CSV)
107
- puts "#{YELLOW}No servers found. Add some using the 'add' option.#{RESET_COLOR}"
108
- return
109
- end
110
-
111
- puts "#{CYAN}%-15s %-25s %-6s %-15s %-30s#{RESET_COLOR}" % ["Alias", "Hostname", "Port", "Username", "SSH Key"]
112
- puts "-" * 95
113
-
114
- CSV.foreach(SERVERS_CSV, headers: true) do |row|
115
- puts "%-15s %-25s %-6s %-15s %-30s" % [row['alias'], row['hostname'], row['port'], row['username'], row['ssh_key']]
116
- end
117
- end
118
-
119
- # Add a new server to the CSV file
120
- def add_server
121
- puts "#{CYAN}Adding a new server...#{RESET_COLOR}"
122
- print "Alias: "
123
- alias_name = gets.chomp.strip
124
- return puts "#{RED}Alias cannot be empty!#{RESET_COLOR}" if alias_name.empty?
125
-
126
- print "Hostname or IP: "
127
- hostname = gets.chomp.strip
128
- return puts "#{RED}Hostname cannot be empty!#{RESET_COLOR}" if hostname.empty?
129
-
130
- print "Port (default 22): "
131
- port = gets.chomp.strip
132
- port = '22' if port.empty?
133
-
134
- print "Username: "
135
- username = gets.chomp.strip
136
- return puts "#{RED}Username cannot be empty!#{RESET_COLOR}" if username.empty?
137
-
138
- print "Path to SSH key (leave blank if none): "
139
- ssh_key = gets.chomp.strip
140
-
141
- CSV.open(SERVERS_CSV, 'a+') do |csv|
142
- csv << [alias_name, hostname, port, username, ssh_key]
143
- end
144
-
145
- puts "#{GREEN}Server '#{alias_name}' added successfully!#{RESET_COLOR}"
146
- end
147
-
148
- # Edit an existing server's details
149
- def edit_server
150
- print "Enter alias of the server to edit: "
151
- alias_name = gets.chomp.strip
152
- servers = CSV.table(SERVERS_CSV)
153
-
154
- server = servers.find { |row| row[:alias] == alias_name }
155
- unless server
156
- puts "#{RED}No server found with alias '#{alias_name}'.#{RESET_COLOR}"
157
- return
158
- end
159
-
160
- print "New Hostname (leave blank to keep current: #{server[:hostname]}): "
161
- new_hostname = gets.chomp.strip
162
- server[:hostname] = new_hostname unless new_hostname.empty?
163
-
164
- print "New Port (leave blank to keep current: #{server[:port]}): "
165
- new_port = gets.chomp.strip
166
- server[:port] = new_port unless new_port.empty?
167
-
168
- print "New Username (leave blank to keep current: #{server[:username]}): "
169
- new_username = gets.chomp.strip
170
- server[:username] = new_username unless new_username.empty?
171
-
172
- print "New SSH Key Path (leave blank to keep current: #{server[:ssh_key]}): "
173
- new_ssh_key = gets.chomp.strip
174
- server[:ssh_key] = new_ssh_key unless new_ssh_key.empty?
175
-
176
- CSV.open(SERVERS_CSV, 'w') do |csv|
177
- csv << servers.headers
178
- servers.each { |row| csv << row }
179
- end
180
-
181
- puts "#{GREEN}Server '#{alias_name}' updated successfully!#{RESET_COLOR}"
182
- end
183
-
184
- # Delete a server from the CSV file
185
- def delete_server
186
- print "Enter alias of the server to delete: "
187
- alias_name = gets.chomp.strip
188
- servers = CSV.table(SERVERS_CSV)
189
-
190
- if servers.delete_if { |row| row[:alias] == alias_name }
191
- CSV.open(SERVERS_CSV, 'w') do |csv|
192
- csv << servers.headers
193
- servers.each { |row| csv << row }
194
- end
195
- puts "#{GREEN}Server '#{alias_name}' deleted successfully!#{RESET_COLOR}"
196
- else
197
- puts "#{RED}No server found with alias '#{alias_name}'.#{RESET_COLOR}"
198
- end
199
- end
200
-
201
- # Connect to a server using SSH
202
- def connect_to_server(alias_name = nil)
203
- # If no alias is provided, ask the user for one
204
- if alias_name.nil?
205
- print "Enter alias of the server to connect: "
206
- alias_name = gets.chomp.strip
207
- end
208
-
209
- # Search for the server in the CSV file
210
- server = nil
211
- CSV.foreach(SERVERS_CSV, headers: true) do |row|
212
- if row['alias'] == alias_name
213
- server = row
214
- break
215
- end
216
- end
217
-
218
- unless server
219
- LOGGER.error("Failed connection attempt to #{alias_name}: No server found")
220
- puts "#{RED}No server found with alias '#{alias_name}'.#{RESET_COLOR}"
221
- return
222
- end
223
-
224
- ssh_command = "ssh #{server['username']}@#{server['hostname']} -p #{server['port']}"
225
- ssh_command += " -i #{server['ssh_key']}" unless server['ssh_key'].to_s.empty?
226
-
227
- LOGGER.info("Connecting to #{alias_name}...")
228
-
229
- # Use system to log successful connection
230
- if system(ssh_command)
231
- LOGGER.info("Successfully connected to #{alias_name}")
232
- else
233
- LOGGER.error("Failed to connect to #{alias_name}")
234
- end
235
- end
236
- end
237
- end
1
+ require_relative 'constants'
2
+ require_relative 'cli'
3
+ require_relative 'server_manager'
4
+ require_relative 'utils'
@@ -0,0 +1,28 @@
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
@@ -1,5 +1,5 @@
1
1
  # lib/sshman/version.rb
2
2
 
3
3
  module Sshman
4
- VERSION = "0.2.4"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sshman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - SubnetMasked
@@ -20,12 +20,19 @@ extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
22
  - exe/sshman
23
+ - lib/sshman/cli.rb
24
+ - lib/sshman/constants.rb
25
+ - lib/sshman/server_manager.rb
23
26
  - lib/sshman/sshman.rb
27
+ - lib/sshman/utils.rb
24
28
  - lib/sshman/version.rb
25
29
  homepage: https://github.com/subnetmasked/sshman
26
30
  licenses:
27
31
  - GPL-3.0
28
- metadata: {}
32
+ metadata:
33
+ homepage_uri: https://github.com/subnetmasked/sshman
34
+ source_code_uri: https://github.com/subnetmasked/sshman
35
+ bug_tracker_uri: https://github.com/subnetmasked/sshman/issues
29
36
  post_install_message:
30
37
  rdoc_options: []
31
38
  require_paths: