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