santoku 0.0.3 → 0.0.4
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/bin/santoku +15 -3
- data/lib/santoku.rb +31 -101
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2d8bfadb34d6d3a3afdfcc83ab1278c9a39e578
|
4
|
+
data.tar.gz: df7f809fa31474ab1eef2cbb3b75ce2541e0f903
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bbd5a78c001b6ba734b547c20964020560bf57bb75b5ab99d999946f974e0f8d41e388ad4f3a1430568ec57ad177f730a52d666a2d570888ab05bc63d8ad712
|
7
|
+
data.tar.gz: cb620bb5d996f0286047fd59d71ee456615e0241be082013c10a38e68d9e03b81ed6f917fb68f326c777726aa71ffb604733342e811f648136545ea916fc38d8
|
data/bin/santoku
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'santoku'
|
3
|
+
require "rubygems"
|
4
|
+
require 'thor'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
class SantokuCommand < Thor
|
7
|
+
map '-t' => :test
|
8
|
+
|
9
|
+
desc 'test COMMAND [QUERY]', 'Execute command on nodes, scoped on the given query if query is given. Query syntax should be the same as `knife search` syntax.'
|
10
|
+
option :invert, type: :boolean, desc: "invert matched results (DOESN'T WORK YET)", default: false
|
11
|
+
option :timeout, type: :numeric, desc: 'timeout interval per ssh connection (default: 15)', default: 15
|
12
|
+
option :'print-success', type: :boolean, desc: 'prints output of successful commands', default: false
|
13
|
+
def test(command, query='name:*')
|
14
|
+
Santoku.test(command, query, options[:timeout], options[:'print-success'], options[:'invert'])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
SantokuCommand.start
|
data/lib/santoku.rb
CHANGED
@@ -1,112 +1,42 @@
|
|
1
|
-
require 'colorize'
|
2
|
-
require 'net/ssh'
|
3
1
|
require 'peach'
|
4
|
-
require 'ridley'
|
5
|
-
require 'yaml'
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
output_stream = Array.new
|
10
|
-
failed_output_stream = Array.new
|
11
|
-
timeout_output_stream = Array.new
|
3
|
+
require 'santoku/helpers'
|
4
|
+
require 'santoku/printers'
|
12
5
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
6
|
+
class Santoku
|
7
|
+
class << self
|
8
|
+
def test(command, query, timeout_interval, verbose_success, invert)
|
9
|
+
@verbose_success = verbose_success
|
10
|
+
@invert = invert
|
11
|
+
|
12
|
+
ridley.search(:node, query).peach(5) do |node|
|
13
|
+
begin
|
14
|
+
timeout timeout_interval do
|
15
|
+
Net::SSH.start(node.chef_id, 'root', paranoid: false, forward_agent: true) do |ssh|
|
16
|
+
output = ssh_exec!(ssh, command)
|
17
|
+
if output[2] == 0 && !invert?
|
18
|
+
succeeded "#{node.chef_id}: #{output[0]}"
|
19
|
+
elsif output[2] != 0 && invert?
|
20
|
+
succeeded "#{node.chef_id} returned #{output[2]}: #{output[1]} #{output[0]}"
|
21
|
+
else
|
22
|
+
failed "#{node.chef_id} returned #{output[2]}: #{output[1]} #{output[0]}"
|
23
|
+
end
|
24
24
|
end
|
25
25
|
end
|
26
|
+
rescue TimeoutError
|
27
|
+
timed_out "#{node.chef_id}: connection timed out"
|
28
|
+
rescue Errno::ETIMEDOUT
|
29
|
+
timed_out "#{node.chef_id}: Operation timed out - connect(2)"
|
30
|
+
rescue SocketError
|
31
|
+
timed_out "#{node.chef_id}: node does not resolve"
|
32
|
+
rescue Errno::EHOSTUNREACH
|
33
|
+
timed_out "#{node.chef_id}: no route to host"
|
34
|
+
rescue Exception => e
|
35
|
+
timed_out "#{node.chef_id}: #{e.inspect}"
|
26
36
|
end
|
27
|
-
|
28
|
-
rescue TimeoutError
|
29
|
-
timeout_output_stream.push "#{node.chef_id}: connection timed out"
|
30
|
-
print '*'.yellow
|
31
|
-
rescue SocketError
|
32
|
-
timeout_output_stream.push "#{node.chef_id}: node does not resolve"
|
33
|
-
print '*'.yellow
|
34
|
-
rescue Errno::EHOSTUNREACH
|
35
|
-
timeout_output_stream.push "#{node.chef_id}: no route to host"
|
36
|
-
print '*'.yellow
|
37
|
-
rescue Exception => e
|
38
|
-
failed_output_stream.push "#{node.chef_id}: #{e.inspect}"
|
39
|
-
print 'F'.red
|
40
37
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
print "\n"
|
44
|
-
|
45
|
-
timeout_output_stream.each do |output|
|
46
|
-
puts output.yellow
|
47
|
-
end
|
48
|
-
|
49
|
-
failed_output_stream.each do |output|
|
50
|
-
puts output.red
|
51
|
-
end
|
52
|
-
|
53
|
-
output_stream.each do |output|
|
54
|
-
puts output.green
|
55
|
-
end
|
56
|
-
|
57
|
-
puts "\n---------------------------------------\n"
|
58
|
-
|
59
|
-
puts "#{'Success'.green}: #{output_stream.count}"
|
60
|
-
puts "#{'Timed out or does not resolve'.yellow}: #{timeout_output_stream.count}"
|
61
|
-
puts "#{'Failed'.red}: #{failed_output_stream.count}"
|
62
|
-
end
|
63
38
|
|
64
|
-
|
65
|
-
def self.knife_config
|
66
|
-
if ::File.exist?(File.expand_path("../knife.rb", __FILE__))
|
67
|
-
Ridley::Chef::Config.from_file(File.expand_path("../knife.rb", __FILE__))
|
68
|
-
elsif ::File.exist?("#{ENV['HOME']}/.chef/knife.rb")
|
69
|
-
Ridley::Chef::Config.from_file("#{ENV['HOME']}/.chef/knife.rb")
|
70
|
-
else
|
71
|
-
raise 'Could not find knife.rb in current directory or home '
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.ridley
|
76
|
-
@ridley ||= Ridley.new(
|
77
|
-
server_url: knife_config.chef_server_url,
|
78
|
-
client_name: knife_config.node_name,
|
79
|
-
client_key: knife_config.client_key
|
80
|
-
)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def ssh_exec!(ssh, command)
|
85
|
-
# I am not awesome enough to have made this method myself
|
86
|
-
# I've just modified it a bit
|
87
|
-
# Originally submitted by 'flitzwald' over here: http://stackoverflow.com/a/3386375
|
88
|
-
stdout_data = ""
|
89
|
-
stderr_data = ""
|
90
|
-
exit_code = nil
|
91
|
-
|
92
|
-
ssh.open_channel do |channel|
|
93
|
-
channel.exec(command) do |ch, success|
|
94
|
-
unless success
|
95
|
-
abort "FAILED: couldn't execute command (ssh.channel.exec)"
|
96
|
-
end
|
97
|
-
channel.on_data do |ch,data|
|
98
|
-
stdout_data+=data
|
99
|
-
end
|
100
|
-
|
101
|
-
channel.on_extended_data do |ch,type,data|
|
102
|
-
stderr_data+=data
|
103
|
-
end
|
104
|
-
|
105
|
-
channel.on_request("exit-status") do |ch,data|
|
106
|
-
exit_code = data.read_long
|
107
|
-
end
|
39
|
+
print_summary
|
108
40
|
end
|
109
41
|
end
|
110
|
-
ssh.loop
|
111
|
-
[stdout_data, stderr_data, exit_code]
|
112
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: santoku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven De Coeyer
|
8
|
+
- Mike Morraye
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-11-17 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: colorize
|
@@ -52,9 +53,23 @@ dependencies:
|
|
52
53
|
- - '>='
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: '0'
|
55
|
-
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: thor
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
description: A gem to perform command over parallel ssh connections on multiple chef
|
56
71
|
serverspec. Output is rspec-like.
|
57
|
-
email:
|
72
|
+
email: tech@openminds.be
|
58
73
|
executables:
|
59
74
|
- santoku
|
60
75
|
extensions: []
|