Bottlenecks testcase rebuild
[bottlenecks.git] / utils / parser.py
1 #!/usr/bin/env python
2 ##############################################################################
3 # Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
10 '''This file realize the function of how to parser a config file.
11 This contain Two part:
12 Frist is Init some variables the will be used.
13 Second is reading config file.'''
14
15 import os
16 import yaml
17 import json
18 import time
19 from pyroute2 import IPDB
20 import utils.infra_setup.runner.docker_env as docker_env
21
22
23 class Parser():
24
25     bottlenecks_config = {}
26     bottlenecks_test = {}
27
28     @classmethod
29     def config_init(cls):
30         cls.code_dir = os.path.dirname(os.path.abspath(__file__))
31         cls.root_dir = os.path.dirname(cls.code_dir)
32         cls.test_dir = os.path.join(cls.root_dir, 'testsuites')
33         config_dir = os.path.join(
34             cls.root_dir,
35             'config',
36             'config.yaml')
37
38         with open(config_dir) as file:
39             config_info = yaml.load(file)
40             common_config = config_info['common_config']
41             cls.bottlenecks_config["releng_dir"] = common_config["releng_dir"]
42             cls.bottlenecks_config["fetch_os"] = common_config["fetch_os_file"]
43             cls.bottlenecks_config["log_dir"] = common_config['log_dir']
44             cls.bottlenecks_config["rc_dir"] = common_config['rc_dir']
45             cls.bottlenecks_config["yardstick_rc_dir"] = \
46                 common_config['yardstick_rc_dir']
47             cls.config_dir_check(cls.bottlenecks_config["log_dir"])
48
49     @classmethod
50     def story_read(cls, testcase, story_name):
51         story_dir = os.path.join(
52             cls.test_dir,
53             testcase,
54             'testsuite_story',
55             story_name + '.yaml')
56         with open(story_dir) as file:
57             story_parser = yaml.load(file)
58         for case_name in story_parser['testcase']:
59             Parser.testcase_read(testcase, case_name)
60
61         return cls.bottlenecks_test
62
63     @classmethod
64     def testcase_read(cls, testcase, testcase_name):
65
66         testcase_dir = os.path.join(
67             cls.test_dir,
68             testcase,
69             'testcase_cfg',
70             testcase_name)
71         testcase_local = testcase_dir + ".yaml"
72         with open(testcase_local) as f:
73             cls.bottlenecks_test[testcase_name] = yaml.load(f)
74
75         return cls.bottlenecks_test
76
77     @classmethod
78     def config_dir_check(cls, dirname):
79         if dirname is None:
80             dirname = '/tmp/'
81         if not os.path.exists(dirname):
82             os.makedirs(dirname)
83
84     @classmethod
85     def testcase_out_dir(cls, testcase):
86         suffix_name = os.getenv("SUFFIX_STRING")
87         if suffix_name is None:
88             file_suffix = time.strftime('%H_%M', time.localtime(time.time()))
89         else:
90             file_suffix = suffix_name
91         suffix_name = str(suffix_name)
92         suffix_name = "_" + suffix_name
93         out_name = cls.bottlenecks_config["log_dir"] + testcase + file_suffix
94         outfile_name = out_name + ".out"
95         return outfile_name
96
97     @staticmethod
98     def config_parser(testcase_cfg, parameters):
99         test_cfg = testcase_cfg['test_config']
100         stack_cfg = testcase_cfg['stack_config']
101         # TO-DO add cli parameters to stack_config.
102         return test_cfg, stack_cfg
103
104     @staticmethod
105     def convert_docker_env(config, ip_type):
106         if ip_type is "dashboard":
107             config["contexts"]["dashboard_ip"] = \
108                 docker_env.ELK_info["ip"] + ":9200"
109         elif ip_type is "yardstick":
110             config["contexts"]["yardstick_ip"] = \
111                 docker_env.yardstick_info["ip"] + ":8888"
112
113     @staticmethod
114     def ip_parser(ip_type):
115         with IPDB() as ip:
116             GATEWAY_IP = ip.routes['default'].gateway
117         if ip_type is "dashboard":
118             TEST_IP = GATEWAY_IP + ":9200"
119         elif ip_type is "yardstick_test_ip":
120             TEST_IP = GATEWAY_IP + ":8888"
121         return TEST_IP
122
123     @staticmethod
124     def result_to_file(data, file_name):
125         with open(file_name, "a") as f:
126             f.write(json.dumps(data, f))
127             f.write("\n")
128
129
130 class HeatTemplate_Parser():
131     """parser a Heat template and a method to deploy template to a stack"""
132
133     def __init__(self):
134         self.heat_date = {}
135         self.heat_date["resources"] = {}
136         self.heat_date["outputs"] = {}
137         self.heat_date["heat_template_version"] = "2013-05-23"
138         self.heat_date["description"] = {"Stack built by the bottlenecks"
139                                          " framework for root."}
140
141     def add_security_group(self, name):
142         """add to the template a Neutron SecurityGroup"""
143         security_name = name + "-security_group"
144         self.heat_date["resources"][security_name] = {
145             "type": "OS::Neutron::SecurityGroup",
146             "properties": {
147                 "name": security_name,
148                 "description": "Group allowing icmp and upd/tcp on all ports",
149                 "rules": [
150                     {"remote_ip_prefix": "0.0.0.0/0",
151                      "protocol": "tcp",
152                      "port_range_min": "1",
153                      "port_range_max": "65535"},
154                     {"remote_ip_prefix": "0.0.0.0/0",
155                      "protocol": "udp",
156                      "port_range_min": "1",
157                      "port_range_max": "65535"},
158                     {"remote_ip_prefix": "0.0.0.0/0",
159                      "protocol": "icmp"}
160                 ]
161             }
162         }
163
164         self.heat_date["outputs"][security_name] = {
165             "description": "ID of Security Group",
166             "value": {"get_resource": security_name}
167         }
168
169     def add_keypair(self, name):
170         """add to the template a Nova KeyPair"""
171         key_name = name + "key"
172         with open(Parser.root_dir +
173                   "utils/infra_setup/"
174                   "bottlenecks_key/bottlenecks_key.pub") as f:
175             key_content = f.read()
176             self.heat_date["resources"][key_name] = {
177                 "type": "OS::Nova::KeyPair",
178                 "properties": {
179                     "name": key_name,
180                     "public_key": key_content
181                 }
182             }
183
184     def add_network(self, name):
185         """add to the template a Neutron Net"""
186         network_name = name + "-net"
187         self.heat_date["resources"][network_name] = {
188             "type": "OS::Neutron::Net",
189             "properties": {"name": network_name}
190         }
191
192     def add_subnet(self, name, cidr):
193         """add to the template a Neutron Subnet"""
194         network_name = name + "-net"
195         subnet_name = name + "-subnet"
196         self.heat_date["resources"][subnet_name] = {
197             "type": "OS::Neutron::Subnet",
198             "depends_on": network_name,
199             "properties": {
200                 "name": subnet_name,
201                 "cidr": cidr,
202                 "network_id": {"get_resource": network_name}
203             }
204         }
205
206         self.heat_date["outputs"][subnet_name] = {
207             "description": "subnet %s ID" % subnet_name,
208             "value": {"get_resource": subnet_name}
209         }
210
211     def add_router(self, name, ext_gw_net):
212         """add to the template a Neutron Router and interface"""
213         router_name = name + "-route"
214         subnet_name = name + "-subnet"
215
216         self.heat_date["resources"][router_name] = {
217             "type": "OS::Neutron::Router",
218             "depends_on": [subnet_name],
219             "properties": {
220                 "name": router_name,
221                 "external_gateway_info": {
222                     "network": ext_gw_net
223                 }
224             }
225         }
226
227     def add_router_interface(self, name):
228         """add to the template a Neutron RouterInterface and interface"""
229         router_name = name + "-route"
230         subnet_name = name + "-subnet"
231         router_if_name = name + "-interface"
232
233         self.heat_date["resources"][router_if_name] = {
234             "type": "OS::Neutron::RouterInterface",
235             "depends_on": [router_name, subnet_name],
236             "properties": {
237                 "router_id": {"get_resource": router_name},
238                 "subnet_id": {"get_resource": subnet_name}
239             }
240         }
241
242     def add_server(self, name, image, flavor, user, ports=None):
243         """add to the template a Nova Server"""
244
245         key_name = "bottlenecks-poscakey"
246         port_name = name + "-port"
247         self.heat_date["resources"][name] = {
248             "type": "OS::Nova::Server",
249             "properties": {
250                 "name": name,
251                 "flavor": flavor,
252                 "image": image,
253                 "key_name": {"get_resource": key_name},
254                 "admin_user": user,
255                 "networks": [{
256                     "port": {"get_resource": port_name}
257                 }]
258             }
259         }
260
261         self.heat_date["outputs"][name] = {
262             "description": "VM UUID",
263             "value": {"get_resource": name}
264         }
265
266     def add_port(self, name, stack_name=None):
267         """add to the template a named Neutron Port"""
268         network_name = stack_name + "-net"
269         subnet_name = stack_name + "-subnet"
270         port_name = name + "-port"
271         security_name = stack_name + "-security_group"
272
273         self.heat_date["resources"][port_name] = {
274             "type": "OS::Neutron::Port",
275             "depends_on": [subnet_name],
276             "properties": {
277                 "name": port_name,
278                 "fixed_ips": [{"subnet": {"get_resource": subnet_name}}],
279                 "network_id": {"get_resource": network_name},
280                 "replacement_policy": "AUTO",
281                 "security_groups": [{"get_resource": security_name}]
282             }
283         }
284
285         self.heat_date["outputs"][port_name] = {
286             "description": "Address for interface %s" % port_name,
287             "value": {"get_attr": [port_name, "fixed_ips", 0, "ip_address"]}
288         }
289
290     def add_floating_ip(self, name, stack_name, network_ext):
291         """add to the template a Nova FloatingIP resource
292         see: https://bugs.launchpad.net/heat/+bug/1299259
293         """
294         port_name = name + "-port"
295         floating_ip_name = name + "-floating"
296         router_if_name = stack_name + "-interface"
297
298         self.heat_date["resources"][floating_ip_name] = {
299             "depends_on": [router_if_name, port_name],
300             "type": "OS::Nova::FloatingIP",
301             "properties": {
302                 "pool": network_ext,
303             }
304         }
305         self.heat_date['outputs'][floating_ip_name] = {
306             'description': 'floating ip %s' % name,
307             'value': {'get_attr': [name, 'ip']}
308         }
309
310     def add_floating_ip_ass(self, name):
311         """add to the template a Nova FloatingIP resource
312         see: https://bugs.launchpad.net/heat/+bug/1299259
313         """
314         port_name = name + "-port"
315         floating_ip_name = name + "-floating"
316         floating_ass = name + "-floating_ass"
317
318         self.heat_date["resources"][floating_ass] = {
319             "type": 'OS::Neutron::FloatingIPAssociation',
320             "depends_on": [port_name, floating_ip_name],
321             "properties": {
322                 "floatingip_id": {'get_resource': floating_ip_name},
323                 "port_id": {"get_resource": port_name}
324             }
325         }
326
327     def get_template_date(self):
328         return self.heat_date