diff --git a/ffmap/db/gws.py b/ffmap/db/gws.py new file mode 100755 index 0000000..b6e43cc --- /dev/null +++ b/ffmap/db/gws.py @@ -0,0 +1,59 @@ +#!/usr/bin/python3 + +import os +import sys +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/' + '../..')) + +from ffmap.mysqltools import FreifunkMySQL + +mysql = FreifunkMySQL() + +mysql.execute(""" + CREATE TABLE gw ( + `id` smallint(5) UNSIGNED NOT NULL, + `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL, + `stats_page` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL, + `last_contact` datetime NOT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci +""") + +mysql.execute(""" + ALTER TABLE gw + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `name` (`name`) +""") + +mysql.execute(""" + ALTER TABLE gw + MODIFY `id` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT +""") + +mysql.execute(""" + CREATE TABLE gw_admin ( + `gw` smallint(5) UNSIGNED NOT NULL, + `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL, + `prio` tinyint(3) UNSIGNED NOT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci +""") + +mysql.execute(""" + ALTER TABLE gw_admin + ADD PRIMARY KEY (`gw`,`name`) +""") + +mysql.execute(""" + CREATE TABLE gw_netif ( + `gw` smallint(5) UNSIGNED NOT NULL, + `mac` char(17) COLLATE utf8_unicode_ci NOT NULL, + `netif` varchar(15) COLLATE utf8_unicode_ci NOT NULL, + `vpnif` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci +""") + +mysql.execute(""" + ALTER TABLE gw_netif + ADD PRIMARY KEY (`mac`), + ADD KEY `gw` (`gw`) +""") + +mysql.close() diff --git a/ffmap/gwtools.py b/ffmap/gwtools.py new file mode 100644 index 0000000..6d2e7a7 --- /dev/null +++ b/ffmap/gwtools.py @@ -0,0 +1,64 @@ +#!/usr/bin/python3 + +import os +import sys +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/' + '..')) + +from ffmap.mysqltools import FreifunkMySQL +from ffmap.misc import * +from ffmap.config import CONFIG +from flask import request + +import datetime +import time + +def import_gw_data(mysql, gw_data): + if "hostname" in gw_data and "netifs" in gw_data: + time = utcnow().strftime('%Y-%m-%d %H:%M:%S') + stats_page = gw_data.get("stats_page","") + if not stats_page: + stats_page = None + mysql.execute(""" + INSERT INTO gw (name, stats_page, last_contact) + VALUES (%s, %s, %s) + ON DUPLICATE KEY UPDATE + stats_page=VALUES(stats_page), + last_contact=VALUES(last_contact) + """,(gw_data["hostname"],gw_data["stats_page"],time,)) + + newid = mysql.findone("SELECT id FROM gw WHERE name = %s LIMIT 1",(gw_data["hostname"],),"id") + + ndata = [] + for n in gw_data["netifs"]: + if len(n["mac"])<17: + continue + if n["netif"].startswith("l2tp") or n["netif"].startswith("br-"): + continue + if not "vpnif" in n or not n["vpnif"]: + n["vpnif"] = None + ndata.append((newid,n["mac"],n["netif"],n["vpnif"])) + + mysql.executemany(""" + INSERT INTO gw_netif (gw, mac, netif, vpnif) + VALUES (%s, %s, %s, %s) + ON DUPLICATE KEY UPDATE + gw=VALUES(gw), + netif=VALUES(netif), + vpnif=VALUES(vpnif) + """,ndata) + + adata = [] + aid = 0 + for a in gw_data["admins"]: + aid += 1 + adata.append((newid,a,aid,)) + + mysql.execute("DELETE FROM gw_admin WHERE gw = %s",(newid,)) + mysql.executemany(""" + INSERT INTO gw_admin (gw, name, prio) + VALUES (%s, %s, %s) + ON DUPLICATE KEY UPDATE + prio=VALUES(prio) + """,adata) + else: + writelog(CONFIG["debug_dir"] + "/fail_gwinfo.txt", "{} - Corrupted file.".format(request.environ['REMOTE_ADDR'])) diff --git a/ffmap/web/api.py b/ffmap/web/api.py index d2084dd..9e97fa9 100755 --- a/ffmap/web/api.py +++ b/ffmap/web/api.py @@ -1,6 +1,7 @@ #!/usr/bin/python3 from ffmap.routertools import * +from ffmap.gwtools import * from ffmap.maptools import * from ffmap.mysqltools import FreifunkMySQL from ffmap.stattools import record_global_stats, record_hood_stats @@ -129,6 +130,32 @@ def alfred(): import traceback writefulllog("Warning: Error while processing ALFRED data: %s\n__%s" % (e, traceback.format_exc().replace("\n", "\n__"))) +@api.route('/gwinfo', methods=['GET', 'POST']) +def gwinfo(): + try: + start_time = time.time() + mysql = FreifunkMySQL() + #set_data = {65: "hallo", 66: "welt"} + set_data = {} + r = make_response(json.dumps(set_data)) + if request.method == 'POST': + gw_data = request.get_json() + + if gw_data: + import_gw_data(mysql,gw_data) + mysql.commit() + r.headers['X-API-STATUS'] = "GW data imported" + mysql.close() + + writelog(CONFIG["debug_dir"] + "/gwtime.txt", "%s - %.3f seconds" % (request.environ['REMOTE_ADDR'],time.time() - start_time)) + + r.mimetype = 'application/json' + return r + except Exception as e: + writelog(CONFIG["debug_dir"] + "/fail_gwinfo.txt", "{} - {}".format(request.environ['REMOTE_ADDR'],str(e))) + import traceback + writefulllog("Warning: Error while processing GWINFO data: %s\n__%s" % (e, traceback.format_exc().replace("\n", "\n__"))) + # https://github.com/ffansbach/de-map/blob/master/schema/nodelist-schema-1.0.0.json @api.route('/nodelist') diff --git a/gwinfo/sendgwinfo.sh b/gwinfo/sendgwinfo.sh new file mode 100755 index 0000000..3c43557 --- /dev/null +++ b/gwinfo/sendgwinfo.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# +# Gateway data script for FFF Monitoring +# Copyright Adrian Schmutzler, 2018. +# License GPLv3 +# +# v1.2.1 - 2018-01-12 +# - Added "grep fff" to support L2TP +# +# v1.2 - 2018-01-12 +# - Added batctl command and vpnif +# +# v1.1 - 2018-01-12 +# - Initial Version +# + +# Config +#api_url="http://192.168.1.84/api/gwinfo" +api_url="http://monitoring.freifunk-franken.de/api/gwinfo" +batctlpath=/usr/local/sbin/batctl # Adjust to YOUR path! +hostname="MyHost" +admin1="Admin" +admin2= +admin3= +statslink="" # Provide link to stats page (MRTG or similar) + +# Code +tmp=$(/bin/mktemp) +echo "{\"hostname\":\"$hostname\",\"stats_page\":\"$statslink\",\"netifs\":[" > $tmp + +comma="" +for netif in $(ls /sys/class/net); do + if [ "$netif" = "lo" ] ; then + continue + fi + mac="$(cat "/sys/class/net/$netif/address")" + batctl="$("$batctlpath" -m "$netif" if | grep "fff" | sed -n 's/:.*//p')" + echo "$comma{\"mac\":\"$mac\",\"netif\":\"$netif\",\"vpnif\":\"$batctl\"}" >> $tmp + comma="," +done + +echo "],\"admins\":[" >> $tmp + +comma="" +[ -n "$admin1" ] && echo "\"$admin1\"" >> $tmp && comma="," +[ -n "$admin2" ] && echo "$comma\"$admin2\"" >> $tmp && comma="," +[ -n "$admin3" ] && echo "$comma\"$admin3\"" >> $tmp + +echo "]}" >> $tmp + +/usr/bin/curl -k -v -H "Content-type: application/json; charset=UTF-8" -X POST --data-binary @$tmp $api_url +/bin/rm "$tmp"