From: JINMEI Tatuya Date: Sat, 15 Dec 2012 20:12:03 +0000 (-0800) Subject: [2380] added minimal post-load zone checks X-Git-Tag: bind10-1.0.0-beta-release~9^2~14^2~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d08ad5667f5b4fe540a1a00921e8a10d706cd88f;p=thirdparty%2Fkea.git [2380] added minimal post-load zone checks --- diff --git a/src/bin/loadzone/loadzone.py.in b/src/bin/loadzone/loadzone.py.in index 4f5e063b44..621f08d9db 100755 --- a/src/bin/loadzone/loadzone.py.in +++ b/src/bin/loadzone/loadzone.py.in @@ -204,6 +204,28 @@ class LoadZoneRunner: self._zone_class) raise LoadFailure(str(ex)) + def _post_load_checks(self): + '''Perform minimal validity checks on the loaded zone. + + We do this ourselves because the underlying library currently + doesn't do any checks. Once the library support post-load validation + this check should be removed. + + ''' + datasrc_client = DataSourceClient(self._datasrc_type, + self._datasrc_config) + _, finder = datasrc_client.find_zone(self._zone_name) # should succeed + result = finder.find(self._zone_name, RRType.SOA())[0] + if result is not finder.SUCCESS: + self._post_load_warning('zone has no SOA') + result = finder.find(self._zone_name, RRType.NS())[0] + if result is not finder.SUCCESS: + self._post_load_warning('zone has no NS') + + def _post_load_warning(self, msg): + logger.warn(LOADZONE_POSTLOAD_ISSUE, self._zone_name, + self._zone_class, msg) + def run(self): '''Top-level method, simply calling other helpers''' @@ -211,6 +233,7 @@ class LoadZoneRunner: self._parse_args() self._do_load() logger.info(LOADZONE_DONE, self._zone_name, self._zone_class) + self._post_load_checks() return 0 except BadArgument as ex: logger.error(LOADZONE_ARGUMENT_ERROR, ex) diff --git a/src/bin/loadzone/loadzone_messages.mes b/src/bin/loadzone/loadzone_messages.mes index 541fb2b61d..ed126a5319 100644 --- a/src/bin/loadzone/loadzone_messages.mes +++ b/src/bin/loadzone/loadzone_messages.mes @@ -29,3 +29,5 @@ % LOADZONE_LOADING Loaded %1 RRs into %2/%3, continued % LOADZONE_DONE Load zone %1/%2 completed + +% LOADZONE_POSTLOAD_ISSUE New version of zone %1/%2 has an issue: %3 diff --git a/src/bin/loadzone/tests/Makefile.am b/src/bin/loadzone/tests/Makefile.am index 641bc6eda4..1918bb5cfd 100644 --- a/src/bin/loadzone/tests/Makefile.am +++ b/src/bin/loadzone/tests/Makefile.am @@ -4,6 +4,8 @@ PYTESTS = loadzone_test.py EXTRA_DIST = $(PYTESTS) EXTRA_DIST += testdata/example.org.zone EXTRA_DIST += testdata/broken-example.org.zone +EXTRA_DIST += testdata/example-nosoa.org.zone +EXTRA_DIST += testdata/example-nons.org.zone # If necessary (rare cases), explicitly specify paths to dynamic libraries # required by loadable python modules. diff --git a/src/bin/loadzone/tests/loadzone_test.py b/src/bin/loadzone/tests/loadzone_test.py index 62e7db6777..a7fa3da27b 100755 --- a/src/bin/loadzone/tests/loadzone_test.py +++ b/src/bin/loadzone/tests/loadzone_test.py @@ -125,6 +125,8 @@ class TestLoadZoneRunner(unittest.TestCase): """Check that the given SOA RR exists and matches the expected string If soa_txt is None, the zone is expected to be non-existent. + Otherwise, if soa_txt is False, the zone should exist but SOA is + expected to be missing. """ @@ -135,8 +137,11 @@ class TestLoadZoneRunner(unittest.TestCase): return self.assertEqual(client.SUCCESS, result) result, rrset, _ = finder.find(zone_name, RRType.SOA()) - self.assertEqual(finder.SUCCESS, result) - self.assertEqual(soa_txt, rrset.to_text()) + if soa_txt: + self.assertEqual(finder.SUCCESS, result) + self.assertEqual(soa_txt, rrset.to_text()) + else: + self.assertEqual(finder.NXRRSET, result) def test_load_update(self): '''successful case to loading new contents to an existing zone.''' @@ -190,6 +195,39 @@ class TestLoadZoneRunner(unittest.TestCase): # _do_load() should have once created the zone but then canceled it. self.__check_zone_soa(None, zone_name=Name('example.com')) + def __common_post_load_setup(self, zone_file): + '''Common setup procedure for post load tests.''' + # replace the LoadZoneRunner's original _post_load_warning() for + # inspection + self.__warnings = [] + self.__runner._post_load_warning = \ + lambda msg: self.__warnings.append(msg) + + # perform load and invoke checks + self.__common_load_setup() + self.__runner._zone_file = zone_file + self.__check_zone_soa(ORIG_SOA_TXT) + self.__runner._do_load() + self.__runner._post_load_checks() + + def test_load_fail_create_cancel(self): + '''Load succeeds but warns about missing SOA, should cause warn''' + self.__common_load_setup() + self.__common_post_load_setup(LOCAL_TESTDATA_PATH + + '/example-nosoa.org.zone') + self.__check_zone_soa(False) + self.assertEqual(1, len(self.__warnings)) + self.assertEqual('zone has no SOA', self.__warnings[0]) + + def test_load_fail_create_cancel(self): + '''Load succeeds but warns about missing NS, should cause warn''' + self.__common_load_setup() + self.__common_post_load_setup(LOCAL_TESTDATA_PATH + + '/example-nons.org.zone') + self.__check_zone_soa(NEW_SOA_TXT) + self.assertEqual(1, len(self.__warnings)) + self.assertEqual('zone has no NS', self.__warnings[0]) + def test_run_success(self): '''Check for the top-level method. diff --git a/src/bin/loadzone/tests/testdata/example-nons.org.zone b/src/bin/loadzone/tests/testdata/example-nons.org.zone new file mode 100644 index 0000000000..f37fa28938 --- /dev/null +++ b/src/bin/loadzone/tests/testdata/example-nons.org.zone @@ -0,0 +1,10 @@ +;; Intentionally missing SOA for testing post-load checks +example.org. 3600 IN SOA ( + ns.example.org. + admin.example.org. + 1235 + 3600 ;1H + 1800 ;30M + 2419200 + 7200) +ns.example.org. 3600 IN A 192.0.2.1 diff --git a/src/bin/loadzone/tests/testdata/example-nosoa.org.zone b/src/bin/loadzone/tests/testdata/example-nosoa.org.zone new file mode 100644 index 0000000000..3bf0d0e638 --- /dev/null +++ b/src/bin/loadzone/tests/testdata/example-nosoa.org.zone @@ -0,0 +1,3 @@ +;; Intentionally missing SOA for testing post-load checks +example.org. 3600 IN NS ns.example.org. +ns.example.org. 3600 IN A 192.0.2.1