Introduce infrastructure to receive and process gateway information

This requires changes to the MySQL database!

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
This commit is contained in:
Adrian Schmutzler 2018-01-12 12:52:57 +01:00
parent 516eb07924
commit 898c06d8c6
4 changed files with 202 additions and 0 deletions

59
ffmap/db/gws.py Executable file
View File

@ -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()

64
ffmap/gwtools.py Normal file
View File

@ -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']))

View File

@ -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')

52
gwinfo/sendgwinfo.sh Executable file
View File

@ -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"