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