Merge ~cgrabowski/maas:backport_fix_dynamic_updates_for_glue_zones_to_3.3 into maas:3.3

Proposed by Christian Grabowski
Status: Merged
Approved by: Alberto Donato
Approved revision: feec45549f83bf7110fe47aaf1d3b666a6c22c6d
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~cgrabowski/maas:backport_fix_dynamic_updates_for_glue_zones_to_3.3
Merge into: maas:3.3
Diff against target: 231 lines (+159/-7)
4 files modified
src/maasserver/dns/tests/test_zonegenerator.py (+44/-0)
src/maasserver/dns/zonegenerator.py (+26/-6)
src/provisioningserver/dns/tests/test_zoneconfig.py (+87/-0)
src/provisioningserver/dns/zoneconfig.py (+2/-1)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Christian Grabowski Approve
Review via email: mp+434708@code.launchpad.net

Commit message

fix adding dynamic updates for reverse glue zones
(cherry picked from commit 654d7968ef00118b3ed8dda9769ec1f578e81339)

To post a comment you must log in.
Revision history for this message
Christian Grabowski (cgrabowski) wrote :

self-approving backport

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

LANDING
-b backport_fix_dynamic_updates_for_glue_zones_to_3.3 lp:~cgrabowski/maas/+git/maas into -b 3.3 lp:~maas-committers/maas

STATUS: FAILED BUILD
LOG: http://maas-ci.internal:8080/job/maas-tester/1643/consoleText

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b backport_fix_dynamic_updates_for_glue_zones_to_3.3 lp:~cgrabowski/maas/+git/maas into -b 3.3 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: feec45549f83bf7110fe47aaf1d3b666a6c22c6d

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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
48from maastesting.factory import factory as maastesting_factory48from maastesting.factory import factory as maastesting_factory
49from maastesting.fakemethod import FakeMethod49from maastesting.fakemethod import FakeMethod
50from maastesting.matchers import MockAnyCall, MockCalledOnceWith, MockNotCalled50from maastesting.matchers import MockAnyCall, MockCalledOnceWith, MockNotCalled
51from provisioningserver.dns.config import DynamicDNSUpdate
51from provisioningserver.dns.zoneconfig import (52from provisioningserver.dns.zoneconfig import (
52 DNSForwardZoneConfig,53 DNSForwardZoneConfig,
53 DNSReverseZoneConfig,54 DNSReverseZoneConfig,
@@ -510,6 +511,49 @@ class TestZoneGenerator(MAASServerTestCase):
510 }511 }
511 self.assertEqual(expected_map, zones[0]._other_mapping)512 self.assertEqual(expected_map, zones[0]._other_mapping)
512513
514 def test_glue_receives_correct_dynamic_updates(self):
515 domain = factory.make_Domain()
516 subnet = factory.make_Subnet(cidr=str(IPNetwork("10/29").cidr))
517 sip = factory.make_StaticIPAddress(subnet=subnet)
518 factory.make_Node_with_Interface_on_Subnet(
519 subnet=subnet, vlan=subnet.vlan, fabric=subnet.vlan.fabric
520 )
521 update_rec = factory.make_DNSResource(
522 name=factory.make_name(), domain=domain, ip_addresses=[sip]
523 )
524 updates = [
525 DynamicDNSUpdate(
526 operation="INSERT",
527 name=update_rec.name,
528 zone=domain.name,
529 rectype="A",
530 answer=sip.ip,
531 )
532 ]
533 zones = ZoneGenerator(
534 domain,
535 subnet,
536 serial=random.randint(0, 65535),
537 dynamic_updates=updates,
538 ).as_list()
539 self.assertCountEqual(zones[0]._dynamic_updates, updates)
540 self.assertCountEqual(
541 zones[1]._dynamic_updates,
542 [
543 DynamicDNSUpdate.as_reverse_record_update(
544 updates[0], str(IPNetwork("10/29"))
545 )
546 ],
547 )
548 self.assertCountEqual(
549 zones[2]._dynamic_updates,
550 [
551 DynamicDNSUpdate.as_reverse_record_update(
552 updates[0], str(IPNetwork("10/24"))
553 )
554 ],
555 )
556
513 def test_parent_of_default_domain_gets_glue(self):557 def test_parent_of_default_domain_gets_glue(self):
514 default_domain = Domain.objects.get_default_domain()558 default_domain = Domain.objects.get_default_domain()
515 default_domain.name = "maas.example.com"559 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:
452 glue = set()452 glue = set()
453453
454 domain_updates = [454 domain_updates = [
455 DynamicDNSUpdate.as_reverse_record_update(update, subnet)455 DynamicDNSUpdate.as_reverse_record_update(
456 update, str(subnet.cidr)
457 )
456 for update in dynamic_updates458 for update in dynamic_updates
457 if update.answer459 if update.answer
458 and update.answer_is_ip460 and update.answer_is_ip
@@ -476,6 +478,28 @@ class ZoneGenerator:
476 )478 )
477 # Now provide any remaining rfc2317 glue networks.479 # Now provide any remaining rfc2317 glue networks.
478 for network, ranges in rfc2317_glue.items():480 for network, ranges in rfc2317_glue.items():
481 exclude_set = {
482 IPNetwork(s.cidr)
483 for s in subnets
484 if network in IPNetwork(s.cidr)
485 }
486 domain_updates = []
487 for update in dynamic_updates:
488 glue_update = True
489 for exclude_net in exclude_set:
490 if (
491 update.answer
492 and update.answer_is_ip
493 and IPAddress(update.answer) in exclude_net
494 ):
495 glue_update = False
496 break
497 if glue_update:
498 domain_updates.append(
499 DynamicDNSUpdate.as_reverse_record_update(
500 update, str(network)
501 )
502 )
479 yield DNSReverseZoneConfig(503 yield DNSReverseZoneConfig(
480 ns_host_name,504 ns_host_name,
481 serial=serial,505 serial=serial,
@@ -483,11 +507,7 @@ class ZoneGenerator:
483 network=network,507 network=network,
484 ns_host_name=ns_host_name,508 ns_host_name=ns_host_name,
485 rfc2317_ranges=ranges,509 rfc2317_ranges=ranges,
486 exclude={510 exclude=exclude_set,
487 IPNetwork(s.cidr)
488 for s in subnets
489 if network in IPNetwork(s.cidr)
490 },
491 dynamic_updates=domain_updates,511 dynamic_updates=domain_updates,
492 force_config_write=force_config_write,512 force_config_write=force_config_write,
493 )513 )
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):
967 stdin=expected_stdin.encode("ascii"),967 stdin=expected_stdin.encode("ascii"),
968 )968 )
969969
970 def test_glue_network_zone_contains_appropriate_dynamic_updates(self):
971 patch_zone_file_config_path(self)
972 domain = factory.make_string()
973 network = IPNetwork("10.0.0.0/26")
974 glue_network = IPNetwork("10.0.0.0/24")
975 ip1 = factory.pick_ip_in_network(network)
976 ip2 = factory.pick_ip_in_network(network)
977 hostname1 = f"{factory.make_string()}.{domain}"
978 hostname2 = f"{factory.make_string()}.{domain}"
979 fwd_updates = [
980 DynamicDNSUpdate(
981 operation="INSERT",
982 zone=domain,
983 name=hostname1,
984 rectype="A",
985 answer=ip1,
986 ),
987 DynamicDNSUpdate(
988 operation="INSERT",
989 zone=domain,
990 name=hostname2,
991 rectype="A",
992 answer=ip2,
993 ),
994 ]
995 rev_updates = [
996 DynamicDNSUpdate.as_reverse_record_update(update, str(network))
997 for update in fwd_updates
998 ]
999 zone = DNSReverseZoneConfig(
1000 domain,
1001 serial=random.randint(1, 100),
1002 network=network,
1003 dynamic_updates=rev_updates,
1004 )
1005 glue_rev_updates = [
1006 DynamicDNSUpdate.as_reverse_record_update(
1007 update, str(glue_network)
1008 )
1009 for update in fwd_updates
1010 ]
1011 glue_zone = DNSReverseZoneConfig(
1012 domain,
1013 serial=random.randint(1, 100),
1014 network=glue_network,
1015 dynamic_updates=glue_rev_updates,
1016 )
1017 expected_stdin = "\n".join(
1018 [
1019 "server localhost",
1020 "zone 0-26.0.0.10.in-addr.arpa",
1021 f"update add {IPAddress(ip1).reverse_dns} {zone.default_ttl} PTR {hostname1}",
1022 f"update add {IPAddress(ip2).reverse_dns} {zone.default_ttl} PTR {hostname2}",
1023 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}",
1024 "send\n",
1025 ]
1026 )
1027 glue_expected_stdin = "\n".join(
1028 [
1029 "server localhost",
1030 "zone 0.0.10.in-addr.arpa",
1031 f"update add {IPAddress(ip1).reverse_dns} {zone.default_ttl} PTR {hostname1}",
1032 f"update add {IPAddress(ip2).reverse_dns} {zone.default_ttl} PTR {hostname2}",
1033 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}",
1034 "send\n",
1035 ]
1036 )
1037 run_command = self.patch(actions, "run_command")
1038 glue_zone.write_config()
1039 glue_zone.write_config()
1040 run_command.assert_called_with(
1041 "nsupdate",
1042 "-k",
1043 get_nsupdate_key_path(),
1044 "-v",
1045 stdin=glue_expected_stdin.encode("ascii"),
1046 )
1047 zone.write_config()
1048 zone.write_config()
1049 run_command.assert_called_with(
1050 "nsupdate",
1051 "-k",
1052 get_nsupdate_key_path(),
1053 "-v",
1054 stdin=expected_stdin.encode("ascii"),
1055 )
1056
9701057
971class TestDNSReverseZoneConfig_GetGenerateDirectives(MAASTestCase):1058class TestDNSReverseZoneConfig_GetGenerateDirectives(MAASTestCase):
972 """Tests for `DNSReverseZoneConfig.get_GENERATE_directives()`."""1059 """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:
177 [177 [
178 update178 update
179 for update in self._dynamic_updates179 for update in self._dynamic_updates
180 if update.zone == zone_info.zone_name or update.subnet180 if update.zone == zone_info.zone_name
181 or IPNetwork(update.subnet) == zone_info.subnetwork
181 ],182 ],
182 serial=self.serial,183 serial=self.serial,
183 ttl=self.default_ttl,184 ttl=self.default_ttl,

Subscribers

People subscribed via source and target branches