1module MCollective
2  class Application::Nettest < Application
3    description "Network tests from a mcollective host"
4
5    usage <<-END_OF_USAGE
6mco nettest <ping|connect> <HOST NAME> [PORT]
7
8The ACTION can be one of the following:
9
10    ping    - return round-trip time between this and remote host
11    connect - check connectivity of remote host on specific port
12        END_OF_USAGE
13
14    def raise_message(action, message, *args)
15      messages = {1 => "Please specify an action and optional arguments",
16                  2 => "Action can only to be ping or connect",
17                  3 => "Do you really want to perform network tests unfiltered? (y/n): "}
18
19      send(action, messages[message] % args)
20    end
21
22    def post_option_parser(configuration)
23      if ARGV.size < 2
24        raise_message(:raise, 1)
25      else
26        action = ARGV.shift
27
28        host_name = ARGV.shift
29        remote_port = ARGV.shift
30
31        if action =~ /^ping$/
32          arguments = {:fqdn => host_name}
33        elsif action =~  /^connect$/
34          # Cast port to an integer since it will be coming in as a string from the cli
35          arguments = {:fqdn => host_name, :port => DDL.string_to_number(remote_port)}
36        else
37          raise_message(:raise, 2)
38        end
39
40        configuration[:action] = action
41        configuration[:arguments] = arguments
42      end
43    end
44
45    def validate_configuration(configuration)
46      if MCollective::Util.empty_filter?(options[:filter])
47        raise_message(:print, 3)
48
49        STDOUT.flush
50
51        # Only match letter "y" or complete word "yes" ...
52        exit(1) unless STDIN.gets.strip.match(/^(?:y|yes)$/i)
53      end
54    end
55
56    def main
57      nettest = rpcclient('nettest')
58      nettest_result = nettest.send(configuration[:action], configuration[:arguments])
59
60      nettest_result.each do |result|
61        node = result[:data][:rtt] || result[:data][:connect]
62
63        if result[:statuscode] == 0
64          node = node.to_s
65          case configuration[:action]
66          when 'ping'
67            if nettest.verbose
68              puts "%-40s time = %s\t\t%s" % [result[:sender], node, result[:statusmsg]]
69            else
70              puts "%-40s time = %s" % [result[:sender], node]
71            end
72          when 'connect'
73            if nettest.verbose
74              puts "%-40s status = %s\t\t%s" % [result[:sender], node, result[:statusmsg]]
75            else
76              puts "%-40s status = %s" % [result[:sender], node]
77            end
78          end
79        else
80          puts "%-40s %s \t\t%s" % [result[:sender], node, result[:statusmsg]]
81        end
82      end
83
84      puts
85      printrpcstats :summarize => true, :caption => "%s Nettest results" % configuration[:action]
86      halt(nettest.stats)
87    end
88  end
89end
90