Parcourir la source

[2911] add request_ixfr zone option to finer policy control on use of IXFR.

currently just recognize the option.  no behavior change due to it yet.
JINMEI Tatuya il y a 12 ans
Parent
commit
e532e4f564
3 fichiers modifiés avec 81 ajouts et 14 suppressions
  1. 47 11
      src/bin/xfrin/tests/xfrin_test.py
  2. 29 3
      src/bin/xfrin/xfrin.py.in
  3. 5 0
      src/bin/xfrin/xfrin.spec

+ 47 - 11
src/bin/xfrin/tests/xfrin_test.py

@@ -2748,6 +2748,19 @@ class TestXfrin(unittest.TestCase):
             else:
                 # if not set, should default to False
                 self.assertFalse(zone_info.use_ixfr)
+            if ('request_ixfr' in zone_config and
+                zone_config.get('request_ixfr')):
+                cfg_val = zone_config.get('request_ixfr')
+                val = zone_info.request_ixfr
+                if cfg_val == 'yes':
+                    self.assertEqual(ZoneInfo.REQUEST_IXFR_FIRST, val)
+                elif cfg_val == 'no':
+                    self.assertEqual(ZoneInfo.REQUEST_IXFR_DISABLED, val)
+                elif cfg_val == 'only':
+                    self.assertEqual(ZoneInfo.REQUEST_IXFR_ONLY, val)
+            else:               # check the default
+                self.assertEqual(ZoneInfo.REQUEST_IXFR_FIRST,
+                                 zone_info.request_ixfr)
 
     def test_config_handler_zones(self):
         # This test passes a number of good and bad configs, and checks whether
@@ -2759,7 +2772,7 @@ class TestXfrin(unittest.TestCase):
                    { 'name': 'test.example.',
                     'master_addr': '192.0.2.1',
                     'master_port': 53,
-                    'use_ixfr': False
+                    'request_ixfr': 'yes'
                    }
                  ]}
         self.assertEqual(self.xfr.config_handler(config1)['result'][0], 0)
@@ -2771,12 +2784,24 @@ class TestXfrin(unittest.TestCase):
                     'master_addr': '192.0.2.2',
                     'master_port': 53,
                     'tsig_key': "example.com:SFuWd/q99SzF8Yzd1QbB9g==",
-                    'use_ixfr': True
+                    'request_ixfr': 'no'
                    }
                  ]}
         self.assertEqual(self.xfr.config_handler(config2)['result'][0], 0)
         self._check_zones_config(config2)
 
+        config3 = {'transfers_in': 4,
+                   'zones': [
+                   { 'name': 'test.example.',
+                    'master_addr': '192.0.2.2',
+                    'master_port': 53,
+                    'tsig_key': "example.com:SFuWd/q99SzF8Yzd1QbB9g==",
+                    'request_ixfr': 'only'
+                   }
+                 ]}
+        self.assertEqual(self.xfr.config_handler(config3)['result'][0], 0)
+        self._check_zones_config(config3)
+
         # test that configuring the zone multiple times fails
         zones = { 'transfers_in': 5,
                   'zones': [
@@ -2791,7 +2816,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'name': 'test.example.',
@@ -2801,7 +2826,7 @@ class TestXfrin(unittest.TestCase):
                   }
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'master_addr': '192.0.2.4',
@@ -2810,7 +2835,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'name': 'bad..zone.',
@@ -2820,7 +2845,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'name': '',
@@ -2830,7 +2855,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'name': 'test.example',
@@ -2840,7 +2865,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'name': 'test.example',
@@ -2850,7 +2875,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         zones = { 'zones': [
                   { 'name': 'test.example',
@@ -2862,7 +2887,7 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
 
         # let's also add a zone that is correct too, and make sure
         # that the new config is not partially taken
@@ -2879,7 +2904,18 @@ class TestXfrin(unittest.TestCase):
                 ]}
         self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
         # since this has failed, we should still have the previous config
-        self._check_zones_config(config2)
+        self._check_zones_config(config3)
+
+        # invalid request_ixfr value
+        zones = { 'zones': [
+                  { 'name': 'test.example',
+                    'master_addr': '192.0.2.7',
+                    'request_ixfr': 'bad value'
+                  }
+                ]}
+        self.assertEqual(self.xfr.config_handler(zones)['result'][0], 1)
+        # since this has failed, we should still have the previous config
+        self._check_zones_config(config3)
 
     def test_config_handler_zones_default(self):
         # Checking it some default config values apply.  Using a separate

+ 29 - 3
src/bin/xfrin/xfrin.py.in

@@ -1238,6 +1238,11 @@ class XfrinRecorder:
         return ret
 
 class ZoneInfo:
+    # Internal values corresponding to request_ixfr
+    REQUEST_IXFR_FIRST = 0      # request_ixfr=yes, use IXFR 1st then AXFR
+    REQUEST_IXFR_ONLY = 1       # request_ixfr=only, use IXFR only
+    REQUEST_IXFR_DISABLED = 2   # request_ixfr=no, AXFR-only
+
     def __init__(self, config_data, module_cc):
         """Creates a zone_info with the config data element as
            specified by the 'zones' list in xfrin.spec. Module_cc is
@@ -1250,6 +1255,17 @@ class ZoneInfo:
         self.set_zone_class(config_data.get('class'))
         self.set_tsig_key_name(config_data.get('tsig_key'))
         self.set_use_ixfr(config_data.get('use_ixfr'))
+        self.set_request_ixfr(config_data.get('request_ixfr'))
+
+    @property
+    def request_ixfr(self):
+        """Policy on the use of IXFR.
+
+        Possible values are REQUEST_IXFR_xxx, internally stored in
+        __request_ixfr, read-only outside of the class.
+
+        """
+        return self.__request_ixfr
 
     def set_name(self, name_str):
         """Set the name for this zone given a name string.
@@ -1338,15 +1354,25 @@ class ZoneInfo:
 
     def set_use_ixfr(self, use_ixfr):
         """Set use_ixfr. If set to True, it will use
-           IXFR for incoming transfers. If set to False, it will use AXFR.
-           At this moment there is no automatic fallback"""
-        # TODO: http://bind10.isc.org/ticket/1279
+           IXFR for incoming transfers. If set to False, it will use AXFR."""
         if use_ixfr is None:
             self.use_ixfr = \
                 self._module_cc.get_default_value("zones/use_ixfr")
         else:
             self.use_ixfr = use_ixfr
 
+    def set_request_ixfr(self, request_ixfr):
+        if request_ixfr is None:
+            request_ixfr = 'yes' # if unspecified, use the default
+        cfg_to_val = { 'yes': self.REQUEST_IXFR_FIRST,
+                       'only': self.REQUEST_IXFR_ONLY,
+                       'no': self.REQUEST_IXFR_DISABLED }
+        try:
+            self.__request_ixfr = cfg_to_val[request_ixfr]
+        except KeyError:
+            raise XfrinZoneInfoException('invalid value for request_ixfr: ' +
+                                         request_ixfr)
+
     def get_master_addr_info(self):
         return (self.master_addr.family, socket.SOCK_STREAM,
                 (str(self.master_addr), self.master_port))

+ 5 - 0
src/bin/xfrin/xfrin.spec

@@ -48,6 +48,11 @@
             "item_type": "boolean",
             "item_optional": false,
             "item_default": false
+          },
+          { "item_name": "request_ixfr",
+            "item_type": "string",
+            "item_optional": false,
+            "item_default": "yes"
           }
           ]
         }