COE-43: Check for stale veth ports
[integration/test.git] / csit / libraries / VsctlListParser.py
1 """
2 Library for the robot based system test tool of the OpenDaylight project.
3
4 This library will parse 'ovs-vstcl list Bridge' and 'ovs-vstcl list Controller'
5 commands and create dictionaries with parsed details which will be used
6 for another pruposes.
7
8 Authors: pgubka@cisco.com
9 Created: 2016-04-04
10 """
11
12 import re
13 import copy
14 import traceback
15
16
17 def _parse_stdout(stdout):
18     """ Transforms stdout to dict """
19     text = stdout.replace(" ", "")
20     text = text.replace("\r", "")
21     pat = re.compile(r'(?P<key>\w+):(?P<value>.+)')
22     regroups = re.finditer(pat, text)
23     outdict = {}
24     for g in regroups:
25         print g.group()
26         if g.group('key') == '_uuid':
27             cntl_uuid = g.group('value')
28             outdict[cntl_uuid] = {}
29         outdict[cntl_uuid][g.group('key')] = g.group('value')
30     return outdict
31
32
33 def _postprocess_data(bridges, controllers):
34     """What is done here:
35     - merge bridges and controllers
36     - replace controller 'key' (ip instead uuid)
37     - transformed controller's connected status to bool
38     """
39     brs = copy.deepcopy(bridges)
40     cntls = copy.deepcopy(controllers)
41
42     # replacing string value of is_connected key with boolean
43     for key, cntl in cntls.iteritems():
44         if cntl['is_connected'] == 'false':
45             cntl['is_connected'] = False
46         elif cntl['is_connected'] == 'true':
47             cntl['is_connected'] = True
48         else:
49             cntl['is_connected'] = None
50
51     # replacing keys with the same values
52     for key, value in bridges.iteritems():
53         brs[value['name'][1:-1]] = brs[key]
54         del brs[key]
55
56     for key, value in brs.iteritems():
57         # replace string with references with dict of controllers
58         ctl_refs = value['controller'][1:-1].split(',')
59         value['controller'] = {}
60         for ctl_ref in ctl_refs:
61             if ctl_ref is not '':
62                 value['controller'][ctl_ref] = cntls[ctl_ref]
63
64     for brkey, bridge in brs.iteritems():
65         new_cntls = {}
66         for cnkey, cntl in bridge['controller'].iteritems():
67             # port 6654 is set by OvsMAnager.robot to disconnect from controller
68             if '6653' in cntl['target'] or '6633' in cntl['target'] or '6654' in cntl['target']:
69                 new_key = cntl['target'].split(":")[1]     # getting middle from "tcp:ip:6653"
70             else:
71                 new_key = cntl['target'][1:-1]  # getting string without quotes "ptcp:6638"
72             new_cntls[new_key] = cntl
73         bridge['controller'] = new_cntls
74
75     return brs
76
77
78 def parse(bridge_stdout, cntl_stdout):
79     """Produces dictionary with data for future usege
80
81     Args:
82         :param bridge_stdout: output of 'ovs-vsclt list Bridge' command
83
84         :param cntl_stdout: output of 'ovs-vsclt list Controller' command
85
86     Returns:
87         :returns processed: processed output dictionary
88
89         :returns bridges: list bridge command output transformed to dist
90
91         :returns controllers: list controller command output transformed to dist
92     """
93
94     try:
95         bridges = _parse_stdout(bridge_stdout)
96         controllers = _parse_stdout(cntl_stdout)
97         processed = _postprocess_data(bridges, controllers)
98     except Exception:
99         traceback.print_exc()
100         raise
101     return processed, bridges, controllers