From a555a274e6ac0e444222cc5f34ed62fb888b27c5 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sat, 4 Nov 2023 00:15:00 +0900 Subject: [PATCH] Validate [designate] ipvN_ptr_zone_prefix_size at config layer This change re-implements validation of ipvN_ptr_zone_prefix_size at config definition layer. This brings a few benefits. - The validation is executed at an earlier stage - The validation can be leveraged by the oslo-config-validator. Change-Id: Ib72109bcb537b3e44719efb6f33ea46f0d45a1ef --- .../conf/services/extdns_designate_driver.py | 32 ++++++++++++++- .../externaldns/drivers/designate/driver.py | 25 ------------ .../drivers/designate/test_driver.py | 40 ++++++++++++------- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/neutron/conf/services/extdns_designate_driver.py b/neutron/conf/services/extdns_designate_driver.py index 093fcc597e6..2d830ee6892 100644 --- a/neutron/conf/services/extdns_designate_driver.py +++ b/neutron/conf/services/extdns_designate_driver.py @@ -15,9 +15,35 @@ from keystoneauth1 import loading from oslo_config import cfg +from oslo_config import types from neutron._i18n import _ + +class ZonePrefixIPv4(types.Integer): + def __init__(self): + super(ZonePrefixIPv4, self).__init__( + min=8, max=24, type_name='IPv4 zone prefix') + + def __call__(self, value): + value = super(ZonePrefixIPv4, self).__call__(value) + if value % 8 != 0: + raise ValueError(_('Should be multiple of 8')) + return value + + +class ZonePrefixIPv6(types.Integer): + def __init__(self): + super(ZonePrefixIPv6, self).__init__( + min=4, max=124, type_name='IPv6 zone prefix') + + def __call__(self, value): + value = super(ZonePrefixIPv6, self).__call__(value) + if value % 4 != 0: + raise ValueError(_('Should be multiple of 4')) + return value + + designate_opts = [ cfg.StrOpt('url', help=_('URL for connecting to designate')), @@ -59,14 +85,16 @@ designate_opts = [ 'context')), cfg.BoolOpt('allow_reverse_dns_lookup', default=True, help=_('Allow the creation of PTR records')), - cfg.IntOpt( + cfg.Opt( 'ipv4_ptr_zone_prefix_size', default=24, + type=ZonePrefixIPv4(), help=_('Number of bits in an IPv4 PTR zone that will be considered ' 'network prefix. It has to align to byte boundary. Minimum ' 'value is 8. Maximum value is 24. As a consequence, range ' 'of values is 8, 16 and 24')), - cfg.IntOpt( + cfg.Opt( 'ipv6_ptr_zone_prefix_size', default=120, + type=ZonePrefixIPv6(), help=_('Number of bits in an IPv6 PTR zone that will be considered ' 'network prefix. It has to align to nyble boundary. Minimum ' 'value is 4. Maximum value is 124. As a consequence, range ' diff --git a/neutron/services/externaldns/drivers/designate/driver.py b/neutron/services/externaldns/drivers/designate/driver.py index 210ef7ab465..75c2c638316 100644 --- a/neutron/services/externaldns/drivers/designate/driver.py +++ b/neutron/services/externaldns/drivers/designate/driver.py @@ -28,11 +28,6 @@ from oslo_log import log from neutron.conf.services import extdns_designate_driver from neutron.services.externaldns import driver -IPV4_PTR_ZONE_PREFIX_MIN_SIZE = 8 -IPV4_PTR_ZONE_PREFIX_MAX_SIZE = 24 -IPV6_PTR_ZONE_PREFIX_MIN_SIZE = 4 -IPV6_PTR_ZONE_PREFIX_MAX_SIZE = 124 - _SESSION = None CONF = cfg.CONF @@ -74,26 +69,6 @@ def get_all_projects_client(context): class Designate(driver.ExternalDNSService): """Driver for Designate.""" - def __init__(self): - ipv4_ptr_zone_size = CONF.designate.ipv4_ptr_zone_prefix_size - ipv6_ptr_zone_size = CONF.designate.ipv6_ptr_zone_prefix_size - - if (ipv4_ptr_zone_size < IPV4_PTR_ZONE_PREFIX_MIN_SIZE or - ipv4_ptr_zone_size > IPV4_PTR_ZONE_PREFIX_MAX_SIZE or - (ipv4_ptr_zone_size % 8) != 0): - raise dns_exc.InvalidPTRZoneConfiguration( - parameter='ipv4_ptr_zone_size', number='8', - maximum=str(IPV4_PTR_ZONE_PREFIX_MAX_SIZE), - minimum=str(IPV4_PTR_ZONE_PREFIX_MIN_SIZE)) - - if (ipv6_ptr_zone_size < IPV6_PTR_ZONE_PREFIX_MIN_SIZE or - ipv6_ptr_zone_size > IPV6_PTR_ZONE_PREFIX_MAX_SIZE or - (ipv6_ptr_zone_size % 4) != 0): - raise dns_exc.InvalidPTRZoneConfiguration( - parameter='ipv6_ptr_zone_size', number='4', - maximum=str(IPV6_PTR_ZONE_PREFIX_MAX_SIZE), - minimum=str(IPV6_PTR_ZONE_PREFIX_MIN_SIZE)) - def create_record_set(self, context, dns_domain, dns_name, records): designate, designate_admin = get_clients(context) v4, v6 = self._classify_records(records) diff --git a/neutron/tests/unit/services/externaldns/drivers/designate/test_driver.py b/neutron/tests/unit/services/externaldns/drivers/designate/test_driver.py index 233c2703f99..22e10203d66 100644 --- a/neutron/tests/unit/services/externaldns/drivers/designate/test_driver.py +++ b/neutron/tests/unit/services/externaldns/drivers/designate/test_driver.py @@ -254,25 +254,37 @@ class TestDesignateDriver(base.BaseTestCase): ) def test_ipv4_ptr_is_misconfigured(self): - cfg.CONF.set_override( - 'ipv4_ptr_zone_prefix_size', -1, group='designate' + self.assertRaises( + ValueError, + cfg.CONF.set_override, + 'ipv4_ptr_zone_prefix_size', 0, group='designate' + ) + self.assertRaises( + ValueError, + cfg.CONF.set_override, + 'ipv4_ptr_zone_prefix_size', 32, group='designate' ) - self.assertRaisesRegex( - dns_exc.InvalidPTRZoneConfiguration, - 'Value of ipv4_ptr_zone_size has to be multiple of 8, with ' - 'maximum value of 24 and minimum value of 8', - driver.Designate + ValueError, + 'Should be multiple of 8', + cfg.CONF.set_override, + 'ipv4_ptr_zone_prefix_size', 9, group='designate' ) def test_ipv6_ptr_is_misconfigured(self): - cfg.CONF.set_override( - 'ipv6_ptr_zone_prefix_size', -1, group='designate' + self.assertRaises( + ValueError, + cfg.CONF.set_override, + 'ipv6_ptr_zone_prefix_size', 0, group='designate' + ) + self.assertRaises( + ValueError, + cfg.CONF.set_override, + 'ipv6_ptr_zone_prefix_size', 128, group='designate' ) - self.assertRaisesRegex( - dns_exc.InvalidPTRZoneConfiguration, - 'Value of ipv6_ptr_zone_size has to be multiple of 4, with ' - 'maximum value of 124 and minimum value of 4', - driver.Designate + ValueError, + 'Should be multiple of 4', + cfg.CONF.set_override, + 'ipv6_ptr_zone_prefix_size', 5, group='designate' )