added option to choose the architecture of hyperconverged ot not.
[joid.git] / ci / genBundle.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 """
5 This script generates a juju deployer bundle based on
6 scenario name, and lab config file.
7
8 Parameters:
9  -s, --scenario : scenario name
10  -l, --lab      : lab config file
11 """
12
13 from optparse import OptionParser
14 from jinja2 import Environment, FileSystemLoader
15 import os
16 import random
17 import yaml
18 import sys
19
20 #
21 # Parse parameters
22 #
23
24 parser = OptionParser()
25 parser.add_option("-s", "--scenario", dest="scenario", help="scenario name")
26 parser.add_option("-l", "--lab", dest="lab", help="lab config file")
27 (options, args) = parser.parse_args()
28 scenario = options.scenario
29 labconfig_file = options.lab
30
31 #
32 # Set Path and configs path
33 #
34
35 scenarioconfig_file = 'default_deployment_config.yaml'
36 # Capture our current directory
37 TPL_DIR = os.path.dirname(os.path.abspath(__file__))+'/config_tpl/bundle_tpl'
38
39 #
40 # Prepare variables
41 #
42
43 # Prepare a storage for passwords
44 passwords_store = dict()
45
46 #
47 # Local Functions
48 #
49
50
51 def load_yaml(filepath):
52     """Load YAML file"""
53     with open(filepath, 'r') as stream:
54         try:
55             return yaml.load(stream)
56         except yaml.YAMLError as exc:
57             print(exc)
58
59 #
60 # Templates functions
61 #
62
63
64 def unit_qty():
65     """Return quantity of units to deploy"""
66     global config
67     if config['os']['ha']['mode'] == 'ha':
68         return config['os']['ha']['cluster_size']
69     else:
70         return 1
71
72
73 def unit_ceph_qty():
74     """Return size of the ceph cluster"""
75     global config
76     if config['os']['ha']['mode'] == 'ha':
77         return config['os']['ha']['cluster_size']
78     else:
79         if config['opnfv']['units'] >= 3:
80             return config['os']['ha']['cluster_size']
81         else:
82             return 2
83
84
85 def to_select(qty=False):
86     """Return a random list of machines numbers to deploy"""
87     global config
88     if not qty:
89         qty = config['os']['ha']['cluster_size'] if \
90                 config['os']['ha']['mode'] == 'ha' else 1
91     if config['os']['hyperconverged']:
92         return random.sample(range(0, config['opnfv']['units']), qty)
93     else:
94         return random.sample(range(0, qty), qty)
95
96
97 def get_password(key, length=16, special=False):
98     """Return a new random password or a already created one"""
99     global passwords_store
100     if key not in passwords_store.keys():
101         alphabet = "abcdefghijklmnopqrstuvwxyz"
102         upperalphabet = alphabet.upper()
103         char_list = alphabet + upperalphabet + '0123456789'
104         pwlist = []
105         if special:
106             char_list += "+-,;./:?!*"
107         for i in range(length):
108             pwlist.append(char_list[random.randrange(len(char_list))])
109         random.shuffle(pwlist)
110         passwords_store[key] = "".join(pwlist)
111     return passwords_store[key]
112
113 #
114 # Config import
115 #
116
117 # Load scenario Config
118 config = load_yaml(scenarioconfig_file)
119 # Load lab Config
120 config.update(load_yaml(labconfig_file))
121
122 # We transform array to hash for an easier work
123 config['opnfv']['spaces_dict'] = dict()
124 for space in config['opnfv']['spaces']:
125     config['opnfv']['spaces_dict'][space['type']] = space
126 config['opnfv']['storage_dict'] = dict()
127 for storage in config['opnfv']['storage']:
128     config['opnfv']['storage_dict'][storage['type']] = storage
129
130 #
131 # Parse scenario name
132 #
133
134 # Set default scenario name
135 if not scenario:
136     scenario = "os-nosdn-nofeature-nonha"
137
138 # Parse scenario name
139 try:
140     sc = scenario.split('-')
141     (sdn, features, hamode) = sc[1:4]
142     features = features.split('_')
143     if len(sc) > 4:
144         extra = sc[4].split('_')
145     else:
146         extra = []
147 except ValueError as err:
148     print('Error: Bad scenario name syntax, use '
149           '"os-<controller>-<nfvfeature>-<mode>[-<extrastuff>]" format')
150     sys.exit(1)
151
152 #
153 # Update config with scenario name
154 #
155
156 # change ha mode
157 config['os']['ha']['mode'] = hamode
158
159 # change ha mode
160 config['os']['network']['controller'] = sdn
161
162 # Change features
163 if 'lxd' in features:
164     config['os']['lxd'] = True
165 if 'dvr' in features:
166     config['os']['network']['dvr'] = True
167 if 'ipv6' in features:
168     config['os']['network']['ipv6'] = True
169 if 'ovs' in features:
170     config['os']['network']['enhanced_ovs'] = True
171 if 'sfc' in features:
172     config['os']['network']['sfc'] = True
173 if 'dpdk' in features:
174     config['os']['network']['dpdk'] = True
175 if 'bgpvpn' in features:
176     config['os']['network']['bgpvpn'] = True
177 if 'odll3' in features:
178     config['os']['network']['odll3'] = True
179 if 'dishypcon' in features:
180     config['os']['hyperconverged'] = False
181
182 # Set beta option from extra
183 if 'publicapi' in extra:
184     config['os']['beta']['public_api'] = True
185 if 'radosgwcluster' in extra:
186     config['os']['beta']['hacluster_ceph_radosgw'] = True
187 if 'hugepages' in extra:
188     config['os']['beta']['huge_pages'] = True
189 if 'trusty' in extra:
190     config['ubuntu']['release'] = 'trusty'
191     if 'liberty' in extra:
192         config['os']['release'] = 'liberty'
193 if 'dishypcon' in extra:
194     config['os']['hyperconverged'] = False
195
196 #
197 # Transform template to bundle.yaml according to config
198 #
199
200 # Create the jinja2 environment.
201 env = Environment(loader=FileSystemLoader(TPL_DIR),
202                   trim_blocks=True)
203 template = env.get_template('bundle.yaml')
204
205 # Add functions
206 env.globals.update(get_password=get_password)
207 env.globals.update(unit_qty=unit_qty)
208 env.globals.update(unit_ceph_qty=unit_ceph_qty)
209 env.globals.update(to_select=to_select)
210
211 # Render the template
212 output = template.render(**config)
213
214 # Check output syntax
215 try:
216     yaml.load(output)
217 except yaml.YAMLError as exc:
218     print(exc)
219
220 # print output
221 print(output)