From f30aa3514472ab5448af63b8e9098b1d8a8a4332 Mon Sep 17 00:00:00 2001 From: Mike Crute Date: Sun, 13 Dec 2015 17:49:35 -0800 Subject: Add flask app --- ddns.cfg | 6 +++++ ddns.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 ddns.cfg create mode 100644 ddns.py diff --git a/ddns.cfg b/ddns.cfg new file mode 100644 index 0000000..3628b53 --- /dev/null +++ b/ddns.cfg @@ -0,0 +1,6 @@ +AMAZON_KEY_ID = "" +AMAZON_SECRET_KEY = "" + +# These are bearer tokens, care should be taken not to expose them +# on the web. +CLIENTS = {} diff --git a/ddns.py b/ddns.py new file mode 100644 index 0000000..5fa7c8c --- /dev/null +++ b/ddns.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +import os +import flask +import hashlib +import functools +from boto.route53.record import ResourceRecordSets +from boto.route53.connection import Route53Connection + + +app = flask.Flask(__name__) +app.config.from_pyfile("/etc/ddns.cfg", silent=True) +app.config.from_pyfile("ddns.cfg", silent=True) +if "AMAZON_KEY_ID" not in app.config: + raise Exception("Not configured") + + +def returns_plain_text(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + return flask.Response(f(*args, **kwargs), content_type="text/plain") + + return wrapper + + +def update_record(zone, record, ip): + conn = Route53Connection(app.config["AMAZON_KEY_ID"], + app.config["AMAZON_SECRET_KEY"]) + change_set = ResourceRecordSets(conn, conn.get_zone(zone).id) + change_set.add_change("UPSERT", record, type="A", ttl=60).add_value(ip) + change_set.commit() + + +@app.errorhandler(404) +@app.errorhandler(405) +@app.errorhandler(500) +def handle_error(ex): + response = flask.Response("Error", content_type="text/plain") + response.status_code = getattr(ex, "code", 500) + return response + + +@app.route("/new-secret", methods=["GET"]) +@returns_plain_text +def new_secret(): + return hashlib.sha256(os.urandom(100)).hexdigest() + + +@app.route("/update", methods=["POST"]) +def update_ip(): + key = flask.request.form.get("key") + config = app.config["CLIENTS"].get(key) + + if not config: + flask.abort(404) + + try: + update_record(config["zone"], config["resource"], + flask.request.remote_addr) + return "OK" + except: + flask.abort(500) + + +@app.route("/", methods=["GET"]) +@returns_plain_text +def get_ip(): + return flask.request.remote_addr + + +@app.route("/config") +@returns_plain_text +def get_config(): + return repr(app.config.items()) + + +if __name__ == "__main__": + app.debug = True + app.run() -- cgit v1.2.3