2 # -*- coding: utf-8 -*-
5 This script generates a juju deployer bundle based on
6 scenario name, and lab config file.
9 -s, --scenario : scenario name
10 -l, --lab : lab config file
13 from optparse import OptionParser
14 from jinja2 import Environment, FileSystemLoader
15 from distutils.version import LooseVersion, StrictVersion
26 parser = OptionParser()
27 parser.add_option("-s", "--scenario", dest="scenario", help="scenario name")
28 parser.add_option("-l", "--lab", dest="lab", help="lab config file")
29 (options, args) = parser.parse_args()
30 scenario = options.scenario
31 labconfig_file = options.lab
34 # Set Path and configs path
37 scenarioconfig_file = 'default_deployment_config.yaml'
38 TPL_DIR = os.path.dirname(os.path.abspath(__file__))+'/config_tpl/juju2/bundle_tpl'
44 # Prepare a storage for passwords
45 passwords_store = dict()
52 def load_yaml(filepath):
54 with open(filepath, 'r') as stream:
56 return yaml.load(stream)
57 except yaml.YAMLError as exc:
66 """Return quantity of units to deploy"""
68 if config['os']['ha']['mode'] == 'ha':
69 return config['os']['ha']['cluster_size']
75 """Return size of the ceph cluster"""
77 if config['os']['ha']['mode'] == 'ha':
78 return config['os']['ha']['cluster_size']
80 if config['opnfv']['units'] >= 3:
81 return config['os']['ha']['cluster_size']
85 def unit_scaleio_qty():
86 """Return size of the scaleio cluster"""
89 def to_select(qty=False):
90 """Return a random list of machines numbers to deploy"""
93 qty = config['os']['ha']['cluster_size'] if \
94 config['os']['ha']['mode'] == 'ha' else 1
95 if config['os']['hyperconverged']:
96 return random.sample(range(0, config['opnfv']['units']), qty)
98 return random.sample(range(0, qty), qty)
101 def get_password(key, length=16, special=False):
102 """Return a new random password or a already created one"""
103 global passwords_store
104 if key not in passwords_store.keys():
105 alphabet = "abcdefghijklmnopqrstuvwxyz"
106 upperalphabet = alphabet.upper()
107 char_list = alphabet + upperalphabet + '0123456789'
110 char_list += "+-,;./:?!*"
111 for i in range(length):
112 pwlist.append(char_list[random.randrange(len(char_list))])
113 random.shuffle(pwlist)
114 passwords_store[key] = "".join(pwlist)
115 return passwords_store[key]
121 # Load scenario Config
122 config = load_yaml(scenarioconfig_file)
124 config.update(load_yaml(labconfig_file))
126 # We transform array to hash for an easier work
127 config['opnfv']['spaces_dict'] = dict()
128 for space in config['opnfv']['spaces']:
129 config['opnfv']['spaces_dict'][space['type']] = space
130 config['opnfv']['storage_dict'] = dict()
131 for storage in config['opnfv']['storage']:
132 config['opnfv']['storage_dict'][storage['type']] = storage
135 # Parse scenario name
138 # Set default scenario name
140 scenario = "os-nosdn-nofeature-noha"
142 # Parse scenario name
144 sc = scenario.split('-')
145 (sdn, features, hamode) = sc[1:4]
146 features = features.split('_')
148 extra = sc[4].split('_')
151 except ValueError as err:
152 print('Error: Bad scenario name syntax, use '
153 '"os-<controller>-<nfvfeature>-<mode>[-<extrastuff>]" format')
157 # Update config with scenario name
161 config['os']['ha']['mode'] = hamode
164 config['os']['network']['controller'] = sdn
167 config['os']['hyperconverged'] = False
170 if 'lxd' in features:
171 config['os']['lxd'] = True
172 if 'dvr' in features:
173 config['os']['network']['dvr'] = True
174 if 'ipv6' in features:
175 config['os']['network']['ipv6'] = True
176 if 'ovs' in features:
177 config['os']['network']['enhanced_ovs'] = True
178 if 'sfc' in features:
179 config['os']['network']['sfc'] = True
180 if 'dpdk' in features:
181 config['os']['network']['dpdk'] = True
182 config['os']['beta']['huge_pages'] = True
183 config['os']['beta']['cpu_pin'] = True
184 if 'bgpvpn' in features:
185 config['os']['network']['bgpvpn'] = True
186 if 'odll3' in features:
187 config['os']['network']['odll3'] = True
188 if 'dishypcon' in features:
189 config['os']['hyperconverged'] = False
190 if 'hugepages' in features:
191 config['os']['beta']['huge_pages'] = True
192 config['os']['beta']['cpu_pin'] = True
193 if 'openbaton' in features:
194 config['os']['service']['openbaton'] = True
197 # Set beta option from extra
198 if 'radosgwcluster' in extra:
199 config['os']['beta']['hacluster_ceph_radosgw'] = True
200 if 'hugepages' in extra:
201 config['os']['beta']['huge_pages'] = True
202 config['os']['beta']['cpu_pin'] = True
204 config['os']['release'] = 'ocata'
206 config['os']['release'] = 'pike'
207 if 'trusty' in extra:
208 config['ubuntu']['release'] = 'trusty'
210 config['os']['release'] = 'mitaka'
211 if 'xenial' in extra:
212 config['ubuntu']['release'] = 'xenial'
213 if 'dishypcon' in extra:
214 config['os']['hyperconverged'] = False
215 if 'openbaton' in features:
216 config['os']['service']['openbaton'] = True
219 # Transform template to bundle.yaml according to config
222 # Create the jinja2 environment.
223 env = Environment(loader=FileSystemLoader(TPL_DIR),
225 template = env.get_template('bundle.yaml')
228 env.globals.update(get_password=get_password)
229 env.globals.update(unit_qty=unit_qty)
230 env.globals.update(unit_ceph_qty=unit_ceph_qty)
231 env.globals.update(unit_scaleio_qty=unit_scaleio_qty)
232 env.globals.update(to_select=to_select)
234 # Render the template
235 output = template.render(**config)
237 # Check output syntax
240 except yaml.YAMLError as exc: