diff options
author | Mike Crute <mcrute@gmail.com> | 2015-12-13 17:49:35 -0800 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2015-12-13 17:49:35 -0800 |
commit | f30aa3514472ab5448af63b8e9098b1d8a8a4332 (patch) | |
tree | 6b23d839ce2b93520ca2641ad23794380b78266f | |
parent | 75248d48862c884b5461059a8ca78f75fa0314da (diff) | |
download | dynamic_dns-f30aa3514472ab5448af63b8e9098b1d8a8a4332.tar.bz2 dynamic_dns-f30aa3514472ab5448af63b8e9098b1d8a8a4332.tar.xz dynamic_dns-f30aa3514472ab5448af63b8e9098b1d8a8a4332.zip |
Add flask app
-rw-r--r-- | ddns.cfg | 6 | ||||
-rw-r--r-- | ddns.py | 79 |
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 @@ | |||
1 | AMAZON_KEY_ID = "" | ||
2 | AMAZON_SECRET_KEY = "" | ||
3 | |||
4 | # These are bearer tokens, care should be taken not to expose them | ||
5 | # on the web. | ||
6 | CLIENTS = {} | ||
@@ -0,0 +1,79 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | import os | ||
4 | import flask | ||
5 | import hashlib | ||
6 | import functools | ||
7 | from boto.route53.record import ResourceRecordSets | ||
8 | from boto.route53.connection import Route53Connection | ||
9 | |||
10 | |||
11 | app = flask.Flask(__name__) | ||
12 | app.config.from_pyfile("/etc/ddns.cfg", silent=True) | ||
13 | app.config.from_pyfile("ddns.cfg", silent=True) | ||
14 | if "AMAZON_KEY_ID" not in app.config: | ||
15 | raise Exception("Not configured") | ||
16 | |||
17 | |||
18 | def 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 | |||
26 | def 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) | ||
37 | def 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 | ||
45 | def new_secret(): | ||
46 | return hashlib.sha256(os.urandom(100)).hexdigest() | ||
47 | |||
48 | |||
49 | @app.route("/update", methods=["POST"]) | ||
50 | def 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 | ||
67 | def get_ip(): | ||
68 | return flask.request.remote_addr | ||
69 | |||
70 | |||
71 | @app.route("/config") | ||
72 | @returns_plain_text | ||
73 | def get_config(): | ||
74 | return repr(app.config.items()) | ||
75 | |||
76 | |||
77 | if __name__ == "__main__": | ||
78 | app.debug = True | ||
79 | app.run() | ||