from ipaddress import ip_network from bundlewrap.exceptions import NoSuchNode from bundlewrap.metadata import atomic defaults = { 'apt': { 'packages': { 'bird2': { 'needed_by': { 'svc_systemd:bird', }, }, }, }, 'pacman': { 'packages': { 'bird': { 'needed_by': { 'svc_systemd:bird', }, }, }, }, 'sysctl': { 'options': { 'net.ipv4.conf.all.forwarding': '1', 'net.ipv6.conf.all.forwarding': '1', }, }, } @metadata_reactor.provides( 'bird/bgp_neighbors', ) def neighbor_info_from_wireguard(metadata): neighbors = {} my_as = repo.libs.s2s.AS_NUMBERS[metadata.get('location')] for name, config in metadata.get('wireguard/peers', {}).items(): try: rnode = repo.get_node(name) except NoSuchNode: continue if not rnode.has_bundle('bird'): continue neighbors[name] = { 'local_ip': config['my_ip'], 'local_as': my_as, 'neighbor_ip': config['their_ip'], 'neighbor_as': repo.libs.s2s.AS_NUMBERS[rnode.metadata.get('location')], } return { 'bird': { 'bgp_neighbors': neighbors, }, } @metadata_reactor.provides( 'bird/my_ip', ) def my_ip(metadata): if node.has_bundle('wireguard'): wg_ifaces = sorted({iface for iface in metadata.get('interfaces').keys() if iface.startswith('wg_')}) if not wg_ifaces: return {} my_ip = sorted(metadata.get(f'interfaces/{wg_ifaces[0]}/ips'))[0].split('/')[0] else: my_ip = str(sorted(repo.libs.tools.resolve_identifier(repo, node.name))[0]) return { 'bird': { 'my_ip': my_ip, }, } @metadata_reactor.provides( 'firewall/port_rules', ) def firewall(metadata): sources = set() for config in metadata.get('bird/bgp_neighbors', {}).values(): sources.add(config['neighbor_ip']) return { 'firewall': { 'port_rules': { '179/tcp': atomic(sources), }, }, }