summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--hosts.txt.example1
-rw-r--r--up-www.rb124
-rw-r--r--up.rb65
4 files changed, 192 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..6169803
--- /dev/null
+++ b/README
@@ -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
diff --git a/up.rb b/up.rb
new file mode 100644
index 0000000..d32804e
--- /dev/null
+++ b/up.rb
@@ -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