pvl/dns/serial.py
author Tero Marttila <terom@paivola.fi>
Mon, 09 Mar 2015 23:31:13 +0200
changeset 738 3104fdf7ea26
parent 245 5c1c57bc510a
permissions -rw-r--r--
pvl.hosts.hosts: drop support for instanced ip.* in favor of improved interface:ip.* =
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    Generating zone serials.
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
import datetime
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
import logging; log = logging.getLogger('pvl.dns.serial')
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
# date fmt to use in serial
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
DATE_FMT = '%Y%m%d'
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
DATE_LEN = 8
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
SERIAL_FMT = "{date:8}{count:02}"
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
SERIAL_LEN = 10
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
def format_serial (date, count) :
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    17
    """
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    18
        Format serial as string.
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    19
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    20
        >>> format_serial(datetime.date(2013, 9, 10), 0)
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    21
        '2013091000'
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    22
        >>> format_serial(datetime.date(2013, 9, 10), 1)
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    23
        '2013091001'
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    24
    """
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    25
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    26
    assert 0 <= count <= 99
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    27
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
    return SERIAL_FMT.format(date=date.strftime(DATE_FMT), count=count)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    30
def next_serial (date, count) :
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
    """
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
        Return serial with next count.
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    33
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    34
        >>> next_serial(datetime.date(2013, 9, 10), 1)
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    35
        '2013091002'
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    36
        >>> next_serial(datetime.date(2013, 9, 10), 99)
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    37
        '2013091100'
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    """
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
    # check
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    42
    if count < 99 :
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    43
        return format_serial(date, count + 1)
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    44
    else:
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    45
        serial = str(int(format_serial(date, count)) + 1)
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
        log.warn("Serial count rollover: %s, %s; fallback -> %s", date, count, serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
        return serial
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    51
def update_serial (serial, today=None) :
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
    """
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
        Parse given serial number (string), returning an updated serial, based on date.
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    54
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    55
        Raises ValueError on invalid (non-numeric) serial.
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    56
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    57
        >>> print update_serial('', today=datetime.date(2013, 9, 10))
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    58
        2013091001
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    59
        >>> print update_serial('13', today=datetime.date(2013, 9, 10))
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    60
        14
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    61
        >>> print update_serial('2013083501', today=datetime.date(2013, 9, 10))
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    62
        2013083502
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    63
        >>> print update_serial('2013083102', today=datetime.date(2013, 9, 10))
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    64
        2013091001
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    65
        >>> print update_serial('2013091002', today=datetime.date(2013, 9, 10))
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    66
        2013091003
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    67
        >>> print update_serial('2013091102', today=datetime.date(2013, 9, 10))
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    68
        2013091103
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
    """
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    71
    if not today:
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
    72
        today = datetime.date.today()
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
    # handle
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
    if not serial :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
        # fresh
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
        log.info("Setting initial serial: %s01", today)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
        
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
        return format_serial(today, 1)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
    elif len(serial) != SERIAL_LEN :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
        log.warn("Invalid serial format: %s", serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
        
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        value = int(serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
        serial = str(value + 1)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
        log.info("Incrementing serial: %d -> %s", value, serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
        return serial
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
    else :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
        # parse
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
        value = int(serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        try :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
            date = datetime.datetime.strptime(serial[:DATE_LEN], DATE_FMT).date()
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
            count = int(serial[DATE_LEN:])
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        except ValueError, e :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
            # invalid date/count format?
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
            log.warn("Unable to parse serial: %s: %s", serial, e)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
            serial = str(value + 1)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
            log.info("Incrementing serial: %d -> %s", value, serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
            return serial
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
            
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
        log.debug("old serial=%s, value=%d, date=%s, count=%s", serial, value, date, count)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
    # update
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
    if date < today :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
        log.info("Updating to today: %s -> %s", date, today)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
        # update date
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
        return format_serial(today, 1)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
    elif date == today :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
        # keep date, update count
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
        log.info("Updating today's count: %s, %s", date, count)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
        
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
        # handle count rollover
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
   123
        return next_serial(date, count)
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   124
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   125
    elif date > today :
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
        # keep, update count
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
   127
        serial = next_serial(date, count)
234
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
        log.warn("Serial in future; incrementing count: %s, %s -> %s", date, count, serial)
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
        return serial
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
472f0a422234 split up pvl.dns-serial into pvl.dns.serial module
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
    else :
245
5c1c57bc510a doctest pvl.dns.serial
Tero Marttila <terom@paivola.fi>
parents: 234
diff changeset
   134
        raise Exception("Impossible serial: %s:%s", date, count)