diff options
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | hosts.txt.example | 1 | ||||
-rw-r--r-- | up-www.rb | 124 | ||||
-rw-r--r-- | up.rb | 65 |
4 files changed, 192 insertions, 0 deletions
@@ -0,0 +1,2 @@ +# TODO +- check specific websites diff --git a/hosts.txt.example b/hosts.txt.example new file mode 100644 index 0000000..2574169 --- /dev/null +++ b/hosts.txt.example @@ -0,0 +1 @@ +google.de http:80/tcp diff --git a/up-www.rb b/up-www.rb new file mode 100644 index 0000000..049f897 --- /dev/null +++ b/up-www.rb @@ -0,0 +1,124 @@ +#!/usr/bin/env ruby + +require "sinatra" +require "zipf" +require "./up" + +configure do + hosts = {} + ReadFile.new("./hosts.txt").readlines.each { |line| + hosts[line.split[0]] = Host.new line + } + puts "> loaded #{hosts.keys.size} hosts" + set :hosts, hosts +end + +get '/host/:host' do + hostname = params[:host] + if settings.hosts.include? hostname + check = settings.hosts[hostname].check + if not check["up"] + "off #{check.to_s}" + elsif check.values.all?{|v|v} + "ok #{check.to_s}" + elsif check.select{|k,_|k.end_with?"/tcp"}.values.all?{|v|v} \ + and not check.select{|k,_|k.end_with?"/udp"}.values.all?{|v|v} + "maybe-ok #{check.to_s}" + else + "not-ok #{check.to_s}" + end + else + "unknown" + end +end + +get '/host/raw/:host' do + hostname = params[:host] + if settings.hosts.include? hostname + "#{settings.hosts[hostname].check}" + else + "" + end +end + +get '/all-hosts' do + "#{settings.hosts.keys.join ","}" +end + +get '/check-all-hosts' do + out = "<html><head></head><body><ul>" + settings.hosts.each_value { |host| + out += " <li>#{host.hostname}: #{host.check}</li>" + } + out += "</ul></body></html>" + out +end + +get '/' do + out =<<EOS + <head> + <style type="text/css"> + .box { border:2px dashed black; + float:left; + padding:1em; + margin:.5em; + background:#eee; + cursor:pointer; } + </style> + <script type="text/javascript"> +function update_host(host) +{ + request = new XMLHttpRequest(); + request.__host = host + request.onload = function (e) { + status = this.responseText.split(" ")[0]; + response = this.responseText; + if (status == "ok") { + document.getElementById(this.__host).style.background = "green"; + document.getElementById(this.__host).style.border = "2px solid green"; + document.getElementById(this.__host).style.color = "white"; + } else if (status == "off") { + document.getElementById(this.__host).style.background = "black"; + document.getElementById(this.__host).style.border = "2px solid white"; + document.getElementById(this.__host).style.color = "white"; + } else if (status == "maybe-ok") { + document.getElementById(this.__host).style.background = "yellow"; + document.getElementById(this.__host).style.border = "2px dashed white"; + } else { + document.getElementById(this.__host).style.background = "red"; + document.getElementById(this.__host).style.border = "2px dashed white"; + } + document.getElementById(this.__host).__full_status = response; + document.getElementById(this.__host).onclick = function () { + document.getElementById("info").innerHTML = this.__full_status; + } + } + request.open("GET", "/host/" + host); + request.send(); +} + +request = new XMLHttpRequest(); +request.onload = function (e) { + hosts = this.responseText.split(","); + for (hostname of hosts) { + new_node = document.createElement("div"); + new_node.id = hostname; + new_node.className = "box"; + new_text_node = document.createTextNode(hostname); + new_node.appendChild(new_text_node); + document.getElementById("boxes").appendChild(new_node); + update_host(hostname); + } +} +request.open("GET", "/all-hosts", true); +request.send(); + </script> + </head> + <body> + <div id="boxes"></div> + <p style="clear:left" id="info"></p> + </body> +</html> +EOS + out +end @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby + +require "net/ping" +require "socket" + +class Host + def initialize s + # example: 'nash ssh:2001 mqtt:1883' + parts = s.split + @hostname = parts.first + @services_and_ports = {} + parts.slice(1, parts.size).each { |part| + service, port_and_protocol = part.split ":" + port, protocol = port_and_protocol.split "/" + @services_and_ports["#{service}/#{protocol}"] = [port.to_i, protocol] + } + end + + def hostname + return @hostname + end + + def up? hostname + ping = Net::Ping::External.new @hostname + ping.ping? + end + + def service_up? service, port, protocol + if protocol == "tcp" + begin + sock = TCPSocket.new @hostname, port + sock.close + return true + rescue + return false + end + elsif protocol == "udp" + system "nc -u -z -w 1 #{@hostname} #{port+1} &>/dev/null" + return $?.success? + else + STDERR.write "unknown protocol '#{protocol}'\n" + end + end + + def check + ret = {} + ret["up"] = up? @hostname + return ret if not ret["up"] + @services_and_ports.each_key { |k| + ret[k] = service_up? k, @services_and_ports[k][0], @services_and_ports[k][1] + } + return ret + end +end + +def main + while line = STDIN.gets + h = Host.new line + puts h.check.to_s + end +end + +if __FILE__ == $0 + main +end |