aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/dhcpns/config/ddns.py10
-rw-r--r--tools/dhcpns/config/dhcp4.py16
-rw-r--r--tools/dhcpns/main.py63
3 files changed, 48 insertions, 41 deletions
diff --git a/tools/dhcpns/config/ddns.py b/tools/dhcpns/config/ddns.py
index 531fc34..8490967 100644
--- a/tools/dhcpns/config/ddns.py
+++ b/tools/dhcpns/config/ddns.py
@@ -8,7 +8,13 @@ def base(ddns_domains = [], ddns_reverse_domains = []):
"socket-type": "unix",
"socket-name": "/tmp/kea-ddns-ctrl-socket"
},
- "tsig-keys": [],
+ "tsig-keys": [
+ {
+ "name": os.environ['KEA_DDNS_KEY_NAME'],
+ "algorithm": os.environ['KEA_DDNS_ALGORITHM'],
+ "secret": os.environ['KEA_DDNS_SECRET']
+ }
+ ],
"forward-ddns": {
"ddns-domains": ddns_domains
},
@@ -37,7 +43,7 @@ def ddns_domain(domain_name):
"key-name": os.environ['KEA_DDNS_KEY_NAME'],
"dns-servers": [
{
- "ip-address": os.environ['NS1_V6'],
+ "ip-address": "::1",
"port": 53
}
]
diff --git a/tools/dhcpns/config/dhcp4.py b/tools/dhcpns/config/dhcp4.py
index f9a9382..d1a779d 100644
--- a/tools/dhcpns/config/dhcp4.py
+++ b/tools/dhcpns/config/dhcp4.py
@@ -37,6 +37,17 @@ def base(subnet4):
}
}
],
+ "dhcp-ddns": {
+ "enable-updates": True,
+ "server-ip": "::1",
+ },
+ "ddns-send-updates": True,
+ "ddns-override-no-update": False,
+ "ddns-override-client-update": False,
+ "ddns-replace-client-name": "always",
+ "ddns-generated-prefix": "dyn",
+ "ddns-update-on-renew": False,
+ "ddns-use-conflict-resolution": True,
"interfaces-config": {
"interfaces": [
os.environ.get('DHCP_INTERFACE', 'eth0')
@@ -222,10 +233,14 @@ def base(subnet4):
def subnet(vlan, prefix, domain_name, vlan_domain_name):
network = ipaddress.ip_network(prefix.prefix)
gw, start_ip, end_ip = network[1], network[2], network[-2]
+
return {
"id": prefix.id,
"subnet": prefix.prefix,
"ddns-qualifying-suffix": vlan_domain_name,
+ # Check if the VLAN in netbox has dhcp-ddns. This will enable full ddns using client hostnames.
+ # Generate automatically using IP if not.
+ "ddns-replace-client-name": "always" if not any(t['slug'] == 'dhcp-ddns' for t in vlan.tags) else "when-not-present",
"pools": [
{
"pool": f"{start_ip} - {end_ip}"
@@ -256,6 +271,7 @@ def fap(vlan, prefix):
network = ipaddress.ip_network(prefix.prefix)
gw, start_ip, end_ip = network[1], network[(
math.ceil(network.num_addresses / 2))], network[-2]
+
return {
"id": prefix.id,
"client-class": "fap-class",
diff --git a/tools/dhcpns/main.py b/tools/dhcpns/main.py
index b81042f..e826a5f 100644
--- a/tools/dhcpns/main.py
+++ b/tools/dhcpns/main.py
@@ -46,7 +46,7 @@ kea_rddns_domains = []
# dhcp-client
vlans = nb.ipam.vlans.filter(tag='dhcp-client')
for vlan in vlans:
- vlan_domain_name = f"{vlan.name}.{DOMAIN_NAME}"
+ vlan_domain_name = f"net-{vlan.name}.{DOMAIN_NAME}"
prefixes4 = []
prefixes6 = []
kea_ddns_domains.append(ddns_domain(vlan_domain_name))
@@ -72,7 +72,7 @@ for vlan in vlans:
network = ipaddress.ip_network(prefix)
# Network ID
- zone_rrsets.append({'name': f'net-{network[0]}.{vlan_domain_name}.', 'changetype': 'replace', 'type': 'A', 'records': [
+ zone_rrsets.append({'name': f'id-{network[0]}.{vlan_domain_name}.', 'changetype': 'replace', 'type': 'A', 'records': [
{'content': str(network[0]), 'disabled': False, 'type':'A'}], 'ttl': 900})
# Gateway
@@ -160,45 +160,30 @@ for device in devices:
zone = "tg23.gathering.org"
- print(device.name)
- r = re.search('^([A-Za-z1-9]*)\.([A-Za-z1-9]*)$', device.name)
-
- if f"{device.name}.{zone}." in zones:
- device_name = ""
- zone = f"{device.name}.{zone}"
- elif r is not None:
- device_name = r.group(1) + "."
- zone = "{}.{}".format(r.group(2), zone)
- elif re.search('^([A-Za-z1-9]*) \(([A-Za-z1-9 -\/]*)\)', device.name) is not None:
- zone = "{}".format(zone)
- device_name = re.search(
- '^([A-Za-z1-9]*) \(([A-Za-z1-9 -\/]*)\)', device.name).group(1) + "."
- else:
- zone = "{}".format(zone)
- device_name = device.name + "."
-
- print(f"zone: {zone}")
- print(f"name: {device_name}")
- print(str(netaddr.IPNetwork(str(device.primary_ip4)).ip))
- print()
-
- # Network ID
+ # IPv4
zone_rrsets = []
- zone_rrsets.append({'name': f'{device_name}{zone}.', 'changetype': 'replace', 'type': 'A', 'records': [
- {'content': str(netaddr.IPNetwork(str(device.primary_ip4)).ip), 'disabled': False, 'type': 'A'}], 'ttl': 900})
-
- # Apply zone_rrsets
- print(pdns.set_records(f"{zone}", zone_rrsets))
-
- rdns_zone = pdns.get_rdns_zone_from_ip(
- str(netaddr.IPNetwork(str(device.primary_ip4)).ip))
- rdns_rrsets = []
- if rdns_zone is None:
- print(f"Failed to find RDNS Zone for IP")
-
- # Broadcast
+ if device.primary_ip4 is not None:
+ zone_rrsets.append({'name': f'{device.name}.{zone}.', 'changetype': 'replace', 'type': 'A', 'records': [
+ {'content': str(netaddr.IPNetwork(str(device.primary_ip4)).ip), 'disabled': False, 'type': 'A'}], 'ttl': 900})
+
+ # IPv6
+ if device.primary_ip6 is not None:
+ zone_rrsets.append({'name': f'{device.name}.{zone}.', 'changetype': 'replace', 'type': 'AAAA', 'records': [
+ {'content': str(netaddr.IPNetwork(str(device.primary_ip6)).ip), 'disabled': False, 'type': 'A'}], 'ttl': 900})
+
+ if len(zone_rrsets) > 1:
+ # Apply zone_rrsets
+ print(pdns.set_records(zone, zone_rrsets))
+
+ rdns_zone = pdns.get_rdns_zone_from_ip(
+ str(netaddr.IPNetwork(str(device.primary_ip4)).ip))
+ rdns_rrsets = []
+ if rdns_zone is None:
+ print(f"Failed to find RDNS Zone for IP")
+
+ # IPv4 RDNS
rdns_rrsets.append({"name": ipaddress.ip_address(str(netaddr.IPNetwork(str(device.primary_ip4)).ip)).reverse_pointer + '.', "changetype": "replace", "type": "PTR", "records": [
- {"content": f'{device_name}{zone}.', "disabled": False, "type": "PTR"}], "ttl": 900})
+ {"content": f'{device.name}.{zone}.', "disabled": False, "type": "PTR"}], "ttl": 900})
# Apply rdns_rrsets
print(pdns.set_records(rdns_zone, rdns_rrsets))