Skip to content

Instantly share code, notes, and snippets.

@StalkingKillah
Created January 7, 2015 16:14

Revisions

  1. StalkingKillah created this gist Jan 7, 2015.
    138 changes: 138 additions & 0 deletions dynflare.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,138 @@
    #!/usr/bin/env python
    # encoding: utf-8
    """
    dynflare
    Created by Djordje Stojanovic <djordje.stojanovic@shadow-inc.net>
    """
    import sys
    import socket
    import logging
    try:
    import json
    except ImportError:
    import simplejson as json
    try:
    import requests
    except ImportError:
    logging.error('`requests` library required. Install with `sudo pip install requests`')
    sys.exit(1)
    try:
    import dns.resolver as resolver
    except ImportError:
    logging.error('`dnspython` library required. Install with `sudo pip install dnspython`')
    sys.exit(1)

    class CloudFlare(object):
    def __init__(self, email, token):
    self.url = 'https://www.cloudflare.com/api_json.html'
    self.email = email
    self.token = token

    def _request(self, payload):
    r = requests.get(self.url, params=payload)
    if r.status_code == 200:
    return r.json()
    else:
    logging.error('Unable to make request to CloudFlare!')
    return None

    def _create_payload(self, action, data=None):
    payload = {
    'a': action,
    'tkn': self.token,
    'email': self.email
    }
    return ((data is not None and type(data) is dict) and dict(payload, **data)) or payload

    def get_records(self, domain):
    data = { 'z': domain }
    payload = self._create_payload('rec_load_all', data)
    return self._request(payload)

    def get_record(self, domain, name):
    records = self.get_records(domain)['response']['recs']
    fqdn = "{}.{}".format(name, domain)
    record = filter(lambda record: record['name'] == fqdn, records['objs'])
    if len(record) > 0:
    return record[0]
    else:
    logging.warning('Record for %s not found.', fqdn)
    return None

    def create_record(self, domain, name, content, record_type='A', ttl=1):
    record_types = ['A', 'CNAME', 'MX', 'TXT', 'SPF', 'AAAA', 'NS', 'SRV', 'LOC']
    if record_type.upper() in record_types:
    data = {
    'z': domain,
    'type': record_type.upper(),
    'name': name,
    'content': content,
    'ttl': ttl
    }
    payload = self._create_payload('rec_new', data)
    return self._request(payload)
    else:
    logging.error('Record type is not in %s', '/'.join(record_types))
    return None

    def edit_record(self, domain, name, content, record_type='', ttl=None):
    record = self.get_record(domain, name)
    if record is not None:
    filter_non_empty = lambda dictionary: dict([ (i, dictionary[i]) for i in dictionary if dictionary[i] is not None or dictionary[i] is not ''])
    data = {
    'z': domain,
    'type': record_type,
    'id': record['rec_id'],
    'content': content,
    'ttl': ttl
    }
    data = filter_non_empty(data)
    payload = self._create_payload('rec_edit', data)
    return self._request(payload)
    else:
    return None

    def delete_record(self, domain, name):
    record = self.get_record(domain, name)
    if record is not None:
    data = {
    'z': domain,
    'id': record['rec_id']
    }
    payload = self._create_payload('rec_delete', data)
    return self._request(payload)
    else:
    return None

    def get_public_ip():
    r = resolver.Resolver()
    r.nameservers = [socket.gethostbyname('resolver1.opendns.com')]
    return r.query('myip.opendns.com', 'A')[0].address

    def main():
    hostname = socket.gethostname()
    ip = get_public_ip()
    cf = CloudFlare("YOUR_EMAIL", "YOUR_CF_TOKEN")
    domain = 'YOUR_DOMAIN'
    record = cf.get_record(domain, hostname)
    r = None
    if record is not None:
    if 'name' in record:
    logging.info('Updating record for %s.%s', hostname, domain)
    r = cf.edit_record(domain, hostname, ip)
    else:
    logging.info('Creating record for %s.%s', hostname, domain)
    r = cf.create_record(domain, hostname, ip)
    if r is None:
    logging.error('Errored out while editing CloudFlare DNS Record')
    print r
    sys.exit(1)
    logging.info('%s.%s -> %s', hostname, domain, ip)
    logging.info('Update sucessfull')
    # print hostname+'.'+domain+' -> '+ip
    # print 'Update sucessfull'
    sys.exit(0)

    if __name__ == '__main__':
    main()