summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mcrute@gmail.com>2015-12-13 17:49:35 -0800
committerMike Crute <mcrute@gmail.com>2015-12-13 17:49:35 -0800
commitf30aa3514472ab5448af63b8e9098b1d8a8a4332 (patch)
tree6b23d839ce2b93520ca2641ad23794380b78266f
parent75248d48862c884b5461059a8ca78f75fa0314da (diff)
downloaddynamic_dns-f30aa3514472ab5448af63b8e9098b1d8a8a4332.tar.bz2
dynamic_dns-f30aa3514472ab5448af63b8e9098b1d8a8a4332.tar.xz
dynamic_dns-f30aa3514472ab5448af63b8e9098b1d8a8a4332.zip
Add flask app
-rw-r--r--ddns.cfg6
-rw-r--r--ddns.py79
2 files changed, 85 insertions, 0 deletions
diff --git a/ddns.cfg b/ddns.cfg
new file mode 100644
index 0000000..3628b53
--- /dev/null
+++ b/ddns.cfg
@@ -0,0 +1,6 @@
1AMAZON_KEY_ID = ""
2AMAZON_SECRET_KEY = ""
3
4# These are bearer tokens, care should be taken not to expose them
5# on the web.
6CLIENTS = {}
diff --git a/ddns.py b/ddns.py
new file mode 100644
index 0000000..5fa7c8c
--- /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 update_record(zone, record, ip):
27 conn = Route53Connection(app.config["AMAZON_KEY_ID"],
28 app.config["AMAZON_SECRET_KEY"])
29 change_set = ResourceRecordSets(conn, conn.get_zone(zone).id)
30 change_set.add_change("UPSERT", record, type="A", ttl=60).add_value(ip)
31 change_set.commit()
32
33
34@app.errorhandler(404)
35@app.errorhandler(405)
36@app.errorhandler(500)
37def handle_error(ex):
38 response = flask.Response("Error", content_type="text/plain")
39 response.status_code = getattr(ex, "code", 500)
40 return response
41
42
43@app.route("/new-secret", methods=["GET"])
44@returns_plain_text
45def new_secret():
46 return hashlib.sha256(os.urandom(100)).hexdigest()
47
48
49@app.route("/update", methods=["POST"])
50def update_ip():
51 key = flask.request.form.get("key")
52 config = app.config["CLIENTS"].get(key)
53
54 if not config:
55 flask.abort(404)
56
57 try:
58 update_record(config["zone"], config["resource"],
59 flask.request.remote_addr)
60 return "OK"
61 except:
62 flask.abort(500)
63
64
65@app.route("/", methods=["GET"])
66@returns_plain_text
67def get_ip():
68 return flask.request.remote_addr
69
70
71@app.route("/config")
72@returns_plain_text
73def get_config():
74 return repr(app.config.items())
75
76
77if __name__ == "__main__":
78 app.debug = True
79 app.run()