Adds Heat Manger and tests to ApexLake
[yardstick.git] / yardstick / vTC / apexlake / experimental_framework / heat_template_generation.py
1 # Copyright (c) 2015 Intel Research and Development Ireland Ltd.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15
16 '''
17 This file contains the code to Generate the heat templates from the base
18 template
19 '''
20
21 import json
22 import os
23 import shutil
24 from experimental_framework import common
25 from experimental_framework.constants import framework_parameters as fp
26
27
28 class TreeNode:
29     """
30     This class represent the node of the configuration tree.\
31     Each node represents a single configuration value for a single
32     configuration parameter.
33     """
34
35     def __init__(self):
36         self.up = None
37         self.down = []
38         self.variable_name = ''
39         self.variable_value = 0
40
41     def add_child(self, node):
42         """
43         Adds a node as a child for the current node
44         :param node: node to be added as a child (type: TreeNode)
45         :return: None
46         """
47         node.up = self
48         self.down.append(node)
49
50     def get_parent(self):
51         """
52         Returns the parent node of the current one
53         :return type: TreeNode
54         """
55         return self.up
56
57     def get_children(self):
58         """
59         Returns the children of the current node
60         :return type: list of TreeNode
61         """
62         if len(self.down) == 0:
63             # return [self]
64             return []
65         return self.down
66
67     def get_variable_name(self):
68         """
69         Returns the name of the variable correspondent to the current node
70         :return type: str
71         """
72         return self.variable_name
73
74     def get_variable_value(self):
75         """
76         Returns the value of the variable correspondent to the current node
77         :return type: str or int
78         """
79         return self.variable_value
80
81     def set_variable_name(self, name):
82         """
83         Sets the name of the variable for the current node
84         :param name: Name of the variable (type: str)
85         :return None
86         """
87         self.variable_name = name
88
89     def set_variable_value(self, value):
90         """
91         Sets the value of the variable for the current node
92         :param value: value of the variable (type: str)
93         :return None
94         """
95         self.variable_value = value
96
97     def get_path(self):
98         """
99         Returns all the path from the current node to the root of the tree.
100         :return type: list of TreeNode
101         """
102         ret_val = []
103         if not self.up:
104             ret_val.append(self)
105             return ret_val
106         for node in self.up.get_path():
107             ret_val.append(node)
108         ret_val.append(self)
109         return ret_val
110
111     def __str__(self):
112         return str(self.variable_name) + " --> " + str(self.variable_value)
113
114     def __repr__(self):
115         return str(self.variable_name) + " = " + str(self.variable_value)
116
117     @staticmethod
118     def _get_leaves(node, leaves):
119         """
120         Returns all the leaves of a tree.
121         It changes the "leaves" list.
122         :param node: root of the tree (type: TreeNode)
123         :param leaves: partial list of leaves (type: list of TreeNode)
124         :return type: None
125         """
126         children = node.get_children()
127         if len(children) == 0:
128             leaves.append(node)
129             return
130         for child in children:
131             TreeNode._get_leaves(child, leaves)
132
133     @staticmethod
134     def get_leaves(node):
135         """
136         Returns all the leaves of a tree.
137         :param node: root of the tree (TreeNode)
138         :return type: list
139         """
140         leaves = list()
141         TreeNode._get_leaves(node, leaves)
142         return leaves
143
144
145 template_name = fp.EXPERIMENT_TEMPLATE_NAME
146
147
148 def generates_templates(base_heat_template, deployment_configuration):
149     """
150     Generates the heat templates for the experiments
151     :return: None
152     """
153     # Load useful parameters from file
154     template_dir = common.get_template_dir()
155     template_file_extension = fp.TEMPLATE_FILE_EXTENSION
156     template_base_name = base_heat_template
157
158     variables = deployment_configuration
159
160     # Delete the templates eventually generated in previous running of the
161     # framework
162     common.LOG.info("Removing the heat templates previously generated")
163     os.system("rm " + template_dir + template_name + "_*")
164
165     # Creation of the tree with all the new configurations
166     common.LOG.info("Creation of the tree with all the new configurations")
167     tree = TreeNode()
168     for variable in variables:
169         leaves = TreeNode.get_leaves(tree)
170         common.LOG.debug("LEAVES: " + str(leaves))
171         common.LOG.debug("VALUES: " + str(variables[variable]))
172
173         for value in variables[variable]:
174             for leaf in leaves:
175                 new_node = TreeNode()
176                 new_node.set_variable_name(variable)
177                 new_node.set_variable_value(value)
178                 leaf.add_child(new_node)
179
180     common.LOG.debug("CONFIGURATION TREE: " + str(tree))
181
182     common.LOG.info("Heat Template and metadata file creation")
183     leaves = TreeNode.get_leaves(tree)
184     counter = 1
185     for leaf in leaves:
186         heat_template_vars = leaf.get_path()
187         if os.path.isabs(template_base_name):
188             base_template = template_base_name
189         else:
190             base_template = template_dir + template_base_name
191         if os.path.isabs(template_name):
192             new_template = template_name
193         else:
194             new_template = template_dir + template_name
195         new_template += "_" + str(counter) + template_file_extension
196         shutil.copy(base_template, new_template)
197
198         metadata = dict()
199         for var in heat_template_vars:
200             if var.get_variable_name():
201                 common.replace_in_file(new_template, "#" +
202                                        var.get_variable_name(),
203                                        var.get_variable_value())
204                 metadata[var.get_variable_name()] = var.get_variable_value()
205
206         # Save the metadata on a JSON file
207         with open(new_template + ".json", 'w') as outfile:
208             json.dump(metadata, outfile)
209
210         common.LOG.debug("Heat Templates and Metadata file " + str(counter) +
211                          " created")
212         counter += 1
213
214     # Creation of the template files
215     common.LOG.info(str(counter - 1) + " Heat Templates and Metadata files "
216                                        "created")
217
218
219 def get_all_heat_templates(template_dir, template_file_extension):
220     """
221     Loads and returns all the generated heat templates
222     :param template_dir: directory to search in (type: str)
223     :param template_file_extension: extension of the file for templates
224             (type: str)
225     :return: type: list
226     """
227     template_files = list()
228     for dirname, dirnames, filenames in os.walk(template_dir):
229         for filename in filenames:
230             if template_file_extension in filename and \
231                     filename.endswith(template_file_extension) and \
232                     template_name in filename:
233                 template_files.append(filename)
234     template_files.sort()
235     return template_files