3 # Copyright 2015 Red Hat Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
23 _PARAM_FORMAT = u""" # %(description)s
24 %(mandatory)s# Type: %(type)s
27 _STATIC_MESSAGE_START = (
28 ' # ******************************************************\n'
29 ' # Static parameters - these are values that must be\n'
30 ' # included in the environment but should not be changed.\n'
31 ' # ******************************************************\n'
33 _STATIC_MESSAGE_END = (' # *********************\n'
34 ' # End static parameters\n'
35 ' # *********************\n'
38 '# *******************************************************************\n'
39 '# This file was created automatically by the sample environment\n'
40 '# generator. Developers should use `tox -e genconfig` to update it.\n'
41 '# Users are recommended to make changes to a copy of the file instead\n'
42 '# of the original, if any customizations are needed.\n'
43 '# *******************************************************************\n'
45 # Certain parameter names can't be changed, but shouldn't be shown because
46 # they are never intended for direct user input.
47 _PRIVATE_OVERRIDES = ['server', 'servers', 'NodeIndex']
50 def _create_output_dir(target_file):
52 os.makedirs(os.path.dirname(target_file))
54 if e.errno == errno.EEXIST:
60 def _generate_environment(input_env, parent_env=None):
61 if parent_env is None:
63 env = dict(parent_env)
65 parameter_defaults = {}
67 for template_file, template_data in env['files'].items():
68 with open(template_file) as f:
69 f_data = yaml.safe_load(f)
70 f_params = f_data['parameters']
71 parameter_defaults.update(f_params)
72 if template_data['parameters'] == 'all':
73 new_names = [k for k, v in f_params.items()]
75 new_names = template_data['parameters']
76 missing_params = [name for name in new_names
77 if name not in f_params]
79 raise RuntimeError('Did not find specified parameter names %s '
80 'in file %s for environment %s' %
81 (missing_params, template_file,
83 param_names += new_names
85 static_names = env.get('static', [])
86 static_defaults = {k: v for k, v in parameter_defaults.items()
87 if k in param_names and
90 parameter_defaults = {k: v for k, v in parameter_defaults.items()
91 if k in param_names and
92 k not in _PRIVATE_OVERRIDES and
93 not k.startswith('_') and
96 for k, v in env.get('sample_values', {}).items():
97 if k in parameter_defaults:
98 parameter_defaults[k]['sample'] = v
99 if k in static_defaults:
100 static_defaults[k]['sample'] = v
102 def write_sample_entry(f, name, value):
103 default = value.get('default')
106 mandatory = ('# Mandatory. This parameter must be set by the '
109 if value.get('sample') is not None:
110 default = value['sample']
114 # If the default value is something like %index%, yaml won't
115 # parse the output correctly unless we wrap it in quotes.
116 # However, not all default values can be wrapped so we need to
117 # do it conditionally.
118 if default.startswith('%'):
119 default = "'%s'" % default
120 except AttributeError:
123 values = {'name': name,
124 'type': value['type'],
126 value.get('description', '').rstrip().replace('\n',
129 'mandatory': mandatory,
131 f.write(_PARAM_FORMAT % values + '\n')
133 target_file = os.path.join('environments', env['name'] + '.yaml')
134 _create_output_dir(target_file)
135 with open(target_file, 'w') as env_file:
136 env_file.write(_FILE_HEADER)
137 # TODO(bnemec): Once Heat allows the title and description to live in
138 # the environment itself, uncomment these entries and make them
139 # top-level keys in the YAML.
140 env_title = env.get('title', '')
141 env_file.write(u'# title: %s\n' % env_title)
142 env_desc = env.get('description', '')
143 env_file.write(u'# description: |\n')
144 for line in env_desc.splitlines():
145 env_file.write(u'# %s\n' % line)
147 if parameter_defaults:
148 env_file.write(u'parameter_defaults:\n')
149 for name, value in sorted(parameter_defaults.items()):
150 write_sample_entry(env_file, name, value)
152 env_file.write(_STATIC_MESSAGE_START)
153 for name, value in sorted(static_defaults.items()):
154 write_sample_entry(env_file, name, value)
156 env_file.write(_STATIC_MESSAGE_END)
158 if env.get('resource_registry'):
159 env_file.write(u'resource_registry:\n')
160 for res, value in sorted(env.get('resource_registry', {}).items()):
161 env_file.write(u' %s: %s\n' % (res, value))
162 print('Wrote sample environment "%s"' % target_file)
164 for e in env.get('children', []):
165 _generate_environment(e, env)
168 def generate_environments(config_file):
169 with open(config_file) as f:
170 config = yaml.safe_load(f)
171 for env in config['environments']:
172 _generate_environment(env)
175 def usage(exit_code=1):
176 print('Usage: %s <filename.yaml>' % sys.argv[0])
182 config_file = sys.argv[1]
185 generate_environments(config_file)
188 if __name__ == '__main__':