aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2021-06-08 13:30:09 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2021-06-08 13:30:09 +0200
commitdfc13ed7befa06cb827c549ad8f0c1f3b264b681 (patch)
tree9de9722a8da6af3f2fef8fc5fd1b30a2dd344725
parente989b5b5f193a52381a2d82a6a911763c0c3c620 (diff)
downloadoctodns-custom-provider-dfc13ed7befa06cb827c549ad8f0c1f3b264b681.tar.gz
ZoneFileSource: add support for non-trivial records, add parameters for SOA
-rw-r--r--README.md8
-rwxr-xr-xoctodns-custom-providers/provider/zonefile.py89
-rwxr-xr-xsetup.py3
3 files changed, 79 insertions, 21 deletions
diff --git a/README.md b/README.md
index 6c490f5..1f00ab8 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,14 @@ providers:
zonefile:
class: octodns-custom-providers.provider.zonefile.ZoneFileProvider
directory: zonefiles
+ soa:
+ mname: ns.example.com
+ rname: dns.example.com
+ serial: 123456
+ refresh: 7200
+ retry: 3600
+ expire: 1209600
+ minimum: 3600
```
## octodns-custom-providers.source.phpipam.PhpipamSource
diff --git a/octodns-custom-providers/provider/zonefile.py b/octodns-custom-providers/provider/zonefile.py
index ea36a5c..f03f578 100755
--- a/octodns-custom-providers/provider/zonefile.py
+++ b/octodns-custom-providers/provider/zonefile.py
@@ -1,7 +1,4 @@
-#from octodns.zone import Zone
from octodns.provider.base import BaseProvider
-from octodns.provider.plan import Plan
-#from octodns.source.axfr import ZoneFileSource
import logging
@@ -9,24 +6,57 @@ import dns.zone
import dns.rdataclass
import dns.rdatatype
-class ZoneFileProvider(BaseProvider):
- SUPPORTS_GEO=False
- SUPPORTS = set(('A', 'AAAA', 'CAA', 'CNAME', 'MX', 'NS', 'PTR', 'SPF',
- 'SRV', 'TXT'))
+class RdataParameterException(Exception):
+ def __init__(self, msg):
+ super().__init__(msg)
+
+def _create_rdata( rdclass, rdtype, data ):
+ if isinstance(data,str):
+ return dns.rdata.from_text(rdclass, rdtype, data)
+
+ cls = dns.rdata.get_rdata_class(rdclass, rdtype)
+
+ for slot in cls.__slots__:
+ if not slot in data:
+ raise RdataParameterException('{} is missing'.format(slot))
+ return cls(rdclass, rdtype, **data)
- def __init__(self, id, directory):
+class ZoneFileProvider(BaseProvider):
+
+ SUPPORTS_GEO = False
+ SUPPORTS = set(('A', 'AAAA', 'CAA', 'CNAME', 'MX', 'NS', 'PTR', 'SPF',
+ 'SRV', 'TXT'))
+
+ '''
+ SOA dict
+ {
+ mname
+ rname
+ serial
+ refresh
+ retry
+ expire
+ ttl
+ }
+ '''
+
+ def __init__(self, id, directory, soa, soa_ttl=3600, file_extension = ''):
'''
Arguments
=========
id: str
directory: str
- check_origin: bool
+ soa: dict
+ extension: str
'''
self.log = logging.getLogger('ZoneFileProvider[{}]'.format(id))
self.log.debug('__init__: directory={}'.format(directory))
self.directory = directory
+ self.file_extension = file_extension
+ self.soa = soa
+ self.soa_ttl = soa_ttl
super(ZoneFileProvider, self).__init__(id)
@@ -34,36 +64,55 @@ class ZoneFileProvider(BaseProvider):
if target:
return False
- raise NotImplementedError("ZoneFileProvider only implements the target part."+
- " Use OctoDns' own ZoneFileSource to read from ZoneFiles.")
+ raise NotImplementedError(
+ "ZoneFileProvider only implements the target part." +
+ " Use OctoDns' own ZoneFileSource to read from ZoneFiles.")
- def _apply(self,plan):
+
+ def _apply(self, plan):
'''
Arguments
=========
plan: octodns.provider.plan.Plan
'''
- records = plan.desired.records
zone = dns.zone.Zone(plan.desired.name)
+ soaset = dns.rdataset.Rdataset(
+ dns.rdataclass.IN, dns.rdatatype.SOA)
+ soaset.add(_create_rdata(
+ dns.rdataclass.IN,
+ dns.rdatatype.SOA,
+ self.soa), self.soa_ttl)
+ zone.replace_rdataset('@',soaset)
+
for record in plan.desired.records:
data = record.data
name = record.name
- rdset = dns.rdataset.Rdataset(dns.rdataclass.IN, dns.rdatatype.from_text(record._type))
+ rdset = dns.rdataset.Rdataset(
+ dns.rdataclass.IN, dns.rdatatype.from_text(record._type))
if 'value' in data:
- rdset.add(dns.rdata.from_text(dns.rdataclass.IN,
- dns.rdatatype.from_text(record._type), data['value']), ttl=int(data['ttl'] ))
+ rdset.add(
+ _create_rdata(
+ dns.rdataclass.IN,
+ dns.rdatatype.from_text(record._type),
+ data['value']),
+ ttl=int(data['ttl']))
elif 'values' in data:
for value in data['values']:
- rdset.add(dns.rdata.from_text(dns.rdataclass.IN,
- dns.rdatatype.from_text(record._type), value), ttl=int(data['ttl'] ))
+ rdset.add(
+ _create_rdata(
+ dns.rdataclass.IN,
+ dns.rdatatype.from_text(record._type),
+ value),
+ ttl=int(data['ttl']))
else:
- self.log.warning("neither value nor values found in {}".format(name))
+ self.log.warning(
+ "neither value nor values found in {}".format(name))
continue
zone.replace_rdataset(name, rdset)
- zone.to_file( self.directory + '/' + plan.desired.name)
+ zone.to_file(self.directory + '/' + plan.desired.name + self.file_extension)
diff --git a/setup.py b/setup.py
index 39d7efe..fd77f90 100755
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,8 @@ setup(
packages=setuptools.find_packages(),
install_requires=[
"octodns",
- "phpipam-api>=1.0.0"
+ "phpipam-api>=1.0.0",
+ "dnspython>=2.1.0"
],
license='MIT',
long_description=open('README.md').read(),