Browse Source

[1976] Send the loadzone command every time

With the new configuration syntax, it would be hard for the DDNS and
XfrIn to check if the zone needs to be reloaded or not. So we send the
command every time and leave it up to the ClientList to decide on the
other side.

Also, the datasrc parameter is no longer supported and makes no sense,
so it was removed.

A lot of tests had to be modified or ripped out (the ripped ones tested
the command is not sent when not needed).
Michal 'vorner' Vaner 12 years ago
parent
commit
441ea8549d

+ 17 - 21
src/bin/ddns/tests/ddns_test.py

@@ -1132,7 +1132,7 @@ class TestDDNSSession(unittest.TestCase):
         num_rrsets = len(self.__req_message.get_section(SECTION_PREREQUISITE))
         num_rrsets = len(self.__req_message.get_section(SECTION_PREREQUISITE))
         self.assertEqual(2, num_rrsets)
         self.assertEqual(2, num_rrsets)
 
 
-    def check_session_msg(self, result, expect_recv=1, notify_auth=False):
+    def check_session_msg(self, result, expect_recv=2):
         '''Check post update communication with other modules.'''
         '''Check post update communication with other modules.'''
         # iff the update succeeds, b10-ddns should tell interested other
         # iff the update succeeds, b10-ddns should tell interested other
         # modules the information about the update zone.  Possible modules
         # modules the information about the update zone.  Possible modules
@@ -1141,32 +1141,28 @@ class TestDDNSSession(unittest.TestCase):
         #                         'zone_class', <updated_zone_class>}]}
         #                         'zone_class', <updated_zone_class>}]}
         # for auth, it should be:
         # for auth, it should be:
         # {'command': ['loadzone', {'origin': <updated_zone_name>,
         # {'command': ['loadzone', {'origin': <updated_zone_name>,
-        #                           'class', <updated_zone_class>,
+        #                           'class', <updated_zone_class>}]}
-        #                           'datasrc', <datasrc type, should be
-        #                                       "memory" in practice>}]}
         # and expect an answer by calling group_recvmsg().
         # and expect an answer by calling group_recvmsg().
         #
         #
         # expect_recv indicates the expected number of calls to
         # expect_recv indicates the expected number of calls to
-        # group_recvmsg(), which is normally 1, but can be 0 if send fails;
+        # group_recvmsg(), which is normally 2, but can be 0 if send fails;
         # if the message is to be sent
         # if the message is to be sent
         if result == UPDATE_SUCCESS:
         if result == UPDATE_SUCCESS:
-            expected_sentmsg = 2 if notify_auth else 1
+            expected_sentmsg = 2
             self.assertEqual(expected_sentmsg,
             self.assertEqual(expected_sentmsg,
                              len(self.__cc_session._sent_msg))
                              len(self.__cc_session._sent_msg))
             self.assertEqual(expect_recv, self.__cc_session._recvmsg_called)
             self.assertEqual(expect_recv, self.__cc_session._recvmsg_called)
             msg_cnt = 0
             msg_cnt = 0
-            if notify_auth:
+            sent_msg, sent_group = self.__cc_session._sent_msg[msg_cnt]
-                sent_msg, sent_group = self.__cc_session._sent_msg[msg_cnt]
+            sent_cmd = sent_msg['command']
-                sent_cmd = sent_msg['command']
+            self.assertEqual('Auth', sent_group)
-                self.assertEqual('Auth', sent_group)
+            self.assertEqual('loadzone', sent_cmd[0])
-                self.assertEqual('loadzone', sent_cmd[0])
+            self.assertEqual(2, len(sent_cmd[1]))
-                self.assertEqual(3, len(sent_cmd[1]))
+            self.assertEqual(TEST_ZONE_NAME.to_text(),
-                self.assertEqual(TEST_ZONE_NAME.to_text(),
+                             sent_cmd[1]['origin'])
-                                 sent_cmd[1]['origin'])
+            self.assertEqual(TEST_RRCLASS.to_text(),
-                self.assertEqual(TEST_RRCLASS.to_text(),
+                             sent_cmd[1]['class'])
-                                 sent_cmd[1]['class'])
+            msg_cnt += 1
-                self.assertEqual('memory', sent_cmd[1]['datasrc'])
-                msg_cnt += 1
             sent_msg, sent_group = self.__cc_session._sent_msg[msg_cnt]
             sent_msg, sent_group = self.__cc_session._sent_msg[msg_cnt]
             sent_cmd = sent_msg['command']
             sent_cmd = sent_msg['command']
             self.assertEqual('Xfrout', sent_group)
             self.assertEqual('Xfrout', sent_group)
@@ -1232,21 +1228,21 @@ class TestDDNSSession(unittest.TestCase):
             [{'type': 'memory', 'class': 'IN', 'zones': [
             [{'type': 'memory', 'class': 'IN', 'zones': [
                     {'origin': TEST_ZONE_NAME_STR, 'filetype': 'sqlite3'}]}]
                     {'origin': TEST_ZONE_NAME_STR, 'filetype': 'sqlite3'}]}]
         self.check_session()
         self.check_session()
-        self.check_session_msg(UPDATE_SUCCESS, expect_recv=2, notify_auth=True)
+        self.check_session_msg(UPDATE_SUCCESS)
 
 
         # Let sendmsg() raise an exception.  The first exception shouldn't
         # Let sendmsg() raise an exception.  The first exception shouldn't
         # stop sending the second message.  There's just no recv calls.
         # stop sending the second message.  There's just no recv calls.
         self.__cc_session.clear_msg()
         self.__cc_session.clear_msg()
         self.__cc_session._sendmsg_exception = SessionError('send error')
         self.__cc_session._sendmsg_exception = SessionError('send error')
         self.check_session()
         self.check_session()
-        self.check_session_msg(UPDATE_SUCCESS, expect_recv=0, notify_auth=True)
+        self.check_session_msg(UPDATE_SUCCESS, expect_recv=0)
 
 
         # Likewise, in the case recvmsg() raises (and there should be recv
         # Likewise, in the case recvmsg() raises (and there should be recv
         # calls in this case)
         # calls in this case)
         self.__cc_session.clear_msg()
         self.__cc_session.clear_msg()
         self.__cc_session._recvmsg_exception = SessionError('recv error')
         self.__cc_session._recvmsg_exception = SessionError('recv error')
         self.check_session()
         self.check_session()
-        self.check_session_msg(UPDATE_SUCCESS, expect_recv=2, notify_auth=True)
+        self.check_session_msg(UPDATE_SUCCESS)
 
 
     def test_session_with_config(self):
     def test_session_with_config(self):
         '''Check a session with more realistic config setups.
         '''Check a session with more realistic config setups.

+ 7 - 143
src/bin/xfrin/tests/xfrin_test.py

@@ -2739,18 +2739,8 @@ class TestMain(unittest.TestCase):
 
 
 class TestXfrinProcessMockCC:
 class TestXfrinProcessMockCC:
     def __init__(self):
     def __init__(self):
-        self.get_called = False
-        self.get_called_correctly = False
         self.config = []
         self.config = []
 
 
-    def get_remote_config_value(self, module, identifier):
-        self.get_called = True
-        if module == 'Auth' and identifier == 'datasources':
-            self.get_called_correctly = True
-            return (self.config, False)
-        else:
-            return (None, True)
-
 class TestXfrinProcessMockCCSession:
 class TestXfrinProcessMockCCSession:
     def __init__(self):
     def __init__(self):
         self.send_called = False
         self.send_called = False
@@ -2869,22 +2859,17 @@ class TestXfrinProcess(unittest.TestCase):
         # Create a connection for each attempt
         # Create a connection for each attempt
         self.assertEqual(len(transfers), self.__created_connections)
         self.assertEqual(len(transfers), self.__created_connections)
         self.assertEqual([published], self.__published)
         self.assertEqual([published], self.__published)
-        if published == XFRIN_OK:
-            self.assertTrue(self._module_cc.get_called)
-            self.assertTrue(self._module_cc.get_called_correctly)
-        else:
-            self.assertFalse(self._module_cc.get_called)
-            self.assertFalse(self._module_cc.get_called_correctly)
 
 
     def test_ixfr_ok(self):
     def test_ixfr_ok(self):
         """
         """
         Everything OK the first time, over IXFR.
         Everything OK the first time, over IXFR.
         """
         """
         self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
         self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
+        # Check there was loadzone command
-        self.assertFalse(self._send_cc_session.send_called_correctly)
+        self.assertTrue(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.recv_called)
+        self.assertTrue(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
+        self.assertTrue(self._send_cc_session.recv_called)
+        self.assertTrue(self._send_cc_session.recv_called_correctly)
 
 
     def test_axfr_ok(self):
     def test_axfr_ok(self):
         """
         """
@@ -2916,137 +2901,16 @@ class TestXfrinProcess(unittest.TestCase):
         self.__do_test([XFRIN_FAIL, XFRIN_FAIL],
         self.__do_test([XFRIN_FAIL, XFRIN_FAIL],
                        [RRType.IXFR(), RRType.AXFR()], RRType.IXFR())
                        [RRType.IXFR(), RRType.AXFR()], RRType.IXFR())
 
 
-    def test_inmem_ok(self):
+    def test_send_loadzone(self):
         """
         """
-        Inmem configuration where all the configuration is just right
+        Check the loadzone command is sent after successful transfer.
-        for loadzone to be sent to b10-auth (origin is the name received
-        by xfrin, filetype is sqlite3, type is memory and class is the
-        one received by xfrin).
         """
         """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org', 'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'type': 'memory', 'class': 'IN'}]
         self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
         self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
         self.assertTrue(self._send_cc_session.send_called)
         self.assertTrue(self._send_cc_session.send_called)
         self.assertTrue(self._send_cc_session.send_called_correctly)
         self.assertTrue(self._send_cc_session.send_called_correctly)
         self.assertTrue(self._send_cc_session.recv_called)
         self.assertTrue(self._send_cc_session.recv_called)
         self.assertTrue(self._send_cc_session.recv_called_correctly)
         self.assertTrue(self._send_cc_session.recv_called_correctly)
 
 
-    def test_inmem_datasource_type_not_memory(self):
-        """
-        Inmem configuration where the datasource type is not memory. In
-        this case, loadzone should not be sent to b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org', 'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'type': 'punched-card', 'class': 'IN'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_datasource_type_is_missing(self):
-        """
-        Inmem configuration where the datasource type is missing. In
-        this case, loadzone should not be sent to b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org', 'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'class': 'IN'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_backend_type_not_sqlite3(self):
-        """
-        Inmem configuration where the datasource backing file is not of
-        type sqlite3. In this case, loadzone should not be sent to
-        b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org', 'filetype': 'postgresql',
-                                              'file': 'data/inmem-xfrin.db'}],
-                                   'type': 'memory', 'class': 'IN'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_backend_type_is_missing(self):
-        """
-        Inmem configuration where the datasource backing file type is
-        not set. In this case, loadzone should not be sent to b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org',
-                                              'file': 'data/inmem-xfrin'}],
-                                   'type': 'memory', 'class': 'IN'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_class_is_different(self):
-        """
-        Inmem configuration where the datasource class does not match
-        the received class. In this case, loadzone should not be sent to
-        b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org', 'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'type': 'memory', 'class': 'XX'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_class_is_missing(self):
-        """
-        Inmem configuration where the datasource class is missing. In
-        this case, we assume the IN class and loadzone may be sent to
-        b10-auth if everything else matches.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'example.org', 'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'type': 'memory'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertTrue(self._send_cc_session.send_called)
-        self.assertTrue(self._send_cc_session.send_called_correctly)
-        self.assertTrue(self._send_cc_session.recv_called)
-        self.assertTrue(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_name_doesnt_match(self):
-        """
-        Inmem configuration where the origin does not match the received
-        name. In this case, loadzone should not be sent to b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'origin': 'isc.org', 'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'type': 'memory', 'class': 'IN'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
-    def test_inmem_name_is_missing(self):
-        """
-        Inmem configuration where the origin is missing. In this case,
-        loadzone should not be sent to b10-auth.
-        """
-        self._module_cc.config = [{'zones': [{'filetype': 'sqlite3',
-                                              'file': 'data/inmem-xfrin.sqlite3'}],
-                                   'type': 'memory', 'class': 'IN'}]
-        self.__do_test([XFRIN_OK], [RRType.IXFR()], RRType.IXFR())
-        self.assertFalse(self._send_cc_session.send_called)
-        self.assertFalse(self._send_cc_session.send_called_correctly)
-        self.assertFalse(self._send_cc_session.recv_called)
-        self.assertFalse(self._send_cc_session.recv_called_correctly)
-
 class TestFormatting(unittest.TestCase):
 class TestFormatting(unittest.TestCase):
     # If the formatting functions are moved to a more general library
     # If the formatting functions are moved to a more general library
     # (ticket #1379), these tests should be moved with them.
     # (ticket #1379), these tests should be moved with them.

+ 1 - 1
src/bin/xfrin/xfrin.py.in

@@ -1252,7 +1252,7 @@ def _do_auth_loadzone(server, zone_name, zone_class):
     if msg is not None:
     if msg is not None:
         param = msg['command'][1]
         param = msg['command'][1]
         logger.debug(DBG_XFRIN_TRACE, XFRIN_AUTH_LOADZONE, param["origin"],
         logger.debug(DBG_XFRIN_TRACE, XFRIN_AUTH_LOADZONE, param["origin"],
-                     param["class"], param["datasrc"])
+                     param["class"])
         seq = server._send_cc_session.group_sendmsg(msg, AUTH_MODULE_NAME)
         seq = server._send_cc_session.group_sendmsg(msg, AUTH_MODULE_NAME)
         answer, env = server._send_cc_session.group_recvmsg(False, seq)
         answer, env = server._send_cc_session.group_recvmsg(False, seq)
 
 

+ 3 - 4
src/bin/xfrin/xfrin_messages.mes

@@ -15,10 +15,9 @@
 # No namespace declaration - these constants go in the global namespace
 # No namespace declaration - these constants go in the global namespace
 # of the xfrin messages python module.
 # of the xfrin messages python module.
 
 
-% XFRIN_AUTH_LOADZONE sending Auth loadzone for origin=%1, class=%2, datasrc=%3
+% XFRIN_AUTH_LOADZONE sending Auth loadzone for origin=%1, class=%2
-There was a successful zone transfer, and the zone is served by b10-auth
+There was a successful zone transfer.  We send the "loadzone" command for the
-in the in-memory data source using sqlite3 as a backend. We send the
+zone to b10-auth.
-"loadzone" command for the zone to b10-auth.
 
 
 % XFRIN_AXFR_INCONSISTENT_SOA AXFR SOAs are inconsistent for %1: %2 expected, %3 received
 % XFRIN_AXFR_INCONSISTENT_SOA AXFR SOAs are inconsistent for %1: %2 expected, %3 received
 The serial fields of the first and last SOAs of AXFR (including AXFR-style
 The serial fields of the first and last SOAs of AXFR (including AXFR-style

+ 10 - 43
src/lib/python/isc/server_common/auth_command.py

@@ -26,9 +26,7 @@ AUTH_MODULE_NAME = 'Auth'
 def auth_loadzone_command(module_cc, zone_name, zone_class):
 def auth_loadzone_command(module_cc, zone_name, zone_class):
     '''Create a 'loadzone' command with a given zone for Auth server.
     '''Create a 'loadzone' command with a given zone for Auth server.
 
 
-    This function checks the Auth module configuration to see if it
+    This function generates an inter-module command for Auth
-    servers a given zone via an in-memory data source on top of SQLite3
-    data source, and, if so, generate an inter-module command for Auth
     to force it to reload the zone.
     to force it to reload the zone.
 
 
     Parameters:
     Parameters:
@@ -38,9 +36,7 @@ def auth_loadzone_command(module_cc, zone_name, zone_class):
     zone_class (isc.dns.RRClass): the RR class of the zone to be possibly
     zone_class (isc.dns.RRClass): the RR class of the zone to be possibly
       reloaded.
       reloaded.
 
 
-    Return: a CC command message for the reload if the zone is found;
+    Return: a CC command message for the reload.
-      otherwise None.
-
     '''
     '''
     # Note: this function was originally a dedicated subroutine of xfrin,
     # Note: this function was originally a dedicated subroutine of xfrin,
     # but was moved here so it can be shared by some other modules
     # but was moved here so it can be shared by some other modules
@@ -50,41 +46,12 @@ def auth_loadzone_command(module_cc, zone_name, zone_class):
     # deprecated (which is a more likely scenario).  For this reason, the
     # deprecated (which is a more likely scenario).  For this reason, the
     # corresponding tests were still kept in xfrin.
     # corresponding tests were still kept in xfrin.
 
 
-    datasources, is_default =\
+    # Note: The function got very simplified by #1976. There's plan to move
-        module_cc.get_remote_config_value(AUTH_MODULE_NAME, "datasources")
+    # to notification-driven approach, at which point the function would
-    if is_default:
+    # be changed a lot.
-        return None
-    for d in datasources:
-        if "type" not in d:
-            continue
-        try:
-            if "class" in d:
-                dclass = RRClass(d["class"])
-            else:
-                dclass = RRClass("IN")
-        except InvalidRRClass as err:
-            logger.info(PYSERVER_COMMON_AUTH_CONFIG_RRCLASS_ERROR, err)
-            continue
-
-        if d["type"].lower() == "memory" and dclass == zone_class:
-            for zone in d["zones"]:
-                if "filetype" not in zone:
-                    continue
-                if "origin" not in zone:
-                    continue
-                if "filetype" not in zone:
-                    continue
-                try:
-                    name = Name(zone["origin"])
-                except (EmptyLabel, TooLongLabel, BadLabelType, BadEscape,
-                        TooLongName, IncompleteName):
-                    logger.info(PYSERVER_COMMON_AUTH_CONFIG_NAME_PARSER_ERROR,
-                                err)
-                    continue
 
 
-                if zone["filetype"].lower() == "sqlite3" and name == zone_name:
+    param = {
-                    param = {"origin": zone_name.to_text(),
+        "origin": zone_name.to_text(),
-                             "class": zone_class.to_text(),
+        "class": zone_class.to_text()
-                             "datasrc": d["type"]}
+    }
-                    return create_command("loadzone", param)
+    return create_command("loadzone", param)
-    return None

+ 0 - 6
src/lib/python/isc/server_common/server_common_messages.mes

@@ -21,12 +21,6 @@
 # have that at this moment. So when adding a message, make sure that
 # have that at this moment. So when adding a message, make sure that
 # the name is not already used in src/lib/config/config_messages.mes
 # the name is not already used in src/lib/config/config_messages.mes
 
 
-% PYSERVER_COMMON_AUTH_CONFIG_NAME_PARSER_ERROR Invalid name when parsing Auth configuration: %1
-There was an invalid name when parsing Auth configuration.
-
-% PYSERVER_COMMON_AUTH_CONFIG_RRCLASS_ERROR Invalid RRClass when parsing Auth configuration: %1
-There was an invalid RR class when parsing Auth configuration.
-
 % PYSERVER_COMMON_DNS_TCP_SEND_DONE completed sending TCP message to %1 (%2 bytes in total)
 % PYSERVER_COMMON_DNS_TCP_SEND_DONE completed sending TCP message to %1 (%2 bytes in total)
 Debug message.  A complete DNS message has been successfully
 Debug message.  A complete DNS message has been successfully
 transmitted over a TCP connection, possibly after multiple send
 transmitted over a TCP connection, possibly after multiple send