summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark McLoughlin <markmc@redhat.com>2014-07-02 15:41:33 +0100
committerMark McLoughlin <markmc@redhat.com>2014-07-02 16:17:16 +0100
commita5c3f634a6fd03cfc20011d570e86a907bbe3b5e (patch)
tree2c8fef47d65be922157eb753e480f785d156411f
parenta72e49c3ec7ec28c88d501b50d94bf46e08d515e (diff)
downloadoslo-config-a5c3f634a6fd03cfc20011d570e86a907bbe3b5e.tar.gz
cfg,generator: add Opt.sample_default attribute
Some default values for configuration options are dynamic and environment dependent. For example, an option might default to the hostname of the machine. However, such default values should never end up in a sample configuration file - you don't want your hostname or path to your personal home directory to be included in sample config files. A simple solution to this is to add a 'sample_default' string attribute which is used in place of a default, for those cases where the real value is an unsuitable sample default. For example: cfg.StrOpt('hostname', default=get_my_host(), sample_default='myhostname') blueprint: oslo-config-generator Change-Id: I319d128a0a88b1197d8e2be105681f2b56240439
-rw-r--r--oslo/config/cfg.py6
-rw-r--r--oslo/config/generator.py16
-rw-r--r--tests/test_generator.py30
3 files changed, 48 insertions, 4 deletions
diff --git a/oslo/config/cfg.py b/oslo/config/cfg.py
index 8c6d749..ca90c4c 100644
--- a/oslo/config/cfg.py
+++ b/oslo/config/cfg.py
@@ -594,6 +594,8 @@ class Opt(object):
a single character CLI option name
default:
the default value of the option
+ sample_default:
+ a sample default value string to include in sample config files
positional:
True if the option is a positional CLI argument
metavar:
@@ -607,7 +609,7 @@ class Opt(object):
default=None, positional=False, metavar=None, help=None,
secret=False, required=False,
deprecated_name=None, deprecated_group=None,
- deprecated_opts=None):
+ deprecated_opts=None, sample_default=None):
"""Construct an Opt object.
The only required parameter is the option's name. However, it is
@@ -627,6 +629,7 @@ class Opt(object):
:param deprecated_name: deprecated name option. Acts like an alias
: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
"""
if name.startswith('_'):
raise ValueError('illegal name %s with prefix _' % (name,))
@@ -645,6 +648,7 @@ class Opt(object):
self.dest = dest
self.short = short
self.default = default
+ self.sample_default = sample_default
self.positional = positional
self.metavar = metavar
self.help = help
diff --git a/oslo/config/generator.py b/oslo/config/generator.py
index 46d21c1..5e8e9ef 100644
--- a/oslo/config/generator.py
+++ b/oslo/config/generator.py
@@ -96,7 +96,13 @@ The default runtime values of configuration options are not always the most
suitable values to include in sample config files - for example, rather than
including the IP address or hostname of the machine where the config file
was generated, you might want to include something like '10.0.0.1'. To
-facilitate this, applications can supply their own 'sanitizer' function via
+facilitate this, options can be supplied with a 'sample_default' attribute::
+
+ cfg.StrOpt('base_dir'
+ default=os.getcwd(),
+ sample_default='/usr/lib/myapp')
+
+Alternatively, applications can supply their own 'sanitizer' function via
the 'oslo.config.sanitizer' entry point namespace. For example::
def sanitize_default(self, opt, default_str):
@@ -208,12 +214,16 @@ class _OptFormatter(object):
(d.group or 'DEFAULT', d.name or opt.dest))
if isinstance(opt, cfg.MultiStrOpt):
- if opt.default is None:
+ if opt.sample_default is not None:
+ defaults = opt.sample_default
+ elif opt.default is None:
defaults = ['<None>']
else:
defaults = opt.default
else:
- if opt.default is None:
+ if opt.sample_default is not None:
+ default_str = str(opt.sample_default)
+ elif opt.default is None:
default_str = '<None>'
elif isinstance(opt, cfg.StrOpt):
default_str = opt.default
diff --git a/tests/test_generator.py b/tests/test_generator.py
index 3275408..a126933 100644
--- a/tests/test_generator.py
+++ b/tests/test_generator.py
@@ -61,6 +61,9 @@ class GeneratorTestCase(base.BaseTestCase):
'str_opt': cfg.StrOpt('str_opt',
default='foo bar',
help='a string'),
+ 'str_opt_sample_default': cfg.StrOpt('str_opt',
+ default='fooishbar',
+ help='a string'),
'str_opt_with_space': cfg.StrOpt('str_opt',
default=' foo bar ',
help='a string with spaces'),
@@ -82,6 +85,10 @@ class GeneratorTestCase(base.BaseTestCase):
'multi_opt': cfg.MultiStrOpt('multi_opt',
default=['1', '2', '3'],
help='multiple strings'),
+ 'multi_opt_sample_default': cfg.MultiStrOpt('multi_opt',
+ default=['1', '2', '3'],
+ sample_default=['5', '6'],
+ help='multiple strings'),
}
content_scenarios = [
@@ -401,6 +408,29 @@ class GeneratorTestCase(base.BaseTestCase):
#multi_opt = 2
#multi_opt = 3
''')),
+ ('str_opt_sample_default',
+ dict(opts=[('test', [(None, [opts['str_opt_sample_default']])])],
+ expected='''[DEFAULT]
+
+#
+# From test
+#
+
+# a string (string value)
+#str_opt = fooishbar
+''')),
+ ('multi_opt_sample_default',
+ dict(opts=[('test', [(None, [opts['multi_opt_sample_default']])])],
+ expected='''[DEFAULT]
+
+#
+# From test
+#
+
+# multiple strings (multi valued)
+#multi_opt = 5
+#multi_opt = 6
+''')),
('sanitizer',
dict(opts=[('test', [(None, [opts['str_opt']])])],
sanitizer=lambda o, s: s.replace(' ', 'ish'),