Merge "Add expose_opt to CfgFilter"

This commit is contained in:
Jenkins 2015-03-02 04:26:15 +00:00 committed by Gerrit Code Review
commit a4abbdbbd7
2 changed files with 100 additions and 1 deletions

@ -13,7 +13,7 @@
# under the License.
r"""
There are two use cases for the ConfigFilter class:
There are three use cases for the ConfigFilter class:
1. Help enforce that a given module does not access options registered
by another module, without first declaring those cross-module
@ -22,6 +22,8 @@ There are two use cases for the ConfigFilter class:
2. Prevent private configuration opts from being visible to modules
other than the one which registered it.
3. Limit the options on a Cfg object that can be accessed.
Cross-Module Option Dependencies
--------------------------------
@ -96,6 +98,31 @@ which the API user supplies to the library. For example::
print(widget.foo)
print(conf.foo) # raises NoSuchOptError
Limited Configuration Options
-----------------------------
It may be required that when passing a CONF object to other functions we want
to filter that the receiving code is only able to access a restricted subset
of the options that are available on the CONF object. This is essentially a
more general case of the Private Configuration Options and Cross-Module Options
whereby we expose an option that is already present on the underlying CONF
object without providing any means to load it if not present.
So given a CONF object with options defined::
CONF.register_opt(StrOpt('foo'))
CONF.register_opt(StrOpt('bar'))
we can expose options such that only those options are present::
restricted_conf = CfgFilter(CONF)
restricted_conf.expose_opt('foo')
print(restricted_conf.foo)
print(restricted_conf.bar) # raises NoSuchOptError
"""
import collections
@ -273,6 +300,28 @@ class ConfigFilter(collections.Mapping):
self._imported_groups[group_name] = group
return group
def expose_opt(self, opt_name, group=None):
"""Expose an option from the underlying conf object.
This allows an object that has already been imported or used from the
base conf object to be seen from the filter object.
:param opt_name: the name/dest of the opt
:param group: an option OptGroup object or group name
"""
self._import_opt(opt_name, group)
def expose_group(self, group):
"""Expose all option from a group in the underlying conf object.
This allows an object that has already been imported or used from the
base conf object to be seen from the filter object.
:param group: an option OptGroup object or group name
"""
group = self._import_group(group)
group._all_opts = True
class GroupAttr(collections.Mapping):
"""Helper class to wrap a group object.

@ -278,3 +278,53 @@ class ImportTestCase(BaseTestCase):
self.fconf.import_group('fbaar', 'tests.testmods.fbaar_baa_opt')
self.assertTrue(hasattr(self.fconf, 'fbaar'))
self.assertTrue(hasattr(self.fconf.fbaar, 'baa'))
class ExposeTestCase(BaseTestCase):
def test_expose_opt(self):
self.assertFalse(hasattr(self.conf, 'foo'))
self.assertFalse(hasattr(self.fconf, 'foo'))
self.conf.register_opt(cfg.StrOpt('foo'))
self.conf.set_override('foo', 'bar')
self.assertTrue(hasattr(self.conf, 'foo'))
self.assertEqual(self.conf.foo, 'bar')
self.assertFalse(hasattr(self.fconf, 'foo'))
self.fconf.expose_opt('foo')
self.assertTrue(hasattr(self.conf, 'foo'))
self.assertTrue(hasattr(self.fconf, 'foo'))
self.assertEqual(self.fconf.foo, 'bar')
def test_expose_opt_with_group(self):
self.assertFalse(hasattr(self.conf, 'foo'))
self.assertFalse(hasattr(self.fconf, 'foo'))
self.conf.register_opt(cfg.StrOpt('foo'), group='group')
self.conf.set_override('foo', 'bar', group='group')
self.assertTrue(hasattr(self.conf.group, 'foo'))
self.assertEqual(self.conf.group.foo, 'bar')
self.assertFalse(hasattr(self.fconf, 'group'))
self.fconf.expose_opt('foo', group='group')
self.assertTrue(hasattr(self.conf.group, 'foo'))
self.assertTrue(hasattr(self.fconf.group, 'foo'))
self.assertEqual(self.fconf.group.foo, 'bar')
def test_expose_group(self):
self.conf.register_opts([cfg.StrOpt('foo'),
cfg.StrOpt('bar')], group='group')
self.conf.register_opts([cfg.StrOpt('foo'),
cfg.StrOpt('bar')], group='another')
self.conf.set_override('foo', 'a', group='group')
self.conf.set_override('bar', 'b', group='group')
self.fconf.expose_group('group')
self.assertEqual('a', self.fconf.group.foo)
self.assertEqual('b', self.fconf.group.bar)
self.assertFalse(hasattr(self.fconf, 'another'))
self.assertTrue(hasattr(self.conf, 'another'))