2 ###############################################################################
3 # Copyright (c) 2016 Ericsson AB and others.
4 # peter.barabas@ericsson.com
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ###############################################################################
26 class Templater(object):
27 def __init__(self, base_file, template_file, output_file):
28 self.template_file = template_file
29 self.output_file = output_file
30 self.base = self.load_yaml(base_file)
32 def load_yaml(self, filename):
34 with io.open(filename) as yaml_file:
35 return yaml.load(yaml_file)
36 except Exception as error:
37 err('Error opening YAML file: %s' % error)
39 def save_yaml(self, filename, content):
41 with io.open(filename, 'w') as yaml_file:
42 yaml_file.write(content)
43 except Exception as error:
44 err('Error writing YAML file: %s' % error)
46 def get_indent(self, line):
47 return len(line) - len(line.lstrip(' '))
49 def format_fragment(self, fragment, indent):
53 for line in fragment.splitlines():
54 # Skip indenting the first line as it is already indented
59 line = ' ' * indent + line + '\n'
63 return result.rstrip('\n')
65 def format_substitution(self, string):
66 if isinstance(string, basestring):
69 return yaml.dump(string, default_flow_style=False)
71 def parse_interface_tag(self, tag):
72 # Remove 'interface(' prefix, trailing ')' and split arguments
73 args = tag[len('interface('):].rstrip(')').split(',')
75 if len(args) == 1 and not args[0]:
76 err('No arguments for interface().')
77 elif len(args) == 2 and (not args[0] or not args[1]):
78 err('Empty argument for interface().')
80 err('Too many arguments for interface().')
84 def get_interface_from_network(self, interfaces, network):
85 nics = self.base[interfaces]
87 if network in nics[nic]:
90 err('Network not found: %s' % network)
92 def get_role_interfaces(self, role):
93 nodes = self.base['nodes']
95 if role in node['role']:
96 return node['interfaces']
98 err('Role not found: %s' % role)
100 def lookup_interface(self, args):
101 nodes = self.base['nodes']
104 interfaces = nodes[0]['interfaces']
106 interfaces = self.get_role_interfaces(args[1])
108 return self.get_interface_from_network(interfaces, args[0])
110 def parse_tag(self, tag, indent):
113 if 'interface(' in tag:
114 args = self.parse_interface_tag(tag)
115 fragment = self.lookup_interface(args)
117 path = tag.split(DELIMITER)
121 fragment = fragment.get(i)
123 err('Error: key "%s" does not exist in base YAML file' % i)
125 fragment = self.format_substitution(fragment)
127 return self.format_fragment(fragment, indent)
132 regex = re.compile(re.escape(TAG_START) + r'([a-z].+)' + re.escape(TAG_END),
134 with io.open(self.template_file) as f:
136 indent = self.get_indent(line)
137 result += re.sub(regex,
138 lambda match: self.parse_tag(match.group(1), indent),
141 self.save_yaml(self.output_file, result)
144 def parse_arguments():
145 description = '''Process 'template_file' using 'base_file' as source for
146 template variable substitution and write the results to 'output_file'.'''
148 parser = ArgParser(prog='python %s' % __file__,
149 description=description)
150 parser.add_argument('base_file',
151 help='Base YAML filename')
152 parser.add_argument('template_file',
153 help='Fragment filename')
154 parser.add_argument('output_file',
155 help='Output filename')
157 args = parser.parse_args()
158 return(args.base_file, args.template_file, args.output_file)
162 base_file, template_file, output_file = parse_arguments()
164 templater = Templater(base_file, template_file, output_file)
168 if __name__ == '__main__':