Fixes issue where ceph was being disabled by default
[apex.git] / lib / python / apex / deploy_settings.py
1 ##############################################################################
2 # Copyright (c) 2016 Michael Chapman (michapma@redhat.com) and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10
11 import yaml
12 import logging
13
14 REQ_DEPLOY_SETTINGS = ['sdn_controller',
15                        'odl_version',
16                        'sdn_l3',
17                        'tacker',
18                        'congress',
19                        'dataplane',
20                        'sfc',
21                        'vpn',
22                        'vpp',
23                        'ceph']
24
25 OPT_DEPLOY_SETTINGS = ['performance', 'vsperf', 'ceph_device']
26
27 VALID_ROLES = ['Controller', 'Compute', 'ObjectStorage']
28 VALID_PERF_OPTS = ['kernel', 'nova', 'vpp']
29 VALID_DATAPLANES = ['ovs', 'ovs_dpdk', 'fdio']
30
31
32 class DeploySettings(dict):
33     """
34     This class parses a APEX deploy settings yaml file into an object
35
36     Currently the parsed object is dumped into a bash global definition file
37     for deploy.sh consumption. This object will later be used directly as
38     deployment script move to python.
39     """
40     def __init__(self, filename):
41         init_dict = {}
42         if isinstance(filename, str):
43             with open(filename, 'r') as deploy_settings_file:
44                 init_dict = yaml.safe_load(deploy_settings_file)
45         else:
46             # assume input is a dict to build from
47             init_dict = filename
48
49         super().__init__(init_dict)
50         self._validate_settings()
51
52     def _validate_settings(self):
53         """
54         Validates the deploy settings file provided
55
56         DeploySettingsException will be raised if validation fails.
57         """
58
59         if 'deploy_options' not in self:
60             raise DeploySettingsException("No deploy options provided in"
61                                           " deploy settings file")
62         if 'global_params' not in self:
63             raise DeploySettingsException("No global options provided in"
64                                           " deploy settings file")
65
66         deploy_options = self['deploy_options']
67         if not isinstance(deploy_options, dict):
68             raise DeploySettingsException("deploy_options should be a list")
69
70         for setting, value in deploy_options.items():
71             if setting not in REQ_DEPLOY_SETTINGS + OPT_DEPLOY_SETTINGS:
72                 raise DeploySettingsException("Invalid deploy_option {} "
73                                               "specified".format(setting))
74             if setting == 'dataplane':
75                 if value not in VALID_DATAPLANES:
76                     planes = ' '.join(VALID_DATAPLANES)
77                     raise DeploySettingsException(
78                         "Invalid dataplane {} specified. Valid dataplanes:"
79                         " {}".format(value, planes))
80
81         for req_set in REQ_DEPLOY_SETTINGS:
82             if req_set not in deploy_options:
83                 if req_set == 'dataplane':
84                     self['deploy_options'][req_set] = 'ovs'
85                 elif req_set == 'ceph':
86                     self['deploy_options'][req_set] = True
87                 else:
88                     self['deploy_options'][req_set] = False
89
90         if 'performance' in deploy_options:
91             if not isinstance(deploy_options['performance'], dict):
92                 raise DeploySettingsException("Performance deploy_option"
93                                               "must be a dictionary.")
94             for role, role_perf_sets in deploy_options['performance'].items():
95                 if role not in VALID_ROLES:
96                     raise DeploySettingsException("Performance role {}"
97                                                   "is not valid, choose"
98                                                   "from {}".format(
99                                                       role,
100                                                       " ".join(VALID_ROLES)
101                                                   ))
102
103                 for key in role_perf_sets:
104                     if key not in VALID_PERF_OPTS:
105                         raise DeploySettingsException("Performance option {} "
106                                                       "is not valid, choose"
107                                                       "from {}".format(
108                                                           key,
109                                                           " ".join(
110                                                               VALID_PERF_OPTS)
111                                                       ))
112
113     def _dump_performance(self):
114         """
115         Creates performance settings string for bash consumption.
116
117         Output will be in the form of a list that can be iterated over in
118         bash, with each string being the direct input to the performance
119         setting script in the form <role> <category> <key> <value> to
120         facilitate modification of the correct image.
121         """
122         bash_str = 'performance_options=(\n'
123         deploy_options = self['deploy_options']
124         for role, settings in deploy_options['performance'].items():
125             for category, options in settings.items():
126                 for key, value in options.items():
127                     bash_str += "\"{} {} {} {}\"\n".format(role,
128                                                            category,
129                                                            key,
130                                                            value)
131         bash_str += ')\n'
132         bash_str += '\n'
133         bash_str += 'performance_roles=(\n'
134         for role in self['deploy_options']['performance']:
135             bash_str += role + '\n'
136         bash_str += ')\n'
137         bash_str += '\n'
138
139         return bash_str
140
141     def _dump_deploy_options_array(self):
142         """
143         Creates deploy settings array in bash syntax.
144         """
145         bash_str = ''
146         for key, value in self['deploy_options'].items():
147             if not isinstance(value, bool):
148                 bash_str += "deploy_options_array[{}]=\"{}\"\n".format(key,
149                                                                        value)
150             else:
151                 bash_str += "deploy_options_array[{}]={}\n".format(key,
152                                                                    value)
153         return bash_str
154
155     def dump_bash(self, path=None):
156         """
157         Prints settings for bash consumption.
158
159         If optional path is provided, bash string will be written to the file
160         instead of stdout.
161         """
162         bash_str = ''
163         for key, value in self['global_params'].items():
164             bash_str += "{}={}\n".format(key, value)
165         if 'performance' in self['deploy_options']:
166             bash_str += self._dump_performance()
167         bash_str += self._dump_deploy_options_array()
168
169         if path:
170             with open(path, 'w') as file:
171                 file.write(bash_str)
172         else:
173             print(bash_str)
174
175
176 class DeploySettingsException(Exception):
177     def __init__(self, value):
178         self.value = value
179
180     def __str__(self):
181         return self.value