modified to accomodate the scaleio bundles and charms.
[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 def unit_scaleio_qty():
85     """Return size of the scaleio cluster"""
86     return 3
87
88 def to_select(qty=False):
89     """Return a random list of machines numbers to deploy"""
90     global config
91     if not qty:
92         qty = config['os']['ha']['cluster_size'] if \
93                 config['os']['ha']['mode'] == 'ha' else 1
94     if config['os']['hyperconverged']:
95         return random.sample(range(0, config['opnfv']['units']), qty)
96     else:
97         return random.sample(range(0, qty), qty)
98
99
100 def get_password(key, length=16, special=False):
101     """Return a new random password or a already created one"""
102     global passwords_store
103     if key not in passwords_store.keys():
104         alphabet = "abcdefghijklmnopqrstuvwxyz"
105         upperalphabet = alphabet.upper()
106         char_list = alphabet + upperalphabet + '0123456789'
107         pwlist = []
108         if special:
109             char_list += "+-,;./:?!*"
110         for i in range(length):
111             pwlist.append(char_list[random.randrange(len(char_list))])
112         random.shuffle(pwlist)
113         passwords_store[key] = "".join(pwlist)
114     return passwords_store[key]
115
116 #
117 # Config import
118 #
119
120 # Load scenario Config
121 config = load_yaml(scenarioconfig_file)
122 # Load lab Config
123 config.update(load_yaml(labconfig_file))
124
125 # We transform array to hash for an easier work
126 config['opnfv']['spaces_dict'] = dict()
127 for space in config['opnfv']['spaces']:
128     config['opnfv']['spaces_dict'][space['type']] = space
129 config['opnfv']['storage_dict'] = dict()
130 for storage in config['opnfv']['storage']:
131     config['opnfv']['storage_dict'][storage['type']] = storage
132
133 #
134 # Parse scenario name
135 #
136
137 # Set default scenario name
138 if not scenario:
139     scenario = "os-nosdn-nofeature-nonha"
140
141 # Parse scenario name
142 try:
143     sc = scenario.split('-')
144     (sdn, features, hamode) = sc[1:4]
145     features = features.split('_')
146     if len(sc) > 4:
147         extra = sc[4].split('_')
148     else:
149         extra = []
150 except ValueError as err:
151     print('Error: Bad scenario name syntax, use '
152           '"os-<controller>-<nfvfeature>-<mode>[-<extrastuff>]" format')
153     sys.exit(1)
154
155 #
156 # Update config with scenario name
157 #
158
159 # change ha mode
160 config['os']['ha']['mode'] = hamode
161
162 # change ha mode
163 config['os']['network']['controller'] = sdn
164
165 # Change features
166 if 'lxd' in features:
167     config['os']['lxd'] = True
168 if 'dvr' in features:
169     config['os']['network']['dvr'] = True
170 if 'ipv6' in features:
171     config['os']['network']['ipv6'] = True
172 if 'ovs' in features:
173     config['os']['network']['enhanced_ovs'] = True
174 if 'sfc' in features:
175     config['os']['network']['sfc'] = True
176 if 'dpdk' in features:
177     config['os']['network']['dpdk'] = True
178 if 'bgpvpn' in features:
179     config['os']['network']['bgpvpn'] = True
180 if 'odll3' in features:
181     config['os']['network']['odll3'] = True
182 if 'dishypcon' in features:
183     config['os']['hyperconverged'] = False
184
185 # Set beta option from extra
186 if 'publicapi' in extra:
187     config['os']['beta']['public_api'] = True
188 if 'radosgwcluster' in extra:
189     config['os']['beta']['hacluster_ceph_radosgw'] = True
190 if 'hugepages' in extra:
191     config['os']['beta']['huge_pages'] = True
192 if 'trusty' in extra:
193     config['ubuntu']['release'] = 'trusty'
194     if 'liberty' in extra:
195         config['os']['release'] = 'liberty'
196 if 'dishypcon' in extra:
197     config['os']['hyperconverged'] = False
198
199 #
200 # Transform template to bundle.yaml according to config
201 #
202
203 # Create the jinja2 environment.
204 env = Environment(loader=FileSystemLoader(TPL_DIR),
205                   trim_blocks=True)
206 template = env.get_template('bundle.yaml')
207
208 # Add functions
209 env.globals.update(get_password=get_password)
210 env.globals.update(unit_qty=unit_qty)
211 env.globals.update(unit_ceph_qty=unit_ceph_qty)
212 env.globals.update(unit_scaleio_qty=unit_scaleio_qty)
213 env.globals.update(to_select=to_select)
214
215 # Render the template
216 output = template.render(**config)
217
218 # Check output syntax
219 try:
220     yaml.load(output)
221 except yaml.YAMLError as exc:
222     print(exc)
223
224 # print output
225 print(output)