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