summaryrefslogtreecommitdiff
path: root/ddns.py
diff options
context:
space:
mode:
Diffstat (limited to 'ddns.py')
-rwxr-xr-xddns.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/ddns.py b/ddns.py
new file mode 100755
index 0000000..5ec92da
--- /dev/null
+++ b/ddns.py
@@ -0,0 +1,79 @@
1#!/usr/bin/env python
2
3import os
4import flask
5import hashlib
6import functools
7from boto.route53.record import ResourceRecordSets
8from boto.route53.connection import Route53Connection
9
10
11app = flask.Flask(__name__)
12app.config.from_pyfile("/etc/ddns.cfg", silent=True)
13app.config.from_pyfile("ddns.cfg", silent=True)
14if "AMAZON_KEY_ID" not in app.config:
15 raise Exception("Not configured")
16
17
18def returns_plain_text(f):
19 @functools.wraps(f)
20 def wrapper(*args, **kwargs):
21 return flask.Response(f(*args, **kwargs), content_type="text/plain")
22
23 return wrapper
24
25
26def get_ip():
27 if "X-Forwarded-For" in flask.request.headers:
28 return flask.request.headers["X-Forwarded-For"]
29 else:
30 return flask.request.remote_addr
31
32
33def update_record(zone, record, ip):
34 conn = Route53Connection(app.config["AMAZON_KEY_ID"],
35 app.config["AMAZON_SECRET_KEY"])
36 change_set = ResourceRecordSets(conn, conn.get_zone(zone).id)
37 change_set.add_change("UPSERT", record, type="A", ttl=60).add_value(ip)
38 change_set.commit()
39
40
41@app.errorhandler(404)
42@app.errorhandler(405)
43@app.errorhandler(500)
44def handle_error(ex):
45 response = flask.Response("Error", content_type="text/plain")
46 response.status_code = getattr(ex, "code", 500)
47 return response
48
49
50@app.route("/new-secret", methods=["GET"])
51@returns_plain_text
52def new_secret():
53 return hashlib.sha256(os.urandom(100)).hexdigest()
54
55
56@app.route("/update", methods=["POST"])
57def update_ip():
58 key = flask.request.form.get("key")
59 config = app.config["CLIENTS"].get(key)
60
61 if not config:
62 flask.abort(404)
63
64 try:
65 update_record(config["zone"], config["resource"], get_ip())
66 return "OK"
67 except:
68 flask.abort(500)
69
70
71@app.route("/", methods=["GET"])
72@returns_plain_text
73def handle_home():
74 return get_ip()
75
76
77if __name__ == "__main__":
78 app.debug = True
79 app.run()