1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
"""
localzone.context
~~~~~~~~~~~~~~~~~
This module implements the methods for localzone context management.
:copyright: (c) 2018 Andrew Grant Spencer
:license: BSD, see LICENSE for more details.
"""
from contextlib import contextmanager
import dns.name
import dns.rdataclass
import dns.tokenizer
import dns.zone
try:
# The api for the zonefile reader was exposed in dnspython 2.1
from dns.zonefile import Reader
DNSPYTHON21 = True
except ImportError:
from dns.zone import _MasterReader
DNSPYTHON21 = False
from .models import Zone
@contextmanager
def manage(filename, origin=None, autosave=False):
"""
A context manager that yields a :class:`Zone <Zone>` object.
:param filename: The path to the zone's master file.
:type filename: string
:param origin: (optional) The zone's origin domain
:type origin: string
:param autosave: (optional) controls whether or not the zone's master file
is written to disk upon exit
:type autosave: bool
:return: :class:`Zone <Zone>` object
:rtype: localzone.models.Zone
"""
if origin:
# perform basic validation/sanitization on origin
origin = dns.name.from_text(origin).to_text()
zone = load(filename, origin)
try:
yield zone
finally:
if autosave:
zone.save()
def load(filename, origin=None):
"""
Read a master zone file and construct a :class:`Zone <Zone>` object.
:param filename: The path to the zone's master file.
:type filename: string
:param origin: (optional) The zone's origin domain
:type origin: string
:return: :class:`Zone <Zone>` object
:rtype: localzone.Zone
"""
with open(filename) as text:
tok = dns.tokenizer.Tokenizer(text, filename)
if DNSPYTHON21:
zone = Zone(
origin,
dns.rdataclass.IN,
relativize=True,
)
with zone.writer() as txn:
reader = Reader(
tok,
rdclass=dns.rdataclass.IN,
txn=txn,
allow_include=True,
)
reader.read()
else:
reader = _MasterReader(
tok,
origin=origin,
rdclass=dns.rdataclass.IN,
relativize=True,
zone_factory=Zone,
allow_include=True,
check_origin=True,
)
reader.read()
zone = reader.zone
# TODO: remember that any method using the zone.filename property should
# have it passed as a parameter
zone._filename = filename
# starting with dnspython v1.16.0, use default_ttl
try:
zone._ttl = reader.default_ttl
except AttributeError:
zone._ttl = reader.ttl
return zone
|