← Back to team overview

sts-sponsors team mailing list archive

[Merge] ~cgrabowski/maas:backport_ensure_dns_is_reloaded_on_restart_to_3.3 into maas:3.3

 

Christian Grabowski has proposed merging ~cgrabowski/maas:backport_ensure_dns_is_reloaded_on_restart_to_3.3 into maas:3.3.

Commit message:
start region controller loop with conditions to reload DNS
reload DNS when a controller is modified
(cherry picked from commit d3851a9f6d496b93adce8bae62bbef87cdb5760b)



Requested reviews:
  Christian Grabowski (cgrabowski)

For more details, see:
https://code.launchpad.net/~cgrabowski/maas/+git/maas/+merge/435271
-- 
Your team MAAS Committers is subscribed to branch maas:3.3.
diff --git a/src/maasserver/region_controller.py b/src/maasserver/region_controller.py
index 69eae10..a7fa69c 100644
--- a/src/maasserver/region_controller.py
+++ b/src/maasserver/region_controller.py
@@ -94,11 +94,11 @@ class RegionControllerService(Service):
         self.processing = LoopingCall(self.process)
         self.processing.clock = self.clock
         self.processingDefer = None
-        self.needsDNSUpdate = False
+        self.needsDNSUpdate = True  # reload DNS on start of region
         self.needsProxyUpdate = False
         self.needsRBACUpdate = False
         self._dns_updates = []
-        self._dns_requires_full_reload = False
+        self._dns_requires_full_reload = True
         self.postgresListener = postgresListener
         self.dnsResolver = Resolver(
             resolv=None,
diff --git a/src/maasserver/tests/test_region_controller.py b/src/maasserver/tests/test_region_controller.py
index 4f40354..4e97cdd 100644
--- a/src/maasserver/tests/test_region_controller.py
+++ b/src/maasserver/tests/test_region_controller.py
@@ -53,7 +53,7 @@ class TestRegionControllerService(MAASServerTestCase):
             MatchesStructure.byEquality(
                 clock=reactor,
                 processingDefer=None,
-                needsDNSUpdate=False,
+                needsDNSUpdate=True,
                 postgresListener=sentinel.listener,
             ),
         )
@@ -157,6 +157,19 @@ class TestRegionControllerService(MAASServerTestCase):
 
     @wait_for_reactor
     @inlineCallbacks
+    def test_reload_dns_on_start(self):
+        service = self.make_service(sentinel.listener)
+        mock_dns_update_all_zones = self.patch(
+            region_controller, "dns_update_all_zones"
+        )
+        service.startProcessing()
+        yield service.processingDefer
+        mock_dns_update_all_zones.assert_called_once()
+        self.assertFalse(service.needsDNSUpdate)
+        self.assertFalse(service._dns_requires_full_reload)
+
+    @wait_for_reactor
+    @inlineCallbacks
     def test_process_doesnt_update_zones_when_nothing_to_process(self):
         service = self.make_service(sentinel.listener)
         service.needsDNSUpdate = False
@@ -218,7 +231,7 @@ class TestRegionControllerService(MAASServerTestCase):
         service.startProcessing()
         yield service.processingDefer
         mock_dns_update_all_zones.assert_called_once_with(
-            dynamic_updates=[], requires_reload=False
+            dynamic_updates=[], requires_reload=True
         )
         self.assertThat(mock_check_serial, MockCalledOnceWith(dns_result))
         self.assertThat(
@@ -263,7 +276,7 @@ class TestRegionControllerService(MAASServerTestCase):
         self.assertThat(
             mock_dns_update_all_zones,
             MockCallsMatch(
-                call(dynamic_updates=[], requires_reload=False),
+                call(dynamic_updates=[], requires_reload=True),
                 call(dynamic_updates=[], requires_reload=False),
             ),
         )
@@ -321,7 +334,7 @@ class TestRegionControllerService(MAASServerTestCase):
         service.startProcessing()
         yield service.processingDefer
         mock_dns_update_all_zones.assert_called_once_with(
-            dynamic_updates=[], requires_reload=False
+            dynamic_updates=[], requires_reload=True
         )
         self.assertThat(
             mock_err, MockCalledOnceWith(ANY, "Failed configuring DNS.")
@@ -410,7 +423,7 @@ class TestRegionControllerService(MAASServerTestCase):
         service.startProcessing()
         yield service.processingDefer
         mock_dns_update_all_zones.assert_called_once_with(
-            dynamic_updates=[], requires_reload=False
+            dynamic_updates=[], requires_reload=True
         )
         mock_proxy_update_config.assert_called_once_with(reload_proxy=True)
         mock_rbacSync.assert_called_once()
@@ -635,7 +648,7 @@ class TestRegionControllerServiceTransactional(MAASTransactionServerTestCase):
         service.startProcessing()
         yield service.processingDefer
         mock_dns_update_all_zones.assert_called_once_with(
-            dynamic_updates=[], requires_reload=False
+            dynamic_updates=[], requires_reload=True
         )
         self.assertThat(mock_check_serial, MockCalledOnceWith(dns_result))
         self.assertThat(
@@ -681,7 +694,7 @@ class TestRegionControllerServiceTransactional(MAASTransactionServerTestCase):
             for publication in reversed(publications[1:])
         )
         mock_dns_update_all_zones.assert_called_once_with(
-            dynamic_updates=[], requires_reload=False
+            dynamic_updates=[], requires_reload=True
         )
         self.assertThat(mock_check_serial, MockCalledOnceWith(dns_result))
         self.assertThat(mock_msg, MockCalledOnceWith(expected_msg))
diff --git a/src/maasserver/triggers/system.py b/src/maasserver/triggers/system.py
index 3f7f328..8e5ba5a 100644
--- a/src/maasserver/triggers/system.py
+++ b/src/maasserver/triggers/system.py
@@ -12,6 +12,7 @@ for.
 
 from textwrap import dedent
 
+from maasserver.enum import NODE_TYPE
 from maasserver.models.dnspublication import zone_serial
 from maasserver.triggers import register_procedure, register_trigger
 from maasserver.utils.orm import transactional
@@ -2131,22 +2132,34 @@ dns_dynamic_update_static_ip_address_update = dedent(
     """
 )
 
-dns_dynamic_update_node_delete = dedent(
-    """\
-    CREATE OR REPLACE FUNCTION sys_dns_updates_maasserver_node_delete()
-    RETURNS trigger as $$
-    DECLARE
-      hostname text;
-      domain text;
-      address_ttl int;
-    BEGIN
-      SELECT name, COALESCE(ttl, 0) INTO domain, address_ttl FROM maasserver_domain WHERE id=OLD.domain_id;
-      PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || OLD.hostname || ' A');
-      RETURN NULL;
-    END;
-    $$ LANGUAGE plpgsql;
-    """
-)
+
+def render_dns_dynamic_update_node(op):
+    return dedent(
+        f"""\
+        CREATE OR REPLACE FUNCTION sys_dns_updates_maasserver_node_{op}()
+        RETURNS trigger as $$
+        DECLARE
+          hostname text;
+          domain text;
+          address_ttl int;
+        BEGIN
+          IF ((TG_OP = 'INSERT' OR  TG_OP = 'UPDATE') AND TG_LEVEL = 'ROW') THEN
+              IF NEW.node_type <> {NODE_TYPE.DEVICE} AND NEW.node_type <> {NODE_TYPE.MACHINE} THEN
+                  PERFORM pg_notify('sys_dns_updates', 'RELOAD');
+              END IF;
+          ELSE
+              IF NEW.node_type <> {NODE_TYPE.DEVICE} AND NEW.node_type <> {NODE_TYPE.MACHINE} THEN
+                  PERFORM pg_notify('sys_dns_updates', 'RELOAD');
+              ELSE
+                  SELECT name, COALESCE(ttl, 0) INTO domain, address_ttl FROM maasserver_domain WHERE id=OLD.domain_id;
+                  PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || OLD.hostname || ' A');
+              END IF;
+          END IF;
+          RETURN NULL;
+        END;
+        $$ LANGUAGE plpgsql;
+        """
+    )
 
 
 dns_dynamic_update_interface_delete = dedent(
@@ -2543,7 +2556,19 @@ def register_system_triggers():
         "sys_dns_updates_ip_update",
         "update",
     )
-    register_procedure(dns_dynamic_update_node_delete)
+    register_procedure(render_dns_dynamic_update_node("insert"))
+    register_trigger(
+        "maasserver_node",
+        "sys_dns_updates_maasserver_node_insert",
+        "insert",
+    )
+    register_procedure(render_dns_dynamic_update_node("update"))
+    register_trigger(
+        "maasserver_node",
+        "sys_dns_updates_maasserver_node_update",
+        "update",
+    )
+    register_procedure(render_dns_dynamic_update_node("delete"))
     register_trigger(
         "maasserver_node",
         "sys_dns_updates_maasserver_node_delete",
diff --git a/src/maasserver/triggers/tests/test_init.py b/src/maasserver/triggers/tests/test_init.py
index 34395f1..73bfcde 100644
--- a/src/maasserver/triggers/tests/test_init.py
+++ b/src/maasserver/triggers/tests/test_init.py
@@ -102,6 +102,8 @@ class TestTriggersUsed(MAASServerTestCase):
         "node_sys_dhcp_node_update",
         "node_sys_dns_node_delete",
         "node_sys_dns_node_update",
+        "node_sys_dns_updates_maasserver_node_insert",
+        "node_sys_dns_updates_maasserver_node_update",
         "node_sys_dns_updates_maasserver_node_delete",
         "rbacsync_sys_rbac_sync",
         "regionrackrpcconnection_sys_core_rpc_delete",
diff --git a/src/maasserver/triggers/tests/test_system.py b/src/maasserver/triggers/tests/test_system.py
index 4337984..ce7398e 100644
--- a/src/maasserver/triggers/tests/test_system.py
+++ b/src/maasserver/triggers/tests/test_system.py
@@ -7,7 +7,7 @@ from contextlib import closing
 from django.db import connection
 from twisted.internet.defer import inlineCallbacks
 
-from maasserver.enum import NODE_STATUS
+from maasserver.enum import NODE_STATUS, NODE_TYPE
 from maasserver.models import Domain
 from maasserver.models.dnspublication import zone_serial
 from maasserver.testing.factory import factory
@@ -386,11 +386,20 @@ class TestSysDNSUpdates(
         subnet = yield deferToDatabase(
             self.create_subnet, params={"vlan": vlan}
         )
+        rack_controller = yield deferToDatabase(
+            self.create_rack_controller,
+            params={"vlan": vlan, "subnet": subnet},
+        )
         self.start_reading()
         try:
             node = yield deferToDatabase(
                 self.create_node_with_interface,
-                params={"subnet": subnet, "status": NODE_STATUS.DEPLOYED},
+                params={
+                    "subnet": subnet,
+                    "status": NODE_STATUS.DEPLOYED,
+                    "node_type": NODE_TYPE.MACHINE,
+                    "primary_rack": rack_controller,
+                },
             )
             domain = yield deferToDatabase(Domain.objects.get_default_domain)
             expected_iface = yield deferToDatabase(
@@ -438,6 +447,10 @@ class TestSysDNSUpdates(
             self.create_subnet, params={"vlan": vlan}
         )
         domain = yield deferToDatabase(self.create_domain)
+        rack_controller = yield deferToDatabase(
+            self.create_rack_controller,
+            params={"vlan": vlan, "subnet": subnet},
+        )
         self.start_reading()
         try:
             node = yield deferToDatabase(
@@ -446,6 +459,8 @@ class TestSysDNSUpdates(
                     "subnet": subnet,
                     "status": NODE_STATUS.DEPLOYED,
                     "domain": domain,
+                    "node_type": NODE_TYPE.MACHINE,
+                    "primary_rack": rack_controller,
                 },
             )
             expected_iface = yield deferToDatabase(
@@ -589,6 +604,48 @@ class TestSysDNSUpdates(
 
     @wait_for_reactor
     @inlineCallbacks
+    def test_dns_dynamic_update_controller_insert(self):
+        listener = self.make_listener_without_delay()
+        yield self.set_service(listener)
+        yield deferToDatabase(
+            self.register_trigger,
+            "maasserver_node",
+            "sys_dns_updates",
+            ops=("insert",),
+        )
+        self.start_reading()
+        try:
+            yield deferToDatabase(self.create_rack_controller)
+            msg = yield self.get_notify("sys_dns_updates")
+            self.assertEqual(msg, "RELOAD")
+        finally:
+            self.stop_reading()
+            yield self.postgres_listener_service.stopService()
+
+    @wait_for_reactor
+    @inlineCallbacks
+    def test_dns_dynamic_update_controller_update(self):
+        listener = self.make_listener_without_delay()
+        yield self.set_service(listener)
+        yield deferToDatabase(
+            self.register_trigger,
+            "maasserver_node",
+            "sys_dns_updates",
+            ops=("update",),
+        )
+        self.start_reading()
+        controller = yield deferToDatabase(self.create_rack_controller)
+        try:
+            controller.cpu_speed = 10
+            yield deferToDatabase(controller.save)
+            msg = yield self.get_notify("sys_dns_updates")
+            self.assertEqual(msg, "RELOAD")
+        finally:
+            self.stop_reading()
+            yield self.postgres_listener_service.stopService()
+
+    @wait_for_reactor
+    @inlineCallbacks
     def test_dns_dynamic_update_node_delete(self):
         listener = self.make_listener_without_delay()
         yield self.set_service(listener)

Follow ups