83 lines
2.3 KiB
Python
83 lines
2.3 KiB
Python
from ipaddress import ip_address, ip_network
|
|
|
|
defaults = {
|
|
'apt': {
|
|
'packages': {
|
|
'kea-dhcp4-server': {},
|
|
},
|
|
},
|
|
'kea-dhcp-server': {
|
|
'config': {
|
|
'authoritative': True,
|
|
'rebind-timer': 450,
|
|
'renew-timer': 300,
|
|
'valid-lifetime': 600,
|
|
'expired-leases-processing': {
|
|
'max-reclaim-leases': 0,
|
|
'max-reclaim-time': 0,
|
|
},
|
|
'lease-database': {
|
|
'lfc-interval': 3600,
|
|
'name': '/var/lib/kea/kea-leases4.csv',
|
|
'persist': True,
|
|
'type': 'memfile',
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
@metadata_reactor.provides(
|
|
'kea-dhcp-server/fixed_allocations',
|
|
)
|
|
def get_static_allocations(metadata):
|
|
result = {}
|
|
mapping = {}
|
|
|
|
for iface, config in metadata.get('kea-dhcp-server/subnets', {}).items():
|
|
result[iface] = {}
|
|
mapping[iface] = ip_network(config['subnet'])
|
|
|
|
for rnode in repo.nodes:
|
|
if (
|
|
rnode.metadata.get('location', '') != metadata.get('location', '')
|
|
or rnode == node
|
|
):
|
|
continue
|
|
|
|
for iface_name, iface_config in rnode.metadata.get('interfaces', {}).items():
|
|
if iface_config.get('dhcp', False) and iface_config.get('mac'):
|
|
for ip in iface_config.get('ips', set()):
|
|
ipaddr = ip_address(ip)
|
|
|
|
for kea_iface, kea_subnet in mapping.items():
|
|
if ipaddr in kea_subnet:
|
|
result[kea_iface][f'{rnode.name}_{iface_name}'] = {
|
|
'ip': ip,
|
|
'mac': iface_config['mac'],
|
|
}
|
|
break
|
|
|
|
return {
|
|
'kea-dhcp-server': {
|
|
'fixed_allocations': result,
|
|
}
|
|
}
|
|
|
|
|
|
@metadata_reactor.provides(
|
|
'nftables/input/10-kea-dhcp-server',
|
|
)
|
|
def nftables(metadata):
|
|
rules = set()
|
|
for iface in node.metadata.get('kea-dhcp-server/subnets', {}):
|
|
rules.add(f'udp dport {{ 67, 68 }} iifname {iface} accept')
|
|
|
|
return {
|
|
'nftables': {
|
|
'input': {
|
|
# can't use port_rules here, because we're generating interface based rules.
|
|
'10-kea-dhcp-server': sorted(rules),
|
|
},
|
|
}
|
|
}
|