Nachdem ich von @PetaByteBoy darauf aufmerksam gemacht wurde, dass es für den einen oder anderen in Zukunft interessant sein könnte, alle Nodes einer Stadt zu ermitteln, falls ein Domain Split durchgeführt werden soll, möchte ich gerne die Lösung mit den Interessierten teilen.
Dadurch könnt Ihr die IPv6 Adressen der gesuchten Router rausfiltern, um dann die Server für Firmware Updates umzubiegen.
Die Basis hierfür ist Elasticsearch (ES) und die Geokoordinaten einer Stadt als Polygon (GeoJSON Utilities - Anzeige, Auswahl und Export von Verwaltungsgebieten in Deutschland)
Ablauf in Kürze:
- ES installieren
- Anlegen eines Index in ES
- Erstellen eines Mapping für den Index (muss geschehen, bevor die die Daten reingepumpt werden)
- nodes.json in Elasticsearch reinpumpen
- query mit dem Polygon deiner Stadt durchführen
- Glücklich sein
Hinweis1: Das Python Script und das Mapping stammen aus einem anderen ES Test und ich war zu faul, es für diesen Zweck zu optimieren (wir könnten auch die nodes.json direkt per curl in ES reinschaufeln), aber dann hätte ich eventuell das Mapping anpassen müssen).
1. ES installieren
Quelle und Dokumentation für ES: Download Elasticsearch | Elastic
2. Index erstellen
curl -XPUT 'http://localhost:9200/freifunk-bg'
3. Mapping erstellen
curl -XPUT 'http://localhost:9200/freifunk-bg/_mapping/nodes' -d '{
"nodes" : {
"properties" : {
"nodeinfo" : {
"properties" : {
"node_id" : { "type" : "string", "index" : "not_analyzed" },
"location" : { "type" : "geo_point" },
"hostname" : { "type" : "string", "index" : "not_analyzed" },
"software" : {
"properties" : {
"firmware" : {
"properties" : {
"base" : { "type" : "string", "index" : "not_analyzed" },
"release" : { "type" : "string", "index" : "not_analyzed" }
}
}
},
"fastd" : {
"properties" : {
"version" : { "type" : "string", "index" : "not_analyzed" }
}
},
"batman-adv" : {
"properties" : {
"version" : { "type" : "string", "index" : "not_analyzed" }
}
},
"hardware" : {
"properties" : {
"model" : { "type" : "string", "index" : "not_analyzed" }
}
}
}
}
}
}
}
}
}'
4. Pyhon3 (Python 2.x nicht getestet) Script für den Download der nodes.json und den Upload in ES
import sys, datetime, requests, json, elasticsearch
from elasticsearch import Elasticsearch
JSONURL = "http://map.ff.petabyteboy.de/data/nodes.json"
INDEX = "freifunk-bg"
DOC = "nodes"
JSONGET = requests.get(JSONURL)
APS = json.loads(JSONGET.text)
es = Elasticsearch([{'host': 'localhost', 'port': 9200}])
for AP in APS['nodes']:
if 'location' in APS['nodes'][AP]['nodeinfo']:
if 'latitude' in APS['nodes'][AP]['nodeinfo']['location']:
APS['nodes'][AP]['nodeinfo']['location']['lat'] = APS['nodes'][AP]['nodeinfo']['location']['latitude']
del APS['nodes'][AP]['nodeinfo']['location']['latitude']
APS['nodes'][AP]['nodeinfo']['location']['lon'] = APS['nodes'][AP]['nodeinfo']['location']['longitude']
del APS['nodes'][AP]['nodeinfo']['location']['longitude']
if 'altitude' in APS['nodes'][AP]['nodeinfo']['location']:
del APS['nodes'][AP]['nodeinfo']['location']['altitude']
APS['nodes'][AP]['timestamp'] = APS['timestamp']
res = es.index(index=INDEX, doc_type=DOC, body=APS['nodes'][AP])
den Python Aufruf hinter curl kann man auch weglassen…
5. Polygon in ES abfragen
curl -XGET http://localhost:9200/freifunk-bg/_search -d @bg.json | python -m json.tool
Inhalt der bg.json, wo ihr die Geokoordinaten einfügt, sollte direkt ersichtlich sein...
{ "query" : {
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_polygon" : {
"nodeinfo.location" : {
"points" :
[[7.080716373054297,51.0262244485241], ……,[7.080716373054297,51.0262244485241]]
}
}
}
}
}
}
6. Glücklich sein
HINWEIS2: OPnotDEV: Verbesserungsvorschläge sind Willkommen! Das war jetzt eine Quick&Dirty Lösung
HINWEIS3: Ich hoffe, dass ich nichts vergessen habe
Ich möchte mich bei den folgenden Personen bedanken:
@Michael1 : Für die Bereitstellung von Infrastuktur
@nomaster : Für die Anregung mit ES
@PetaByteBoy: Betatester