Add support for outputting role-specific parameters
It is possible to pass parameters only to a specific role by using an environment with a <role name>Parameters dict. This change adds support for sample environments with such nested parameters. Change-Id: I7eb91d4262013341fab733342ab313caf8cec118
This commit is contained in:
parent
39c6233306
commit
615128f1c4
|
@ -14,25 +14,26 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
_PARAM_FORMAT = u""" # %(description)s
|
_PARAM_FORMAT = u"""%(indent_space)s # %(description)s
|
||||||
%(mandatory)s# Type: %(type)s
|
%(mandatory)s%(indent_space)s# Type: %(type)s
|
||||||
%(name)s:%(default)s
|
%(indent_space)s%(name)s:%(default)s
|
||||||
"""
|
"""
|
||||||
_STATIC_MESSAGE_START = (
|
_STATIC_MESSAGE_START = (
|
||||||
' # ******************************************************\n'
|
'%(indent_space)s # ******************************************************\n'
|
||||||
' # Static parameters - these are values that must be\n'
|
'%(indent_space)s # Static parameters - these are values that must be\n'
|
||||||
' # included in the environment but should not be changed.\n'
|
'%(indent_space)s # included in the environment but should not be changed.\n'
|
||||||
' # ******************************************************\n'
|
'%(indent_space)s # ******************************************************\n'
|
||||||
)
|
)
|
||||||
_STATIC_MESSAGE_END = (' # *********************\n'
|
_STATIC_MESSAGE_END = ('%(indent_space)s # *********************\n'
|
||||||
' # End static parameters\n'
|
'%(indent_space)s # End static parameters\n'
|
||||||
' # *********************\n'
|
'%(indent_space)s # *********************\n'
|
||||||
)
|
)
|
||||||
_FILE_HEADER = (
|
_FILE_HEADER = (
|
||||||
'# *******************************************************************\n'
|
'# *******************************************************************\n'
|
||||||
|
@ -42,6 +43,7 @@ _FILE_HEADER = (
|
||||||
'# of the original, if any customizations are needed.\n'
|
'# of the original, if any customizations are needed.\n'
|
||||||
'# *******************************************************************\n'
|
'# *******************************************************************\n'
|
||||||
)
|
)
|
||||||
|
_PARAMETERS = "parameters"
|
||||||
# Certain parameter names can't be changed, but shouldn't be shown because
|
# Certain parameter names can't be changed, but shouldn't be shown because
|
||||||
# they are never intended for direct user input.
|
# they are never intended for direct user input.
|
||||||
_PRIVATE_OVERRIDES = ['server', 'servers', 'NodeIndex', 'DefaultPasswords']
|
_PRIVATE_OVERRIDES = ['server', 'servers', 'NodeIndex', 'DefaultPasswords']
|
||||||
|
@ -54,6 +56,12 @@ _HIDDEN_PARAMS = ['EndpointMap', 'RoleName', 'RoleParameters',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _initialize_params_dict(params_dict, k, v):
|
||||||
|
for role, param_name in params_dict.items():
|
||||||
|
if k in param_name:
|
||||||
|
params_dict[role][k]['sample'] = v
|
||||||
|
|
||||||
|
|
||||||
def _create_output_dir(target_file):
|
def _create_output_dir(target_file):
|
||||||
try:
|
try:
|
||||||
os.makedirs(os.path.dirname(target_file))
|
os.makedirs(os.path.dirname(target_file))
|
||||||
|
@ -70,23 +78,24 @@ def _generate_environment(input_env, output_path, parent_env=None):
|
||||||
env = dict(parent_env)
|
env = dict(parent_env)
|
||||||
env.pop('children', None)
|
env.pop('children', None)
|
||||||
env.update(input_env)
|
env.update(input_env)
|
||||||
parameter_defaults = {}
|
f_parameter_defaults = {}
|
||||||
param_names = []
|
param_names = defaultdict(list)
|
||||||
sample_values = env.get('sample_values', {})
|
sample_values = env.get('sample_values', {})
|
||||||
static_names = env.get('static', [])
|
static_names = env.get('static', [])
|
||||||
for template_file, template_data in env['files'].items():
|
for template_file, template_data in env['files'].items():
|
||||||
with open(template_file) as f:
|
with open(template_file) as f:
|
||||||
f_data = yaml.safe_load(f)
|
f_data = yaml.safe_load(f)
|
||||||
f_params = f_data['parameters']
|
f_params = f_data['parameters']
|
||||||
parameter_defaults.update(f_params)
|
f_parameter_defaults.update(f_params)
|
||||||
if template_data['parameters'] == 'all':
|
for t_param_role, t_params in template_data.items():
|
||||||
|
if t_params == 'all':
|
||||||
new_names = [k for k, v in f_params.items()]
|
new_names = [k for k, v in f_params.items()]
|
||||||
for hidden in _HIDDEN_PARAMS:
|
for hidden in _HIDDEN_PARAMS:
|
||||||
if (hidden not in (static_names + list(sample_values)) and
|
if (hidden not in (static_names + list(sample_values)) and
|
||||||
hidden in new_names):
|
hidden in new_names):
|
||||||
new_names.remove(hidden)
|
new_names.remove(hidden)
|
||||||
else:
|
else:
|
||||||
new_names = template_data['parameters']
|
new_names = t_params
|
||||||
missing_params = [name for name in new_names
|
missing_params = [name for name in new_names
|
||||||
if name not in f_params]
|
if name not in f_params]
|
||||||
if missing_params:
|
if missing_params:
|
||||||
|
@ -94,26 +103,28 @@ def _generate_environment(input_env, output_path, parent_env=None):
|
||||||
'in file %s for environment %s' %
|
'in file %s for environment %s' %
|
||||||
(missing_params, template_file,
|
(missing_params, template_file,
|
||||||
env['name']))
|
env['name']))
|
||||||
param_names += new_names
|
param_names[t_param_role] += new_names
|
||||||
|
|
||||||
static_defaults = {k: v for k, v in parameter_defaults.items()
|
static_defaults = defaultdict(dict)
|
||||||
if k in param_names and
|
parameter_defaults = defaultdict(dict)
|
||||||
k in static_names
|
for role, params in param_names.items():
|
||||||
}
|
static_defaults[role] = {name: f_parameter_defaults[name]
|
||||||
parameter_defaults = {k: v for k, v in parameter_defaults.items()
|
for name in params
|
||||||
if k in param_names and
|
if name in f_parameter_defaults and
|
||||||
k not in _PRIVATE_OVERRIDES and
|
name in static_names}
|
||||||
not k.startswith('_') and
|
parameter_defaults[role] = {name: f_parameter_defaults[name]
|
||||||
k not in static_names
|
for name in params
|
||||||
}
|
if name in f_parameter_defaults and
|
||||||
|
name not in _PRIVATE_OVERRIDES and
|
||||||
|
not name.startswith('_') and
|
||||||
|
name not in static_names}
|
||||||
|
|
||||||
for k, v in sample_values.items():
|
for k, v in sample_values.items():
|
||||||
if k in parameter_defaults:
|
_initialize_params_dict(parameter_defaults, k, v)
|
||||||
parameter_defaults[k]['sample'] = v
|
_initialize_params_dict(static_defaults, k, v)
|
||||||
if k in static_defaults:
|
|
||||||
static_defaults[k]['sample'] = v
|
|
||||||
|
|
||||||
def write_sample_entry(f, name, value):
|
def write_sample_entry(f, name, value, indent_space_count=0):
|
||||||
|
indent_space = " " * indent_space_count
|
||||||
default = value.get('default')
|
default = value.get('default')
|
||||||
mandatory = ''
|
mandatory = ''
|
||||||
if default is None:
|
if default is None:
|
||||||
|
@ -138,15 +149,28 @@ def _generate_environment(input_env, output_path, parent_env=None):
|
||||||
values = {'name': name,
|
values = {'name': name,
|
||||||
'type': value['type'],
|
'type': value['type'],
|
||||||
'description':
|
'description':
|
||||||
value.get('description', '').rstrip().replace('\n',
|
value.get('description', '').rstrip().
|
||||||
'\n # '),
|
replace('\n', '\n%s # ' % indent_space).rstrip(),
|
||||||
'default': default,
|
'default': default,
|
||||||
'mandatory': mandatory,
|
'mandatory': mandatory,
|
||||||
|
'indent_space': indent_space,
|
||||||
}
|
}
|
||||||
f.write(_PARAM_FORMAT % values + '\n')
|
f.write(_PARAM_FORMAT % values + '\n')
|
||||||
|
|
||||||
target_file = os.path.join(output_path, env['name'] + '.yaml')
|
target_file = os.path.join(output_path, env['name'] + '.yaml')
|
||||||
_create_output_dir(target_file)
|
_create_output_dir(target_file)
|
||||||
|
|
||||||
|
def write_params_entry(f, parameter_defaults_tuple, static_defaults_tuple, indent_space_count):
|
||||||
|
for param_name, param_value in sorted(parameter_defaults_tuple.items()):
|
||||||
|
write_sample_entry(f, param_name,
|
||||||
|
param_value, indent_space_count)
|
||||||
|
if static_defaults_tuple:
|
||||||
|
f.write(_STATIC_MESSAGE_START % {"indent_space": " " * indent_space_count})
|
||||||
|
for param_name, param_value in sorted(static_defaults_tuple.items()):
|
||||||
|
write_sample_entry(f, param_name,
|
||||||
|
param_value, indent_space_count)
|
||||||
|
f.write(_STATIC_MESSAGE_END % {"indent_space": " " * indent_space_count})
|
||||||
|
|
||||||
with open(target_file, 'w') as env_file:
|
with open(target_file, 'w') as env_file:
|
||||||
env_file.write(_FILE_HEADER)
|
env_file.write(_FILE_HEADER)
|
||||||
# TODO(bnemec): Once Heat allows the title and description to live in
|
# TODO(bnemec): Once Heat allows the title and description to live in
|
||||||
|
@ -158,18 +182,15 @@ def _generate_environment(input_env, output_path, parent_env=None):
|
||||||
env_file.write(u'# description: |\n')
|
env_file.write(u'# description: |\n')
|
||||||
for line in env_desc.splitlines():
|
for line in env_desc.splitlines():
|
||||||
env_file.write(u'# %s\n' % line)
|
env_file.write(u'# %s\n' % line)
|
||||||
|
|
||||||
if parameter_defaults or static_defaults:
|
if parameter_defaults or static_defaults:
|
||||||
env_file.write(u'parameter_defaults:\n')
|
env_file.write(u'parameter_defaults:\n')
|
||||||
for name, value in sorted(parameter_defaults.items()):
|
write_params_entry(env_file, parameter_defaults[_PARAMETERS],
|
||||||
write_sample_entry(env_file, name, value)
|
static_defaults[_PARAMETERS], 0)
|
||||||
if static_defaults:
|
param_names.pop(_PARAMETERS, None)
|
||||||
env_file.write(_STATIC_MESSAGE_START)
|
for name in param_names:
|
||||||
for name, value in sorted(static_defaults.items()):
|
env_file.write(u' %s:\n' % name)
|
||||||
write_sample_entry(env_file, name, value)
|
write_params_entry(env_file, parameter_defaults[name],
|
||||||
if static_defaults:
|
static_defaults[name], 2)
|
||||||
env_file.write(_STATIC_MESSAGE_END)
|
|
||||||
|
|
||||||
if env.get('resource_registry'):
|
if env.get('resource_registry'):
|
||||||
env_file.write(u'resource_registry:\n')
|
env_file.write(u'resource_registry:\n')
|
||||||
for res, value in sorted(env.get('resource_registry', {}).items()):
|
for res, value in sorted(env.get('resource_registry', {}).items()):
|
||||||
|
|
|
@ -82,6 +82,36 @@ parameters:
|
||||||
resources:
|
resources:
|
||||||
# None
|
# None
|
||||||
'''
|
'''
|
||||||
|
basic_role_param_template = '''
|
||||||
|
parameters:
|
||||||
|
RoleParam:
|
||||||
|
description: Role param description
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
FooParam:
|
||||||
|
description: Foo description
|
||||||
|
default: foo
|
||||||
|
type: string
|
||||||
|
resources:
|
||||||
|
# None
|
||||||
|
'''
|
||||||
|
multiline_role_param_template = '''
|
||||||
|
parameters:
|
||||||
|
RoleParam:
|
||||||
|
description: |
|
||||||
|
Role Parameter with
|
||||||
|
multi-line description
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
FooParam:
|
||||||
|
description: |
|
||||||
|
Parameter with
|
||||||
|
multi-line description
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
resources:
|
||||||
|
# None
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
class GeneratorTestCase(base.BaseTestCase):
|
class GeneratorTestCase(base.BaseTestCase):
|
||||||
|
@ -455,6 +485,219 @@ parameter_defaults:
|
||||||
# Type: string
|
# Type: string
|
||||||
FooParam: ''
|
FooParam: ''
|
||||||
|
|
||||||
|
''',
|
||||||
|
}),
|
||||||
|
('basic_role_param',
|
||||||
|
{'template': basic_role_param_template,
|
||||||
|
'exception': None,
|
||||||
|
'nested_output': '',
|
||||||
|
'input_file': '''environments:
|
||||||
|
-
|
||||||
|
name: basic_role_param
|
||||||
|
title: Basic Role Parameters Environment
|
||||||
|
description: Basic description
|
||||||
|
files:
|
||||||
|
foo.yaml:
|
||||||
|
RoleParameters:
|
||||||
|
- RoleParam
|
||||||
|
''',
|
||||||
|
'expected_output': '''# title: Basic Role Parameters Environment
|
||||||
|
# description: |
|
||||||
|
# Basic description
|
||||||
|
parameter_defaults:
|
||||||
|
RoleParameters:
|
||||||
|
# Role param description
|
||||||
|
# Type: string
|
||||||
|
RoleParam: ''
|
||||||
|
|
||||||
|
''',
|
||||||
|
}),
|
||||||
|
('multiline_role_param',
|
||||||
|
{'template': multiline_role_param_template,
|
||||||
|
'exception': None,
|
||||||
|
'nested_output': '',
|
||||||
|
'input_file': '''environments:
|
||||||
|
-
|
||||||
|
name: multiline_role_param
|
||||||
|
title: Multiline Role Parameters Environment
|
||||||
|
description: Multiline description
|
||||||
|
files:
|
||||||
|
foo.yaml:
|
||||||
|
RoleParameters:
|
||||||
|
- RoleParam
|
||||||
|
''',
|
||||||
|
'expected_output': '''# title: Multiline Role Parameters Environment
|
||||||
|
# description: |
|
||||||
|
# Multiline description
|
||||||
|
parameter_defaults:
|
||||||
|
RoleParameters:
|
||||||
|
# Role Parameter with
|
||||||
|
# multi-line description
|
||||||
|
# Type: string
|
||||||
|
RoleParam: ''
|
||||||
|
|
||||||
|
''',
|
||||||
|
}),
|
||||||
|
('Basic mix params',
|
||||||
|
{'template': basic_role_param_template,
|
||||||
|
'exception': None,
|
||||||
|
'nested_output': '',
|
||||||
|
'input_file': '''environments:
|
||||||
|
-
|
||||||
|
name: basic_mix_params
|
||||||
|
title: Basic Mix Parameters Environment
|
||||||
|
description: Basic description
|
||||||
|
files:
|
||||||
|
foo.yaml:
|
||||||
|
parameters:
|
||||||
|
- FooParam
|
||||||
|
RoleParameters:
|
||||||
|
- RoleParam
|
||||||
|
''',
|
||||||
|
'expected_output': '''# title: Basic Mix Parameters Environment
|
||||||
|
# description: |
|
||||||
|
# Basic description
|
||||||
|
parameter_defaults:
|
||||||
|
# Foo description
|
||||||
|
# Type: string
|
||||||
|
FooParam: foo
|
||||||
|
|
||||||
|
RoleParameters:
|
||||||
|
# Role param description
|
||||||
|
# Type: string
|
||||||
|
RoleParam: ''
|
||||||
|
|
||||||
|
''',
|
||||||
|
}),
|
||||||
|
('Multiline mix params',
|
||||||
|
{'template': multiline_role_param_template,
|
||||||
|
'exception': None,
|
||||||
|
'nested_output': '',
|
||||||
|
'input_file': '''environments:
|
||||||
|
-
|
||||||
|
name: multiline_mix_params
|
||||||
|
title: Multiline mix params Environment
|
||||||
|
description: Multiline description
|
||||||
|
files:
|
||||||
|
foo.yaml:
|
||||||
|
parameters:
|
||||||
|
- FooParam
|
||||||
|
RoleParameters:
|
||||||
|
- RoleParam
|
||||||
|
''',
|
||||||
|
'expected_output': '''# title: Multiline mix params Environment
|
||||||
|
# description: |
|
||||||
|
# Multiline description
|
||||||
|
parameter_defaults:
|
||||||
|
# Parameter with
|
||||||
|
# multi-line description
|
||||||
|
# Type: string
|
||||||
|
FooParam: ''
|
||||||
|
|
||||||
|
RoleParameters:
|
||||||
|
# Role Parameter with
|
||||||
|
# multi-line description
|
||||||
|
# Type: string
|
||||||
|
RoleParam: ''
|
||||||
|
|
||||||
|
''',
|
||||||
|
}),
|
||||||
|
('Basic role static param',
|
||||||
|
{'template': basic_role_param_template,
|
||||||
|
'exception': None,
|
||||||
|
'nested_output': '',
|
||||||
|
'input_file': '''environments:
|
||||||
|
-
|
||||||
|
name: basic_role_static_param
|
||||||
|
title: Basic Role Static Prams Environment
|
||||||
|
description: Basic Role Static Prams description
|
||||||
|
files:
|
||||||
|
foo.yaml:
|
||||||
|
parameters:
|
||||||
|
- FooParam
|
||||||
|
RoleParameters:
|
||||||
|
- RoleParam
|
||||||
|
static:
|
||||||
|
- FooParam
|
||||||
|
- RoleParam
|
||||||
|
''',
|
||||||
|
'expected_output': '''# title: Basic Role Static Prams Environment
|
||||||
|
# description: |
|
||||||
|
# Basic Role Static Prams description
|
||||||
|
parameter_defaults:
|
||||||
|
# ******************************************************
|
||||||
|
# Static parameters - these are values that must be
|
||||||
|
# included in the environment but should not be changed.
|
||||||
|
# ******************************************************
|
||||||
|
# Foo description
|
||||||
|
# Type: string
|
||||||
|
FooParam: foo
|
||||||
|
|
||||||
|
# *********************
|
||||||
|
# End static parameters
|
||||||
|
# *********************
|
||||||
|
RoleParameters:
|
||||||
|
# ******************************************************
|
||||||
|
# Static parameters - these are values that must be
|
||||||
|
# included in the environment but should not be changed.
|
||||||
|
# ******************************************************
|
||||||
|
# Role param description
|
||||||
|
# Type: string
|
||||||
|
RoleParam: ''
|
||||||
|
|
||||||
|
# *********************
|
||||||
|
# End static parameters
|
||||||
|
# *********************
|
||||||
|
''',
|
||||||
|
}),
|
||||||
|
('Multiline role static param',
|
||||||
|
{'template': multiline_role_param_template,
|
||||||
|
'exception': None,
|
||||||
|
'nested_output': '',
|
||||||
|
'input_file': '''environments:
|
||||||
|
-
|
||||||
|
name: multline_role_static_param
|
||||||
|
title: Multiline Role Static Prams Environment
|
||||||
|
description: Multiline Role Static Prams description
|
||||||
|
files:
|
||||||
|
foo.yaml:
|
||||||
|
parameters:
|
||||||
|
- FooParam
|
||||||
|
RoleParameters:
|
||||||
|
- RoleParam
|
||||||
|
static:
|
||||||
|
- FooParam
|
||||||
|
- RoleParam
|
||||||
|
''',
|
||||||
|
'expected_output': '''# title: Multiline Role Static Prams Environment
|
||||||
|
# description: |
|
||||||
|
# Multiline Role Static Prams description
|
||||||
|
parameter_defaults:
|
||||||
|
# ******************************************************
|
||||||
|
# Static parameters - these are values that must be
|
||||||
|
# included in the environment but should not be changed.
|
||||||
|
# ******************************************************
|
||||||
|
# Parameter with
|
||||||
|
# multi-line description
|
||||||
|
# Type: string
|
||||||
|
FooParam: ''
|
||||||
|
|
||||||
|
# *********************
|
||||||
|
# End static parameters
|
||||||
|
# *********************
|
||||||
|
RoleParameters:
|
||||||
|
# ******************************************************
|
||||||
|
# Static parameters - these are values that must be
|
||||||
|
# included in the environment but should not be changed.
|
||||||
|
# ******************************************************
|
||||||
|
# Role Parameter with
|
||||||
|
# multi-line description
|
||||||
|
# Type: string
|
||||||
|
RoleParam: ''
|
||||||
|
|
||||||
|
# *********************
|
||||||
|
# End static parameters
|
||||||
|
# *********************
|
||||||
''',
|
''',
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue