#!/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()