Skip to content

Instantly share code, notes, and snippets.

@bjjb
Created January 20, 2015 23:40
Show Gist options
  • Save bjjb/1bf8054da672971a1520 to your computer and use it in GitHub Desktop.
Save bjjb/1bf8054da672971a1520 to your computer and use it in GitHub Desktop.
#!/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