1. Working with CloudFlare DNS in python

Working with CloudFlare DNS in python

stones

Last week I wrote about aDNS discovery feature in Etcd. As a step in the whole process we need to create DNS records in twindb.com zone. CloudFlare provides rich API to work with it. We wrapped it into a Python module twindb_cloudflare and opensourced it:

In the post I will show how to use twindb_cloudflare module.

CloudFlare API credentials

First of all you need to get credentials to work with CloudFlare. Visit https://www.cloudflare.com/a/account/my-account and get “API Key”.

CLOUDFLARE_EMAIL = "aleks@twindb.com"
CLOUDFLARE_AUTH_KEY = "dbb4a7ae063347a306e9ad8c5bda58a7a3cfa"

Installing twindb_cloudflare

The module is available in PyPi. You can install it with pip:

$ pip install twindb_cloudflare
Collecting twindb_cloudflare
  Using cached twindb_cloudflare-0.1.1-py2.py3-none-any.whl
Installing collected packages: twindb-cloudflare
Successfully installed twindb-cloudflare-0.1.1

Creating A record

To create an A record

import socket
import time
from twindb_cloudflare.twindb_cloudflare import CloudFlare, CloudFlareException

CLOUDFLARE_EMAIL = "aleks@twindb.com"
CLOUDFLARE_AUTH_KEY = "dbb4a7ae063347a306e9ad8c5bda58a7a3cfa"

cf = CloudFlare(CLOUDFLARE_EMAIL, CLOUDFLARE_AUTH_KEY)

try:
    cf.create_dns_record('blogtest.twindb.com', 'twindb.com', '10.10.10.10')
    # The new record isn't available right away
    wait_until = time.time() + 600
    while time.time() < wait_until:
        try:
            ip = socket.gethostbyname('blogtest.twindb.com')
            print(ip)
            exit(0)
        except socket.gaierror:
            time.sleep(1)
    print("New record isn't available after 600 seconds")
    exit(-1)
except CloudFlareException as err:
    print(err)
    exit(-1)

The script runs a minute or two:

[16:41:51 aleks@Aleksandrs-MacBook-Pro mydns]$ python create.py
10.10.10.10
[16:43:59 aleks@Aleksandrs-MacBook-Pro mydns]$

Updating A record

Updating a record is pretty straightforward either. In real applications you have to take into account that a DNS response may be cached and CloudFlare changes aren’t available momentarily.

import socket
import time
from twindb_cloudflare.twindb_cloudflare import CloudFlare, CloudFlareException

CLOUDFLARE_EMAIL = "aleks@twindb.com"
CLOUDFLARE_AUTH_KEY = "dbb4a7ae063347a306e9ad8c5bda58a7a3cfa"

cf = CloudFlare(CLOUDFLARE_EMAIL, CLOUDFLARE_AUTH_KEY)

try:
    cf.update_dns_record('blogtest.twindb.com', 'twindb.com', '10.20.20.20')
    # The new record isn't available right away
    wait_until = time.time() + 600
    while time.time() < wait_until:
        try:
            ip = socket.gethostbyname('blogtest.twindb.com')
            if ip == '10.20.20.20':
                print(ip)
                exit(0)
            else:
                time.sleep(1)
        except socket.gaierror:
            time.sleep(1)
    print("New record isn't updated after 600 seconds")
    exit(-1)
except CloudFlareException as err:
    print(err)
    exit(-1)

The change is visible after a minute

[16:54:02 aleks@Aleksandrs-MacBook-Pro mydns]$ python myupdate.py
10.20.20.20
[16:55:03 aleks@Aleksandrs-MacBook-Pro mydns]$

Deleting A record

And finally let’s delete the record we’ve created. Here I won’t wait until the change is propagated and will assume that if there was no exception then we are good.

from twindb_cloudflare.twindb_cloudflare import CloudFlare, CloudFlareException

CLOUDFLARE_EMAIL = "aleks@twindb.com"
CLOUDFLARE_AUTH_KEY = "dbb4a7ae063347a306e9ad8c5bda58a7a3cfa"

cf = CloudFlare(CLOUDFLARE_EMAIL, CLOUDFLARE_AUTH_KEY)

try:
    cf.delete_dns_record('blogtest.twindb.com', 'twindb.com')
except CloudFlareException as err:
    print(err)
    exit(-1)

Final notes

ClaudFlare API provides many more actions than the module implements. However I wanted to start with something small and incrementally implementing more feature as they are needed.

I encourage you to file bugs and feature requests on https://github.com/twindb/twindb_cloudflare/issues.
Also, pull requests are welcomed 🙂

Previous Post Next Post