2022-09-02 18:41:19 +02:00
|
|
|
import hmac
|
2022-09-02 14:06:47 +02:00
|
|
|
import json
|
2022-09-02 18:41:19 +02:00
|
|
|
import logging
|
|
|
|
import os
|
2022-09-02 14:06:47 +02:00
|
|
|
|
2022-09-02 18:41:19 +02:00
|
|
|
from flask import (Flask, request, jsonify, abort)
|
2022-09-02 14:06:47 +02:00
|
|
|
|
|
|
|
from ltsdb_json import LTS
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
log = logging.getLogger()
|
|
|
|
|
|
|
|
@app.route("/")
|
|
|
|
def home():
|
|
|
|
return jsonify({ "success": None })
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/report", methods=["POST"])
|
|
|
|
def report():
|
|
|
|
data = request.get_json()
|
|
|
|
n_ts = 0
|
|
|
|
n_dp = 0
|
|
|
|
for d in data:
|
|
|
|
d["description"]["remote_addr"] = request.remote_addr
|
2022-09-02 18:41:19 +02:00
|
|
|
d["description"]["node"] = verify_node(d)
|
|
|
|
|
2022-09-02 14:06:47 +02:00
|
|
|
log.info("received %s", json.dumps(d))
|
|
|
|
ts = LTS(d["description"])
|
|
|
|
for dp in d["data"]:
|
|
|
|
ts.add(*dp)
|
|
|
|
ts.save()
|
|
|
|
n_dp += 1
|
|
|
|
n_ts += 1
|
|
|
|
return jsonify({ "success": True, "timeseries": n_ts, "datapoints": n_dp })
|
2022-09-02 18:41:19 +02:00
|
|
|
|
2022-09-04 17:58:17 +02:00
|
|
|
@app.route("/ts/<id>")
|
|
|
|
def get_timeseries(id):
|
2022-09-04 21:03:17 +02:00
|
|
|
try:
|
|
|
|
ts = LTS(id=id)
|
|
|
|
except FileNotFoundError:
|
|
|
|
abort(404)
|
2022-09-04 17:58:17 +02:00
|
|
|
return jsonify({"description": ts.description, "data": ts.data})
|
|
|
|
|
2022-09-02 18:41:19 +02:00
|
|
|
def verify_node(d):
|
|
|
|
node = d["auth"]["node"]
|
|
|
|
timestamp = d["auth"]["timestamp"]
|
|
|
|
digest1 = d["auth"]["hmac"]
|
|
|
|
if "/" in node:
|
|
|
|
raise ValueError("invalid node name %s", node)
|
|
|
|
try:
|
2022-09-04 12:48:15 +02:00
|
|
|
log.info("getting client config from %s", "config/" + node)
|
2022-09-02 18:41:19 +02:00
|
|
|
with open("config/" + node) as fh:
|
|
|
|
node_conf = json.load(fh)
|
|
|
|
except Exception as e:
|
|
|
|
log.warning("got %s opening %s", e, "config/" + node)
|
|
|
|
abort(401, "unknown client")
|
|
|
|
last = node_conf["last"]
|
|
|
|
for key in node_conf["keys"]:
|
|
|
|
msg = (node + " " + str(timestamp)).encode("UTF-8")
|
2022-09-04 12:48:15 +02:00
|
|
|
hmac2 = hmac.new(key.encode("UTF-8"), msg, "SHA256")
|
2022-09-02 18:41:19 +02:00
|
|
|
digest2 = hmac2.hexdigest()
|
|
|
|
if hmac.compare_digest(digest1, digest2):
|
|
|
|
if timestamp > node_conf["last"]:
|
|
|
|
node_conf["last"] = timestamp
|
|
|
|
os.replace("config/" + node, "config/" + node + ".old")
|
|
|
|
with open("config/" + node, "w") as fh:
|
|
|
|
json.dump(node_conf, fh) # XXX
|
|
|
|
return node
|
|
|
|
else:
|
|
|
|
abort(409, "timestamp out of sync")
|
|
|
|
abort(401, "auth failed")
|