experiment with mypy type annotations
[zonemaker.git] / zonemaker / zone.py
1 from typing import List, Dict, Any
2 import ipaddress, re
3
4 second = 1
5 minute = 60*second
6 hour = 60*minute
7 day = 24*hour
8
9 def hostname(name: str) -> str:
10     # check hostname for validity
11     label = r'[a-zA-Z90-9]([a-zA-Z90-9-]{0,61}[a-zA-Z90-9])?' # must not start or end with hyphen
12     pattern = r'^{0}(\.{0})*\.?'.format(label)
13     print(pattern)
14     if re.match(pattern, name):
15         return name
16     raise Exception(name+" is not a valid hostname")
17
18 class Address:
19     def __init__(self, IPv4 = None, IPv6 = None):
20         self._IPv4 = None if IPv4 is None else ipaddress.IPv4Address(IPv4)
21         self._IPv6 = None if IPv6 is None else ipaddress.IPv6Address(IPv6)
22     
23     def IPv4(self):
24         return Address(IPv4 = self._IPv4)
25     
26     def IPv6(self):
27         return Address(IPv6 = self._IPv6)
28
29 class Name:
30     def __init__(self, address = None, MX = None, TCP = None, UDP = None):
31         self._address = address
32
33 class Service:
34     def __init__(self, SRV = None, TLSA=None):
35         self._SRV = SRV
36         self._TLSA = TLSA
37
38 class CName:
39     def __init__(self, name):
40         self._name = name
41
42 class Delegation():
43     def __init__(self, NS, DS = None):
44         pass
45
46 class Zone:
47     def __init__(self, name: str, mail: str, NS: List[str],
48                  secondary_refresh: int, secondary_retry: int, secondary_discard: int,
49                  NX_TTL: int = None, A_TTL: int = None, other_TTL: int = None,
50                  domains: Dict[str, Any] = {}) -> None:
51         self._name = hostname(name)
52         if not mail.endswith('.'): raise Exception("Mail must be absolute, end with a dot")
53         atpos = mail.find('@')
54         if atpos < 0 or atpos > mail.find('.'): raise Exception("Mail must contain an @ before the first dot")
55         self._mail = hostname(mail.replace('@', '.', 1))
56         self._NS = list(map(hostname, NS))
57         
58         self._secondary_refresh = secondary_refresh
59         self._secondary_retry = secondary_retry
60         self._secondary_discard = secondary_discard
61         
62         assert other_TTL is not None
63         self._NX_TTL = other_TTL if NX_TTL is None else NX_TTL
64         self._A_TTL = other_TTL if A_TTL is None else A_TTL
65         self._other_TTL = other_TTL
66     
67     def write(self, file):
68         raise NotImplementedError()