BIND 10 master, updated. e7d0dbd6ba745bab334aef6e747056c33f5edaa8 Changelog
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Apr 6 09:11:37 UTC 2011
The branch, master has been updated
via e7d0dbd6ba745bab334aef6e747056c33f5edaa8 (commit)
via 7c1e4d5e1e28e556b1d10a8df8d9486971a3f052 (commit)
via 47b51ddc032a458b42454c3ed774bf26ef4254c1 (commit)
via c139d4bf6b30d7ad9325c7a621911c9455826f6b (commit)
via ddfc6892916bc041e53b79a690abbed10ff99056 (commit)
via af0d35e501aab417b9b032069ae1cb8841debab4 (commit)
via cf5b24f110a927685226e8ef41378a847b002357 (commit)
via 5a7c1928eb5b70c2a9739650961bd4e32b6b26ed (commit)
via f9a697ab99914d58e7e135ca069b3d5a06c00511 (commit)
via 320bafb306878cd9f13ba9703a0d4573fb645341 (commit)
via 0b53561c3b937c5d2585a3c62876b600800815bb (commit)
via e111d142cba584e410c5e385c10b714715f55dc4 (commit)
from 4929dc565823e49c94b1efea1543ba23d9745c9f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit e7d0dbd6ba745bab334aef6e747056c33f5edaa8
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Apr 6 11:04:25 2011 +0200
Changelog
commit 7c1e4d5e1e28e556b1d10a8df8d9486971a3f052
Merge: 4929dc565823e49c94b1efea1543ba23d9745c9f 47b51ddc032a458b42454c3ed774bf26ef4254c1
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Apr 6 11:01:26 2011 +0200
Merge branch 'work/secondary'
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 6 ++
src/bin/zonemgr/tests/zonemgr_test.py | 132 +++++++++++++++++++++------------
src/bin/zonemgr/zonemgr.py.in | 72 ++++++++++++------
src/bin/zonemgr/zonemgr.spec.pre.in | 26 +++++++
4 files changed, 165 insertions(+), 71 deletions(-)
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index ae89d67..447df56 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+ 214. [func]* vorner
+ Zone manager no longer thinks it is secondary master for all zones in the
+ database They are listed in Zonemgr/secondary_zones configuration variable
+ (in the form [{"name": "example.com", "class": "IN"}]).
+ (Trac #670, 7c1e4d5e1e28e556b1d10a8df8d9486971a3f052)
+
213. [bug] naokikambe
Solved incorrect datetime of "bind10.boot_time" and also added a new
command "sendstats" for Bob. This command is to send statistics data to
diff --git a/src/bin/zonemgr/tests/zonemgr_test.py b/src/bin/zonemgr/tests/zonemgr_test.py
index 70dc1b0..2e9f685 100644
--- a/src/bin/zonemgr/tests/zonemgr_test.py
+++ b/src/bin/zonemgr/tests/zonemgr_test.py
@@ -22,10 +22,10 @@ import tempfile
from zonemgr import *
ZONE_NAME_CLASS1_IN = ("sd.cn.", "IN")
-ZONE_NAME_CLASS2_CH = ("tw.cn", "CH")
+ZONE_NAME_CLASS2_CH = ("tw.cn.", "CH")
ZONE_NAME_CLASS3_IN = ("example.com", "IN")
ZONE_NAME_CLASS1_CH = ("sd.cn.", "CH")
-ZONE_NAME_CLASS2_IN = ("tw.cn", "IN")
+ZONE_NAME_CLASS2_IN = ("tw.cn.", "IN")
MAX_TRANSFER_TIMEOUT = 14400
LOWERBOUND_REFRESH = 10
@@ -46,21 +46,43 @@ class MySession():
def group_recvmsg(self, nonblock, seq):
return None, None
+class FakeConfig:
+ def __init__(self):
+ self.zone_list = []
+ self.set_zone_list_from_name_classes([ZONE_NAME_CLASS1_IN,
+ ZONE_NAME_CLASS2_CH])
+ def set_zone_list_from_name_classes(self, zones):
+ self.zone_list = map(lambda nc: {"name": nc[0], "class": nc[1]}, zones)
+ def get(self, name):
+ if name == 'lowerbound_refresh':
+ return LOWERBOUND_REFRESH
+ elif name == 'lowerbound_retry':
+ return LOWERBOUND_RETRY
+ elif name == 'max_transfer_timeout':
+ return MAX_TRANSFER_TIMEOUT
+ elif name == 'jitter_scope':
+ return JITTER_SCOPE
+ elif name == 'secondary_zones':
+ return self.zone_list
+ else:
+ raise ValueError('Uknown config option')
+
class MyZonemgrRefresh(ZonemgrRefresh):
def __init__(self):
- class FakeConfig:
- def get(self, name):
- if name == 'lowerbound_refresh':
- return LOWERBOUND_REFRESH
- elif name == 'lowerbound_retry':
- return LOWERBOUND_RETRY
- elif name == 'max_transfer_timeout':
- return MAX_TRANSFER_TIMEOUT
- elif name == 'jitter_scope':
- return JITTER_SCOPE
- else:
- raise ValueError('Uknown config option')
self._master_socket, self._slave_socket = socket.socketpair()
+ self._zonemgr_refresh_info = {}
+
+ def get_zone_soa(zone_name, db_file):
+ if zone_name == 'sd.cn.':
+ return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
+ 'a.dns.cn. root.cnnic.cn. 2009073106 7200 3600 2419200 21600')
+ elif zone_name == 'tw.cn.':
+ return (1, 2, 'tw.cn.', 'cn.sd.', 21600, 'SOA', None,
+ 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600')
+ else:
+ return None
+ sqlite3_ds.get_zone_soa = get_zone_soa
+
ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
self._slave_socket, FakeConfig())
current_time = time.time()
@@ -70,7 +92,7 @@ class MyZonemgrRefresh(ZonemgrRefresh):
'next_refresh_time': current_time + 6500,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
'zone_state': 0},
- ('tw.cn', 'CH'): {
+ ('tw.cn.', 'CH'): {
'last_refresh_time': current_time,
'next_refresh_time': current_time + 6900,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073112 7200 3600 2419200 21600',
@@ -272,28 +294,6 @@ class TestZonemgrRefresh(unittest.TestCase):
ZONE_NAME_CLASS1_IN)
sqlite3_ds.get_zone_soa = old_get_zone_soa
- def test_build_zonemgr_refresh_info(self):
- soa_rdata = 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600'
-
- def get_zones_info(db_file):
- return [("sd.cn.", "IN")]
-
- def get_zone_soa(zone_name, db_file):
- return (1, 2, 'sd.cn.', 'cn.sd.', 21600, 'SOA', None,
- 'a.dns.cn. root.cnnic.cn. 2009073106 1800 900 2419200 21600')
-
- sqlite3_ds.get_zones_info = get_zones_info
- sqlite3_ds.get_zone_soa = get_zone_soa
-
- self.zone_refresh._zonemgr_refresh_info = {}
- self.zone_refresh._build_zonemgr_refresh_info()
- self.assertEqual(1, len(self.zone_refresh._zonemgr_refresh_info))
- zone_soa_rdata = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_soa_rdata"]
- self.assertEqual(soa_rdata, zone_soa_rdata)
- self.assertEqual(ZONE_OK, self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"])
- self.assertTrue("last_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
- self.assertTrue("next_refresh_time" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
-
def test_zone_handle_notify(self):
self.zone_refresh.zone_handle_notify(ZONE_NAME_CLASS1_IN,"127.0.0.1")
notify_master = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["notify_master"]
@@ -356,7 +356,7 @@ class TestZonemgrRefresh(unittest.TestCase):
'next_refresh_time': time1 + 7200,
'zone_soa_rdata': 'a.dns.cn. root.cnnic.cn. 2009073105 7200 3600 2419200 21600',
'zone_state': ZONE_OK},
- ("tw.cn","CH"):{
+ ("tw.cn.","CH"):{
'last_refresh_time': time1 - 7200,
'next_refresh_time': time1,
'refresh_timeout': time1 + MAX_TRANSFER_TIMEOUT,
@@ -424,7 +424,8 @@ class TestZonemgrRefresh(unittest.TestCase):
"lowerbound_refresh" : 60,
"lowerbound_retry" : 30,
"max_transfer_timeout" : 19800,
- "jitter_scope" : 0.25
+ "jitter_scope" : 0.25,
+ "secondary_zones": []
}
self.zone_refresh.update_config_data(config_data)
self.assertEqual(60, self.zone_refresh._lowerbound_refresh)
@@ -440,6 +441,31 @@ class TestZonemgrRefresh(unittest.TestCase):
self.zone_refresh.shutdown()
self.assertFalse(listener.is_alive())
+ def test_secondary_zones(self):
+ """Test that we can modify the list of secondary zones"""
+ config = FakeConfig()
+ config.zone_list = []
+ # First, remove everything
+ self.zone_refresh.update_config_data(config)
+ self.assertEqual(self.zone_refresh._zonemgr_refresh_info, {})
+ # Put something in
+ config.set_zone_list_from_name_classes([ZONE_NAME_CLASS1_IN])
+ self.zone_refresh.update_config_data(config)
+ self.assertTrue(("sd.cn.", "IN") in
+ 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(("sd.cn.", "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([("sd.cn", "IN")])
+ self.zone_refresh.update_config_data(config)
+ self.assertTrue(("sd.cn.", "IN") in
+ self.zone_refresh._zonemgr_refresh_info)
+
def tearDown(self):
sys.stderr= self.stderr_backup
@@ -464,10 +490,11 @@ class MyZonemgr(Zonemgr):
self._cc = MySession()
self._module_cc = MyCCSession()
self._config_data = {
- "lowerbound_refresh" : 10,
- "lowerbound_retry" : 5,
+ "lowerbound_refresh" : 10,
+ "lowerbound_retry" : 5,
"max_transfer_timeout" : 14400,
- "jitter_scope" : 0.1
+ "jitter_scope" : 0.1,
+ "secondary_zones": []
}
def _start_zone_refresh_timer(self):
@@ -480,12 +507,14 @@ class TestZonemgr(unittest.TestCase):
def test_config_handler(self):
config_data1 = {
- "lowerbound_refresh" : 60,
- "lowerbound_retry" : 30,
+ "lowerbound_refresh" : 60,
+ "lowerbound_retry" : 30,
"max_transfer_timeout" : 14400,
- "jitter_scope" : 0.1
+ "jitter_scope" : 0.1,
+ "secondary_zones": []
}
- self.zonemgr.config_handler(config_data1)
+ self.assertEqual(self.zonemgr.config_handler(config_data1),
+ {"result": [0]})
self.assertEqual(config_data1, self.zonemgr._config_data)
config_data2 = {"zone_name" : "sd.cn.", "port" : "53", "master" : "192.168.1.1"}
self.zonemgr.config_handler(config_data2)
@@ -494,10 +523,19 @@ class TestZonemgr(unittest.TestCase):
config_data3 = {"jitter_scope" : 0.7}
self.zonemgr.config_handler(config_data3)
self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
+ # The zone doesn't exist in database, it should be rejected
+ 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),
+ {"result": [0]})
+ # As it is rejected, the old value should be kept
+ self.assertEqual(0.5, self.zonemgr._config_data.get("jitter_scope"))
def test_get_db_file(self):
self.assertEqual("initdb.file", self.zonemgr.get_db_file())
-
+
def test_parse_cmd_params(self):
params1 = {"zone_name" : "org.cn", "zone_class" : "CH", "master" : "127.0.0.1"}
answer1 = (("org.cn", "CH"), "127.0.0.1")
diff --git a/src/bin/zonemgr/zonemgr.py.in b/src/bin/zonemgr/zonemgr.py.in
index 2cededf..129c673 100755
--- a/src/bin/zonemgr/zonemgr.py.in
+++ b/src/bin/zonemgr/zonemgr.py.in
@@ -100,9 +100,8 @@ class ZonemgrRefresh:
self._cc = cc
self._check_sock = slave_socket
self._db_file = db_file
- self.update_config_data(config_data)
self._zonemgr_refresh_info = {}
- self._build_zonemgr_refresh_info()
+ self.update_config_data(config_data)
self._running = False
def _random_jitter(self, max, jitter):
@@ -148,16 +147,13 @@ class ZonemgrRefresh:
def _zone_not_exist(self, zone_name_class):
""" Zone doesn't belong to zonemgr"""
- if zone_name_class in self._zonemgr_refresh_info.keys():
- return False
- return True
+ return not zone_name_class in self._zonemgr_refresh_info
def zone_refresh_success(self, zone_name_class):
"""Update zone info after zone refresh success"""
if (self._zone_not_exist(zone_name_class)):
raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
"belong to zonemgr" % zone_name_class)
- return
self.zonemgr_reload_zone(zone_name_class)
self._set_zone_refresh_timer(zone_name_class)
self._set_zone_state(zone_name_class, ZONE_OK)
@@ -168,7 +164,6 @@ class ZonemgrRefresh:
if (self._zone_not_exist(zone_name_class)):
raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
"belong to zonemgr" % zone_name_class)
- return
# Is zone expired?
if (self._zone_is_expired(zone_name_class)):
self._set_zone_state(zone_name_class, ZONE_EXPIRED)
@@ -181,7 +176,6 @@ class ZonemgrRefresh:
if (self._zone_not_exist(zone_name_class)):
raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) "
"doesn't belong to zonemgr" % zone_name_class)
- return
self._set_zone_notifier_master(zone_name_class, master)
self._set_zone_notify_timer(zone_name_class)
@@ -192,6 +186,7 @@ class ZonemgrRefresh:
def zonemgr_add_zone(self, zone_name_class):
""" Add a zone into zone manager."""
+ log_msg("Loading zone (%s, %s)" % zone_name_class)
zone_info = {}
zone_soa = sqlite3_ds.get_zone_soa(str(zone_name_class[0]), self._db_file)
if not zone_soa:
@@ -203,14 +198,6 @@ class ZonemgrRefresh:
float(zone_soa[7].split(" ")[REFRESH_OFFSET])
self._zonemgr_refresh_info[zone_name_class] = zone_info
- def _build_zonemgr_refresh_info(self):
- """ Build zonemgr refresh info map."""
- log_msg("Start loading zone into zonemgr.")
- for zone_name, zone_class in sqlite3_ds.get_zones_info(self._db_file):
- zone_name_class = (zone_name, zone_class)
- self.zonemgr_add_zone(zone_name_class)
- log_msg("Finish loading zone into zonemgr.")
-
def _zone_is_expired(self, zone_name_class):
"""Judge whether a zone is expired or not."""
zone_expired_time = float(self._get_zone_soa_rdata(zone_name_class).split(" ")[EXPIRED_OFFSET])
@@ -415,6 +402,32 @@ class ZonemgrRefresh:
def update_config_data(self, new_config):
""" update ZonemgrRefresh config """
+ backup = self._zonemgr_refresh_info.copy()
+ try:
+ required = {}
+ # 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
+ raise
self._lowerbound_refresh = new_config.get('lowerbound_refresh')
self._lowerbound_retry = new_config.get('lowerbound_retry')
self._max_transfer_timeout = new_config.get('max_transfer_timeout')
@@ -471,26 +484,37 @@ class Zonemgr:
def config_handler(self, new_config):
""" Update config data. """
answer = create_answer(0)
+ ok = True
+ complete = self._config_data.copy()
for key in new_config:
- if key not in self._config_data:
+ if key not in complete:
answer = create_answer(1, "Unknown config data: " + str(key))
+ ok = False
continue
- self._config_data[key] = new_config[key]
+ complete[key] = new_config[key]
- self._config_data_check(self._config_data)
- if (self._zone_refresh):
- self._zone_refresh.update_config_data(self._config_data)
+ self._config_data_check(complete)
+ if self._zone_refresh is not None:
+ try:
+ self._zone_refresh.update_config_data(complete)
+ except Exception as e:
+ answer = create_answer(1, str(e))
+ ok = False
+ if ok:
+ self._config_data = complete
return answer
def _config_data_check(self, config_data):
- """Check whether the new config data is valid or
- not. """
+ """Check whether the new config data is valid or
+ not. It contains only basic logic, not full check against
+ database."""
# jitter should not be bigger than half of the original value
if config_data.get('jitter_scope') > 0.5:
config_data['jitter_scope'] = 0.5
log_msg("[b10-zonemgr] jitter_scope is too big, its value will "
- "be set to 0.5")
+ "be set to 0.5")
+
def _parse_cmd_params(self, args, command):
zone_name = args.get("zone_name")
diff --git a/src/bin/zonemgr/zonemgr.spec.pre.in b/src/bin/zonemgr/zonemgr.spec.pre.in
index 0539ef3..9df01f2 100644
--- a/src/bin/zonemgr/zonemgr.spec.pre.in
+++ b/src/bin/zonemgr/zonemgr.spec.pre.in
@@ -25,6 +25,32 @@
"item_type": "real",
"item_optional": false,
"item_default": 0.25
+ },
+ {
+ "item_name": "secondary_zones",
+ "item_type": "list",
+ "item_optional": false,
+ "item_default": [],
+ "list_item_spec": {
+ "item_name": "secondary_zone",
+ "item_type": "map",
+ "item_optional": false,
+ "item_default": {},
+ "map_item_spec": [
+ {
+ "item_name": "class",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "IN"
+ },
+ {
+ "item_name": "name",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ }
+ ]
+ }
}
],
"commands": [
More information about the bind10-changes
mailing list