Browse Source

[trac1153] avoid zonemgr exits on empty zones

chenzhengzhang 13 years ago
parent
commit
ce3be84b9f
2 changed files with 50 additions and 63 deletions
  1. 24 18
      src/bin/zonemgr/tests/zonemgr_test.py
  2. 26 45
      src/bin/zonemgr/zonemgr.py.in

+ 24 - 18
src/bin/zonemgr/tests/zonemgr_test.py

@@ -304,8 +304,8 @@ class TestZonemgrRefresh(unittest.TestCase):
         def get_zone_soa2(zone_name, db_file):
             return None
         sqlite3_ds.get_zone_soa = get_zone_soa2
-        self.assertRaises(ZonemgrException, self.zone_refresh.zonemgr_add_zone, \
-                                         ZONE_NAME_CLASS1_IN)
+        self.zone_refresh.zonemgr_add_zone(ZONE_NAME_CLASS2_IN)
+        self.assertFalse(ZONE_NAME_CLASS2_IN in self.zone_refresh._zonemgr_refresh_info)
         sqlite3_ds.get_zone_soa = old_get_zone_soa
 
     def test_zone_handle_notify(self):
@@ -440,6 +440,8 @@ class TestZonemgrRefresh(unittest.TestCase):
                                            "class": "IN" } ]
                 }
         self.zone_refresh.update_config_data(config_data)
+        self.assertTrue(("example.net.", "IN") in
+                        self.zone_refresh._zonemgr_refresh_info)
 
         # update all values
         config_data = {
@@ -479,14 +481,15 @@ class TestZonemgrRefresh(unittest.TestCase):
                     "secondary_zones": [ { "name": "doesnotexist",
                                            "class": "IN" } ]
                 }
-        self.assertRaises(ZonemgrException,
-                          self.zone_refresh.update_config_data,
-                          config_data)
-        self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
-        self.assertEqual(30, self.zone_refresh._lowerbound_retry)
-        self.assertEqual(19800, self.zone_refresh._max_transfer_timeout)
-        self.assertEqual(0.25, self.zone_refresh._refresh_jitter)
-        self.assertEqual(0.35, self.zone_refresh._reload_jitter)
+        self.zone_refresh.update_config_data(config_data)
+        self.assertFalse(("doesnotexist.", "IN")
+                         in self.zone_refresh._zonemgr_refresh_info)
+        # The other configs should be updated successful
+        self.assertEqual(61, self.zone_refresh._lowerbound_refresh)
+        self.assertEqual(31, self.zone_refresh._lowerbound_retry)
+        self.assertEqual(19801, self.zone_refresh._max_transfer_timeout)
+        self.assertEqual(0.21, self.zone_refresh._refresh_jitter)
+        self.assertEqual(0.71, self.zone_refresh._reload_jitter)
 
         # Make sure we accept 0 as a value
         config_data = {
@@ -526,10 +529,11 @@ class TestZonemgrRefresh(unittest.TestCase):
                         self.zone_refresh._zonemgr_refresh_info)
         # This one does not exist
         config.set_zone_list_from_name_classes(["example.net", "CH"])
-        self.assertRaises(ZonemgrException,
-                          self.zone_refresh.update_config_data, config)
-        # So it should not affect the old ones
-        self.assertTrue(("example.net.", "IN") in
+        self.zone_refresh.update_config_data(config)
+        self.assertFalse(("example.net.", "CH") in
+                        self.zone_refresh._zonemgr_refresh_info)
+        # Simply skip the zone, the other configs should be updated successful
+        self.assertFalse(("example.net.", "IN") in
                         self.zone_refresh._zonemgr_refresh_info)
         # Make sure it works even when we "accidentally" forget the final dot
         config.set_zone_list_from_name_classes([("example.net", "IN")])
@@ -596,15 +600,17 @@ class TestZonemgr(unittest.TestCase):
         config_data3 = {"refresh_jitter" : 0.7}
         self.zonemgr.config_handler(config_data3)
         self.assertEqual(0.5, self.zonemgr._config_data.get("refresh_jitter"))
-        # The zone doesn't exist in database, it should be rejected
+        # The zone doesn't exist in database, simply skip it and log an error
         self.zonemgr._zone_refresh = ZonemgrRefresh(None, "initdb.file", None,
                                                     config_data1)
         config_data1["secondary_zones"] = [{"name": "nonexistent.example",
                                             "class": "IN"}]
-        self.assertNotEqual(self.zonemgr.config_handler(config_data1),
+        self.assertEqual(self.zonemgr.config_handler(config_data1),
                             {"result": [0]})
-        # As it is rejected, the old value should be kept
-        self.assertEqual(0.5, self.zonemgr._config_data.get("refresh_jitter"))
+        # other configs should be updated successful
+        self.assertFalse(("nonexistent.example.", "IN") in
+                          self.zonemgr._zone_refresh._zonemgr_refresh_info)
+        self.assertEqual(0.1, self.zonemgr._config_data.get("refresh_jitter"))
 
     def test_get_db_file(self):
         self.assertEqual("initdb.file", self.zonemgr.get_db_file())

+ 26 - 45
src/bin/zonemgr/zonemgr.py.in

@@ -202,7 +202,7 @@ class ZonemgrRefresh:
         zone_soa = sqlite3_ds.get_zone_soa(str(zone_name_class[0]), self._db_file)
         if not zone_soa:
             logger.error(ZONEMGR_NO_SOA, zone_name_class[0], zone_name_class[1])
-            raise ZonemgrException("[b10-zonemgr] zone (%s, %s) doesn't have soa." % zone_name_class)
+            return
         zone_info["zone_soa_rdata"] = zone_soa[7]
         zone_info["zone_state"] = ZONE_OK
         zone_info["last_refresh_time"] = self._get_current_time()
@@ -420,12 +420,6 @@ class ZonemgrRefresh:
 
     def update_config_data(self, new_config):
         """ update ZonemgrRefresh config """
-        # TODO: we probably want to store all this info in a nice
-        # class, so that we don't have to backup and restore every
-        # single value.
-        # TODO2: We also don't use get_default_value yet
-        backup = self._zonemgr_refresh_info.copy()
-
         # Get a new value, but only if it is defined (commonly used below)
         # We don't use "value or default", because if value would be
         # 0, we would take default
@@ -435,58 +429,45 @@ class ZonemgrRefresh:
             else:
                 return default
 
-        # store the values so we can restore them if there is a problem
-        lowerbound_refresh_backup = self._lowerbound_refresh
         self._lowerbound_refresh = val_or_default(
             new_config.get('lowerbound_refresh'), self._lowerbound_refresh)
 
-        lowerbound_retry_backup = self._lowerbound_retry
         self._lowerbound_retry = val_or_default(
             new_config.get('lowerbound_retry'), self._lowerbound_retry)
 
-        max_transfer_timeout_backup = self._max_transfer_timeout
         self._max_transfer_timeout = val_or_default(
             new_config.get('max_transfer_timeout'), self._max_transfer_timeout)
 
-        refresh_jitter_backup = self._refresh_jitter
         self._refresh_jitter = val_or_default(
             new_config.get('refresh_jitter'), self._refresh_jitter)
 
-        reload_jitter_backup = self._reload_jitter
         self._reload_jitter = val_or_default(
             new_config.get('reload_jitter'), self._reload_jitter)
-        try:
-            required = {}
-            secondary_zones = new_config.get('secondary_zones')
-            if secondary_zones is not None:
-                # Add new zones
-                for secondary_zone in new_config.get('secondary_zones'):
-                    name = secondary_zone['name']
-                    # Be tolerant to sclerotic users who forget the final dot
-                    if name[-1] != '.':
-                        name = name + '.'
-                    name_class = (name, secondary_zone['class'])
-                    required[name_class] = True
-                    # Add it only if it isn't there already
-                    if not name_class in self._zonemgr_refresh_info:
-                        self.zonemgr_add_zone(name_class)
-                # Drop the zones that are no longer there
-                # Do it in two phases, python doesn't like deleting while iterating
-                to_drop = []
-                for old_zone in self._zonemgr_refresh_info:
-                    if not old_zone in required:
-                        to_drop.append(old_zone)
-                for drop in to_drop:
-                    del self._zonemgr_refresh_info[drop]
-        # If we are not able to find it in database, restore the original
-        except:
-            self._zonemgr_refresh_info = backup
-            self._lowerbound_refresh = lowerbound_refresh_backup
-            self._lowerbound_retry = lowerbound_retry_backup
-            self._max_transfer_timeout = max_transfer_timeout_backup
-            self._refresh_jitter = refresh_jitter_backup
-            self._reload_jitter = reload_jitter_backup
-            raise
+
+        required = {}
+        secondary_zones = new_config.get('secondary_zones')
+        if secondary_zones is not None:
+            # Add new zones
+            for secondary_zone in new_config.get('secondary_zones'):
+                name = secondary_zone['name']
+                # Be tolerant to sclerotic users who forget the final dot
+                if name[-1] != '.':
+                    name = name + '.'
+                name_class = (name, secondary_zone['class'])
+                required[name_class] = True
+                # Add it only if it isn't there already
+                if not name_class in self._zonemgr_refresh_info:
+                    # If we are not able to find it in database, simply skip
+                    # it and log an error
+                    self.zonemgr_add_zone(name_class)
+            # Drop the zones that are no longer there
+            # Do it in two phases, python doesn't like deleting while iterating
+            to_drop = []
+            for old_zone in self._zonemgr_refresh_info:
+                if not old_zone in required:
+                    to_drop.append(old_zone)
+            for drop in to_drop:
+                del self._zonemgr_refresh_info[drop]
 
 class Zonemgr:
     """Zone manager class."""