generate_config.py: Fix running without eyaml
[pharos.git] / config / utils / generate_config.py
1 #!/usr/bin/python
2 ##############################################################################
3 # Copyright (c) 2017 OPNFV and others.
4 #
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 ##############################################################################
10 """This module does blah blah."""
11 import argparse
12 import ipaddress
13 import logging
14 import os
15 import yaml
16 from jinja2 import Environment, FileSystemLoader
17 from subprocess import CalledProcessError, check_output
18
19 PARSER = argparse.ArgumentParser()
20 PARSER.add_argument("--yaml", "-y", type=str, required=True)
21 PARSER.add_argument("--jinja2", "-j", type=str, required=True)
22 ARGS = PARSER.parse_args()
23
24 # Processor architecture vs DPKG architecture mapping
25 DPKG_ARCH_TABLE = {
26     'aarch64': 'arm64',
27     'x86_64': 'amd64',
28 }
29 ARCH_DPKG_TABLE = dict(zip(DPKG_ARCH_TABLE.values(), DPKG_ARCH_TABLE.keys()))
30
31 # Custom filter to allow simple IP address operations returning
32 # a new address from an upper or lower (negative) index
33 def ipaddr_index(base_address, index):
34     """Return IP address in given network at given index"""
35     try:
36         base_address_str = unicode(base_address)
37     #pylint: disable=unused-variable
38     except NameError as ex:
39         base_address_str = str(base_address)
40     return ipaddress.ip_address(base_address_str) + int(index)
41
42 # Custom filter to convert between processor architecture
43 # (as reported by $(uname -m)) and DPKG-style architecture
44 def dpkg_arch(arch, to_dpkg=True):
45     """Return DPKG-compatible from processor arch and vice-versa"""
46     if to_dpkg:
47         return DPKG_ARCH_TABLE[arch]
48     else:
49         return ARCH_DPKG_TABLE[arch]
50
51 ENV = Environment(loader=FileSystemLoader(os.path.dirname(ARGS.jinja2)))
52 ENV.filters['ipaddr_index'] = ipaddr_index
53 ENV.filters['dpkg_arch'] = dpkg_arch
54
55 # Run `eyaml decrypt` on the whole file, in case any PDF data is encrypted
56 # Note: eyaml return code is 0 even if keys are not available
57 try:
58     DICT = yaml.safe_load(check_output(['eyaml', 'decrypt', '-f', ARGS.yaml]))
59 except CalledProcessError as ex:
60     logging.error('eyaml decryption failed, keys might be missing')
61 except OSError as ex:
62     logging.warn('eyaml not found, skipping decryption')
63 try:
64     DICT
65 except NameError as ex:
66     logging.warn('PDF decryption skipped, fallback to using raw data.')
67     with open(ARGS.yaml) as _:
68         DICT = yaml.safe_load(_)
69
70 # If an installer descriptor file (IDF) exists, include it (temporary)
71 IDF_PATH = '/idf-'.join(os.path.split(ARGS.yaml))
72 if os.path.exists(IDF_PATH):
73     with open(IDF_PATH) as _:
74         IDF = yaml.safe_load(_)
75         DICT['idf'] = IDF['idf']
76
77 # Print dictionary generated from yaml (uncomment for debug)
78 # print(DICT)
79
80 # Render template and print generated conf to console
81 TEMPLATE = ENV.get_template(os.path.basename(ARGS.jinja2))
82
83 #pylint: disable=superfluous-parens
84 print(TEMPLATE.render(conf=DICT))