wip
This commit is contained in:
parent
0a0c7cb859
commit
46c12fd05f
3 changed files with 85 additions and 124 deletions
|
@ -20,16 +20,18 @@ def acme_records(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'bind/zones',
|
'bind/views/external/zones',
|
||||||
)
|
)
|
||||||
def acme_zone(metadata):
|
def acme_zone(metadata):
|
||||||
return {
|
return {
|
||||||
'bind': {
|
'bind': {
|
||||||
'zones': {
|
'views': {
|
||||||
metadata.get('bind/acme_zone'): {
|
'external': {
|
||||||
'dynamic': True,
|
'zones': {
|
||||||
'views': ['external'],
|
metadata.get('bind/acme_zone'): {
|
||||||
'records': set(),
|
'dynamic': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
from ipaddress import ip_address, ip_interface
|
from ipaddress import ip_address, ip_interface
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
if node.metadata.get('bind/type') == 'master':
|
|
||||||
zones = node.metadata.get('bind/zones')
|
|
||||||
master_ip = None
|
|
||||||
slave_ips = [
|
|
||||||
ip_interface(repo.get_node(slave).metadata.get('network/external/ipv4')).ip
|
|
||||||
for slave in node.metadata.get('bind/slaves')
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
zones = repo.get_node(node.metadata.get('bind/master_node')).metadata.get('bind/zones')
|
|
||||||
master_ip = ip_interface(repo.get_node(node.metadata.get('bind/master_node')).metadata.get('network/external/ipv4')).ip
|
|
||||||
slave_ips = []
|
|
||||||
|
|
||||||
directories[f'/var/lib/bind'] = {
|
directories[f'/var/lib/bind'] = {
|
||||||
'owner': 'bind',
|
'owner': 'bind',
|
||||||
'group': 'bind',
|
'group': 'bind',
|
||||||
|
@ -48,6 +36,19 @@ files['/etc/bind/named.conf'] = {
|
||||||
'svc_systemd:bind9:restart',
|
'svc_systemd:bind9:restart',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if node.metadata.get('bind/type') == 'master':
|
||||||
|
master_node = node
|
||||||
|
master_ip = None
|
||||||
|
slave_ips = [
|
||||||
|
ip_interface(repo.get_node(slave).metadata.get('network/external/ipv4')).ip
|
||||||
|
for slave in node.metadata.get('bind/slaves')
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
master_node = repo.get_node(node.metadata.get('bind/master_node'))
|
||||||
|
master_ip = ip_interface(repo.get_node(node.metadata.get('bind/master_node')).metadata.get('network/external/ipv4')).ip
|
||||||
|
slave_ips = []
|
||||||
|
|
||||||
files['/etc/bind/named.conf.options'] = {
|
files['/etc/bind/named.conf.options'] = {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'context': {
|
'context': {
|
||||||
|
@ -74,12 +75,11 @@ files['/etc/bind/named.conf.local'] = {
|
||||||
'type': node.metadata.get('bind/type'),
|
'type': node.metadata.get('bind/type'),
|
||||||
'master_ip': master_ip,
|
'master_ip': master_ip,
|
||||||
'views': dict(sorted(
|
'views': dict(sorted(
|
||||||
node.metadata.get('bind/views').items(),
|
master_node.metadata.get('bind/hostname'),
|
||||||
key=lambda e: (e[1].get('default', False), e[0]),
|
key=lambda e: (e[1].get('default', False), e[0]),
|
||||||
)),
|
)),
|
||||||
'zones': zones,
|
'zones': zones,
|
||||||
'hostname': node.metadata.get('bind/hostname'),
|
'hostname': node.metadata.get('bind/hostname'),
|
||||||
'keys': node.metadata.get('bind/keys'),
|
|
||||||
},
|
},
|
||||||
'owner': 'root',
|
'owner': 'root',
|
||||||
'group': 'bind',
|
'group': 'bind',
|
||||||
|
@ -94,24 +94,6 @@ files['/etc/bind/named.conf.local'] = {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
def record_matches_view(record, records, view):
|
|
||||||
if record['type'] in ['A', 'AAAA']:
|
|
||||||
if view == 'external':
|
|
||||||
# no internal addresses in external view
|
|
||||||
if ip_address(record['value']).is_private:
|
|
||||||
return False
|
|
||||||
elif view == 'internal':
|
|
||||||
# external addresses in internal view only, if no internal exists
|
|
||||||
if ip_address(record['value']).is_global:
|
|
||||||
for other_record in records:
|
|
||||||
if (
|
|
||||||
record['name'] == other_record['name'] and
|
|
||||||
record['type'] == other_record['type'] and
|
|
||||||
ip_address(other_record['value']).is_private
|
|
||||||
):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
for view_name, view_conf in node.metadata.get('bind/views').items():
|
for view_name, view_conf in node.metadata.get('bind/views').items():
|
||||||
directories[f"/var/lib/bind/{view_name}"] = {
|
directories[f"/var/lib/bind/{view_name}"] = {
|
||||||
'owner': 'bind',
|
'owner': 'bind',
|
||||||
|
@ -125,18 +107,7 @@ for view_name, view_conf in node.metadata.get('bind/views').items():
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
for zone, conf in zones.items():
|
for zone, conf in view_conf['zones'].items():
|
||||||
if view_name not in conf.get('views', ['internal', 'external']):
|
|
||||||
continue
|
|
||||||
|
|
||||||
records = conf['records']
|
|
||||||
unique_records = [
|
|
||||||
dict(record_tuple)
|
|
||||||
for record_tuple in set(
|
|
||||||
tuple(record.items()) for record in records
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
files[f"/var/lib/bind/{view_name}/db.{zone}"] = {
|
files[f"/var/lib/bind/{view_name}/db.{zone}"] = {
|
||||||
'owner': 'bind',
|
'owner': 'bind',
|
||||||
'group': 'bind',
|
'group': 'bind',
|
||||||
|
@ -150,23 +121,22 @@ for view_name, view_conf in node.metadata.get('bind/views').items():
|
||||||
'svc_systemd:bind9:restart',
|
'svc_systemd:bind9:restart',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
if True or node.metadata.get('bind/type') == 'master': #FIXME: slave doesnt get updated if db doesnt get rewritten on each apply
|
#FIXME: slave doesnt get updated if db doesnt get rewritten on each apply
|
||||||
files[f"/var/lib/bind/{view_name}/db.{zone}"].update({
|
files[f"/var/lib/bind/{view_name}/db.{zone}"].update({
|
||||||
'source': 'db',
|
'source': 'db',
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'unless': f"test -f /var/lib/bind/{view_name}/db.{zone}" if conf.get('dynamic', False) else 'false',
|
'unless': f"test -f /var/lib/bind/{view_name}/db.{zone}" if conf.get('dynamic', False) else 'false',
|
||||||
'context': {
|
'context': {
|
||||||
'view': view_name,
|
'serial': datetime.now().strftime('%Y%m%d%H'),
|
||||||
'serial': datetime.now().strftime('%Y%m%d%H'),
|
'records': list(filter(
|
||||||
'records': list(filter(
|
lambda record: record_matches_view(record, records, view_name),
|
||||||
lambda record: record_matches_view(record, records, view_name),
|
unique_records
|
||||||
unique_records
|
)),
|
||||||
)),
|
'hostname': node.metadata.get('bind/hostname'),
|
||||||
'hostname': node.metadata.get('bind/hostname'),
|
'type': node.metadata.get('bind/type'),
|
||||||
'type': node.metadata.get('bind/type'),
|
'keys': node.metadata.get('bind/keys'),
|
||||||
'keys': node.metadata.get('bind/keys'),
|
},
|
||||||
},
|
})
|
||||||
})
|
|
||||||
|
|
||||||
svc_systemd['bind9'] = {}
|
svc_systemd['bind9'] = {}
|
||||||
|
|
||||||
|
|
|
@ -21,24 +21,18 @@ defaults = {
|
||||||
'172.16.0.0/12',
|
'172.16.0.0/12',
|
||||||
'192.168.0.0/16',
|
'192.168.0.0/16',
|
||||||
},
|
},
|
||||||
'keys': {},
|
|
||||||
'zones': {},
|
'zones': {},
|
||||||
},
|
},
|
||||||
'external': {
|
'external': {
|
||||||
'default': True,
|
'default': True,
|
||||||
'name': 'external',
|
|
||||||
'is_internal': False,
|
'is_internal': False,
|
||||||
'acl': {
|
'acl': {
|
||||||
'any',
|
'any',
|
||||||
},
|
},
|
||||||
'keys': {},
|
|
||||||
'zones': {},
|
'zones': {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'keys': {
|
'zones': {},
|
||||||
'internal': {},
|
|
||||||
'external': {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'telegraf': {
|
'telegraf': {
|
||||||
'config': {
|
'config': {
|
||||||
|
@ -77,7 +71,7 @@ def dns(metadata):
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'bind/zones',
|
'bind/views',
|
||||||
)
|
)
|
||||||
def collect_records(metadata):
|
def collect_records(metadata):
|
||||||
if metadata.get('bind/type') == 'slave':
|
if metadata.get('bind/type') == 'slave':
|
||||||
|
@ -137,15 +131,20 @@ def ns_records(metadata):
|
||||||
]
|
]
|
||||||
return {
|
return {
|
||||||
'bind': {
|
'bind': {
|
||||||
'zones': {
|
'views': {
|
||||||
zone: {
|
view_name: {
|
||||||
'records': {
|
'zones': {
|
||||||
# FIXME: bw currently cant handle lists of dicts :(
|
zone_name: {
|
||||||
h({'name': '@', 'type': 'NS', 'value': f"{nameserver}."})
|
'records': {
|
||||||
for nameserver in nameservers
|
# FIXME: bw currently cant handle lists of dicts :(
|
||||||
}
|
h({'name': '@', 'type': 'NS', 'value': f"{nameserver}."})
|
||||||
|
for nameserver in nameservers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for zone_name, zone_conf in view_conf['zones'].items()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for zone in metadata.get('bind/zones').keys()
|
for view_name, view_conf in metadata.get('bind/views').items()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -176,21 +175,22 @@ def generate_keys(metadata):
|
||||||
return {
|
return {
|
||||||
'bind': {
|
'bind': {
|
||||||
'views': {
|
'views': {
|
||||||
view: {
|
view_name: {
|
||||||
'keys': {
|
'zones': {
|
||||||
f'{view}.{zone}': repo.libs.hmac.hmac_sha512(
|
zone_name: {
|
||||||
zone,
|
'key': repo.libs.hmac.hmac_sha512(
|
||||||
str(repo.vault.random_bytes_as_base64_for(
|
f'{view_name}.{zone_name}',
|
||||||
f"{metadata.get('id')} bind {view} key {zone}",
|
str(repo.vault.random_bytes_as_base64_for(
|
||||||
length=32,
|
f"{metadata.get('id')} bind {view_name} key {zone_name}",
|
||||||
)),
|
length=32,
|
||||||
)
|
)),
|
||||||
for zone, conf in metadata.get('bind/zones').items()
|
)
|
||||||
if conf.get('dynamic', False)
|
}
|
||||||
and view in conf.get('views', metadata.get('bind/views').keys())
|
for zone_name, zone_conf in view_conf['zones'].items()
|
||||||
|
if zone_conf.get('dynamic', False)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for view in metadata.get('bind/views')
|
for view_name, view_conf in metadata.get('bind/views').items()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -199,39 +199,28 @@ def generate_keys(metadata):
|
||||||
@metadata_reactor.provides(
|
@metadata_reactor.provides(
|
||||||
'bind/views',
|
'bind/views',
|
||||||
)
|
)
|
||||||
def allow_keys_in_acl(metadata):
|
def generate_acl_entries_for_keys(metadata):
|
||||||
return {
|
return {
|
||||||
'bind': {
|
'bind': {
|
||||||
'views': {
|
'views': {
|
||||||
view: {
|
view_name: {
|
||||||
'acl': {
|
'acl': {
|
||||||
f'key {key}'
|
*{
|
||||||
for key in conf['keys']
|
f'key {view_name}.{zone_name}'
|
||||||
|
for zone_name, zone_conf in view_conf['zones'].items()
|
||||||
|
if zone_conf.get('key', False)
|
||||||
|
},
|
||||||
|
*{
|
||||||
|
f'! key {other_view_name}.{zone_name}'
|
||||||
|
for other_view_name, other_view_conf in metadata.get('bind/views').items()
|
||||||
|
if other_view_name != view_name
|
||||||
|
for zone_name, zone_conf in other_view_conf['zones'].items()
|
||||||
|
if zone_conf.get('key', False)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for view, conf in metadata.get('bind/views').items()
|
for view_name, view_conf in metadata.get('bind/views').items()
|
||||||
}
|
if not view_conf.get('default')
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@metadata_reactor.provides(
|
|
||||||
'bind/views',
|
|
||||||
)
|
|
||||||
def reject_keys_from_other_views(metadata):
|
|
||||||
return {
|
|
||||||
'bind': {
|
|
||||||
'views': {
|
|
||||||
view: {
|
|
||||||
'acl': {
|
|
||||||
f'! key {key}'
|
|
||||||
for other_view, other_conf in metadata.get('bind/views').items()
|
|
||||||
if other_view != view
|
|
||||||
for key in other_conf['keys']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for view, conf in metadata.get('bind/views').items()
|
|
||||||
if not conf.get('default')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue