bin/process-zone
author Tero Marttila <terom@paivola.fi>
Fri, 16 Mar 2012 15:03:11 +0200
changeset 12 bddc9a060a73
parent 4 3a2221124592
child 23 91c073d5615a
permissions -rwxr-xr-x
process-zone: implement --check-hosts; fix logging processName
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
#!/usr/bin/env python
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
    Process zonefiles.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
"""
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
__version__ = '0.0.1-dev'
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
import optparse
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
import codecs
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
import logging
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    13
log = logging.getLogger('main')
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
# command-line options, global state
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
options = None
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
def parse_options (argv) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
        Parse command-line arguments.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    23
    prog = argv[0]
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    24
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
    parser = optparse.OptionParser(
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    26
            prog        = prog,
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
            usage       = '%prog: [options]',
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
            version     = __version__,
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
            # module docstring
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
            description = __doc__,
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
    )
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
    # logging
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
    general = optparse.OptionGroup(parser, "General Options")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
    37
    general.add_option('-q', '--quiet',     dest='loglevel', action='store_const', const=logging.ERROR, help="Less output")
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    general.add_option('-v', '--verbose',   dest='loglevel', action='store_const', const=logging.INFO,  help="More output")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
    general.add_option('-D', '--debug',     dest='loglevel', action='store_const', const=logging.DEBUG, help="Even more output")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
    parser.add_option_group(general)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    43
    # input/output
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
    parser.add_option('-c', '--input-charset',  metavar='CHARSET',  default='utf-8', 
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
            help="Encoding used for input files")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
    parser.add_option('-o', '--output',         metavar='FILE',     default='-',
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
            help="Write to output file; default stdout")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
    parser.add_option('--output-charset',       metavar='CHARSET',  default='utf-8', 
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
            help="Encoding used for output files")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    53
    # check stage
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    54
    parser.add_option('--check-hosts',          action='store_true',
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    55
            help="Check that host/IPs are unique. Use --quiet to silence warnings, and test exit status")
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    56
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    57
    parser.add_option('--check-exempt',         action='append',
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    58
            help="Allow given names to have multiple records")
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    59
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    60
    # forward stage
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
    parser.add_option('--forward-zone',         action='store_true', 
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
            help="Generate forward zone")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
    parser.add_option('--forward-txt',          action='store_true',
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            help="Generate TXT records for forward zone")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
    parser.add_option('--forward-mx',           metavar='MX',
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
            help="Generate MX records for forward zone")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    70
    # reverse stage
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
    parser.add_option('--reverse-domain',       metavar='DOMAIN',
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
            help="Domain to use for hosts in reverse zone")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
    parser.add_option('--reverse-zone',         metavar='NET',
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
            help="Generate forward zone for given subnet (x.z.y)")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
    # defaults
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
    parser.set_defaults(
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
    79
        loglevel            = logging.WARN,
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    80
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    81
        check_exempt        = [],
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
    )
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
    # parse
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
    options, args = parser.parse_args(argv[1:])
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
    # configure
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
    logging.basicConfig(
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    89
        format  = prog + ': %(name)s: %(levelname)s %(funcName)s : %(message)s',
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
        level   = options.loglevel,
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
    )
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
    return options, args
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
def parse_record (line) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
        Parse (name, ttl, type, data, comment) from bind zonefile.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        Returns None for empty/comment lines.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
    # was line indented?
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
    indent = line.startswith(' ') or line.startswith('\t')
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
    # strip
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
    line = line.strip()
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
    if not line or line.startswith(';') :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
        # skip
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        return
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
    #log.debug("line=%r", line)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
    # parse comment out
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
    parts = line.split(';', 1)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
    if ';' in line :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
        data, comment = line.split(';', 1)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
        line = data.rstrip()
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
        comment = comment.strip()
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   123
    else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   124
        line = line.rstrip()
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   125
        comment = None
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   127
    #log.debug("line=%r, comment=%r", line, comment)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
    # parse data out?
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
    if '"' in line :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
        line, data, end = line.split('"')
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
        parts = line.split()
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
       
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
    else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   135
        parts = line.split()
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
        data = parts.pop(-1)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
    #log.debug("parts=%r, data=%r", parts, data)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
    # indented lines don't have name
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
    if indent :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
        name = None
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
    else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
        name = parts.pop(0)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   146
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
    #log.debug("name=%r", name)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
    # parse ttl/cls/type
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
    ttl = cls = None
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   152
    if parts and parts[0][0].isdigit() :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
        ttl = parts.pop(0)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   155
    if parts and parts[0].upper() in ('IN', 'CH') :
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
        cls = parts.pop(0)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   158
    type = parts.pop(0)
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   159
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
    #log.debug("ttl=%r, cls=%r, parts=%r", ttl, cls, parts)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
    if parts :
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   163
        log.debug("extra data: %r + %r", parts, data)
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   164
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   165
        # extra data
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   166
        data = ' '.join(parts + [data])
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   167
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
    return name, ttl, type, data, comment
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
def parse_zone (file) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
        Parse
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
            (name, ttl, type, data, comment) 
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        data from zonefile.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
    for lineno, line in enumerate(file) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
        data = parse_record(line)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
        if data :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
            yield data
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   184
def check_zone_hosts (zone, whitelist=None) :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   185
    """
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   186
        Parse host/IP pairs from the zone, and verify that they are unique.
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   187
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   188
        As an exception, names listed in the given whitelist may have multiple IPs.
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   189
    """
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   190
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   191
    by_name = {}
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   192
    by_ip = {}
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   193
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   194
    fail = None
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   195
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   196
    for item in zone :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   197
        text = ' '.join(pp for pp in item if pp)
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   198
        name, ttl, type, data, comment = item
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   199
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   200
        # name
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   201
        if name not in by_name :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   202
            by_name[name] = text
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   203
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   204
        elif name in whitelist :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   205
            log.debug("Duplicate whitelist entry: %r", item)
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   206
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   207
        else :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   208
            # fail!
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   209
            log.warn("Duplicate name: %s <-> %s", text, by_name[name])
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   210
            fail = True
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   211
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   212
        # ip
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   213
        if type == 'A' :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   214
            ip = data
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   215
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   216
            if ip not in by_ip :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   217
                by_ip[ip] = text
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   218
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   219
            else :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   220
                # fail!
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   221
                log.warn("Duplicate IP: %s <-> %s", text, by_ip[ip])
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   222
                fail = True
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   223
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   224
    return fail
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   225
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
def process_zone_forwards (zone, txt=False, mx=False) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
        Process zone data -> forward zone data.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
    for name, ttl, type, data, comment in zone :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
        yield name, ttl, type, data
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
        if type == 'A' :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
            if txt and comment :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
                # name
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
                yield None, ttl, 'TXT', u'"{0}"'.format(comment)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
            
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
            # XXX: RP, do we need it?
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   240
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   241
            if mx :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
                # XXX: is this a good idea?
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
                yield None, ttl, 'MX', '10 {mx}'.format(mx=mx)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
def reverse_addr (ip) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
        Return in-addr.arpa reverse for given IPv4 IP.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
    # parse
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
    octets = tuple(int(part) for part in ip.split('.'))
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
    for octet in octets :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
        assert 0 <= octet <= 255
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256
    return '.'.join([str(octet) for octet in reversed(octets)] + ['in-addr', 'arpa'])
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   258
def fqdn (*parts) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
    return '.'.join(parts) + '.'
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
def process_zone_reverse (zone, origin, domain) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
        Process zone data -> reverse zone data.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   266
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
    for name, ttl, type, data, comment in zone :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
        if type != 'A' :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   269
            continue
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
        ip = data
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   272
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   273
        # generate reverse-addr
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   274
        reverse = reverse_addr(ip)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   275
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   276
        # verify
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
        if zone and reverse.endswith(origin) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   278
            reverse = reverse[:-(len(origin) + 1)]
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   279
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   280
        else :
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   281
            log.warning("Reverse does not match zone origin, skipping: (%s) -> %s <-> %s", ip, reverse, origin)
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   282
            continue
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   283
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   284
        # domain to use
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   285
        host_domain = domain
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   286
        host_fqdn = fqdn(name, domain)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   287
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   288
        yield reverse, 'PTR', host_fqdn
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   289
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
def build_zone (zone) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   291
    for item in zone :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   292
        ttl = cls = comment = None
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   293
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   294
        if len(item) == 3 :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   295
            name, type, data = item
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   296
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   297
        elif len(item) == 4 :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   298
            name, ttl, type, data = item
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   299
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   300
        elif len(item) == 5 :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   301
            name, ttl, type, data, comment = item
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   302
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   303
        else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   304
            raise Exception("Weird zone entry: {0}".format(item))
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   305
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   306
        if not name :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   307
            name = ''
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   308
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   309
        if not ttl :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   310
            ttl = ''
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   311
        
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   312
        if not cls :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   313
            cls = ''
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   314
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   315
        if comment :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   316
            comment = '\t;' + comment
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   317
        else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   318
            comment = ''
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   319
        
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   320
        yield u"{name:25} {ttl:4} {cls:2} {type:5} {data}{comment}".format(name=name, ttl=ttl, cls=cls, type=type, data=data, comment=comment)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   321
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   322
def write_zone (file, zone) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   323
    for line in build_zone(zone) :
4
3a2221124592 process-zone: fix parts handling; default to logging.WARN, cleanup
Tero Marttila <terom@paivola.fi>
parents: 0
diff changeset
   324
        file.write(line + u'\n')
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   325
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   326
def open_file (path, mode, charset) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   327
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   328
        Open unicode-enabled file from path, with - using stdio.
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   329
    """
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   330
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   331
    if path == '-' :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   332
        # use stdin/out based on mode
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   333
        stream, func = {
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   334
            'r':    (sys.stdin, codecs.getreader),
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   335
            'w':    (sys.stdout, codecs.getwriter),
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   336
        }[mode[0]]
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   337
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   338
        # wrap
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   339
        return func(charset)(stream)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   340
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   341
    else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
        # open
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   343
        return codecs.open(path, mode, charset)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   344
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   345
def main (argv) :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   346
    global options
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   347
    
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   348
    options, args = parse_options(argv)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   349
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   350
    if args :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   351
        # open files
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   352
        input_files = [open_file(path, 'r', options.input_charset) for path in args]
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   353
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   354
    else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   355
        # default to stdout
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   356
        input_files = [open_file('-', 'r', options.input_charset)]
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   357
   
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   358
    # process zone data
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   359
    zone = []
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   360
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   361
    for file in input_files :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   362
        log.info("Reading zone: %s", file)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   363
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   364
        zone += list(parse_zone(file))
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   365
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   366
    # check?
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   367
    if options.check_hosts :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   368
        whitelist = set(options.check_exempt)
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   369
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   370
        log.debug("checking hosts; whitelist=%r", whitelist)
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   371
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   372
        if check_zone_hosts(zone, whitelist=whitelist) :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   373
            log.warn("Hosts check failed")
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   374
            return 2
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   375
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   376
        else :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   377
            log.info("Hosts check OK")
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   378
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   379
    # output file
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   380
    output = open_file(options.output, 'w', options.output_charset)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   381
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   382
    if options.forward_zone :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   383
        log.info("Write forward zone: %s", output)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   384
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   385
        zone = list(process_zone_forwards(zone, txt=options.forward_txt, mx=options.forward_mx))
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   386
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   387
    elif options.reverse_zone :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   388
        origin = reverse_addr(options.reverse_zone)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   389
        domain = options.reverse_domain
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   390
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   391
        if not domain :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   392
            log.error("--reverse-zone requires --reverse-domain")
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   393
            return 1
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   395
        zone = list(process_zone_reverse(zone, origin=origin, domain=domain))
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   397
    elif options.check_hosts :
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   398
        # we only did that, done
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   399
        return 0
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   400
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   401
    else :
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   402
        log.warn("Nothing to do")
12
bddc9a060a73 process-zone: implement --check-hosts; fix logging processName
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   403
        return 1
0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   404
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   405
    write_zone(output, zone)
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   406
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   407
    return 0
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   408
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   409
if __name__ == '__main__':
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   410
    import sys
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   411
f0ac5a96fb19 process-zone: forward/reverse zonefile operations
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   412
    sys.exit(main(sys.argv))