Class: Santoku

Inherits:
Object
  • Object
show all
Defined in:
lib/santoku.rb,
lib/santoku/ssh.rb,
lib/santoku/chef.rb,
lib/santoku/helpers.rb,
lib/santoku/santoku.rb,
lib/santoku/printers.rb

Class Method Summary collapse

Class Method Details

.execute_query(fqdn) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/santoku/santoku.rb', line 5

def execute_query fqdn
  begin
    timeout @timeout_interval do
      Net::SSH.start(fqdn, 'root', paranoid: false, forward_agent: true) do |ssh|
        output = ssh_exec!(ssh, @command)
        parse_output output, fqdn
      end
    end
  rescue TimeoutError, Errno::ETIMEDOUT, SocketError, Errno::EHOSTUNREACH => e
    timed_out "#{fqdn}: #{e.message}"
  rescue Exception => e
    timed_out "#{fqdn}: #{e.inspect}"
  end
end

.failed(reason) ⇒ Object



5
6
7
8
# File 'lib/santoku/helpers.rb', line 5

def failed(reason)
  failed_output_stream.push reason
  print_fail
end

.failed_output_streamObject



24
25
26
# File 'lib/santoku/helpers.rb', line 24

def failed_output_stream
  @failed_output_stream ||= Array.new
end

.invert?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/santoku/helpers.rb', line 36

def invert?
  @invert
end

.knife_search(query) ⇒ Object



5
6
7
8
9
10
11
12
13
14
# File 'lib/santoku/chef.rb', line 5

def knife_search query
  # Monkey patch Chef::Knife::UI to hide stdout
  Chef::Knife::UI.class_eval do
    def stdout
      @stdout_hack ||= ::File.new('/dev/null', 'w')
    end
  end

  Chef::Knife.run(['search', 'node', query]).map { |node| node[:fqdn] }
end

.parse_output(output, fqdn) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/santoku/santoku.rb', line 20

def parse_output output, fqdn
  if output[2] == 0 && !invert?
    succeeded "#{fqdn}: #{output[0]}"
  elsif output[2] != 0 && invert?
    succeeded "#{fqdn} returned #{output[2]}: #{output[1]} #{output[0]}"
  else
    failed "#{fqdn} returned #{output[2]}: #{output[1]} #{output[0]}"
  end
end


5
6
7
# File 'lib/santoku/printers.rb', line 5

def print_fail
  print 'F'.red
end


23
24
25
26
27
# File 'lib/santoku/printers.rb', line 23

def print_failed_stream
  failed_output_stream.each do |output|
    puts output.red
  end
end


9
10
11
# File 'lib/santoku/printers.rb', line 9

def print_success
  print '.'.green
end


29
30
31
32
33
# File 'lib/santoku/printers.rb', line 29

def print_success_stream
  success_output_stream.each do |output|
    puts output.green
  end
end


35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/santoku/printers.rb', line 35

def print_summary
  print "\n"
  print_timeout_stream
  print_failed_stream
  print_success_stream if verbose_success?

  puts "\n---------------------------------------\n"

  puts "#{'Success'.green}: #{success_output_stream.count}"
  puts "#{'Timed out or does not resolve'.yellow}: #{timeout_output_stream.count}"
  puts "#{'Failed'.red}: #{failed_output_stream.count}"
  puts "#{'Total'.blue}: #{success_output_stream.count + timeout_output_stream.count + failed_output_stream.count}"
end


13
14
15
# File 'lib/santoku/printers.rb', line 13

def print_timeout
  print '*'.yellow
end


17
18
19
20
21
# File 'lib/santoku/printers.rb', line 17

def print_timeout_stream
  timeout_output_stream.each do |output|
    puts output.yellow
  end
end

.ssh_exec!(ssh, command) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/santoku/ssh.rb', line 3

def ssh_exec!(ssh, command)
  # I am not awesome enough to have made this method myself
  # Originally submitted by 'flitzwald' over here: http://stackoverflow.com/a/3386375
  stdout_data = ''
  stderr_data = ''
  exit_code = nil

  ssh.open_channel do |channel|
    channel.exec(command) do |ch, success|
      unless success
        abort "FAILED: couldn't execute command (ssh.channel.exec)"
      end
      channel.on_data do |ch,data|
        stdout_data+=data
      end

      channel.on_extended_data do |ch,type,data|
        stderr_data+=data
      end

      channel.on_request('exit-status') do |ch,data|
        exit_code = data.read_long
      end
    end
  end
  ssh.loop
  [stdout_data, stderr_data, exit_code]
end

.succeeded(reason) ⇒ Object



10
11
12
13
# File 'lib/santoku/helpers.rb', line 10

def succeeded(reason)
  success_output_stream.push reason
  print_success
end

.success_output_streamObject



28
29
30
# File 'lib/santoku/helpers.rb', line 28

def success_output_stream
  @success_output_stream ||= Array.new
end

.test(command, query, timeout_interval, verbose_success, invert) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/santoku.rb', line 11

def test command, query, timeout_interval, verbose_success, invert
  @command = command
  @query = query
  @timeout_interval = timeout_interval
  @verbose_success = verbose_success
  @invert = invert

  knife_search(@query).peach(5) do |fqdn|
    execute_query fqdn
  end

  print_summary
end

.timed_out(reason) ⇒ Object



15
16
17
18
# File 'lib/santoku/helpers.rb', line 15

def timed_out(reason)
  timeout_output_stream.push reason
  print_timeout
end

.timeout_output_streamObject



20
21
22
# File 'lib/santoku/helpers.rb', line 20

def timeout_output_stream
  @timeout_output_stream ||= Array.new
end

.verbose_success?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/santoku/helpers.rb', line 32

def verbose_success?
  @verbose_success
end