Required Option

Required options currently are not pushed to the
top of each section, and they are also not marked
as required.  This will mark the option as required
and push it to the top, uncommented.  This will
allow users to know for sure what options are
minimally required to get the service started.

Change-Id: Ic194498ec695d268cce0a26d19f9469ba800412e
Implements: blueprint oslo-generator-required
This commit is contained in:
Brian Stajkowski 2016-05-26 08:29:59 -07:00
parent 792a43fbf4
commit 229a7624c7
2 changed files with 50 additions and 7 deletions

View File

@ -48,6 +48,8 @@ _generator_opts = [
required=True,
help='Option namespace under "oslo.config.opts" in which '
'to query for options.'),
cfg.BoolOpt('minimal', default=False,
help='Generate a minimal required configuration.'),
]
@ -161,7 +163,7 @@ class _OptFormatter(object):
lines = ['[%s]\n' % groupname]
self.writelines(lines)
def format(self, opt, group_name):
def format(self, opt, group_name, minimal=False):
"""Format a description of an option to the output file.
:param opt: a cfg.Opt instance
@ -246,7 +248,10 @@ class _OptFormatter(object):
for default_str in defaults:
if default_str:
default_str = ' ' + default_str
lines.append('#%s =%s\n' % (opt.dest, default_str))
if minimal:
lines.append('%s =%s\n' % (opt.dest, default_str))
else:
lines.append('#%s =%s\n' % (opt.dest, default_str))
self.writelines(lines)
@ -354,15 +359,18 @@ def on_load_failure_callback(*args, **kwargs):
raise
def _output_opts(f, group, group_data):
def _output_opts(f, group, group_data, minimal=False):
f.format_group(group_data['object'] or group)
for (namespace, opts) in sorted(group_data['namespaces'],
key=operator.itemgetter(0)):
f.write('\n#\n# From %s\n#\n' % namespace)
for opt in opts:
f.write('\n')
try:
f.format(opt, group)
if minimal and not opt.required:
pass
else:
f.write('\n')
f.format(opt, group, minimal)
except Exception as err:
f.write('# Warning: Failed to format sample for %s\n' %
(opt.dest,))
@ -421,12 +429,12 @@ def generate(conf):
groups = _get_groups(_list_opts(conf.namespace))
# Output the "DEFAULT" section as the very first section
_output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT'))
_output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT'), conf.minimal)
# output all other config sections with groups in alphabetical order
for group, group_data in sorted(groups.items()):
formatter.write('\n\n')
_output_opts(formatter, group, group_data)
_output_opts(formatter, group, group_data, conf.minimal)
def main(args=None):

View File

@ -1101,4 +1101,39 @@ class ChangeDefaultsTestCase(base.BaseTestCase):
self.assertIs(orig_opt, the_opt)
class RequiredOptionTestCase(base.BaseTestCase):
opts = [cfg.StrOpt('foo', help='foo option', default='fred'),
cfg.StrOpt('bar', help='bar option', required=True),
cfg.StrOpt('foo_bar', help='foobar'),
cfg.StrOpt('bars', help='bars foo', required=True)]
def test_required_option_order_single_ns(self):
config = [("namespace1", [
("alpha", self.opts)])]
groups = generator._get_groups(config)
fd, tmp_file = tempfile.mkstemp()
with open(tmp_file, 'w+') as f:
formatter = generator._OptFormatter(output_file=f)
generator._output_opts(formatter, 'alpha',
groups.pop('alpha'), True)
expected = '''[alpha]
#
# From namespace1
#
# bar option (string value)
bar = <None>
# bars foo (string value)
bars = <None>
'''
with open(tmp_file, 'r') as f:
actual = f.read()
self.assertEqual(expected, actual)
GeneratorTestCase.generate_scenarios()