Original file line number Diff line number Diff line change 1+ #!/usr/bin/env ruby
2+ require 'net/http'
3+ require 'json'
4+
5+ class CheckHost
6+ attr_reader :nodes
7+
8+ def initialize ( host , options = { :type => 'http' , :max_nodes => 3 } )
9+ supported_types = %w( ping http tcp dns udp )
10+ raise ( ArgumentError , "unsupported check type (valid values: #{ supported_types . join ( ' ' ) } )" ) unless supported_types . include? ( options [ :type ] )
11+ raise ( ArgumentError , "maximum number of nodes has to be integer" ) unless options [ :max_nodes ] . is_a? Integer
12+
13+ @host = host
14+ @options = options
15+ @nodes = [ ]
16+ end
17+
18+ def run
19+ res = parse ( query ( :newcheck , { :host => @host , :type => @options [ :type ] , :max_nodes => @options [ :max_nodes ] } ) )
20+ @id = res [ 'request_id' ]
21+ @nodes_info = res [ 'nodes' ]
22+ @nodes_info . each do |key , value |
23+ @nodes . push ( key ) ;
24+ end
25+ end
26+
27+ def node_info ( code ) # cc, country, location
28+ if @nodes_info . has_key? ( code ) then
29+ return { :cc => @nodes_info [ code ] [ 0 ] ,
30+ :country => @nodes_info [ code ] [ 1 ] ,
31+ :location => @nodes_info [ code ] [ 2 ] }
32+ end
33+ end
34+
35+ def check
36+ res_data = { }
37+ res = parse ( query ( :results , { :request_id => @id } ) )
38+ res . each do |node , value |
39+ if !value . nil? then value . flatten! ( 1 ) end
40+ if !value . nil? && !value [ 0 ] . nil? then # 'cause some return [nil] and can't flatten more
41+ node_data = { }
42+ case @options [ :type ]
43+ when 'ping' # avg_ok, avg_timeout, avg_malformed, ok_count, timeout_count, malformed_count, ip
44+ node_data [ :ok_count ] = 0
45+ node_data [ :timeout_count ] = 0
46+ node_data [ :malformed_count ] = 0
47+ node_data [ :avg_ok ] = 0
48+ node_data [ :avg_timeout ] = 0
49+ node_data [ :avg_malformed ] = 0
50+
51+ value . each do |info |
52+ node_data [ :ip ] = info [ 2 ] if ( info [ 2 ] )
53+ case info [ 0 ]
54+ when 'OK'
55+ node_data [ :avg_ok ] += info [ 1 ]
56+ node_data [ :ok_count ] += 1
57+ when 'TIMEOUT'
58+ node_data [ :avg_timeout ] += info [ 1 ]
59+ node_data [ :timeout_count ] += 1
60+ when 'MALFORMED'
61+ node_data [ :avg_malformed ] += info [ 1 ]
62+ node_data [ :malformed_count ] += 1
63+ end
64+ end
65+
66+ if ( node_data [ :ok_count ] > 0 ) then
67+ node_data [ :avg_ok ] = ( node_data [ :avg_ok ] *1000 ) . to_i
68+ node_data [ :avg_ok ] /= node_data [ :ok_count ]
69+ end
70+ if ( node_data [ :timeout_count ] > 0 ) then
71+ node_data [ :avg_timeout ] = ( node_data [ :avg_timeout ] *1000 ) . to_i
72+ node_data [ :avg_timeout ] /= node_data [ :timeout_count ]
73+ end
74+ if ( node_data [ :malformed_count ] > 0 ) then
75+ node_data [ :avg_malformed ] = ( node_data [ :avg_malformed ] *1000 ) . to_i
76+ node_data [ :avg_malformed ] /= node_data [ :malformed_count ]
77+ end
78+ when 'http' # success, time, message, code, ip
79+ node_data [ :success ] = value [ 0 ]
80+ node_data [ :time ] = ( value [ 1 ] *1000 ) . to_i
81+ node_data [ :message ] = value [ 2 ]
82+ node_data [ :code ] = value [ 3 ] . to_i
83+ node_data [ :ip ] = value [ 4 ]
84+ when 'tcp' , 'udp' # error, time, ip
85+ node_data [ :error ] = value [ 0 ] [ 'error' ]
86+ node_data [ :time ] = ( value [ 0 ] [ 'time' ] *1000 ) . to_i
87+ node_data [ :ip ] = value [ 0 ] [ 'address' ]
88+ when 'dns' # a, aaaa, ttl
89+ node_data [ :a ] = value [ 0 ] [ 'A' ]
90+ node_data [ :aaaa ] = value [ 0 ] [ 'AAAA' ]
91+ node_data [ :ttl ] = value [ 0 ] [ 'TTL' ]
92+ end
93+ res_data [ node ] = node_data
94+ else res_data [ node ] = nil end
95+ end
96+ return res_data
97+ end
98+
99+ private
100+ def query ( action , data ) # action: newcheck, results; data(hash): newcheck:: type, host, max_nodes | results:: request_id
101+ headers = { 'Accept' => 'application/json' }
102+
103+ case action
104+ when :newcheck
105+ uri = URI ( "http://check-host.net/check-#{ data [ :type ] } ?host=#{ data [ :host ] } &max_nodes=#{ data [ :max_nodes ] } " )
106+ api = Net ::HTTP . new ( uri . host )
107+ api . get ( uri , headers ) . body
108+ when :results
109+ uri = URI ( "http://check-host.net/check-result/#{ data [ :request_id ] } " )
110+ api = Net ::HTTP . new ( uri . host )
111+ api . get ( uri , headers ) . body
112+ end
113+ end
114+
115+ def parse ( json )
116+ res = JSON . parse ( json )
117+ raise "check-host.net returned error: #{ res [ 'error' ] } " if res . has_key? ( 'error' )
118+ return res
119+ end
120+ end
0 commit comments