2023-02-05 16:30:58 +00:00
|
|
|
from ipaddress import IPv4Address, IPv6Address, ip_address
|
2021-09-25 09:08:18 +00:00
|
|
|
|
2021-03-21 10:43:17 +00:00
|
|
|
from bundlewrap.metadata import atomic
|
|
|
|
|
2020-10-13 17:06:22 +00:00
|
|
|
defaults = {
|
|
|
|
'apt': {
|
|
|
|
'packages': {
|
|
|
|
'pdns-server': {},
|
|
|
|
'pdns-tools': {},
|
|
|
|
'pdns-backend-bind': {},
|
|
|
|
'pdns-backend-pgsql': {},
|
|
|
|
},
|
|
|
|
},
|
2020-11-21 17:55:34 +00:00
|
|
|
'icinga2_api': {
|
|
|
|
'powerdns': {
|
|
|
|
'services': {
|
|
|
|
'POWERDNS PROCESS': {
|
|
|
|
'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -C pdns_server -c 1:',
|
2020-11-22 07:24:44 +00:00
|
|
|
'vars.notification.mail': True,
|
2021-01-02 11:26:37 +00:00
|
|
|
'vars.notification.sms': True,
|
2020-11-21 17:55:34 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-10-16 15:44:31 +00:00
|
|
|
'powerdns': {
|
|
|
|
'api_key': repo.vault.password_for('{} powerdns api'.format(node.name)),
|
|
|
|
},
|
2020-10-13 17:06:22 +00:00
|
|
|
'postgresql': {
|
2020-11-10 11:37:58 +00:00
|
|
|
'roles': {
|
2020-10-13 17:06:22 +00:00
|
|
|
'powerdns': {
|
|
|
|
'password': repo.vault.password_for('{} postgresql powerdns'.format(node.name)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'databases': {
|
|
|
|
'powerdns': {
|
|
|
|
'owner': 'powerdns',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2020-10-16 21:02:47 +00:00
|
|
|
|
2021-04-23 17:31:28 +00:00
|
|
|
if node.has_bundle('telegraf'):
|
|
|
|
defaults['telegraf'] = {
|
|
|
|
'input_plugins': {
|
|
|
|
'builtin': {
|
2023-01-29 10:02:49 +00:00
|
|
|
'powerdns': [{
|
|
|
|
'unix_sockets': [
|
|
|
|
'/var/run/pdns/pdns.controlsocket',
|
|
|
|
],
|
|
|
|
}],
|
2021-04-23 17:31:28 +00:00
|
|
|
},
|
|
|
|
},
|
2021-04-24 09:45:58 +00:00
|
|
|
'additional_groups': {
|
|
|
|
'pdns',
|
|
|
|
},
|
2021-04-23 17:31:28 +00:00
|
|
|
}
|
|
|
|
|
2020-10-16 21:02:47 +00:00
|
|
|
|
2021-01-07 17:44:38 +00:00
|
|
|
@metadata_reactor.provides(
|
|
|
|
'icinga2_api/powerdns/services',
|
|
|
|
)
|
2020-11-21 17:55:34 +00:00
|
|
|
def monitoring_for_primary_nameserver(metadata):
|
|
|
|
if metadata.get('powerdns/is_secondary', False):
|
|
|
|
return {}
|
|
|
|
|
|
|
|
return {
|
|
|
|
'icinga2_api': {
|
|
|
|
'powerdns': {
|
|
|
|
'services': {
|
|
|
|
'POWERDNS WEB INTERFACE': {
|
|
|
|
'command_on_monitored_host': '/usr/local/share/icinga/plugins/check_http_url_for_string http://localhost:8081/ "PowerDNS"',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-07 17:44:38 +00:00
|
|
|
@metadata_reactor.provides(
|
|
|
|
'powerdns/my_secondary_servers',
|
|
|
|
)
|
2020-10-25 09:53:55 +00:00
|
|
|
def get_ips_of_secondary_nameservers(metadata):
|
|
|
|
if metadata.get('powerdns/is_secondary', False):
|
|
|
|
return {}
|
|
|
|
|
|
|
|
ips = set()
|
|
|
|
for rnode in repo.nodes_in_group('dns'):
|
|
|
|
if rnode.metadata.get('powerdns/is_secondary', False):
|
2023-05-16 17:23:52 +00:00
|
|
|
if rnode.name == node.name:
|
|
|
|
raise BundleError(f'{node.name} cannot be its own secondary')
|
2021-02-12 19:37:36 +00:00
|
|
|
for _, found_ips in repo.libs.tools.resolve_identifier(repo, rnode.name).items():
|
2020-11-09 17:46:37 +00:00
|
|
|
ips.update({str(ip) for ip in found_ips})
|
2020-10-25 09:53:55 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
'powerdns': {
|
|
|
|
'my_secondary_servers': ips,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-01-07 17:44:38 +00:00
|
|
|
@metadata_reactor.provides(
|
|
|
|
'powerdns/my_primary_servers',
|
|
|
|
)
|
2020-10-17 10:56:17 +00:00
|
|
|
def get_ips_of_primary_nameservers(metadata):
|
|
|
|
if not metadata.get('powerdns/is_secondary', False):
|
2020-10-16 21:02:47 +00:00
|
|
|
return {}
|
|
|
|
|
2023-05-16 17:23:52 +00:00
|
|
|
ips = {}
|
2020-10-17 10:56:17 +00:00
|
|
|
for rnode in repo.nodes_in_group('dns'):
|
|
|
|
if not rnode.metadata.get('powerdns/is_secondary', False):
|
2023-05-16 17:23:52 +00:00
|
|
|
if rnode.name == node.name:
|
|
|
|
raise BundleError(f'{node.name} cannot be its own secondary')
|
|
|
|
hostname = rnode.metadata.get('hostname')
|
|
|
|
ips[hostname] = set()
|
2021-02-12 19:37:36 +00:00
|
|
|
for _, found_ips in repo.libs.tools.resolve_identifier(repo, rnode.name).items():
|
2023-05-16 17:23:52 +00:00
|
|
|
ips[hostname].update({str(ip) for ip in found_ips})
|
2020-10-16 21:02:47 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
'powerdns': {
|
2020-10-25 09:53:55 +00:00
|
|
|
'my_primary_servers': ips,
|
2020-10-16 21:02:47 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-07 17:44:38 +00:00
|
|
|
@metadata_reactor.provides(
|
|
|
|
'powerdns/bind-zones/kunbox.net/records',
|
|
|
|
)
|
2020-10-17 10:57:35 +00:00
|
|
|
def generate_dns_entries_for_nodes(metadata):
|
|
|
|
results = set()
|
2020-10-16 21:02:47 +00:00
|
|
|
|
|
|
|
for rnode in repo.nodes:
|
2020-10-17 10:57:35 +00:00
|
|
|
node_name_split = rnode.name.split('.')
|
|
|
|
node_name_split.reverse()
|
|
|
|
dns_name = '.'.join(node_name_split)
|
|
|
|
ip4 = None
|
|
|
|
ip6 = None
|
2020-10-16 21:02:47 +00:00
|
|
|
|
2020-11-09 17:46:37 +00:00
|
|
|
found_ips = repo.libs.tools.resolve_identifier(repo, rnode.name)
|
|
|
|
for ip in sorted(found_ips['ipv4']):
|
|
|
|
if not ip4 and not ip.is_private:
|
2020-11-09 14:37:48 +00:00
|
|
|
ip4 = ip
|
|
|
|
|
2020-11-09 17:46:37 +00:00
|
|
|
for ip in sorted(found_ips['ipv6']):
|
|
|
|
if not ip6 and not ip.is_private:
|
2020-11-09 14:37:48 +00:00
|
|
|
ip6 = ip
|
|
|
|
|
2021-02-12 19:37:36 +00:00
|
|
|
if not ip4 and found_ips['ipv4']:
|
2021-09-25 09:08:18 +00:00
|
|
|
# This node apparently does not have a public IPv4 address.
|
|
|
|
# We now manually iterate over that nodes interfaces to get
|
|
|
|
# a IPv4 address which is tied to a physical interface.
|
|
|
|
# Note we can't use resolve_identifier() here, because we
|
|
|
|
# only want physical interfaces.
|
|
|
|
for interface, config in rnode.metadata.get('interfaces', {}).items():
|
|
|
|
if not (
|
|
|
|
interface.startswith('bond') or
|
|
|
|
interface.startswith('br') or
|
|
|
|
interface.startswith('eno') or
|
|
|
|
interface.startswith('enp') or
|
|
|
|
interface.startswith('eth') or
|
|
|
|
interface == 'default' # dummy nodes use these
|
|
|
|
):
|
|
|
|
continue
|
|
|
|
|
|
|
|
for ip in sorted(config.get('ips', set())):
|
|
|
|
if '/' in ip:
|
|
|
|
addr = ip_address(ip.split('/')[0])
|
|
|
|
else:
|
|
|
|
addr = ip_address(ip)
|
|
|
|
|
|
|
|
if not ip4 and isinstance(addr, IPv4Address):
|
|
|
|
ip4 = addr
|
2020-10-17 10:57:35 +00:00
|
|
|
|
|
|
|
if ip4:
|
|
|
|
results.add('{} IN A {}'.format(dns_name, ip4))
|
2020-10-16 21:02:47 +00:00
|
|
|
|
2020-10-17 10:57:35 +00:00
|
|
|
if ip6:
|
|
|
|
results.add('{} IN AAAA {}'.format(dns_name, ip6))
|
|
|
|
|
|
|
|
return {
|
|
|
|
'powerdns': {
|
|
|
|
'bind-zones': {
|
|
|
|
'kunbox.net': {
|
|
|
|
'records': results,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2020-10-25 09:58:11 +00:00
|
|
|
|
|
|
|
|
2021-01-07 17:44:38 +00:00
|
|
|
@metadata_reactor.provides(
|
|
|
|
'hosts/entries',
|
|
|
|
)
|
2020-10-25 09:58:11 +00:00
|
|
|
def hosts_entries_for_all_dns_servers(metadata):
|
|
|
|
entries = {}
|
|
|
|
|
|
|
|
for rnode in repo.nodes_in_group('dns'):
|
2020-10-25 10:07:23 +00:00
|
|
|
if rnode.name == node.name:
|
|
|
|
continue
|
|
|
|
|
2023-01-29 10:02:49 +00:00
|
|
|
found_ips = repo.libs.tools.resolve_identifier(repo, rnode.name)
|
|
|
|
for ip in sorted(found_ips['ipv4']):
|
|
|
|
if not ip.is_private:
|
|
|
|
entries[str(ip)] = {
|
|
|
|
rnode.metadata.get('hostname'),
|
|
|
|
rnode.name,
|
|
|
|
}
|
|
|
|
|
|
|
|
if rnode.metadata.get('powerdns/my_hostname', None):
|
|
|
|
entries[str(ip)].add(rnode.metadata.get('powerdns/my_hostname'))
|
2020-10-25 09:58:11 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
'hosts': {
|
|
|
|
'entries': entries,
|
|
|
|
},
|
|
|
|
}
|
2021-03-21 10:12:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
@metadata_reactor.provides(
|
2021-06-03 11:59:15 +00:00
|
|
|
'firewall/port_rules',
|
2021-03-21 10:12:18 +00:00
|
|
|
)
|
2021-06-03 11:59:15 +00:00
|
|
|
def firewall(metadata):
|
2021-03-21 10:12:18 +00:00
|
|
|
return {
|
2021-06-03 11:59:15 +00:00
|
|
|
'firewall': {
|
2021-03-21 10:12:18 +00:00
|
|
|
'port_rules': {
|
2023-01-29 07:06:27 +00:00
|
|
|
'53': atomic(metadata.get('powerdns/restrict-to/dns', {'*'})),
|
|
|
|
'53/udp': atomic(metadata.get('powerdns/restrict-to/dns', {'*'})),
|
|
|
|
'8081': atomic(metadata.get('powerdns/restrict-to/api', set())),
|
2021-03-21 10:12:18 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|