-
Notifications
You must be signed in to change notification settings - Fork 50
/
outputs.py
122 lines (98 loc) · 4.86 KB
/
outputs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# Foremast - Pipeline Tooling
#
# Copyright 2018 Gogo, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Write output files for configurations."""
import json
import logging
from pprint import pformat
import foremastutils
from ..consts import APP_FORMATS
from ..utils import DeepChainMap, get_template
LOG = logging.getLogger(__name__)
def convert_ini(config_dict):
"""Convert _config_dict_ into a list of INI formatted strings.
Args:
config_dict (dict): Configuration dictionary to be flattened.
Returns:
(list) Lines to be written to a file in the format of KEY1_KEY2=value.
"""
config_lines = []
for env, configs in sorted(config_dict.items()):
for resource, app_properties in sorted(configs.items()):
try:
for app_property, value in sorted(app_properties.items()):
variable = '{env}_{resource}_{app_property}'.format(
env=env, resource=resource, app_property=app_property).upper()
if isinstance(value, (dict, DeepChainMap)):
safe_value = "'{0}'".format(json.dumps(dict(value)))
else:
safe_value = json.dumps(value)
line = "{variable}={value}".format(variable=variable, value=safe_value)
LOG.debug('INI line: %s', line)
config_lines.append(line)
except AttributeError:
resource = resource.upper()
app_properties = "'{}'".format(json.dumps(app_properties))
line = '{0}={1}'.format(resource, app_properties)
LOG.debug('INI line: %s', line)
config_lines.append(line)
return config_lines
def write_variables(app_configs=None, out_file='', git_short=''):
"""Append _application.json_ configs to _out_file_, .exports, and .json.
Variables are written in INI style, e.g. UPPER_CASE=value. The .exports file
contains 'export' prepended to each line for easy sourcing. The .json file
is a minified representation of the combined configurations.
Args:
app_configs (dict): Environment configurations from _application.json_
files, e.g. {'dev': {'elb': {'subnet_purpose': 'internal'}}}.
out_file (str): Name of INI file to append to.
git_short (str): Short name of Git repository, e.g. forrest/core.
Returns:
dict: Configuration equivalent to the JSON output.
"""
generated = foremastutils.Generator(*foremastutils.Parser(git_short).parse_url(), formats=APP_FORMATS)
json_configs = {}
for env, configs in app_configs.items():
if env != 'pipeline':
instance_profile = generated.iam()['profile']
rendered_configs = json.loads(
get_template(
'configs/configs.json.j2',
env=env,
app=generated.app_name(),
profile=instance_profile,
formats=generated))
json_configs[env] = dict(DeepChainMap(configs, rendered_configs))
region_list = configs.get('regions', rendered_configs['regions'])
json_configs[env]['regions'] = region_list # removes regions defined in templates but not configs.
for region in region_list:
region_config = json_configs[env][region]
json_configs[env][region] = dict(DeepChainMap(region_config, rendered_configs))
else:
default_pipeline_json = json.loads(get_template('configs/pipeline.json.j2', formats=generated))
json_configs['pipeline'] = dict(DeepChainMap(configs, default_pipeline_json))
LOG.debug('Compiled configs:\n%s', pformat(json_configs))
config_lines = convert_ini(json_configs)
with open(out_file, 'at') as jenkins_vars:
LOG.info('Appending variables to %s.', out_file)
jenkins_vars.write('\n'.join(config_lines))
with open(out_file + '.exports', 'wt') as export_vars:
LOG.info('Writing sourceable variables to %s.', export_vars.name)
export_vars.write('\n'.join('export {0}'.format(line) for line in config_lines))
with open(out_file + '.json', 'wt') as json_handle:
LOG.info('Writing JSON to %s.', json_handle.name)
LOG.debug('Total JSON dict:\n%s', json_configs)
json.dump(json_configs, json_handle)
return json_configs