sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #04150
[Merge] ~cgrabowski/maas:backport_fix_dynamic_updates_for_glue_zones_to_3.3 into maas:3.3
Christian Grabowski has proposed merging ~cgrabowski/maas:backport_fix_dynamic_updates_for_glue_zones_to_3.3 into maas:3.3.
Commit message:
fix adding dynamic updates for reverse glue zones
(cherry picked from commit 654d7968ef00118b3ed8dda9769ec1f578e81339)
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~cgrabowski/maas/+git/maas/+merge/434708
--
Your team MAAS Committers is subscribed to branch maas:3.3.
diff --git a/src/maasserver/dns/tests/test_zonegenerator.py b/src/maasserver/dns/tests/test_zonegenerator.py
index 5a3aee1..598074f 100644
--- a/src/maasserver/dns/tests/test_zonegenerator.py
+++ b/src/maasserver/dns/tests/test_zonegenerator.py
@@ -48,6 +48,7 @@ from maasserver.utils.orm import transactional
from maastesting.factory import factory as maastesting_factory
from maastesting.fakemethod import FakeMethod
from maastesting.matchers import MockAnyCall, MockCalledOnceWith, MockNotCalled
+from provisioningserver.dns.config import DynamicDNSUpdate
from provisioningserver.dns.zoneconfig import (
DNSForwardZoneConfig,
DNSReverseZoneConfig,
@@ -510,6 +511,49 @@ class TestZoneGenerator(MAASServerTestCase):
}
self.assertEqual(expected_map, zones[0]._other_mapping)
+ def test_glue_receives_correct_dynamic_updates(self):
+ domain = factory.make_Domain()
+ subnet = factory.make_Subnet(cidr=str(IPNetwork("10/29").cidr))
+ sip = factory.make_StaticIPAddress(subnet=subnet)
+ factory.make_Node_with_Interface_on_Subnet(
+ subnet=subnet, vlan=subnet.vlan, fabric=subnet.vlan.fabric
+ )
+ update_rec = factory.make_DNSResource(
+ name=factory.make_name(), domain=domain, ip_addresses=[sip]
+ )
+ updates = [
+ DynamicDNSUpdate(
+ operation="INSERT",
+ name=update_rec.name,
+ zone=domain.name,
+ rectype="A",
+ answer=sip.ip,
+ )
+ ]
+ zones = ZoneGenerator(
+ domain,
+ subnet,
+ serial=random.randint(0, 65535),
+ dynamic_updates=updates,
+ ).as_list()
+ self.assertCountEqual(zones[0]._dynamic_updates, updates)
+ self.assertCountEqual(
+ zones[1]._dynamic_updates,
+ [
+ DynamicDNSUpdate.as_reverse_record_update(
+ updates[0], str(IPNetwork("10/29"))
+ )
+ ],
+ )
+ self.assertCountEqual(
+ zones[2]._dynamic_updates,
+ [
+ DynamicDNSUpdate.as_reverse_record_update(
+ updates[0], str(IPNetwork("10/24"))
+ )
+ ],
+ )
+
def test_parent_of_default_domain_gets_glue(self):
default_domain = Domain.objects.get_default_domain()
default_domain.name = "maas.example.com"
diff --git a/src/maasserver/dns/zonegenerator.py b/src/maasserver/dns/zonegenerator.py
index ef31cfa..658147f 100644
--- a/src/maasserver/dns/zonegenerator.py
+++ b/src/maasserver/dns/zonegenerator.py
@@ -452,7 +452,9 @@ class ZoneGenerator:
glue = set()
domain_updates = [
- DynamicDNSUpdate.as_reverse_record_update(update, subnet)
+ DynamicDNSUpdate.as_reverse_record_update(
+ update, str(subnet.cidr)
+ )
for update in dynamic_updates
if update.answer
and update.answer_is_ip
@@ -476,6 +478,28 @@ class ZoneGenerator:
)
# Now provide any remaining rfc2317 glue networks.
for network, ranges in rfc2317_glue.items():
+ exclude_set = {
+ IPNetwork(s.cidr)
+ for s in subnets
+ if network in IPNetwork(s.cidr)
+ }
+ domain_updates = []
+ for update in dynamic_updates:
+ glue_update = True
+ for exclude_net in exclude_set:
+ if (
+ update.answer
+ and update.answer_is_ip
+ and IPAddress(update.answer) in exclude_net
+ ):
+ glue_update = False
+ break
+ if glue_update:
+ domain_updates.append(
+ DynamicDNSUpdate.as_reverse_record_update(
+ update, str(network)
+ )
+ )
yield DNSReverseZoneConfig(
ns_host_name,
serial=serial,
@@ -483,11 +507,7 @@ class ZoneGenerator:
network=network,
ns_host_name=ns_host_name,
rfc2317_ranges=ranges,
- exclude={
- IPNetwork(s.cidr)
- for s in subnets
- if network in IPNetwork(s.cidr)
- },
+ exclude=exclude_set,
dynamic_updates=domain_updates,
force_config_write=force_config_write,
)
diff --git a/src/provisioningserver/dns/tests/test_zoneconfig.py b/src/provisioningserver/dns/tests/test_zoneconfig.py
index 948d219..24e18e1 100644
--- a/src/provisioningserver/dns/tests/test_zoneconfig.py
+++ b/src/provisioningserver/dns/tests/test_zoneconfig.py
@@ -967,6 +967,93 @@ class TestDNSReverseZoneConfig(MAASTestCase):
stdin=expected_stdin.encode("ascii"),
)
+ def test_glue_network_zone_contains_appropriate_dynamic_updates(self):
+ patch_zone_file_config_path(self)
+ domain = factory.make_string()
+ network = IPNetwork("10.0.0.0/26")
+ glue_network = IPNetwork("10.0.0.0/24")
+ ip1 = factory.pick_ip_in_network(network)
+ ip2 = factory.pick_ip_in_network(network)
+ hostname1 = f"{factory.make_string()}.{domain}"
+ hostname2 = f"{factory.make_string()}.{domain}"
+ fwd_updates = [
+ DynamicDNSUpdate(
+ operation="INSERT",
+ zone=domain,
+ name=hostname1,
+ rectype="A",
+ answer=ip1,
+ ),
+ DynamicDNSUpdate(
+ operation="INSERT",
+ zone=domain,
+ name=hostname2,
+ rectype="A",
+ answer=ip2,
+ ),
+ ]
+ rev_updates = [
+ DynamicDNSUpdate.as_reverse_record_update(update, str(network))
+ for update in fwd_updates
+ ]
+ zone = DNSReverseZoneConfig(
+ domain,
+ serial=random.randint(1, 100),
+ network=network,
+ dynamic_updates=rev_updates,
+ )
+ glue_rev_updates = [
+ DynamicDNSUpdate.as_reverse_record_update(
+ update, str(glue_network)
+ )
+ for update in fwd_updates
+ ]
+ glue_zone = DNSReverseZoneConfig(
+ domain,
+ serial=random.randint(1, 100),
+ network=glue_network,
+ dynamic_updates=glue_rev_updates,
+ )
+ expected_stdin = "\n".join(
+ [
+ "server localhost",
+ "zone 0-26.0.0.10.in-addr.arpa",
+ f"update add {IPAddress(ip1).reverse_dns} {zone.default_ttl} PTR {hostname1}",
+ f"update add {IPAddress(ip2).reverse_dns} {zone.default_ttl} PTR {hostname2}",
+ f"update add 0-26.0.0.10.in-addr.arpa {zone.default_ttl} SOA 0-26.0.0.10.in-addr.arpa. nobody.example.com. {zone.serial} 600 1800 604800 {zone.default_ttl}",
+ "send\n",
+ ]
+ )
+ glue_expected_stdin = "\n".join(
+ [
+ "server localhost",
+ "zone 0.0.10.in-addr.arpa",
+ f"update add {IPAddress(ip1).reverse_dns} {zone.default_ttl} PTR {hostname1}",
+ f"update add {IPAddress(ip2).reverse_dns} {zone.default_ttl} PTR {hostname2}",
+ f"update add 0.0.10.in-addr.arpa {glue_zone.default_ttl} SOA 0.0.10.in-addr.arpa. nobody.example.com. {glue_zone.serial} 600 1800 604800 {glue_zone.default_ttl}",
+ "send\n",
+ ]
+ )
+ run_command = self.patch(actions, "run_command")
+ glue_zone.write_config()
+ glue_zone.write_config()
+ run_command.assert_called_with(
+ "nsupdate",
+ "-k",
+ get_nsupdate_key_path(),
+ "-v",
+ stdin=glue_expected_stdin.encode("ascii"),
+ )
+ zone.write_config()
+ zone.write_config()
+ run_command.assert_called_with(
+ "nsupdate",
+ "-k",
+ get_nsupdate_key_path(),
+ "-v",
+ stdin=expected_stdin.encode("ascii"),
+ )
+
class TestDNSReverseZoneConfig_GetGenerateDirectives(MAASTestCase):
"""Tests for `DNSReverseZoneConfig.get_GENERATE_directives()`."""
diff --git a/src/provisioningserver/dns/zoneconfig.py b/src/provisioningserver/dns/zoneconfig.py
index eed539a..3c6e383 100644
--- a/src/provisioningserver/dns/zoneconfig.py
+++ b/src/provisioningserver/dns/zoneconfig.py
@@ -177,7 +177,8 @@ class DomainConfigBase:
[
update
for update in self._dynamic_updates
- if update.zone == zone_info.zone_name or update.subnet
+ if update.zone == zone_info.zone_name
+ or IPNetwork(update.subnet) == zone_info.subnetwork
],
serial=self.serial,
ttl=self.default_ttl,
References