Add dataplane deploy setting
[apex.git] / lib / python / apex / deploy_env.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                        'sdn_l3',
16                        'tacker',
17                        'congress',
18                        'dataplane',
19                        'sfc',
20                        'vpn']
21
22 OPT_DEPLOY_SETTINGS = ['performance']
23
24 VALID_ROLES = ['Controller', 'Compute', 'ObjectStorage']
25 VALID_PERF_OPTS = ['kernel','nova']
26 VALID_DATAPLANES = ['ovs','ovs_dpdk','fdio']
27
28 class DeploySettings:
29     """
30     This class parses a APEX deploy settings yaml file into an object
31
32     Currently the parsed object is dumped into a bash global definition file
33     for deploy.sh consumption. This object will later be used directly as
34     deployment script move to python.
35     """
36     def __init__(self, filename):
37         with open(filename, 'r') as settings_file:
38             self.deploy_settings = yaml.load(settings_file)
39             self._validate_settings()
40
41     def _validate_settings(self):
42         """
43         Validates the deploy settings file provided
44
45         DeploySettingsException will be raised if validation fails.
46         """
47
48         if 'deploy_options' not in self.deploy_settings:
49             raise DeploySettingsException("No deploy options provided in"
50                                           " deploy settings file")
51         if 'global_params' not in self.deploy_settings:
52             raise DeploySettingsException("No global options provided in"
53                                           " deploy settings file")
54
55         deploy_options = self.deploy_settings['deploy_options']
56         if not isinstance(deploy_options, dict):
57             raise DeploySettingsException("deploy_options should be a list")
58
59         for setting, value in deploy_options.items():
60             if setting not in REQ_DEPLOY_SETTINGS + OPT_DEPLOY_SETTINGS:
61                 raise DeploySettingsException("Invalid deploy_option {} "
62                                               "specified".format(setting))
63             if setting == 'dataplane':
64                 if value not in VALID_DATAPLANES:
65                     planes = ' '.join(VALID_DATAPLANES)
66                     raise DeploySettingsException("Invalid dataplane {} "
67                                                   "specified. Valid dataplanes:"
68                                                   " {}".format(value,planes))
69
70
71         for req_set in REQ_DEPLOY_SETTINGS:
72             if req_set not in deploy_options:
73                 if req_set == 'dataplane':
74                     self.deploy_settings['deploy_options'][req_set] = 'ovs'
75                 else:
76                     self.deploy_settings['deploy_options'][req_set] = False
77
78         if 'performance' in deploy_options:
79             if not isinstance(deploy_options['performance'], dict):
80                 raise DeploySettingsException("Performance deploy_option"
81                                               "must be a dictionary.")
82             for role,role_perf_sets in deploy_options['performance'].items():
83                 if role not in VALID_ROLES:
84                     raise DeploySettingsException("Performance role {}"
85                                                   "is not valid, choose"
86                                                   "from {}".format(
87                                                   role," ".join(VALID_ROLES)
88                                                   ))
89
90                 for key in role_perf_sets:
91                     if key not in VALID_PERF_OPTS:
92                         raise DeploySettingsException("Performance option {}"
93                                                       "is not valid, choose"
94                                                       "from {}".format(
95                                                       key," ".join(
96                                                       VALID_PERF_OPTS)))
97
98
99     def _dump_performance(self):
100         """
101         Creates performance settings string for bash consumption.
102
103         Output will be in the form of a list that can be iterated over in bash,
104         with each string being the direct input to the performance setting script
105         in the form <role> <category> <key> <value> to facilitate modification of the
106         correct image.
107         """
108         bash_str = 'performance_options=(\n'
109         for role,settings in self.deploy_settings['deploy_options']['performance'].items():
110             for category,options in settings.items():
111                 for key,value in options.items():
112                     bash_str += "\"{} {} {} {}\"\n".format(role, category, key, value)
113         bash_str += ')\n'
114         bash_str += '\n'
115         bash_str += 'performance_roles=(\n'
116         for role in self.deploy_settings['deploy_options']['performance']:
117             bash_str += role + '\n'
118         bash_str += ')\n'
119         bash_str += '\n'
120
121         return bash_str
122
123     def _dump_deploy_options_array(self):
124         """
125         Creates deploy settings array in bash syntax.
126         """
127         bash_str = ''
128         for key,value in self.deploy_settings['deploy_options'].items():
129             if not isinstance(value, bool):
130                 bash_str += "deploy_options_array[{}]=\"{}\"\n".format(key, value)
131             else:
132                 bash_str += "deploy_options_array[{}]={}\n".format(key, value)
133         return bash_str
134
135     def dump_bash(self, path=None):
136         """
137         Prints settings for bash consumption.
138
139         If optional path is provided, bash string will be written to the file
140         instead of stdout.
141         """
142         bash_str = ''
143         for key, value in self.deploy_settings['global_params'].items():
144             bash_str += "{}={}\n".format(key, value)
145         if 'performance' in self.deploy_settings['deploy_options']:
146             bash_str += self._dump_performance()
147         bash_str += self._dump_deploy_options_array()
148
149         if path:
150             with open(path, 'w') as file:
151                 file.write(bash_str)
152         else:
153             print(bash_str)
154
155
156 class DeploySettingsException(Exception):
157     def __init__(self, value):
158         self.value = value
159
160     def __str__(self):
161         return self.value