]> mj.ucw.cz Git - pynsc.git/blob - nsconfig/util.py
Top-of-file comments
[pynsc.git] / nsconfig / util.py
1 # PyNSC: Utility functions
2 # (c) 2024 Martin Mareš <mj@ucw.cz>
3
4 import dns.name
5 from dns.name import Name
6 from ipaddress import ip_address, IPv4Address, IPv6Address, ip_network, IPv4Network, IPv6Network
7 from datetime import timedelta
8 from typing import Any, List, Optional
9
10
11 IPAddress = IPv4Address | IPv6Address
12 IPNetwork = IPv4Network | IPv6Network
13 IPAddr = str | IPAddress | List[str | IPAddress]
14
15
16 def flatten_list(args: Any) -> List[Any]:
17     def flat(args):
18         if isinstance(args, list) or isinstance(args, tuple):
19             for a in args:
20                 flat(a)
21         else:
22             out.append(args)
23
24     out: List[Any] = []
25     flat(args)
26     return out
27
28
29 def parse_address(addr: IPAddress | str) -> IPAddress:
30     if isinstance(addr, IPv4Address) or isinstance(addr, IPv6Address):
31         return addr
32     elif isinstance(addr, str):
33         return ip_address(addr)
34     else:
35         raise ValueError('Cannot parse IP address')
36
37
38 def parse_network(addr: IPNetwork | str) -> IPNetwork:
39     if isinstance(addr, IPv4Network) or isinstance(addr, IPv6Network):
40         return addr
41     elif isinstance(addr, str):
42         return ip_network(addr)
43     else:
44         raise ValueError('Cannot parse IP network')
45
46
47 def parse_name(name: str, relative: bool = False, origin: Optional[Name] = None) -> Name:
48     # FIXME: Names with escaped dots
49     if '.' in name and not relative and origin is None:
50         return dns.name.from_text(name)
51     else:
52         return dns.name.from_text(name, origin=origin)
53
54
55 def parse_duration(delta: timedelta | int) -> int:
56     if isinstance(delta, timedelta):
57         return int(delta.total_seconds())
58     elif isinstance(delta, int):
59         return delta
60     else:
61         raise ValueError('Cannot parse time duration')