arm-pod10: Increase MaaS deploy timeout
[pharos.git] / config / utils / gen_config_lib.py
1 ##############################################################################
2 # Copyright (c) 2018 OPNFV and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 """Library for generate_config functions and custom jinja2 filters"""
10
11 import logging
12 from ipaddress import IPv4Network, IPv4Address
13
14
15 def load_custom_filters(environment):
16     """Load all defined filters into the jinja2 enviroment"""
17
18     # TODO deprecate ipaddr_index and netmask for the better ipnet ones
19     filter_list = {
20         'dpkg_arch': filter_dpkg_arch,
21         'storage_size_num': filter_storage_size_num,
22         'ipnet_hostaddr': filter_ipnet_hostaddr,
23         'ipnet_hostmin': filter_ipnet_hostmin,
24         'ipnet_hostmax': filter_ipnet_hostmax,
25         'ipnet_broadcast': filter_ipnet_broadcast,
26         'ipnet_netmask': filter_ipnet_netmask,
27         'ipnet_contains_ip': filter_ipnet_contains_ip,
28         'ipnet_contains_iprange': filter_ipnet_contains_iprange,
29         'ipnet_range_size': filter_ipnet_range_size,
30         'ipaddr_index': filter_ipaddr_index,
31         'netmask': filter_netmask
32     }
33
34     for name, function in filter_list.items():
35         environment.filters[name] = function
36
37
38 def filter_dpkg_arch(arch, to_dpkg=True):
39     """Convert DPKG-compatible from processor arch and vice-versa"""
40
41     # Processor architecture (as reported by $(uname -m))
42     # vs DPKG architecture mapping
43     dpkg_arch_table = {
44         'aarch64': 'arm64',
45         'x86_64': 'amd64',
46     }
47     arch_dpkg_table = dict(
48         zip(dpkg_arch_table.values(), dpkg_arch_table.keys()))
49
50     if to_dpkg:
51         return dpkg_arch_table[arch]
52     else:
53         return arch_dpkg_table[arch]
54
55
56 def filter_storage_size_num(size_str):
57     """Convert human-readable size string to a string convertible to float"""
58
59     # pattern: '^[1-9][\d\.]*[MGT]B?$', multiplier=1000 (not KiB)
60     if size_str.endswith('B'):
61         size_str = size_str[:-1]
62     try:
63         size_num = 1000000
64         for multiplier in ['M', 'G', 'T']:
65             if size_str.endswith(multiplier):
66                 return '{:.2f}'.format(size_num * float(size_str[:-1]))
67             size_num = size_num * 1000
68         return '{:.2f}'.format(float(size_str))
69     except ValueError as ex:
70         logging.error(size_str + " is not a valid size string")
71         raise
72
73
74 def filter_ipnet_hostaddr(network_cidr, index):
75     """Return the host IP address on given index from an IP network"""
76     try:
77         network_cidr_str = unicode(network_cidr)
78     except NameError as ex:
79         network_cidr_str = str(network_cidr)
80     try:
81         return IPv4Network(network_cidr_str)[index]
82     except ValueError as ex:
83         logging.error(network_cidr_str + " is not a valid network address")
84         raise
85     except IndexError as ex:
86         logging.error(network_cidr_str + " has not enough range for "
87                       + str(index) + " host IPs.")
88         raise
89
90
91 def filter_ipnet_broadcast(network_cidr):
92     """Return broadcast IP address from given IP network"""
93     try:
94         network_cidr_str = unicode(network_cidr)
95     except NameError as ex:
96         network_cidr_str = str(network_cidr)
97     try:
98         return IPv4Network(network_cidr_str).broadcast_address
99     except ValueError as ex:
100         logging.error(network_cidr_str + " is not a valid network address")
101         raise
102
103
104 def filter_ipnet_hostmin(network_cidr):
105     """Return the first host IP address from given IP network"""
106     try:
107         network_cidr_str = unicode(network_cidr)
108     except NameError as ex:
109         network_cidr_str = str(network_cidr)
110     try:
111         return IPv4Network(network_cidr_str)[1]
112     except ValueError as ex:
113         logging.error(network_cidr_str + " is not a valid network address")
114         raise
115
116
117 def filter_ipnet_hostmax(network_cidr):
118     """Return the last host IP address from given IP network"""
119     try:
120         network_cidr_str = unicode(network_cidr)
121     except NameError as ex:
122         network_cidr_str = str(network_cidr)
123     try:
124         return IPv4Network(network_cidr_str)[-2]
125     except ValueError as ex:
126         logging.error(network_cidr_str + " is not a valid network address")
127         raise
128
129
130 def filter_ipnet_netmask(network_cidr):
131     """Return the IP netmask from given IP network"""
132     try:
133         network_cidr_str = unicode(network_cidr)
134     except NameError as ex:
135         network_cidr_str = str(network_cidr)
136     try:
137         return IPv4Network(network_cidr_str).netmask
138     except ValueError as ex:
139         logging.error(network_cidr_str + " is not a valid network address")
140         raise
141
142
143 def filter_ipnet_contains_ip(network_cidr, ip_address):
144     """Check if an IP network cointains a given range"""
145     try:
146         network_cidr_str = unicode(network_cidr)
147         ip_address_str = unicode(ip_address)
148     except NameError as ex:
149         network_cidr_str = str(network_cidr)
150         ip_address_str = str(ip_address)
151     try:
152         return IPv4Address(ip_address_str) in IPv4Network(network_cidr_str)
153     except ValueError as ex:
154         logging.error(network_cidr_str + " is not a valid network address")
155         raise
156
157
158 def filter_ipnet_contains_iprange(network_cidr, range_start, range_end):
159     """Check if an IP network cointains a given range"""
160     try:
161         network_cidr_str = unicode(network_cidr)
162         range_start_str = unicode(range_start)
163         range_end_str = unicode(range_end)
164     except NameError as ex:
165         network_cidr_str = str(network_cidr)
166         range_start_str = str(range_start)
167         range_end_str = str(range_end)
168     try:
169         ipnet = IPv4Network(network_cidr_str)
170         return (IPv4Address(range_start_str) in ipnet
171                 and IPv4Address(range_end_str) in ipnet)
172     except ValueError as ex:
173         logging.error(network_cidr_str + " is not a valid network address")
174         raise
175
176
177 def filter_ipnet_range_size(network_cidr, range_start, range_end):
178     """Get the size of an IP range between two IP addresses"""
179     try:
180         network_cidr_str = unicode(network_cidr)
181         range_start_str = unicode(range_start)
182         range_end_str = unicode(range_end)
183     except NameError as ex:
184         network_cidr_str = str(network_cidr)
185         range_start_str = str(range_start)
186         range_end_str = str(range_end)
187     try:
188         ipnet = IPv4Network(network_cidr_str)
189         ip1 = IPv4Address(range_start_str)
190         ip2 = IPv4Address(range_end_str)
191
192         if ip1 in ipnet and ip2 in ipnet:
193             index1 = list(ipnet.hosts()).index(ip1)
194             index2 = list(ipnet.hosts()).index(ip2)
195             ip_range_size = index2 - index1 + 1
196             return ip_range_size
197         else:
198             raise ValueError
199     except ValueError as ex:
200         logging.error(range_start_str + " and " + range_end_str +
201                       " are not valid IP addresses for range inside " +
202                       network_cidr_str)
203         raise
204
205
206 # This filter is too simple and does not take network mask into account.
207 # TODO Deprecate for filter_ipnet_hostaddr
208 def filter_ipaddr_index(base_address, index):
209     """Return IP address in given network at given index"""
210     try:
211         base_address_str = unicode(base_address)
212     except NameError as ex:
213         base_address_str = str(base_address)
214     return IPv4Address(base_address_str) + int(index)
215
216
217 # TODO deprecate for filter_ipnet_netmask
218 def filter_netmask(prefix):
219     """Get netmask from prefix length integer"""
220     try:
221         prefix_str = unicode(prefix)
222     except NameError as ex:
223         prefix_str = str(prefix)
224     return IPv4Network("1.0.0.0/"+prefix_str).netmask