bin/pvl.dns-zone
author Tero Marttila <terom@paivola.fi>
Thu, 16 May 2013 01:03:29 +0300
changeset 233 c4941645464c
child 247 08a63738f2d1
permissions -rwxr-xr-x
import pvl.dns-* scripts from pvl-dns
233
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
#!/usr/bin/env python
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
    Process zonefiles.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
"""
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
__version__ = '0.0.1-dev'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
import optparse
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
import codecs
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
from datetime import datetime
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
import logging
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
import ipaddr
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
log = logging.getLogger('main')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
# command-line options, global state
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
options = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
def parse_options (argv) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
        Parse command-line arguments.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
    prog = argv[0]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
    parser = optparse.OptionParser(
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
            prog        = prog,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
            usage       = '%prog: [options]',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
            version     = __version__,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
            # module docstring
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
            description = __doc__,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
    )
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
    # logging
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    general = optparse.OptionGroup(parser, "General Options")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
    general.add_option('-q', '--quiet',     dest='loglevel', action='store_const', const=logging.ERROR, help="Less output")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
    general.add_option('-v', '--verbose',   dest='loglevel', action='store_const', const=logging.INFO,  help="More output")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
    general.add_option('-D', '--debug',     dest='loglevel', action='store_const', const=logging.DEBUG, help="Even more output")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
    parser.add_option_group(general)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
    # input/output
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
    parser.add_option('-c', '--input-charset',  metavar='CHARSET',  default='utf-8', 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
            help="Encoding used for input files")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
    parser.add_option('-o', '--output',         metavar='FILE',     default='-',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
            help="Write to output file; default stdout")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
    parser.add_option('--output-charset',       metavar='CHARSET',  default='utf-8', 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
            help="Encoding used for output files")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
    # check stage
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
    parser.add_option('--check-hosts',          action='store_true',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
            help="Check that host/IPs are unique. Use --quiet to silence warnings, and test exit status")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
    parser.add_option('--check-exempt',         metavar='HOST', action='append',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
            help="Allow given names to have multiple records")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
    # meta stage
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
    parser.add_option('--meta-zone',            action='store_true',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            help="Generate host metadata zone; requires --input-line-date")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
    parser.add_option('--meta-ignore',          metavar='HOST', action='append',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
            help="Ignore given hostnames in metadata output")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    parser.add_option('--input-line-date',      action='store_true',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
            help="Parse timestamp prefix from each input line (e.g. `hg blame | ...`)")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
    # forward stage
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
    parser.add_option('--forward-zone',         action='store_true', 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
            help="Generate forward zone")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
    parser.add_option('--forward-txt',          action='store_true',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
            help="Generate TXT records for forward zone")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
    parser.add_option('--forward-mx',           metavar='MX',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
            help="Generate MX records for forward zone")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
    # reverse stage
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
    parser.add_option('--reverse-domain',       metavar='DOMAIN',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
            help="Domain to use for hosts in reverse zone")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
    parser.add_option('--reverse-zone',         metavar='NET',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
            help="Generate forward zone for given subnet (x.z.y | a:b:c:d)")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
    # 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
    parser.add_option('--doctest',              action='store_true',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
            help="Run module doctests")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
    # defaults
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
    parser.set_defaults(
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
        loglevel            = logging.WARN,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        # XXX: combine
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        check_exempt        = [],
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
        meta_ignore         = [],
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
    )
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
    # parse
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
    options, args = parser.parse_args(argv[1:])
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
    # configure
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
    logging.basicConfig(
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
        format  = prog + ': %(name)s: %(levelname)s %(funcName)s : %(message)s',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
        level   = options.loglevel,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
    )
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
    return options, args
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
class ZoneError (Exception) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
    pass
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
class ZoneLineError (ZoneError) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
        ZoneLine-related error
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
    def __init__ (self, line, msg, *args, **kwargs) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   123
        super(ZoneLineError, self).__init__("%s: %s" % (line, msg.format(*args, **kwargs)))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   124
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   125
class ZoneLine (object) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   127
        A line in a zonefile.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
    file = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
    lineno = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
    # data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
    indent = None # was the line indented?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   135
    data = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
    parts = None # split line fields
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
    # optional
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
    timestamp = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
    comment = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
    PARSE_DATETIME_FORMAT = '%Y-%m-%d'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
    @classmethod
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
    def parse (cls, file, lineno, line, line_timestamp_prefix=False) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   146
        """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
            Parse out given line and build.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
        """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
        log.debug("parse: %s:%d: %s", file, lineno, line)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   152
        ts = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
        if line_timestamp_prefix :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   155
            if ': ' not in line :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
                raise ZoneError("%s:%d: Missing timestamp prefix: %s" % (file, lineno, line))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
            # split prefix
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
            prefix, line = line.split(': ', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
            # parse it out
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
            ts = datetime.strptime(prefix, cls.PARSE_DATETIME_FORMAT)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   164
            log.debug("  ts=%r", ts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   165
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
        # was line indented?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
        indent = line.startswith(' ') or line.startswith('\t')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
        # strip
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
        line = line.strip()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
        log.debug("  indent=%r, line=%r", indent, line)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
        # parse comment out?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        if ';' in line :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
            line, comment = line.split(';', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
            line = line.strip()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
            comment = comment.strip()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
            line = line.strip()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
            comment = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   184
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   185
        log.debug("  line=%r, comment=%r", line, comment)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   186
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   187
        # parse fields
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   188
        if '"' in line :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   189
            pre, data, post = line.split('"', 2)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   190
            parts = pre.split() + [data] + post.split()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   191
           
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   192
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   193
            parts = line.split()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   194
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   195
        log.debug("  parts=%r", parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   196
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   197
        # build
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   198
        return cls(file, lineno, indent, line, parts, timestamp=ts, comment=comment)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   199
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   200
    def __init__ (self, file, lineno, indent, data, parts, timestamp=None, comment=None) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   201
        self.file = file
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   202
        self.lineno = lineno
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   203
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   204
        self.indent = indent
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
        self.data = data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
        self.parts = parts
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
        self.timestamp = timestamp
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
        self.comment = comment
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   211
    def __str__ (self) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   212
        return "{file}:{lineno}".format(file=self.file, lineno=self.lineno)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   213
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   214
class ZoneRecord (object) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   215
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   216
        A record from a zonefile.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
    # the underlying line
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
    line = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
    # possible $ORIGIN context
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
    origin = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   225
    # record fields
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
    name = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
    type = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
    # list of data fields
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
    data = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
    # optional
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
    ttl = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
    cls = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
    @classmethod
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
    def parse (cls, line, parts=None, origin=None) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
        """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
            Parse from ZoneLine. Returns None if there is no record on the line..
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   240
        """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   241
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
        if parts is None :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
            parts = list(line.parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
        if not parts :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
            # skip
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
            return
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
        # XXX: indented lines keep name from previous record
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
        if line.indent :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
            name = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
            name = parts.pop(0)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256
        log.debug("  name=%r, origin=%r", name, origin)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   258
        if len(parts) < 2 :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
            raise ZoneLineError(line, "Too few parts to parse: {0!r}", line.data)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
        # parse ttl/cls/type
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
        ttl = _cls = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
        if parts and parts[0][0].isdigit() :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
            ttl = parts.pop(0)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   266
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
        if parts and parts[0].upper() in ('IN', 'CH') :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
            _cls = parts.pop(0)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   269
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
        # always have type
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
        type = parts.pop(0)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   272
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   273
        # remaining parts are data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   274
        data = parts
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   275
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   276
        log.debug("  ttl=%r, cls=%r, type=%r, data=%r", ttl, _cls, type, data)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   278
        return cls(name, type, data,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   279
            origin  = origin,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   280
            ttl     = ttl,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   281
            cls     = _cls,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   282
            line    = line,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   283
        )
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   284
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   285
    def __init__ (self, name, type, data, origin=None, ttl=None, cls=None, line=None, comment=None) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   286
        self.name = name
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   287
        self.type = type
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   288
        self.data = data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   289
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
        self.ttl = ttl
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   291
        self.cls = cls
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   292
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   293
        self.origin = origin
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   294
        self.line = line
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   295
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   296
        # XXX: within line
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   297
        self._comment = comment
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   298
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   299
    def build_line (self) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   300
        """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   301
            Construct a zonefile-format line..."
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   302
        """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   303
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   304
        # XXX: comment?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   305
        if self._comment :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   306
            comment = '\t; ' + self._comment
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   307
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   308
            comment = ''
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   309
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   310
        return u"{name:25} {ttl:4} {cls:2} {type:5} {data}{comment}".format(
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   311
                name    = self.name or '',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   312
                ttl     = self.ttl or '',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   313
                cls     = self.cls or '',
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   314
                type    = self.type,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   315
                data    = ' '.join(unicode(data) for data in self.data),
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   316
                comment = comment,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   317
        )
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   318
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   319
    def __str__ (self) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   320
        return ' '.join((self.name or '', self.type, ' '.join(self.data)))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   321
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   322
class TXTRecord (ZoneRecord) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   323
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   324
        TXT record.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   325
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   326
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   327
    def __init__ (self, name, text, **opts) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   328
        return super(TXTRecord, self).__init__(name, 'TXT', 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   329
            [u'"{0}"'.format(text.replace('"', '\\"'))], 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   330
            **opts
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   331
        )
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   332
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   333
class OffsetValue (object) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   334
    def __init__ (self, value) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   335
        self.value = value
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   336
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   337
    def __getitem__ (self, offset) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   338
        value = self.value + offset
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   339
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   340
        #log.debug("OffsetValue: %d[%d] -> %d", self.value, offset, value)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   341
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
        return value
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   343
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   344
def parse_generate_field (line, field) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   345
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   346
        Parse a $GENERATE lhs/rhs field:
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   347
            $
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   348
            ${<offset>[,<width>[,<base>]]}
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   349
            \$
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   350
            $$
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   351
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   352
        Returns a wrapper that builds the field-value when called with the index.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   353
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   354
        >>> parse_generate_field(None, "foo")(1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   355
        'foo'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   356
        >>> parse_generate_field(None, "foo-$")(1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   357
        'foo-1'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   358
        >>> parse_generate_field(None, "foo-$$")(1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   359
        'foo-$'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   360
        >>> parse_generate_field(None, "\$")(1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   361
        '$'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   362
        >>> parse_generate_field(None, "10.0.0.${100}")(1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   363
        '10.0.0.101'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   364
        >>> parse_generate_field(None, "foo-${0,2,d}")(1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   365
        'foo-01'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   366
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   367
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   368
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   369
    input = field
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   370
    expr = []
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   371
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   372
    while '$' in field :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   373
        # defaults
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   374
        offset = 0
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   375
        width = 0
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   376
        base = 'd'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   377
        escape = False
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   378
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   379
        # different forms
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   380
        if '${' in field :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   381
            pre, body = field.split('${', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   382
            body, post = body.split('}', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   383
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   384
            # parse body
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   385
            parts = body.split(',')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   386
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   387
            # offset
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   388
            offset = int(parts.pop(0))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   389
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   390
            # width
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   391
            if parts :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   392
                width = int(parts.pop(0))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   393
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
            # base
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   395
            if parts :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
                base = parts.pop(0)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   397
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   398
            if parts:
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   399
                # fail
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   400
                raise ZoneLineError(line, "extra data in ${...} body: {0!r}", parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   401
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   402
        elif '$$' in field :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   403
            pre, post = field.split('$$', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   404
            escape = True
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   405
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   406
        elif '\\$' in field :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   407
            pre, post = field.split('\\$', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   408
            escape = True
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   409
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   410
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   411
            pre, post = field.split('$', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   412
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   413
        expr.append(pre)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   414
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   415
        if escape :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   416
            expr.append('$')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   417
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   418
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   419
            # meta-format
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   420
            fmt = '{value[%d]:0%d%s}' % (offset, width, base)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   421
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   422
            log.debug("field=%r -> pre=%r, fmt=%r, post=%r", field, expr, fmt, post)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   423
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   424
            expr.append(fmt)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   425
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   426
        field = post
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   427
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   428
    # final
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   429
    if field :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   430
        expr.append(field)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   431
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   432
    # combine
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   433
    expr = ''.join(expr)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   434
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   435
    log.debug("%s: %s", input, expr)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   436
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   437
    # processed
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   438
    def value_func (value) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   439
        # magic wrapper to implement offsets
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   440
        return expr.format(value=OffsetValue(value))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   441
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   442
    return value_func
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   443
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   444
def process_generate (line, origin, parts) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   445
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   446
        Process a 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   447
            $GENERATE <start>-<stop>[/<step>] lhs [ttl] [class] type rhs [comment]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   448
        directive into a series of ZoneResource's.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   449
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   450
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   451
    range = parts.pop(0)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   452
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   453
    # parse range
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   454
    if '/' in range :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   455
        range, step = range.split('/')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   456
        step = int(step)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   457
    else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   458
        step = 1
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   459
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   460
    start, stop = range.split('-')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   461
    start = int(start)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   462
    stop = int(stop)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   463
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   464
    log.debug("  range: start=%r, stop=%r, step=%r", start, stop, step)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   465
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   466
    # inclusive
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   467
    range = xrange(start, stop + 1, step)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   468
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   469
    lhs_func = parse_generate_field(line, parts.pop(0))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   470
    rhs_func = parse_generate_field(line, parts.pop(-1))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   471
    body = parts
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   472
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   473
    for i in range :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   474
        # build
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   475
        parts = [lhs_func(i)] + body + [rhs_func(i)]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   476
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   477
        log.debug(" %03d: %r", i, parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   478
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   479
        # parse
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   480
        yield ZoneRecord.parse(line, parts=parts, origin=origin)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   481
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   482
def parse_zone_records (file, origin=None, **opts) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   483
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   484
        Parse ZoneRecord items from the given zonefile, ignoring non-record lines.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   485
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   486
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   487
    ttl = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   488
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   489
    skip_multiline = False
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   490
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   491
    for lineno, raw_line in enumerate(file) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   492
        # parse comment
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   493
        if ';' in raw_line :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   494
            line, comment = raw_line.split(';', 1)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   495
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   496
            line = raw_line
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   497
            comment = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   498
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   499
        # XXX: handle multi-line statements...
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   500
        # start
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   501
        if '(' in line :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   502
            skip_multiline = True
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   503
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   504
            log.warn("%s:%d: Start of multi-line statement: %s", file.name, lineno, raw_line)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   505
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   506
        # end?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   507
        if ')' in line :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   508
            skip_multiline = False
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   509
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   510
            log.warn("%s:%d: End of multi-line statement: %s", file.name, lineno, raw_line)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   511
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   512
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   513
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   514
        elif skip_multiline :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   515
            log.warn("%s:%d: Multi-line statement: %s", file.name, lineno, raw_line)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   516
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   517
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   518
        
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   519
        # parse
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   520
        line = ZoneLine.parse(file.name, lineno, raw_line, **opts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   521
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   522
        if not line.data :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   523
            log.debug("%s: skip empty line: %s", line, raw_line)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   524
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   525
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   526
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   527
        elif line.data.startswith('$') :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   528
            # control record
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   529
            type = line.parts[0]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   530
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   531
            if type == '$ORIGIN':
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   532
                # update
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   533
                origin = line.parts[1]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   534
                
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   535
                log.info("%s: origin: %s", line, origin)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   536
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   537
            elif type == '$GENERATE':
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   538
                # process...
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   539
                log.info("%s: generate: %s", line, line.parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   540
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   541
                for record in process_generate(line, origin, line.parts[1:]) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   542
                    yield record
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   543
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   544
            else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   545
                log.warning("%s: skip control record: %s", line, line.data)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   546
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   547
            # XXX: passthrough!
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   548
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   549
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   550
        # normal record?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   551
        record = ZoneRecord.parse(line, origin=origin)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   552
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   553
        if record :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   554
            yield record
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   555
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   556
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   557
            # unknown
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   558
            log.warning("%s: skip unknown line: %s", line, line.data)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   559
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   560
def check_zone_hosts (zone, whitelist=None, whitelist_types=set(['TXT'])) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   561
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   562
        Parse host/IP pairs from the zone, and verify that they are unique.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   563
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   564
        As an exception, names listed in the given whitelist may have multiple IPs.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   565
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   566
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   567
    by_name = {}
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   568
    by_ip = {}
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   569
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   570
    fail = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   571
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   572
    last_name = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   573
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   574
    for r in zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   575
        name = r.name or last_name
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   576
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   577
        name = (r.origin, name)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   578
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   579
        # name
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   580
        if r.type not in whitelist_types :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   581
            if name not in by_name :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   582
                by_name[name] = r
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   583
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   584
            elif r.name in whitelist :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   585
                log.debug("Duplicate whitelist entry: %s", r)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   586
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   587
            else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   588
                # fail!
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   589
                log.warn("%s: Duplicate name: %s <-> %s", r.line, r, by_name[name])
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   590
                fail = True
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   591
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   592
        # ip
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   593
        if r.type == 'A' :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   594
            ip, = r.data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   595
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   596
            if ip not in by_ip :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   597
                by_ip[ip] = r
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   598
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   599
            else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   600
                # fail!
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   601
                log.warn("%s: Duplicate IP: %s <-> %s", r.line, r, by_ip[ip])
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   602
                fail = True
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   603
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   604
    return fail
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   605
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   606
def process_zone_forwards (zone, txt=False, mx=False) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   607
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   608
        Process zone data -> forward zone data.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   609
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   610
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   611
    for r in zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   612
        yield r
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   613
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   614
        if r.type == 'A' :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   615
            if txt :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   616
                # comment?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   617
                comment = r.line.comment
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   618
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   619
                if comment :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   620
                    yield TXTRecord(None, comment, ttl=r.ttl)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   621
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   622
           
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   623
            # XXX: RP, do we need it?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   624
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   625
            if mx :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   626
                # XXX: is this a good idea?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   627
                yield ZoneRecord(None, 'MX', [10, mx], ttl=r.ttl)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   628
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   629
def process_zone_meta (zone, ignore=None) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   630
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   631
        Process zone metadata -> output.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   632
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   633
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   634
    TIMESTAMP_FORMAT='%Y/%m/%d'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   635
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   636
    for r in zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   637
        if ignore and r.name in ignore :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   638
            # skip
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   639
            log.debug("Ignore record: %s", r)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   640
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   641
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   642
        # for hosts..
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   643
        if r.type == 'A' :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   644
            # timestamp?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   645
            timestamp = r.line.timestamp
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   646
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   647
            if timestamp :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   648
                yield TXTRecord(r.name, timestamp.strftime(TIMESTAMP_FORMAT), ttl=r.ttl)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   649
     
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   650
def reverse_ipv4 (ip) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   651
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   652
        Return in-addr.arpa reverse for given IPv4 prefix.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   653
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   654
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   655
    # parse
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   656
    octets = tuple(int(part) for part in ip.split('.'))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   657
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   658
    for octet in octets :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   659
        assert 0 <= octet <= 255
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   660
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   661
    return '.'.join([str(octet) for octet in reversed(octets)] + ['in-addr', 'arpa'])
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   662
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   663
def reverse_ipv6 (ip6) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   664
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   665
        Return ip6.arpa reverse for given IPv6 prefix.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   666
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   667
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   668
    parts = [int(part, 16) for part in ip6.split(':')]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   669
    parts = ['{0:04x}'.format(part) for part in parts]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   670
    parts = ''.join(parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   671
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   672
    return '.'.join(tuple(reversed(parts)) + ( 'ip6', 'arpa'))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   673
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   674
def fqdn (*parts) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   675
    fqdn = '.'.join(parts)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   676
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   677
    # we may be given an fqdn in parts
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   678
    if not fqdn.endswith('.') :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   679
        fqdn += '.'
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   680
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   681
    return fqdn
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   682
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   683
def process_zone_reverse (zone, origin, domain) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   684
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   685
        Process zone data -> reverse zone data.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   686
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   687
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   688
    name = None
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   689
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   690
    for r in zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   691
        # keep name from previous..
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   692
        if r.name :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   693
            name = r.name
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   694
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   695
        if r.type == 'A' :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   696
            ip, = r.data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   697
            ptr = reverse_ipv4(ip)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   698
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   699
        elif r.type == 'AAAA' :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   700
            ip, = r.data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   701
            ptr = reverse_ipv6(ip)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   702
            
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   703
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   704
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   705
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   706
        # verify
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   707
        if zone and ptr.endswith(origin) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   708
            ptr = ptr[:-(len(origin) + 1)]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   709
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   710
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   711
            log.warning("Reverse does not match zone origin, skipping: (%s) -> %s <-> %s", ip, ptr, origin)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   712
            continue
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   713
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   714
        # domain to use
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   715
        host_domain = r.origin or domain
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   716
        host_fqdn = fqdn(name, host_domain)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   717
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   718
        yield ZoneRecord(ptr, 'PTR', [host_fqdn])
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   719
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   720
def write_zone_records (file, zone) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   721
    for r in zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   722
        file.write(r.build_line() + u'\n')
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   723
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   724
def open_file (path, mode, charset) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   725
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   726
        Open unicode-enabled file from path, with - using stdio.
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   727
    """
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   728
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   729
    if path == '-' :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   730
        # use stdin/out based on mode
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   731
        stream, func = {
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   732
            'r':    (sys.stdin, codecs.getreader),
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   733
            'w':    (sys.stdout, codecs.getwriter),
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   734
        }[mode[0]]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   735
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   736
        # wrap
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   737
        return func(charset)(stream)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   738
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   739
    else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   740
        # open
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   741
        return codecs.open(path, mode, charset)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   742
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   743
def main (argv) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   744
    global options
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   745
    
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   746
    options, args = parse_options(argv)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   747
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   748
    if options.doctest :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   749
        import doctest
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   750
        fail, total = doctest.testmod()
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   751
        return fail
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   752
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   753
    if args :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   754
        # open files
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   755
        input_files = [open_file(path, 'r', options.input_charset) for path in args]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   756
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   757
    else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   758
        # default to stdout
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   759
        input_files = [open_file('-', 'r', options.input_charset)]
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   760
   
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   761
    # process zone data
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   762
    zone = []
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   763
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   764
    for file in input_files :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   765
        log.info("Reading zone: %s", file)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   766
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   767
        zone += list(parse_zone_records(file, 
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   768
            line_timestamp_prefix   = options.input_line_date,
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   769
        ))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   770
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   771
    # check?
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   772
    if options.check_hosts :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   773
        whitelist = set(options.check_exempt)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   774
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   775
        log.debug("checking hosts; whitelist=%r", whitelist)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   776
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   777
        if check_zone_hosts(zone, whitelist=whitelist) :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   778
            log.warn("Hosts check failed")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   779
            return 2
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   780
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   781
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   782
            log.info("Hosts check OK")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   783
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   784
    # output file
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   785
    output = open_file(options.output, 'w', options.output_charset)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   786
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   787
    if options.forward_zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   788
        log.info("Write forward zone: %s", output)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   789
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   790
        zone = list(process_zone_forwards(zone, txt=options.forward_txt, mx=options.forward_mx))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   791
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   792
    elif options.meta_zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   793
        log.info("Write metadata zone: %s", output)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   794
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   795
        if not options.input_line_date :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   796
            log.error("--meta-zone requires --input-line-date")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   797
            return 1
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   798
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   799
        zone = list(process_zone_meta(zone, ignore=set(options.meta_ignore)))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   800
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   801
    elif options.reverse_zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   802
        if ':' in options.reverse_zone :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   803
            # IPv6
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   804
            origin = reverse_ipv6(options.reverse_zone)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   805
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   806
        else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   807
            # IPv4
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   808
            origin = reverse_ipv4(options.reverse_zone)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   809
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   810
        domain = options.reverse_domain
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   811
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   812
        if not domain :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   813
            log.error("--reverse-zone requires --reverse-domain")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   814
            return 1
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   815
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   816
        zone = list(process_zone_reverse(zone, origin=origin, domain=domain))
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   817
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   818
    elif options.check_hosts :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   819
        # we only did that, done
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   820
        return 0
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   821
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   822
    else :
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   823
        log.warn("Nothing to do")
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   824
        return 1
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   825
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   826
    write_zone_records(output, zone)
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   827
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   828
    return 0
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   829
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   830
if __name__ == '__main__':
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   831
    import sys
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   832
c4941645464c import pvl.dns-* scripts from pvl-dns
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   833
    sys.exit(main(sys.argv))