Commit ce3be84b authored by chenzhengzhang's avatar chenzhengzhang
Browse files

[trac1153] avoid zonemgr exits on empty zones

parent 20871297
......@@ -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())
......
......@@ -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."""
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment