pvl/dns/zone.py
author Tero Marttila <terom@paivola.fi>
Sat, 21 Dec 2013 22:57:44 +0200
changeset 329 b3778c190aa5
parent 323 9b3cbd8687eb
child 378 3fed153a1fe6
permissions -rw-r--r--
version 0..0:

pvl.rrd: api.report()
pvl.wlan-syslog: track openwrt hostapd syslog wlan sta activity
pvl.verkko.wlan: basic Table view
pvl.dns-serial
pvl.dns-zone
pvl.dhcp.config: nested blocks
pvl.hosts-import: import hosts from dns/dhcp
pvl.hosts-dns: generate --forward-zone=paivola.fi and --reverse-zone=194.197.235
pvl.hosts-dhcp: generate dhcp hosts conf
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
#!/usr/bin/env python
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
    Process zonefiles.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
"""
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
import codecs
253
8f59ee92583d pvl.dns.zone: tweak datetime import
Tero Marttila <terom@paivola.fi>
parents: 252
diff changeset
     8
import datetime
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
import logging
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
    10
import math
254
358b6e91659d ZoneRecord.parse: support $TTL, and very crudde $INCLUDE
Tero Marttila <terom@paivola.fi>
parents: 253
diff changeset
    11
import os.path
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
log = logging.getLogger('pvl.dns.zone')
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
class ZoneError (Exception) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
    pass
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
class ZoneLineError (ZoneError) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
        ZoneLine-related error
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
    def __init__ (self, line, msg, *args, **kwargs) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
        super(ZoneLineError, self).__init__("%s: %s" % (line, msg.format(*args, **kwargs)))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
class ZoneLine (object) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
    """
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
    28
        A line parsed from a zonefile.
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
    31
    @classmethod
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    32
    def load (cls, file, ttl=None, origin=None, expand_generate=False, expand_include=False, **opts) :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    33
        """
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    34
            Parse ZoneLine, ZoneRecord items from the given zonefile.
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    35
        """
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    36
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    37
        name = None
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    38
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    39
        for line in cls.parse(file, **opts) :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    40
            if not line.parts :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    41
                log.debug("%s: skip empty line", line)
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    42
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    43
            elif line.line.startswith('$') :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    44
                # control record
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    45
                directive = ZoneDirective.parse(line,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    46
                        origin      = origin,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    47
                        comment     = line.comment,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    48
                )
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    49
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    50
                if directive.directive == 'ORIGIN' :
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    51
                    # update
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    52
                    origin, = directive.arguments
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    53
                    
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    54
                    log.info("%s: origin: %s", line, origin)
300
a720bcf96007 pvl.dns.zone: passthrough ORIGIN/TTL lines, better warn on unparsed lines
Tero Marttila <terom@paivola.fi>
parents: 298
diff changeset
    55
                    
a720bcf96007 pvl.dns.zone: passthrough ORIGIN/TTL lines, better warn on unparsed lines
Tero Marttila <terom@paivola.fi>
parents: 298
diff changeset
    56
                    yield line, None
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    57
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    58
                elif directive.directive == 'TTL' :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    59
                    ttl, = directive.arguments
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    60
                    
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    61
                    log.info("%s: ttl: %s", line, ttl)
300
a720bcf96007 pvl.dns.zone: passthrough ORIGIN/TTL lines, better warn on unparsed lines
Tero Marttila <terom@paivola.fi>
parents: 298
diff changeset
    62
                    
a720bcf96007 pvl.dns.zone: passthrough ORIGIN/TTL lines, better warn on unparsed lines
Tero Marttila <terom@paivola.fi>
parents: 298
diff changeset
    63
                    yield line, None
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    64
                
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    65
                elif directive.directive == 'GENERATE' :
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    66
                    if expand_generate :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    67
                        # process...
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    68
                        log.info("%s: generate: %s", line, directive.arguments)
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    69
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    70
                        for record in process_generate(line, origin, directive.arguments) :
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    71
                            yield line, record
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    72
                    else :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    73
                        yield line, None
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    74
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    75
                elif directive.directive == 'INCLUDE' :
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    76
                    if expand_include :
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    77
                        include, = directive.arguments
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    78
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    79
                        path = os.path.join(os.path.dirname(file.name), include)
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    80
                        
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    81
                        log.info("%s: include: %s: %s", line, include, path)
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    82
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    83
                        for record in cls.load(open(path)) :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    84
                            yield line, record
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    85
                    else :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    86
                        yield line, None
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    87
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    88
                else :
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
    89
                    log.warn("%s: skip unknown control record: %r", line, directive)
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    90
                    yield line, None
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    91
                
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    92
            else :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    93
                # normal record?
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    94
                record = ZoneRecord.parse(line,
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    95
                        name    = name,
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    96
                        origin  = origin,
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    97
                        ttl     = ttl,
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    98
                        comment = line.comment,
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
    99
                )
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   100
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   101
                if record :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   102
                    yield line, record
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   103
                    
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   104
                    # keep name across lines
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   105
                    name = record.name
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   106
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   107
                else :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   108
                    # unknown
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   109
                    log.warning("%s: skip unknown line: %s", line, line.line)
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   110
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   111
                    yield line, None
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   112
     
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   113
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   114
    @classmethod
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   115
    def parse (cls, file, filename=None, line_timestamp_prefix=None) :
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   116
        """
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   117
            Yield ZoneLines lexed from a file.
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   118
        """
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   119
        
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   120
        if not filename :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   121
            filename = file.name
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   122
        
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   123
        multiline_start = None
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   124
        multiline_parts = None
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   125
        
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   126
        for lineno, raw_line in enumerate(file) :
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   127
            raw_line = raw_line.rstrip('\n')
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   128
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   129
            # possible mtime prefix for line
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   130
            timestamp = None
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   131
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   132
            if line_timestamp_prefix :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   133
                if ': ' not in raw_line :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   134
                    raise ZoneError("%s:%d: Missing timestamp prefix: %s" % (filename, lineno, raw_line))
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   135
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   136
                # split prefix
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   137
                prefix, raw_line = raw_line.split(': ', 1)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   138
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   139
                # parse it out
253
8f59ee92583d pvl.dns.zone: tweak datetime import
Tero Marttila <terom@paivola.fi>
parents: 252
diff changeset
   140
                timestamp = datetime.datetime.strptime(prefix, cls.PARSE_DATETIME_FORMAT)
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   141
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   142
                log.debug("%s:%d: ts=%r", filename, lineno, ts)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   143
            
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   144
            log.debug("%s:%d: %s", filename, lineno, raw_line)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   145
            
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   146
            # capture indent from raw line
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   147
            indent = raw_line.startswith(' ') or raw_line.startswith('\t')
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   148
            line = raw_line.strip()
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   149
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   150
            # parse comment
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   151
            if ';' in line:
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   152
                line, comment = line.split(';', 1)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   153
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   154
                line = line.strip()
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   155
                comment = comment.strip()
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   156
            else :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   157
                comment = None
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   158
           
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   159
            log.debug("%s:%d: indent=%r, line=%r, comment=%r", filename, lineno, indent, line, comment)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   160
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   161
            # split (quoted) fields
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   162
            if '"' in line :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   163
                pre, data, post = line.split('"', 2)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   164
                parts = pre.split() + [data] + post.split()
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   165
               
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   166
            else :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   167
                parts = line.split()
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   168
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   169
            # handle multi-line statements...
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   170
            if '(' in parts :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   171
                assert not multiline_start
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   172
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   173
                log.debug("%s:%d: Start of multi-line statement: %s", filename, lineno, line)
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   174
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   175
                multiline_start = (lineno, timestamp, indent, comment)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   176
                multiline_line = raw_line
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   177
                multiline_parts = []
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   178
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   179
            if multiline_start:
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   180
                log.debug("%s:%d: Multi-line statement: %s", filename, lineno, line)
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   181
                
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   182
                # XXX: some better way to do this
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   183
                multiline_parts.extend([part for part in parts if part not in set('()')])
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   184
                multiline_line += raw_line
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   185
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   186
            if ')' in parts :
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   187
                assert multiline_start
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   188
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   189
                log.debug("%s:%d: End of multi-line statement: %s", filename, lineno, line)
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   190
                
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   191
                lineno, timestamp, indent, comment = multiline_start
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   192
                raw_line = multiline_line
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   193
                parts = multiline_parts
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   194
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   195
                multiline_start = multiline_line = multiline_parts = None
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   196
        
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   197
            # parse
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   198
            if multiline_start:
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   199
                pass
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   200
            else:
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   201
                yield ZoneLine(filename, lineno, raw_line, indent, parts, comment, timestamp=timestamp)
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   202
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   203
    file = None
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   204
    lineno = None
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
    # data
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
    indent = None # was the line indented?
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
    parts = None # split line fields
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
    # optional
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   211
    timestamp = None
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   212
    comment = None
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   213
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   214
    PARSE_DATETIME_FORMAT = '%Y-%m-%d'
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   215
    
248
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   216
    def __init__ (self, file, lineno, line, indent, parts, comment=None, timestamp=None) :
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   217
        # source
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
        self.file = file
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
        self.lineno = lineno
248
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   220
        self.line = line
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   221
        
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   222
        # parse data
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
        self.indent = indent
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
        self.parts = parts
248
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   225
        
cce9cf4933ca pvl.dns.zone: more multi-line support in the parser..
Tero Marttila <terom@paivola.fi>
parents: 247
diff changeset
   226
        # metadata
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
        self.timestamp = timestamp
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
        self.comment = comment
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
316
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   230
    def __unicode__ (self) :
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   231
        return u"{indent}{parts}".format(
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   232
                indent      = u"\t" if self.indent else '',
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   233
                parts       = u'\t'.join(self.parts),
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   234
        )
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   235
41bd6688b142 pvl.dns.zone: implement --include-path
Tero Marttila <terom@paivola.fi>
parents: 308
diff changeset
   236
    def __repr__ (self) :
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
        return "{file}:{lineno}".format(file=self.file, lineno=self.lineno)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   239
class ZoneDirective (object) :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   240
    """
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   241
        An $DIRECTIVE in a zonefile.
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   242
    """
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   243
    
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   244
    # context
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   245
    line    = None
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   246
    origin  = None
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   247
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   248
    # fields
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   249
    directive   = None
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   250
    arguments   = None
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   251
    
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   252
    @classmethod
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   253
    def parse (cls, line, **opts) :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   254
        # control record
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   255
        args = list(line.parts)
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   256
        directive = args[0][1:]
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   257
        arguments = args[1:]
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   258
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   259
        return cls.build(line, directive, *arguments, **opts)
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   260
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   261
    @classmethod
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   262
    def build (cls, line, directive, *arguments, **opts) :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   263
        return cls(directive, arguments,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   264
                line        = line,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   265
                **opts
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   266
        )
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   267
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   268
    def __init__ (self, directive, arguments, line=None, origin=None, comment=None) :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   269
        self.directive  = directive
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   270
        self.arguments  = arguments
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   271
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   272
        self.line = line
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   273
        self.origin = origin
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   274
        self.comment = comment
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   275
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   276
    def __unicode__ (self) :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   277
        """
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   278
            Construct a zonefile-format line...
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   279
        """
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   280
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   281
        if self.comment :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   282
            comment = '\t; ' + self.comment
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   283
        else :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   284
            comment = ''
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   285
            
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   286
        return u"${directive}\t{arguments}{comment}".format(
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   287
                directive   = self.directive,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   288
                arguments   = '\t'.join(self.arguments),
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   289
                comment     = comment,
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   290
        )
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   291
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   292
    def __repr__ (self) :
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   293
        return '%s(%s)' % (self.__class__.__name__, ', '.join(repr(arg) for arg in (
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   294
            (self.directive) + tuple(self.arguments)
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   295
        )))
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   296
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   297
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   298
class ZoneRecord (object) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   299
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   300
        A record from a zonefile.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   301
    """
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   302
    
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   303
    # context
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   304
    line = None # the underlying line
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   305
    origin = None # possible $ORIGIN context
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   306
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   307
    # record fields
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   308
    name = None
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   309
    ttl = None  # optional
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   310
    cls = None  # optional
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   311
    type = None
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   312
    data = None # list of data fields
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   313
    
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   314
    @classmethod
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   315
    def load (cls, file, **opts) :
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   316
        """
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   317
            Yield ZoneRecords from a file.
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   318
        """
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   319
292
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   320
        for line, record in ZoneLine.load(file, **opts) :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   321
            if record :
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   322
                yield record
cc4a4a2f2b76 pvl.dns.zone: implement ZoneLines.load to yield ZoneLine, ZoneRecord pairs for zone passthrough; change default to not evaluate INCLUDE/GENERATE
Tero Marttila <terom@paivola.fi>
parents: 286
diff changeset
   323
            else :
300
a720bcf96007 pvl.dns.zone: passthrough ORIGIN/TTL lines, better warn on unparsed lines
Tero Marttila <terom@paivola.fi>
parents: 298
diff changeset
   324
                log.warn("%s: unparsed line: %s", file.name, line)
254
358b6e91659d ZoneRecord.parse: support $TTL, and very crudde $INCLUDE
Tero Marttila <terom@paivola.fi>
parents: 253
diff changeset
   325
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   326
    @classmethod
274
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   327
    def parse (cls, line, name=None, parts=None, ttl=None, **opts) :
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   328
        """
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   329
            Build a ZoneRecord from a ZoneLine.
274
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   330
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   331
                name        - default for name, if continuing previous line
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   332
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   333
            Return: (name, ZoneRecord)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   334
        """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   335
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   336
        if parts is None :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   337
            parts = list(line.parts)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   338
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   339
        if not parts :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   340
            # skip
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   341
            return
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
        
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   343
        if line.indent :
274
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   344
            # indented lines keep name from previous record
81af20dd142d pvl.dns.zone: fix runon name handling; typofix $ORIGIN
Tero Marttila <terom@paivola.fi>
parents: 270
diff changeset
   345
            pass
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   346
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   347
        else :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   348
            name = parts.pop(0)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   349
        
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   350
        if len(parts) < 2 :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   351
            raise ZoneLineError(line, "Too few parts to parse: {0!r}", line.data)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   352
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   353
        # parse ttl/cls/type
254
358b6e91659d ZoneRecord.parse: support $TTL, and very crudde $INCLUDE
Tero Marttila <terom@paivola.fi>
parents: 253
diff changeset
   354
        _cls = None
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   355
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   356
        if parts and parts[0][0].isdigit() :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   357
            ttl = parts.pop(0)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   358
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   359
        if parts and parts[0].upper() in ('IN', 'CH') :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   360
            _cls = parts.pop(0)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   361
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   362
        # always have type
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   363
        type = parts.pop(0)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   364
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   365
        # remaining parts are data
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   366
        data = parts
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   367
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   368
        log.debug("  ttl=%r, cls=%r, type=%r, data=%r", ttl, _cls, type, data)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   369
252
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   370
        return cls.build(line, name, ttl, _cls, type, data, **opts)
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   371
    
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   372
    @classmethod
294
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   373
    def build (cls, line, name, ttl, _cls, type, data, **opts) :
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   374
        return cls(name, type, data,
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   375
            ttl     = ttl,
294
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   376
            cls     = _cls,
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   377
            line    = line,
252
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   378
            **opts
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   379
        )
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   380
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   381
    @classmethod
308
08176bed21e3 pvl.hosts: support alias4/6=... for A/AAAA CNAMES
Tero Marttila <terom@paivola.fi>
parents: 300
diff changeset
   382
    def A (cls, name, ip4, **opts) :
08176bed21e3 pvl.hosts: support alias4/6=... for A/AAAA CNAMES
Tero Marttila <terom@paivola.fi>
parents: 300
diff changeset
   383
        return cls(str(name), 'A', [str(ip4)], **opts)
08176bed21e3 pvl.hosts: support alias4/6=... for A/AAAA CNAMES
Tero Marttila <terom@paivola.fi>
parents: 300
diff changeset
   384
08176bed21e3 pvl.hosts: support alias4/6=... for A/AAAA CNAMES
Tero Marttila <terom@paivola.fi>
parents: 300
diff changeset
   385
    @classmethod
08176bed21e3 pvl.hosts: support alias4/6=... for A/AAAA CNAMES
Tero Marttila <terom@paivola.fi>
parents: 300
diff changeset
   386
    def AAAA (cls, name, ip6, **opts) :
08176bed21e3 pvl.hosts: support alias4/6=... for A/AAAA CNAMES
Tero Marttila <terom@paivola.fi>
parents: 300
diff changeset
   387
        return cls(str(name), 'AAAA', [str(ip6)], **opts)
267
8c0c1b6e6aff pvl.dns.zone: ZoneRecord.A/CNAME
Tero Marttila <terom@paivola.fi>
parents: 257
diff changeset
   388
8c0c1b6e6aff pvl.dns.zone: ZoneRecord.A/CNAME
Tero Marttila <terom@paivola.fi>
parents: 257
diff changeset
   389
    @classmethod
8c0c1b6e6aff pvl.dns.zone: ZoneRecord.A/CNAME
Tero Marttila <terom@paivola.fi>
parents: 257
diff changeset
   390
    def CNAME (cls, name, host, **opts) :
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   391
        return cls(str(name), 'CNAME', [str(host)], **opts)
267
8c0c1b6e6aff pvl.dns.zone: ZoneRecord.A/CNAME
Tero Marttila <terom@paivola.fi>
parents: 257
diff changeset
   392
8c0c1b6e6aff pvl.dns.zone: ZoneRecord.A/CNAME
Tero Marttila <terom@paivola.fi>
parents: 257
diff changeset
   393
    @classmethod
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
    def TXT (cls, name, text, **opts) :
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   395
        return cls(str(name), 'TXT',
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
            [u'"{0}"'.format(text.replace('"', '\\"'))], 
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   397
            **opts
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   398
        )
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   399
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   400
    @classmethod
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   401
    def PTR (cls, name, ptr, **opts) :
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   402
        return cls(str(name), 'PTR', [str(ptr)], **opts)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   403
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   404
    @classmethod
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   405
    def MX (cls, name, priority, mx, **opts) :
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   406
        return cls(str(name), 'MX', [int(priority), str(mx)], **opts)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   407
294
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   408
    def __init__ (self, name, type, data, ttl=None, cls=None, line=None, origin=None, comment=None) :
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   409
        self.name = name
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   410
        self.type = type
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   411
        self.data = data
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   412
        
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   413
        self.ttl = ttl
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   414
        self.cls = cls
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   415
        
294
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   416
        self.line = line
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   417
        self.origin = origin
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   418
        self.comment = comment
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   419
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   420
    def __unicode__ (self) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   421
        """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   422
            Construct a zonefile-format line..."
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   423
        """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   424
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   425
        if self.comment :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   426
            comment = '\t; ' + self._comment
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   427
        else :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   428
            comment = ''
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   429
            
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   430
        return u"{name:25} {ttl:4} {cls:2} {type:5} {data}{comment}".format(
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   431
                name    = self.name or '',
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   432
                ttl     = self.ttl or '',
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   433
                cls     = self.cls or '',
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   434
                type    = self.type,
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   435
                data    = ' '.join(unicode(data) for data in self.data),
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   436
                comment = comment,
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   437
        )
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   438
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   439
    def __repr__ (self) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   440
        return '%s(%s)' % (self.__class__.__name__, ', '.join(repr(arg) for arg in (
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   441
            self.name, self.type, self.data
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   442
        )))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   443
252
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   444
class SOA (ZoneRecord) :
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   445
    @classmethod
294
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   446
    def build (cls, line, name, ttl, _cls, type, data, **opts) :
252
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   447
        assert name == '@'
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   448
294
29720bbc5379 pvl.dns.zone: better warnings for pvl.dns.zone.SOA.parse with missing parameters
Tero Marttila <terom@paivola.fi>
parents: 292
diff changeset
   449
        return cls(*data,
252
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   450
            ttl     = ttl,
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   451
            cls     = cls,
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   452
            line    = line,
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   453
            **opts
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   454
        )
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   455
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   456
    def __init__ (self, master, contact, serial, refresh, retry, expire, nxttl, **opts) :
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   457
        super(SOA, self).__init__('@', 'SOA',
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   458
            [master, contact, serial, refresh, retry, expire, nxttl],
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   459
            **opts
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   460
        )
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   461
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   462
        self.master = master
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   463
        self.contact = contact
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   464
        self.serial = serial
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   465
        self.refresh = refresh
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   466
        self.retry = retry
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   467
        self.expire = expire
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   468
        self.nxttl = nxttl
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   469
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   470
class OffsetValue (object) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   471
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   472
        Magic for $GENERATE offsets.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   473
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   474
        >>> OffsetValue(0)[1]
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   475
        1
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   476
        >>> OffsetValue(10)[5]
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   477
        15
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   478
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   479
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   480
    def __init__ (self, base) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   481
        self.base = base
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   482
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   483
    def __getitem__ (self, offset) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   484
        return self.base + offset
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   485
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   486
def parse_generate_field (field, line=None) :
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   487
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   488
        Parse a $GENERATE lhs/rhs field:
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   489
            $
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   490
            ${<offset>[,<width>[,<base>]]}
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   491
            \$
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   492
            $$
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   493
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   494
        Returns a wrapper that builds the field-value when called with the index.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   495
        
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   496
        >>> parse_generate_field("foo")(1)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   497
        'foo'
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   498
        >>> parse_generate_field("foo-$")(1)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   499
        'foo-1'
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   500
        >>> parse_generate_field("foo-$$")(1)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   501
        'foo-$'
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   502
        >>> parse_generate_field("\$")(1)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   503
        '$'
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   504
        >>> parse_generate_field("10.0.0.${100}")(1)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   505
        '10.0.0.101'
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   506
        >>> parse_generate_field("foo-${0,2,d}")(1)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   507
        'foo-01'
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   508
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   509
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   510
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   511
    input = field
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   512
    expr = []
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   513
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   514
    while '$' in field :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   515
        # defaults
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   516
        offset = 0
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   517
        width = 0
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   518
        base = 'd'
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   519
        escape = False
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   520
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   521
        # different forms
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   522
        if '${' in field :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   523
            pre, body = field.split('${', 1)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   524
            body, post = body.split('}', 1)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   525
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   526
            # parse body
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   527
            parts = body.split(',')
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   528
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   529
            # offset
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   530
            offset = int(parts.pop(0))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   531
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   532
            # width
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   533
            if parts :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   534
                width = int(parts.pop(0))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   535
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   536
            # base
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   537
            if parts :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   538
                base = parts.pop(0)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   539
            
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   540
            if parts:
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   541
                # fail
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   542
                raise ZoneLineError(line, "extra data in ${...} body: {0!r}", parts)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   543
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   544
        elif '$$' in field :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   545
            pre, post = field.split('$$', 1)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   546
            escape = True
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   547
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   548
        elif '\\$' in field :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   549
            pre, post = field.split('\\$', 1)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   550
            escape = True
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   551
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   552
        else :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   553
            pre, post = field.split('$', 1)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   554
        
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   555
        expr.append(pre)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   556
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   557
        if escape :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   558
            expr.append('$')
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   559
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   560
        else :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   561
            # meta-format
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   562
            fmt = '{value[%d]:0%d%s}' % (offset, width, base)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   563
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   564
            log.debug("field=%r -> pre=%r, fmt=%r, post=%r", field, expr, fmt, post)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   565
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   566
            expr.append(fmt)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   567
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   568
        field = post
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   569
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   570
    # final
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   571
    if field :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   572
        expr.append(field)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   573
    
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   574
    # combine
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   575
    expr = ''.join(expr)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   576
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   577
    log.debug("%s: %s", input, expr)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   578
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   579
    # processed
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   580
    def value_func (value) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   581
        # magic wrapper to implement offsets
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   582
        return expr.format(value=OffsetValue(value))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   583
    
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   584
    return value_func
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   585
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   586
def parse_generate_range (field) :
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   587
    """
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   588
        Parse a <start>-<stop>[/<step>] field
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   589
    """
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   590
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   591
    if '/' in field :
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   592
        field, step = field.split('/')
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   593
        step = int(step)
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   594
    else :
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   595
        step = 1
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   596
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   597
    start, stop = field.split('-')
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   598
    start = int(start)
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   599
    stop = int(stop)
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   600
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   601
    log.debug("  range: start=%r, stop=%r, step=%r", start, stop, step)
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   602
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   603
    # inclusive
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   604
    return range(start, stop + 1, step)
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   605
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   606
def process_generate (line, origin, parts) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   607
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   608
        Process a 
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   609
            $GENERATE <start>-<stop>[/<step>] lhs [ttl] [class] type rhs [comment]
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   610
        directive into a series of ZoneResource's.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   611
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   612
323
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   613
    parts = list(parts)
9b3cbd8687eb pvl.dns.zone: add ZoneDirective type
Tero Marttila <terom@paivola.fi>
parents: 316
diff changeset
   614
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   615
    range = parse_generate_range(parts.pop(0))
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   616
276
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   617
    lhs_func = parse_generate_field(parts.pop(0), line=line)
8db56588cefc pvl.dns.zone: factor out parse_generate_range
Tero Marttila <terom@paivola.fi>
parents: 274
diff changeset
   618
    rhs_func = parse_generate_field(parts.pop(-1), line=line)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   619
    body = parts
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   620
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   621
    for i in range :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   622
        # build
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   623
        parts = [lhs_func(i)] + body + [rhs_func(i)]
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   624
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   625
        log.debug(" %03d: %r", i, parts)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   626
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   627
        # parse
252
0ea4450fdd40 pvl.dns-zone: --serial
Tero Marttila <terom@paivola.fi>
parents: 251
diff changeset
   628
        yield ZoneRecord.parse(line, parts=parts, origin=origin)
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   629
250
65f0272ce458 pvl.dns.zone: move to ZoneLine/Record.load(file)
Tero Marttila <terom@paivola.fi>
parents: 248
diff changeset
   630
   
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   631
def reverse_ipv4 (ip) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   632
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   633
        Return in-addr.arpa reverse for given IPv4 prefix.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   634
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   635
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   636
    # parse
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   637
    octets = tuple(int(part) for part in ip.split('.'))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   638
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   639
    for octet in octets :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   640
        assert 0 <= octet <= 255
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   641
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   642
    return '.'.join([str(octet) for octet in reversed(octets)] + ['in-addr', 'arpa'])
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   643
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   644
def reverse_ipv6 (ip6) :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   645
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   646
        Return ip6.arpa reverse for given IPv6 prefix.
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   647
    """
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   648
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   649
    parts = [int(part, 16) for part in ip6.split(':')]
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   650
    parts = ['{0:04x}'.format(part) for part in parts]
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   651
    parts = ''.join(parts)
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   652
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   653
    return '.'.join(tuple(reversed(parts)) + ( 'ip6', 'arpa'))
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   654
286
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   655
# TODO: support fqdns in parts
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   656
def join (*parts) :
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   657
    """
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   658
        Join a domain name from labels.
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   659
    """
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   660
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   661
    return '.'.join(str(part) for part in parts)
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   662
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   663
def fqdn (*parts) :
286
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   664
    """
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   665
        Return an FQND from parts, ending in .
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   666
    """
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   667
295
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   668
    fqdn = join(*parts)
286
850bd4632613 pvl.dns.zone.join
Tero Marttila <terom@paivola.fi>
parents: 279
diff changeset
   669
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   670
    # we may be given an fqdn in parts
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   671
    if not fqdn.endswith('.') :
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   672
        fqdn += '.'
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   673
    
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   674
    return fqdn
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   675
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   676
def reverse_label (prefix, address) :
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   677
    """
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   678
        Determine the correct label for the given IP address within the reverse zone for the given prefix.
247
08a63738f2d1 split pvl.dns-zone into pvl.dns.zone
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   679
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   680
        This includes all suffix octets (partially) covered by the prefix.
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   681
    """
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   682
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   683
    assert prefix.version == address.version
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   684
    
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   685
    hostbits = prefix.max_prefixlen - prefix.prefixlen
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   686
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   687
    if prefix.version == 4 :
295
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   688
        # pack into octets
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   689
        octets = [ord(x) for x in address.packed]
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   690
295
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   691
        # take the suffix
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   692
        octets = octets[-int(math.ceil(hostbits / 8.0)):]
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   693
        
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   694
        # reverse in decimal
297
63bce6f67916 pvl.dns.zone: fix ipv4 reverse_label()
Tero Marttila <terom@paivola.fi>
parents: 295
diff changeset
   695
        return '.'.join(reversed(["{0:d}".format(x) for x in octets]))
295
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   696
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   697
    elif prefix.version == 6 :
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   698
        # pack into nibbles
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   699
        nibbles = [((ord(x) >> 4) & 0xf, ord(x) & 0xf) for x in address.packed]
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   700
        nibbles = [nibble for nibblepair in nibbles for nibble in nibblepair]
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   701
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   702
        # take the suffix
298
fa1ab8cda47e pvl.dns.zone: fix ipv6 reverse_label()
Tero Marttila <terom@paivola.fi>
parents: 297
diff changeset
   703
        nibbles = nibbles[-(hostbits / 4):]
295
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   704
        
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   705
        # reverse in hex
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   706
        return '.'.join(reversed(["{0:x}".format(x) for x in nibbles]))
8c6d4565576f pvl.dns.zone: fix fqdn(); implement ipv6 reverse_label
Tero Marttila <terom@paivola.fi>
parents: 294
diff changeset
   707
270
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   708
    else :
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   709
        raise ValueError("unsupported address version: %s" % (prefix, ))
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   710
bafcda3a3c0d pvl.hosts-dns: split to pvl.dns.host, using Host class
Tero Marttila <terom@paivola.fi>
parents: 267
diff changeset
   711