Created
January 20, 2015 23:40
-
-
Save bjjb/1bf8054da672971a1520 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Script to update this host's DNS entry on Cloudflare. Silently succeeds. | |
It requires you to have set the environment variables: | |
- CLOUDFLARE_API_KEY | |
- CLOUDFLARE_EMAIL | |
- CLOUDFLARE_HOSTNAME | |
The latter is the DDNS hostname. You can't add a hostname to a domain that | |
doesn't already exist. But once the domain exists, it will create the A record | |
if needed, or modify an existing A record. | |
""" | |
import os, json | |
from urllib.parse import urlencode | |
from urllib.request import urlopen | |
from collections import namedtuple | |
# The following environment variables MUST be set: | |
api_key = os.environ.get('CLOUDFLARE_API_KEY') | |
email = os.environ.get('CLOUDFLARE_EMAIL') | |
hostname = os.environ.get('CLOUDFLARE_HOSTNAME') | |
name, domain = hostname.split('.', 1) | |
class cloudflare: | |
"""simple cloudflare API client""" | |
endpoint = "https://www.cloudflare.com/api_json.html" | |
def __init__(self, api_key, email): | |
self.api_key = api_key | |
self.email = email | |
def request(self, **params): | |
response = urlopen(self.make_url(**params)) | |
data = json.loads(response.read().decode('utf8')) | |
result = data['result'] | |
if result == 'success': | |
return data['response'] | |
elif result == 'error': | |
raise Exception("error: ", data['msg']) | |
else: | |
raise Exception("Unknown result: " + result) | |
def make_url(self, **params): | |
url = self.endpoint | |
params['tkn'] = api_key | |
params['email'] = email | |
url += '?' | |
url += urlencode(params) | |
return url | |
client = cloudflare(api_key, email) | |
# Find the zone. This script won't create one. | |
zones = client.request(a="zone_load_multi")['zones']['objs'] | |
zone = [z['zone_name'] for z in zones if z['zone_name'] == domain][0] | |
if not zone: | |
raise Exception("Couldn't find zone: ", domain) | |
# Get the public IP address | |
ip = os.popen('dig +short myip.opendns.com @resolver1.opendns.com').read().strip() | |
# Create or update the record | |
recs = client.request(a='rec_load_all', z=zone)['recs']['objs'] | |
rec_id = [r['rec_id'] for r in recs if r['name'] == hostname][0] | |
if rec_id: | |
client.request(a='rec_edit', id=rec_id, type='A', name=name, ttl=1, z=zone, content=ip) | |
else: | |
client.request(a='rec_new', type='A', name=name, z=zone, content=ip, ttl=1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment