ccsh 0.0.4 → 0.0.5
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 +5 -5
- data/lib/ccsh.rb +36 -5
- data/lib/ccsh/host.rb +7 -0
- data/lib/ccsh/hosts.rb +7 -2
- data/lib/ccsh/options.rb +1 -2
- data/lib/ccsh/ssh.rb +46 -8
- data/lib/ccsh/utils.rb +32 -5
- data/lib/ccsh/version.rb +1 -6
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 639d07e71db4651f24cde07acebee595da81371f9e1890260c66a8aac6d0f694
|
4
|
+
data.tar.gz: 583b234ae7902e7c30d701134778ace42b0adc4bbb4a61749bc64650fd8c76bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f16c64f3e57d0504a848acac338edabd30fe2d82ec589e018d198f00e0eb31076781d8976806d15cd886a63e00417814ce40ddc4ea7ee331cbe15df39c0e66ea
|
7
|
+
data.tar.gz: 4ee0fc7b6466475e6c2d446026b079e2411c0a7d77e1b7e1508fbcc66e78d92a3dfda37abb735f8ea7329999e6daf93764ecba057bc4ce32b1e446d851c8d81d
|
data/lib/ccsh.rb
CHANGED
@@ -15,12 +15,36 @@ module CCSH
|
|
15
15
|
ENV['CCSH_DEBUG'] = "true" if options[:debug]
|
16
16
|
ENV['CCSH_VERBOSE'] = "true" if options[:verbose]
|
17
17
|
|
18
|
-
|
18
|
+
if options[:targets].empty?
|
19
|
+
error_msg = "You must specify a target hostname or group name."
|
20
|
+
|
21
|
+
puts error_msg
|
22
|
+
puts "Example:"
|
23
|
+
puts " 'ccsh databases' - select all servers from the database group"
|
24
|
+
puts " 'ccsh all' - select all defined servers"
|
25
|
+
puts "Please run 'ccsh --help' for details"
|
26
|
+
puts ""
|
27
|
+
|
28
|
+
raise error_msg
|
29
|
+
end
|
19
30
|
|
20
31
|
filename = options[:hosts]
|
21
32
|
targets = options[:targets]
|
22
|
-
|
23
33
|
hosts = CCSH::Hosts.new.parser!(filename).filter_by(targets)
|
34
|
+
|
35
|
+
# validate and display pretty message if no hosts was found to the
|
36
|
+
# given target.
|
37
|
+
if hosts.empty?
|
38
|
+
error_msg = "Could not found any hosts that matches the given target(s): '#{targets.join(', ')}'"
|
39
|
+
puts error_msg
|
40
|
+
|
41
|
+
puts "Here are some groups found on the file: '#{filename}'"
|
42
|
+
CCSH::Utils.show_groups(CCSH::Hosts.new.parser!(filename).filter_by('all'))
|
43
|
+
|
44
|
+
puts ""
|
45
|
+
raise error_msg
|
46
|
+
end
|
47
|
+
|
24
48
|
self.start_cli(hosts, options)
|
25
49
|
|
26
50
|
rescue Exception => e
|
@@ -28,8 +52,8 @@ module CCSH
|
|
28
52
|
CCSH::Utils.debug "Backtrace:\n\t#{e.backtrace.join("\n\t")}\n\n"
|
29
53
|
CCSH::Utils.verbose "Backtrace:\n\t#{e.backtrace.join("\n\t")}\n\n"
|
30
54
|
|
31
|
-
puts "An error occur and system exit with the following message: "
|
32
|
-
puts " #{e.message}"
|
55
|
+
STDERR.puts "An error occur and system exit with the following message: "
|
56
|
+
STDERR.puts " #{e.message.gsub("\n", ' ').squeeze(' ')}"
|
33
57
|
|
34
58
|
exit!
|
35
59
|
end
|
@@ -73,6 +97,7 @@ module CCSH
|
|
73
97
|
|
74
98
|
def self.start_cli(hosts, options)
|
75
99
|
CCSH::Utils.display_hosts(hosts) if options[:show_hosts]
|
100
|
+
CCSH::Utils.display_hosts_verbosity(hosts) if options[:verbose]
|
76
101
|
|
77
102
|
quit = false
|
78
103
|
loop do
|
@@ -100,8 +125,14 @@ module CCSH
|
|
100
125
|
threads = []
|
101
126
|
|
102
127
|
batch_hosts.each do |host|
|
103
|
-
|
128
|
+
if command =~ /^([ ]*)sudo/
|
129
|
+
if host.sudo_enabled != true
|
130
|
+
STDERR.puts "WARN: You cannot run sudo on the host #{host.hostname}, please enable sudo mode for this hosts"
|
131
|
+
next
|
132
|
+
end
|
133
|
+
end
|
104
134
|
|
135
|
+
threads << Thread.new do
|
105
136
|
info = with_info(options) do
|
106
137
|
host.run command
|
107
138
|
end
|
data/lib/ccsh/host.rb
CHANGED
@@ -9,6 +9,8 @@ module CCSH
|
|
9
9
|
attr_accessor :private_key
|
10
10
|
attr_accessor :ssh_options
|
11
11
|
attr_accessor :timeout
|
12
|
+
attr_accessor :sudo_enabled
|
13
|
+
attr_accessor :sudo_password
|
12
14
|
|
13
15
|
def initialize
|
14
16
|
@name = ''
|
@@ -19,10 +21,13 @@ module CCSH
|
|
19
21
|
@password = nil
|
20
22
|
@private_key = nil
|
21
23
|
@ssh_options = []
|
24
|
+
@sudo_enabled = false
|
25
|
+
@sudo_password = @password
|
22
26
|
end
|
23
27
|
|
24
28
|
def run(command)
|
25
29
|
CCSH::Utils.debug("Running command '#{command}' on #{@hostname}")
|
30
|
+
|
26
31
|
command = CCSH::SSH.start do |ssh|
|
27
32
|
ssh.user = @user
|
28
33
|
ssh.port = @port
|
@@ -30,6 +35,8 @@ module CCSH
|
|
30
35
|
ssh.password = @password
|
31
36
|
ssh.private_key = @private_key
|
32
37
|
ssh.options = @ssh_options
|
38
|
+
ssh.enable_sudo = @sudo_enabled
|
39
|
+
ssh.sudo_password = @sudo_password
|
33
40
|
|
34
41
|
ssh.command = command
|
35
42
|
ssh.hostname = @hostname || @name
|
data/lib/ccsh/hosts.rb
CHANGED
@@ -36,6 +36,11 @@ module CCSH
|
|
36
36
|
host.private_key = CCSH::Utils.get_options('private_key', h, @defaults['private_key'])
|
37
37
|
host.ssh_options = CCSH::Utils.get_options('ssh_options', h, @defaults['ssh_options'])
|
38
38
|
host.timeout = CCSH::Utils.get_options('timeout', h, @defaults['timeout'])
|
39
|
+
host.sudo_enabled = CCSH::Utils.get_options('sudo_enabled', h, @defaults['sudo_enabled'])
|
40
|
+
host.sudo_password = CCSH::Utils.get_options('sudo_password', h, @defaults['sudo_password'])
|
41
|
+
|
42
|
+
# define the password if the sudo_password is not set
|
43
|
+
host.sudo_password = host.password if host.sudo_password == nil
|
39
44
|
|
40
45
|
host.groups = h['groups']
|
41
46
|
|
@@ -51,12 +56,12 @@ module CCSH
|
|
51
56
|
end
|
52
57
|
|
53
58
|
def filter_by(targets)
|
54
|
-
return @hosts if targets.include?
|
59
|
+
return @hosts if targets.include?('all')
|
55
60
|
|
56
61
|
hosts = []
|
57
62
|
@hosts.each do |host|
|
58
63
|
targets.each do |target|
|
59
|
-
hosts << host if host.groups.include?
|
64
|
+
hosts << host if host.groups != nil && host.groups.include?(target)
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
data/lib/ccsh/options.rb
CHANGED
data/lib/ccsh/ssh.rb
CHANGED
@@ -21,6 +21,8 @@ module CCSH
|
|
21
21
|
attr_accessor :password
|
22
22
|
attr_accessor :private_key
|
23
23
|
attr_accessor :options
|
24
|
+
attr_accessor :enable_sudo
|
25
|
+
attr_accessor :sudo_password
|
24
26
|
|
25
27
|
attr_accessor :stdout
|
26
28
|
attr_accessor :stderr
|
@@ -33,6 +35,10 @@ module CCSH
|
|
33
35
|
@options = []
|
34
36
|
@stdout = ''
|
35
37
|
@stderr = ''
|
38
|
+
|
39
|
+
@enable_sudo = false
|
40
|
+
@sudo_user = 'root'
|
41
|
+
@sudo_password = nil
|
36
42
|
end
|
37
43
|
|
38
44
|
def execute!
|
@@ -48,12 +54,33 @@ module CCSH
|
|
48
54
|
|
49
55
|
Net::SSH.start(@hostname, @user, @options) do |ssh|
|
50
56
|
ssh.open_channel do |ch|
|
51
|
-
ch.exec @command do |ch, success|
|
52
|
-
raise "Could execute command #{command} on #{host}" unless success
|
53
|
-
end
|
54
|
-
|
55
57
|
ch.on_data do |c, data|
|
56
|
-
|
58
|
+
|
59
|
+
if data =~ /^\[sudo\] password for /
|
60
|
+
|
61
|
+
if @enable_sudo
|
62
|
+
if @sudo_password != nil
|
63
|
+
ch.send_data "#{@sudo_password}\n"
|
64
|
+
else
|
65
|
+
msg = """The server #{@hostname} asked for user password
|
66
|
+
by the 'password' or 'sudo_password' option was not defined.
|
67
|
+
""".gsub("\n", ' ').squeeze(' ')
|
68
|
+
|
69
|
+
STDERR.puts "[WARN] #{msg}"
|
70
|
+
ch.send_data "\x03"
|
71
|
+
end
|
72
|
+
else
|
73
|
+
msg = """The server #{@hostname} asked for user password
|
74
|
+
the sudo_enabled option was not allowed
|
75
|
+
skipping this hosts setup
|
76
|
+
""".gsub("\n", ' ').squeeze(' ')
|
77
|
+
|
78
|
+
STDERR.puts "[WARN] #{msg}"
|
79
|
+
ch.send_data "\x03"
|
80
|
+
end
|
81
|
+
else
|
82
|
+
@stdout << data
|
83
|
+
end
|
57
84
|
end
|
58
85
|
|
59
86
|
ch.on_extended_data do |c, type, data|
|
@@ -63,16 +90,27 @@ module CCSH
|
|
63
90
|
ch.on_request("exit-status") do |c,data|
|
64
91
|
@return_code = data.read_long
|
65
92
|
end
|
66
|
-
|
93
|
+
|
67
94
|
ch.on_request("exit-signal") do |c, data|
|
68
95
|
@return_signal = data.read_long
|
69
96
|
end
|
70
97
|
|
71
|
-
|
98
|
+
ch.request_pty do |ch, success|
|
99
|
+
if success
|
100
|
+
CCSH::Utils.debug("pty successfully obtained for #{@hostname}")
|
101
|
+
else
|
102
|
+
CCSH::Utils.debug("pty unsuccessfully obtained for #{@hostname}")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
ch.exec @command do |ch, success|
|
107
|
+
raise "Could execute command #{command} on #{host}" unless success
|
108
|
+
end
|
109
|
+
end.wait
|
72
110
|
end
|
73
111
|
|
74
112
|
return self
|
75
113
|
end
|
76
114
|
end
|
77
115
|
end
|
78
|
-
end
|
116
|
+
end
|
data/lib/ccsh/utils.rb
CHANGED
@@ -6,9 +6,11 @@ module CCSH
|
|
6
6
|
# parameters.
|
7
7
|
def self.merge_defaults(defaults)
|
8
8
|
defaultsValues = {
|
9
|
-
'user'
|
10
|
-
'port'
|
11
|
-
'
|
9
|
+
'user' => 'root',
|
10
|
+
'port' => '22',
|
11
|
+
'sudo_enabled' => false,
|
12
|
+
'sudo_password' => nil,
|
13
|
+
'private_key' => '~/.ssh/id_rsa',
|
12
14
|
}
|
13
15
|
defaultsValues.merge!(defaults) if defaults != nil
|
14
16
|
|
@@ -45,12 +47,37 @@ module CCSH
|
|
45
47
|
hosts.each do |host|
|
46
48
|
puts "+ Server #{host.name}: #{host.user}@#{host.hostname} => Groups: #{host.groups}"
|
47
49
|
end
|
50
|
+
puts
|
51
|
+
end
|
48
52
|
|
53
|
+
##
|
54
|
+
# Display host display_hosts_verbosity
|
55
|
+
def self.display_hosts_verbosity(hosts)
|
56
|
+
hosts.each do |host|
|
57
|
+
CCSH::Utils::verbose("sudo mode enable to host: #{host.hostname}") if host.sudo_enabled
|
58
|
+
end
|
49
59
|
puts
|
50
60
|
end
|
51
61
|
|
52
62
|
##
|
53
|
-
#
|
63
|
+
# Show at least 10 groups names
|
64
|
+
def self.show_groups(hosts)
|
65
|
+
hosts_groups = []
|
66
|
+
hosts.each do |host|
|
67
|
+
if host.groups != nil
|
68
|
+
host.groups.each do |gname|
|
69
|
+
hosts_groups.push(gname) unless hosts_groups.include?(gname)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
hosts_groups.slice(0, 10).each { |gname| puts " - #{gname}" }
|
75
|
+
puts "Example: ccsh #{hosts_groups[0]}" unless hosts_groups[0] == nil
|
76
|
+
puts "Example: ccsh #{hosts_groups.slice(0,2).join(' ')}" unless hosts_groups.slice(0,2) == nil
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# validate the ssh connection before start the ccsh console
|
54
81
|
def self.valid_ssh(options)
|
55
82
|
return true
|
56
83
|
end
|
@@ -64,7 +91,7 @@ module CCSH
|
|
64
91
|
##
|
65
92
|
# Verbosely display a message, if verbose mode is enabled
|
66
93
|
def self.verbose(msg)
|
67
|
-
puts msg if ENV['CCSH_VERBOSE'] == "true"
|
94
|
+
puts "[verbose] #{msg}" if ENV['CCSH_VERBOSE'] == "true"
|
68
95
|
end
|
69
96
|
|
70
97
|
##
|
data/lib/ccsh/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ccsh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Silva - raffs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-ssh
|
@@ -86,7 +86,7 @@ homepage: https://github.com/raffs/ccsh
|
|
86
86
|
licenses:
|
87
87
|
- Apache-2.0
|
88
88
|
metadata: {}
|
89
|
-
post_install_message:
|
89
|
+
post_install_message: Thanks for installing CCSH!
|
90
90
|
rdoc_options: []
|
91
91
|
require_paths:
|
92
92
|
- lib
|
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
102
|
version: '0'
|
103
103
|
requirements: []
|
104
104
|
rubyforge_project:
|
105
|
-
rubygems_version: 2.
|
105
|
+
rubygems_version: 2.7.5
|
106
106
|
signing_key:
|
107
107
|
specification_version: 4
|
108
108
|
summary: Interactive multiple client shell command
|