import hmac import json import logging import os from flask import (Flask, request, jsonify, abort) 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 d["description"]["node"] = verify_node(d) 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 }) 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: log.info("gettingg client config from %s", "config/" + node) 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") hmac2 = hmac.new(key.encode("UTF-8"), msg, "SHA-256") 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")