summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Nemec <bnemec@redhat.com>2015-03-02 19:33:40 +0000
committerBen Nemec <bnemec@redhat.com>2015-03-03 18:53:17 +0000
commitdacc035719d9d937bbc49540d0f18885c2d9c240 (patch)
tree93dd15f07bd56a391091103f81e9cd8f1f9b6e98
parenta4abbdbbd7477ef46180c5995fac075678cb7c3a (diff)
downloadoslo-config-dacc035719d9d937bbc49540d0f18885c2d9c240.tar.gz
Add ability to deprecate opts for removal
Previously opts could only be deprecated by renaming them, but there are circumstances where we may want to remove an opt completely, and we need a way to notify users before this happens. This change adds a deprecated_for_removal parameter to the Opt constructor that can be used to mark opts for which this is planned. When such opts are referenced it will log a message, but only if the default value has been overridden. Change-Id: I0165895d58530f5fce58cbf8a1bbe2acd90e9063
-rw-r--r--oslo_config/cfg.py18
-rw-r--r--oslo_config/tests/test_cfg.py41
2 files changed, 57 insertions, 2 deletions
diff --git a/oslo_config/cfg.py b/oslo_config/cfg.py
index b51b4ec..3d6def7 100644
--- a/oslo_config/cfg.py
+++ b/oslo_config/cfg.py
@@ -622,7 +622,8 @@ class Opt(object):
default=None, positional=False, metavar=None, help=None,
secret=False, required=False,
deprecated_name=None, deprecated_group=None,
- deprecated_opts=None, sample_default=None):
+ deprecated_opts=None, sample_default=None,
+ deprecated_for_removal=False):
"""Construct an Opt object.
The only required parameter is the option's name. However, it is
@@ -643,6 +644,8 @@ class Opt(object):
:param deprecated_group: the group containing a deprecated alias
:param deprecated_opts: array of DeprecatedOpt(s)
:param sample_default: a default string for sample config files
+ :param deprecated_for_removal: indicates whether this opt is planned
+ for removal in a future release
"""
if name.startswith('_'):
raise ValueError('illegal name %s with prefix _' % (name,))
@@ -667,6 +670,8 @@ class Opt(object):
self.help = help
self.secret = secret
self.required = required
+ self.deprecated_for_removal = deprecated_for_removal
+ self._logged_deprecation = False
if deprecated_name is not None:
deprecated_name = deprecated_name.replace('-', '_')
@@ -719,7 +724,16 @@ class Opt(object):
names.append((dgroup if dgroup else group_name,
dname if dname else self.dest))
- return namespace._get_value(names, self.multi, self.positional)
+ value = namespace._get_value(names, self.multi, self.positional)
+ # The previous line will raise a KeyError if no value is set in the
+ # config file, so we'll only log deprecations for set options.
+ if self.deprecated_for_removal and not self._logged_deprecation:
+ self._logged_deprecation = True
+ pretty_group = group_name or 'DEFAULT'
+ LOG.warning('Option "%s" from group "%s" is deprecated for '
+ 'removal. Its value may be silently ignored in the '
+ 'future.', self.dest, pretty_group)
+ return value
def _add_to_cli(self, parser, group=None):
"""Makes the option available in the command line interface.
diff --git a/oslo_config/tests/test_cfg.py b/oslo_config/tests/test_cfg.py
index eb5ddd1..6accd82 100644
--- a/oslo_config/tests/test_cfg.py
+++ b/oslo_config/tests/test_cfg.py
@@ -3660,3 +3660,44 @@ class DeprecationWarningTests(DeprecationWarningTestBase):
current_name, current_group)
)
self.assertEqual(expected + '\n', self.log_fixture.output)
+
+ def test_deprecated_for_removal(self):
+ self.conf.register_opt(cfg.StrOpt('foo',
+ deprecated_for_removal=True))
+ self.conf.register_opt(cfg.StrOpt('bar',
+ deprecated_for_removal=True))
+ paths = self.create_tempfiles([('test',
+ '[DEFAULT]\n' +
+ 'foo=bar\n')])
+ self.conf(['--config-file', paths[0]])
+ # Multiple references should be logged only once.
+ self.assertEqual('bar', self.conf.foo)
+ self.assertEqual('bar', self.conf.foo)
+ # Options not set in the config should not be logged.
+ self.assertEqual(None, self.conf.bar)
+ expected = ('Option "foo" from group "DEFAULT" is deprecated for '
+ 'removal. Its value may be silently ignored in the '
+ 'future.\n')
+ self.assertEqual(expected, self.log_fixture.output)
+
+ def test_deprecated_for_removal_with_group(self):
+ self.conf.register_group(cfg.OptGroup('other'))
+ self.conf.register_opt(cfg.StrOpt('foo',
+ deprecated_for_removal=True),
+ group='other')
+ self.conf.register_opt(cfg.StrOpt('bar',
+ deprecated_for_removal=True),
+ group='other')
+ paths = self.create_tempfiles([('test',
+ '[other]\n' +
+ 'foo=bar\n')])
+ self.conf(['--config-file', paths[0]])
+ # Multiple references should be logged only once.
+ self.assertEqual('bar', self.conf.other.foo)
+ self.assertEqual('bar', self.conf.other.foo)
+ # Options not set in the config should not be logged.
+ self.assertEqual(None, self.conf.other.bar)
+ expected = ('Option "foo" from group "other" is deprecated for '
+ 'removal. Its value may be silently ignored in the '
+ 'future.\n')
+ self.assertEqual(expected, self.log_fixture.output)