123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- import requests
- import json
- from desecapi import settings
- headers = {
- 'User-Agent': 'desecapi',
- 'X-API-Key': settings.POWERDNS_API_TOKEN,
- }
- def normalize_hostname(name):
- if '/' in name or '?' in name:
- raise Exception('Invalid hostname ' + name)
- return name if name.endswith('.') else name + '.'
- def _pdns_post(url, body):
- r = requests.post(settings.POWERDNS_API + url, data=json.dumps(body), headers=headers)
- if r.status_code < 200 or r.status_code >= 300:
- raise Exception(r.text)
- return r
- def _pdns_patch(url, body):
- r = requests.patch(settings.POWERDNS_API + url, data=json.dumps(body), headers=headers)
- if r.status_code < 200 or r.status_code >= 300:
- raise Exception(r.text)
- return r
- def _pdns_get(url):
- r = requests.get(settings.POWERDNS_API + url, headers=headers)
- if (r.status_code < 200 or r.status_code >= 500):
- raise Exception(r.text)
- return r
- def _delete_or_replace_rrset(name, type, value, ttl=60):
- """
- Return pdns API json to either replace or delete a record set, depending on value is empty or not.
- """
- if value != "":
- return \
- {
- "records": [
- {
- "type": type,
- "name": name,
- "disabled": False,
- "content": value,
- }
- ],
- "ttl": ttl,
- "changetype": "REPLACE",
- "type": type,
- "name": name,
- }
- else:
- return \
- {
- "changetype": "DELETE",
- "type": type,
- "name": name
- }
- def create_zone(name, kind='NATIVE'):
- """
- Commands pdns to create a zone with the given name.
- """
- payload = {
- "name": normalize_hostname(name),
- "kind": kind.upper(),
- "masters": [],
- "nameservers": [
- "ns1.desec.io.",
- "ns2.desec.io."
- ]
- }
- _pdns_post('/zones', payload)
- def zone_exists(name):
- """
- Returns whether pdns knows a zone with the given name.
- """
- reply = _pdns_get('/zones/' + normalize_hostname(name))
- if reply.status_code == 200:
- return True
- elif reply.status_code == 422 and 'Could not find domain' in reply.text:
- return False
- else:
- raise Exception(reply.text)
- def set_dyn_records(name, a, aaaa):
- """
- Commands pdns to set the A and AAAA record for the zone with the given name to the given record values.
- Only supports one A, one AAAA record.
- If a or aaaa is None, pdns will be commanded to delete the record.
- """
- name = normalize_hostname(name)
- _pdns_patch('/zones/' + name, {
- "rrsets": [
- _delete_or_replace_rrset(name, 'a', a),
- _delete_or_replace_rrset(name, 'aaaa', aaaa),
- ]
- })
|