santoku 0.0.5 → 0.0.6

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
  SHA1:
3
- metadata.gz: fbf7295813d610a5e5f36bc497af900d690b98c1
4
- data.tar.gz: 95089cdb8cfe09bb57ad35c1fd2ce7a3894ec763
3
+ metadata.gz: fb52db36d32657b634327f65e244f02cb9994390
4
+ data.tar.gz: 132f2d8bb28bb26773bbec2a4c19bbcec0c6639f
5
5
  SHA512:
6
- metadata.gz: 68f756ff452d1f66604752a69107445e30728b7e8478284de23fbb5ae106626d778213bd6bc1a78dd7ceb7bdc2a1501d7bb1bacfc6ec769fd81b4041be8e0466
7
- data.tar.gz: 84c3d165ba29d80644a1319468814be213461219fe12b89884d348f78d9ef6f6bfe7654e4a2cc170e994fc199fe2653a5c2e162aa011bcaf84f139e028428c84
6
+ metadata.gz: ee647aa900f3d34521211f176c34a0ee9f717bc722974e811f04a7de15c08060cb7d2320b2885cbfdfa3cdf2462d3e668d95215ba4f0ff3c14313133b95b2507
7
+ data.tar.gz: 55a051ddb3cb0379f983bef058bdd6d41e7637f8e39a783ae853d0d658c3681f73bf9f5093519a892f9ff1d2e6813bec9326760f5621a07a26b13bf187a6f339
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Openminds BVBA
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ santoku
2
+ =======
3
+
4
+ Parrallel ssh commands over chef servers with rspec-like output
5
+
6
+ install
7
+ =======
8
+
9
+ This is just a proof of concept for now. Install with:
10
+
11
+ gem install santoku
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'santoku'
3
- require "rubygems"
3
+ require 'rubygems'
4
4
  require 'thor'
5
5
 
6
6
  class SantokuCommand < Thor
7
7
  map '-t' => :test
8
8
 
9
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
10
+ option :invert, type: :boolean, desc: 'invert matched results', default: false
11
11
  option :timeout, type: :numeric, desc: 'timeout interval per ssh connection (default: 15)', default: 15
12
12
  option :'print-success', type: :boolean, desc: 'prints output of successful commands', default: false
13
13
  def test(command, query='name:*')
14
- Santoku.test(command, query, options[:timeout], options[:'print-success'], options[:'invert'])
14
+ Santoku.test(command, query, options[:timeout], options[:'print-success'], options[:invert])
15
15
  end
16
16
  end
17
17
 
@@ -1,39 +1,22 @@
1
1
  require 'peach'
2
2
 
3
+ require 'santoku/chef'
3
4
  require 'santoku/helpers'
4
5
  require 'santoku/printers'
6
+ require 'santoku/santoku'
7
+ require 'santoku/ssh'
5
8
 
6
9
  class Santoku
7
10
  class << self
8
- def test(command, query, timeout_interval, verbose_success, invert)
11
+ def test command, query, timeout_interval, verbose_success, invert
12
+ @command = command
13
+ @query = query
14
+ @timeout_interval = timeout_interval
9
15
  @verbose_success = verbose_success
10
16
  @invert = invert
11
17
 
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
- end
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}"
36
- end
18
+ knife_search(@query).peach(5) do |fqdn|
19
+ execute_query fqdn
37
20
  end
38
21
 
39
22
  print_summary
@@ -0,0 +1,16 @@
1
+ require 'chef/knife'
2
+
3
+ class Santoku
4
+ class << self
5
+ def knife_search query
6
+ # Monkey patch Chef::Knife::UI to hide stdout
7
+ Chef::Knife::UI.class_eval do
8
+ def stdout
9
+ @stdout_hack ||= ::File.new('/dev/null', 'w')
10
+ end
11
+ end
12
+
13
+ Chef::Knife.run(['search', 'node', query]).map { |node| node[:fqdn] }
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,3 @@
1
- require 'ridley'
2
- require 'net/ssh'
3
1
  require 'santoku/printers'
4
2
 
5
3
  class Santoku
@@ -38,53 +36,5 @@ class Santoku
38
36
  def invert?
39
37
  @invert
40
38
  end
41
-
42
- private
43
- def knife_config
44
- if ::File.exist?(File.expand_path("../knife.rb", __FILE__))
45
- Ridley::Chef::Config.from_file(File.expand_path("../knife.rb", __FILE__))
46
- elsif ::File.exist?("#{ENV['HOME']}/.chef/knife.rb")
47
- Ridley::Chef::Config.from_file("#{ENV['HOME']}/.chef/knife.rb")
48
- else
49
- raise 'Could not find knife.rb in current directory or home '
50
- end
51
- end
52
-
53
- def ridley
54
- @ridley ||= Ridley.new(
55
- server_url: knife_config.chef_server_url,
56
- client_name: knife_config.node_name,
57
- client_key: knife_config.client_key
58
- )
59
- end
60
-
61
- def ssh_exec!(ssh, command)
62
- # I am not awesome enough to have made this method myself
63
- # Originally submitted by 'flitzwald' over here: http://stackoverflow.com/a/3386375
64
- stdout_data = ""
65
- stderr_data = ""
66
- exit_code = nil
67
-
68
- ssh.open_channel do |channel|
69
- channel.exec(command) do |ch, success|
70
- unless success
71
- abort "FAILED: couldn't execute command (ssh.channel.exec)"
72
- end
73
- channel.on_data do |ch,data|
74
- stdout_data+=data
75
- end
76
-
77
- channel.on_extended_data do |ch,type,data|
78
- stderr_data+=data
79
- end
80
-
81
- channel.on_request("exit-status") do |ch,data|
82
- exit_code = data.read_long
83
- end
84
- end
85
- end
86
- ssh.loop
87
- [stdout_data, stderr_data, exit_code]
88
- end
89
39
  end
90
40
  end
@@ -0,0 +1,30 @@
1
+ require 'net/ssh'
2
+
3
+ class Santoku
4
+ class << self
5
+ def execute_query fqdn
6
+ begin
7
+ timeout @timeout_interval do
8
+ Net::SSH.start(fqdn, 'root', paranoid: false, forward_agent: true) do |ssh|
9
+ output = ssh_exec!(ssh, @command)
10
+ parse_output output, fqdn
11
+ end
12
+ end
13
+ rescue TimeoutError, Errno::ETIMEDOUT, SocketError, Errno::EHOSTUNREACH => e
14
+ timed_out "#{fqdn}: #{e.message}"
15
+ rescue Exception => e
16
+ timed_out "#{fqdn}: #{e.inspect}"
17
+ end
18
+ end
19
+
20
+ def parse_output output, fqdn
21
+ if output[2] == 0 && !invert?
22
+ succeeded "#{fqdn}: #{output[0]}"
23
+ elsif output[2] != 0 && invert?
24
+ succeeded "#{fqdn} returned #{output[2]}: #{output[1]} #{output[0]}"
25
+ else
26
+ failed "#{fqdn} returned #{output[2]}: #{output[1]} #{output[0]}"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ class Santoku
2
+ class << self
3
+ def ssh_exec!(ssh, command)
4
+ # I am not awesome enough to have made this method myself
5
+ # Originally submitted by 'flitzwald' over here: http://stackoverflow.com/a/3386375
6
+ stdout_data = ""
7
+ stderr_data = ""
8
+ exit_code = nil
9
+
10
+ ssh.open_channel do |channel|
11
+ channel.exec(command) do |ch, success|
12
+ unless success
13
+ abort "FAILED: couldn't execute command (ssh.channel.exec)"
14
+ end
15
+ channel.on_data do |ch,data|
16
+ stdout_data+=data
17
+ end
18
+
19
+ channel.on_extended_data do |ch,type,data|
20
+ stderr_data+=data
21
+ end
22
+
23
+ channel.on_request("exit-status") do |ch,data|
24
+ exit_code = data.read_long
25
+ end
26
+ end
27
+ end
28
+ ssh.loop
29
+ [stdout_data, stderr_data, exit_code]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'santoku'
3
+ spec.version = '0.0.6'
4
+ spec.executables << 'santoku'
5
+ spec.date = '2013-11-17'
6
+ spec.summary = 'Parrallel ssh commands over chef servers with rspec-like output'
7
+ spec.description = 'A gem to perform command over parallel ssh connections on multiple chef serverspec. Output is rspec-like.'
8
+ spec.authors = ['Steven De Coeyer', 'Jeroen Jacobs']
9
+ spec.email = 'tech@openminds.be'
10
+ spec.files = `git ls-files`.split($\)
11
+ spec.homepage = 'https://github.com/openminds/santoku'
12
+ spec.license = 'MIT'
13
+
14
+ spec.add_dependency 'chef', '~> 11.0'
15
+ spec.add_dependency 'colorize'
16
+ spec.add_dependency 'net-ssh'
17
+ spec.add_dependency 'peach'
18
+ spec.add_dependency 'thor'
19
+ end
metadata CHANGED
@@ -1,15 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: santoku
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven De Coeyer
8
+ - Jeroen Jacobs
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
12
  date: 2013-11-17 00:00:00.000000000 Z
12
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: chef
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '11.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '11.0'
13
28
  - !ruby/object:Gem::Dependency
14
29
  name: colorize
15
30
  requirement: !ruby/object:Gem::Requirement
@@ -25,7 +40,7 @@ dependencies:
25
40
  - !ruby/object:Gem::Version
26
41
  version: '0'
27
42
  - !ruby/object:Gem::Dependency
28
- name: peach
43
+ name: net-ssh
29
44
  requirement: !ruby/object:Gem::Requirement
30
45
  requirements:
31
46
  - - '>='
@@ -39,7 +54,7 @@ dependencies:
39
54
  - !ruby/object:Gem::Version
40
55
  version: '0'
41
56
  - !ruby/object:Gem::Dependency
42
- name: ridley
57
+ name: peach
43
58
  requirement: !ruby/object:Gem::Requirement
44
59
  requirements:
45
60
  - - '>='
@@ -74,11 +89,20 @@ executables:
74
89
  extensions: []
75
90
  extra_rdoc_files: []
76
91
  files:
92
+ - .gitignore
93
+ - Gemfile
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - bin/santoku
77
98
  - lib/santoku.rb
99
+ - lib/santoku/chef.rb
78
100
  - lib/santoku/helpers.rb
79
101
  - lib/santoku/printers.rb
80
- - bin/santoku
81
- homepage: https://github.com/zhann/santoku
102
+ - lib/santoku/santoku.rb
103
+ - lib/santoku/ssh.rb
104
+ - santoku.gemspec
105
+ homepage: https://github.com/openminds/santoku
82
106
  licenses:
83
107
  - MIT
84
108
  metadata: {}