CSIT-843: Update actual topology in case of new/updated/deleted interface
[csit.git] / resources / libraries / python / Memif.py
1 # Copyright (c) 2017 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """Memif interface library."""
15
16 from resources.libraries.python.ssh import SSH
17 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
18 from resources.libraries.python.topology import Topology
19
20
21 class Memif(object):
22     """Memif interface class."""
23
24     def __init__(self):
25         pass
26
27     @staticmethod
28     def create_memif_interface(node, socket, mid, role='master'):
29         """Create Memif interface on the given node.
30
31         :param node: Given node to create Memif interface on.
32         :param socket: Memif interface socket path.
33         :param mid: Memif interface ID.
34         :param role: Memif interface role [master|slave]. Default is master.
35         :type node: dict
36         :type socket: str
37         :type mid: str
38         :type role: str
39         :returns: SW interface index.
40         :rtype: int
41         :raises ValueError: If command 'create memif' fails.
42         """
43
44         with VatTerminal(node, json_param=False) as vat:
45             vat.vat_terminal_exec_cmd_from_template(
46                 'memif_create.vat',
47                 socket=socket, id=mid, role=role)
48             if 'sw_if_index' in vat.vat_stdout:
49                 try:
50                     sw_if_idx = int(vat.vat_stdout.split()[4])
51                     if_key = Topology.add_new_port(node, 'memif')
52                     Topology.update_interface_sw_if_index(
53                         node, if_key, sw_if_idx)
54                     ifc_name = Memif.vpp_get_memif_interface_name(
55                         node, sw_if_idx)
56                     Topology.update_interface_name(node, if_key, ifc_name)
57                     ifc_mac = Memif.vpp_get_memif_interface_mac(node, sw_if_idx)
58                     Topology.update_interface_mac_address(node, if_key, ifc_mac)
59                     Topology.update_interface_memif_socket(node, if_key, socket)
60                     Topology.update_interface_memif_id(node, if_key, mid)
61                     Topology.update_interface_memif_role(node, if_key, role)
62                     return sw_if_idx
63                 except KeyError:
64                     raise ValueError('Create Memif interface failed on node '
65                                      '{}'.format(node['host']))
66             else:
67                 raise ValueError('Create Memif interface failed on node '
68                                  '{}'.format(node['host']))
69
70     @staticmethod
71     def show_memif(node):
72         """Show Memif data for the given node.
73
74         :param node: Given node to show Memif data on.
75         :type node: dict
76         """
77         vat = VatExecutor()
78         vat.execute_script("memif_dump.vat", node, json_out=False)
79
80     @staticmethod
81     def clear_memif_socks(node, *socks):
82         """Clear Memif sockets for the given node.
83
84         :param node: Given node to clear Memif sockets on.
85         :param socks: Memif sockets.
86         :type node: dict
87         :type socks: list
88         """
89         ssh = SSH()
90         ssh.connect(node)
91
92         for sock in socks:
93             ssh.exec_command_sudo('rm -f {}'.format(sock))
94
95     @staticmethod
96     def parse_memif_dump_data(memif_data):
97         """Convert Memif data to dictionary.
98
99         :param memif_data: Dump of Memif interfaces data.
100         :type memif_data: str
101         :returns: Memif interfaces data in dictionary.
102         :rtype: dict
103         :raises RuntimeError: If there is no memif interface name found in
104             provided data.
105         """
106         memif_name = None
107         memif_dict = dict()
108         memif_data = str(memif_data)
109         values = dict()
110
111         clutter = ['vat#']
112         for garbage in clutter:
113             memif_data = memif_data.replace(garbage, '')
114
115         for line in memif_data.splitlines():
116             if line.startswith('Sending') or len(line) == 0:
117                 continue
118             elif line.startswith('memif'):
119                 if memif_name:
120                     memif_dict[memif_name] = values
121                 line_split = line.split(':', 1)
122                 memif_name = str(line_split[0])
123                 values = dict()
124                 line = line_split[1]
125             line_split = line.split()
126             for i in range(0, len(line_split), 2):
127                 key = str(line_split[i])
128                 try:
129                     value = line_split[i+1]
130                 except IndexError:
131                     value = None
132                 values[key] = value
133         if memif_name:
134             memif_dict[memif_name] = values
135         else:
136             raise RuntimeError('No memif interface name found')
137
138         return memif_dict
139
140     @staticmethod
141     def vpp_get_memif_interface_name(node, sw_if_idx):
142         """Get Memif interface name from Memif interfaces dump.
143
144         :param node: DUT node.
145         :param sw_if_idx: DUT node.
146         :type node: dict
147         :type sw_if_idx: int
148         :returns: Memif interface name.
149         :rtype: str
150         """
151         with VatTerminal(node, json_param=False) as vat:
152             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
153             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
154             for item in memif_data:
155                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
156                     return item
157                 return None
158
159     @staticmethod
160     def vpp_get_memif_interface_mac(node, sw_if_idx):
161         """Get Memif interface MAC address from Memif interfaces dump.
162
163         :param node: DUT node.
164         :param sw_if_idx: DUT node.
165         :type node: dict
166         :type sw_if_idx: int
167         :returns: Memif interface MAC address.
168         :rtype: str
169         """
170         with VatTerminal(node, json_param=False) as vat:
171             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
172             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
173             for item in memif_data:
174                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
175                     return memif_data[item].get('mac', None)
176
177     @staticmethod
178     def vpp_get_memif_interface_socket(node, sw_if_idx):
179         """Get Memif interface socket path from Memif interfaces dump.
180
181         :param node: DUT node.
182         :param sw_if_idx: DUT node.
183         :type node: dict
184         :type sw_if_idx: int
185         :returns: Memif interface socket path.
186         :rtype: str
187         """
188         with VatTerminal(node, json_param=False) as vat:
189             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
190             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
191             for item in memif_data:
192                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
193                     return memif_data[item].get('socket', None)
194
195     @staticmethod
196     def vpp_get_memif_interface_id(node, sw_if_idx):
197         """Get Memif interface ID from Memif interfaces dump.
198
199         :param node: DUT node.
200         :param sw_if_idx: DUT node.
201         :type node: dict
202         :type sw_if_idx: int
203         :returns: Memif interface ID.
204         :rtype: int
205         """
206         with VatTerminal(node, json_param=False) as vat:
207             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
208             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
209             for item in memif_data:
210                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
211                     return int(memif_data[item].get('id', None))
212
213     @staticmethod
214     def vpp_get_memif_interface_role(node, sw_if_idx):
215         """Get Memif interface role from Memif interfaces dump.
216
217         :param node: DUT node.
218         :param sw_if_idx: DUT node.
219         :type node: dict
220         :type sw_if_idx: int
221         :returns: Memif interface role.
222         :rtype: int
223         """
224         with VatTerminal(node, json_param=False) as vat:
225             vat.vat_terminal_exec_cmd_from_template('memif_dump.vat')
226             memif_data = Memif.parse_memif_dump_data(vat.vat_stdout)
227             for item in memif_data:
228                 if memif_data[item]['sw_if_index'] == str(sw_if_idx):
229                     return memif_data[item].get('role', None)