Validate the transport url query string

When driver load we allow to override option unrelated to the driver and
to set option useless for the driver.

This change validates the query string when the driver load to report as
soon as possible invalid options. And allow to override only option
of the driver option group (ie: [oslo_messaging_<driver_name>].

Related-bug: #1666903

Change-Id: Iaf23f773279c10bf37d545883ada7c2f6a9ffbbf
This commit is contained in:
Mehdi Abaakouk 2017-02-23 09:37:16 +01:00
parent 58b026a2aa
commit 037dee19ed
7 changed files with 35 additions and 17 deletions

View File

@ -460,13 +460,21 @@ class ConfigOptsProxy(collections.Mapping):
and valid) override corresponding values from the configuration.
"""
def __init__(self, conf, url):
def __init__(self, conf, url, group):
self._conf = conf
self._url = url
self._group = group
self._validate_query()
def _validate_query(self):
for name in self._url.query:
self.GroupAttrProxy(self._conf, self._group,
self._conf[self._group],
self._url)[name]
def __getattr__(self, name):
value = getattr(self._conf, name)
if isinstance(value, self._conf.GroupAttr):
if isinstance(value, self._conf.GroupAttr) and name == self._group:
return self.GroupAttrProxy(self._conf, name, value, self._url)
return value

View File

@ -200,7 +200,7 @@ class ProtonDriver(base.BaseDriver):
title='AMQP 1.0 driver options')
conf.register_group(opt_group)
conf.register_opts(opts.amqp1_opts, group=opt_group)
conf = common.ConfigOptsProxy(conf, url)
conf = common.ConfigOptsProxy(conf, url, opt_group.name)
self._hosts = url.hosts
self._conf = conf

View File

@ -144,7 +144,7 @@ class PikaDriver(base.BaseDriver):
conf.register_opts(message_opts, group=opt_group)
conf.register_opts(rpc_opts, group=opt_group)
conf.register_opts(notification_opts, group=opt_group)
conf = common.ConfigOptsProxy(conf, url)
conf = common.ConfigOptsProxy(conf, url, opt_group.name)
self._pika_engine = pika_drv_engine.PikaEngine(
conf, url, default_exchange, allowed_remote_exmods

View File

@ -1335,7 +1335,7 @@ class RabbitDriver(amqpdriver.AMQPDriverBase):
conf.register_opts(rabbit_opts, group=opt_group)
conf.register_opts(rpc_amqp.amqp_opts, group=opt_group)
conf.register_opts(base.base_opts, group=opt_group)
conf = rpc_common.ConfigOptsProxy(conf, url)
conf = rpc_common.ConfigOptsProxy(conf, url, opt_group.name)
self.missing_destination_retry_timeout = (
conf.oslo_messaging_rabbit.kombu_missing_consumer_retry_timeout)

View File

@ -59,4 +59,4 @@ def register_opts(conf, url):
title='Kafka driver options')
conf.register_group(opt_group)
conf.register_opts(KAFKA_OPTS, group=opt_group)
return common.ConfigOptsProxy(conf, url)
return common.ConfigOptsProxy(conf, url, opt_group.name)

View File

@ -210,4 +210,4 @@ def register_opts(conf, url):
conf.register_opts(zmq_opts, group=opt_group)
conf.register_opts(server._pool_opts)
conf.register_opts(base.base_opts)
return common.ConfigOptsProxy(conf, url)
return common.ConfigOptsProxy(conf, url, opt_group.name)

View File

@ -27,7 +27,6 @@ class TestConfigOptsProxy(test_utils.BaseTestCase):
self.config(rabbit_retry_interval=1,
rabbit_qos_prefetch_count=0,
rabbit_max_retries=3,
kombu_reconnect_delay=5.0,
group=group)
dummy_opts = [cfg.ListOpt('list_str', item_type=types.String(),
default=[]),
@ -40,14 +39,12 @@ class TestConfigOptsProxy(test_utils.BaseTestCase):
url = transport.TransportURL.parse(
self.conf, "rabbit:///"
"?rabbit_qos_prefetch_count=2"
"&unknown_opt=4"
"&kombu_reconnect_delay=invalid_value"
"&list_str=1&list_str=2&list_str=3"
"&list_int=1&list_int=2&list_int=3"
"&dict=x:1&dict=y:2&dict=z:3"
"&bool=True"
)
conf = drv_cmn.ConfigOptsProxy(self.conf, url)
conf = drv_cmn.ConfigOptsProxy(self.conf, url, group)
self.assertRaises(cfg.NoSuchOptError,
conf.__getattr__,
'unknown_group')
@ -57,15 +54,28 @@ class TestConfigOptsProxy(test_utils.BaseTestCase):
self.assertEqual(2,
conf.oslo_messaging_rabbit.rabbit_qos_prefetch_count)
self.assertEqual(3, conf.oslo_messaging_rabbit.rabbit_max_retries)
self.assertRaises(cfg.NoSuchOptError,
conf.oslo_messaging_rabbit.__getattr__,
'unknown_opt')
self.assertRaises(ValueError,
conf.oslo_messaging_rabbit.__getattr__,
'kombu_reconnect_delay')
self.assertEqual(['1', '2', '3'], conf.oslo_messaging_rabbit.list_str)
self.assertEqual([1, 2, 3], conf.oslo_messaging_rabbit.list_int)
self.assertEqual({'x': '1', 'y': '2', 'z': '3'},
conf.oslo_messaging_rabbit.dict)
self.assertEqual(True, conf.oslo_messaging_rabbit.bool)
self.assertEqual('default', conf.oslo_messaging_rabbit.str)
def test_not_in_group(self):
group = 'oslo_messaging_rabbit'
url = transport.TransportURL.parse(
self.conf, "rabbit:///?unknown_opt=4"
)
self.assertRaises(cfg.NoSuchOptError,
drv_cmn.ConfigOptsProxy,
self.conf, url, group)
def test_invalid_value(self):
group = 'oslo_messaging_rabbit'
self.config(kombu_reconnect_delay=5.0,
group=group)
url = transport.TransportURL.parse(
self.conf, "rabbit:///?kombu_reconnect_delay=invalid_value"
)
self.assertRaises(ValueError, drv_cmn.ConfigOptsProxy, self.conf,
url, group)