Fix pylint warnings in python libraries
[csit.git] / resources / libraries / python / Classify.py
1 # Copyright (c) 2016 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 """Classify utilities library."""
15
16 from robot.api import logger
17
18 from resources.libraries.python.VatExecutor import VatExecutor, VatTerminal
19
20
21 # pylint: disable=too-many-arguments, invalid-name
22
23 class Classify(object):
24     """Classify utilities."""
25
26     @staticmethod
27     def vpp_creates_classify_table_l3(node, ip_version, direction):
28         """Create classify table for IP address filtering.
29
30         :param node: VPP node to create classify table.
31         :param ip_version: Version of IP protocol.
32         :param direction: Direction of traffic - src/dst.
33         :type node: dict
34         :type ip_version: str
35         :type direction: str
36         :return (table_index, skip_n, match_n)
37         table_index: Classify table index.
38         skip_n: Number of skip vectors.
39         match_n: Number of match vectors.
40         :rtype: tuple(int, int, int)
41         :raises RuntimeError: If VPP can't create table.
42         """
43
44         output = VatExecutor.cmd_from_template(node, "classify_add_table.vat",
45                                                ip_version=ip_version,
46                                                direction=direction)
47
48         if output[0]["retval"] == 0:
49             table_index = output[0]["new_table_index"]
50             skip_n = output[0]["skip_n_vectors"]
51             match_n = output[0]["match_n_vectors"]
52             logger.trace('Classify table with table_index {} created on node {}'
53                          .format(table_index, node['host']))
54         else:
55             raise RuntimeError('Unable to create classify table on node {}'
56                                .format(node['host']))
57
58         return table_index, skip_n, match_n
59
60     @staticmethod
61     def vpp_creates_classify_table_l2(node, direction):
62         """Create classify table for MAC address filtering.
63
64         :param node: VPP node to create classify table.
65         :param direction: Direction of traffic - src/dst.
66         :type node: dict
67         :type direction: str
68         :return (table_index, skip_n, match_n)
69         table_index: Classify table index.
70         skip_n: Number of skip vectors.
71         match_n: Number of match vectors.
72         :rtype: tuple(int, int, int)
73         :raises RuntimeError: If VPP can't create table.
74         """
75         output = VatExecutor.cmd_from_template(node,
76                                                "classify_add_table_l2.vat",
77                                                direction=direction)
78
79         if output[0]["retval"] == 0:
80             table_index = output[0]["new_table_index"]
81             skip_n = output[0]["skip_n_vectors"]
82             match_n = output[0]["match_n_vectors"]
83             logger.trace('Classify table with table_index {} created on node {}'
84                          .format(table_index, node['host']))
85         else:
86             raise RuntimeError('Unable to create classify table on node {}'
87                                .format(node['host']))
88
89         return table_index, skip_n, match_n
90
91     @staticmethod
92     def vpp_creates_classify_table_hex(node, hex_mask):
93         """Create classify table with hex mask.
94
95         :param node: VPP node to create classify table based on hex mask.
96         :param hex_mask: Classify hex mask.
97         :type node: dict
98         :type hex_mask: str
99         :return (table_index, skip_n, match_n)
100         table_index: Classify table index.
101         skip_n: Number of skip vectors.
102         match_n: Number of match vectors.
103         :rtype: tuple(int, int, int)
104         :raises RuntimeError: If VPP can't create table.
105         """
106         output = VatExecutor.cmd_from_template(node,
107                                                "classify_add_table_hex.vat",
108                                                hex_mask=hex_mask)
109
110         if output[0]["retval"] == 0:
111             table_index = output[0]["new_table_index"]
112             skip_n = output[0]["skip_n_vectors"]
113             match_n = output[0]["match_n_vectors"]
114             logger.trace('Classify table with table_index {} created on node {}'
115                          .format(table_index, node['host']))
116         else:
117             raise RuntimeError('Unable to create classify table on node {}'
118                                .format(node['host']))
119
120         return table_index, skip_n, match_n
121
122     @staticmethod
123     def vpp_configures_classify_session_l3(node, acl_method, table_index,
124                                            skip_n, match_n, ip_version,
125                                            direction, address):
126         """Configuration of classify session for IP address filtering.
127
128         :param node: VPP node to setup classify session.
129         :param acl_method: ACL method - deny/permit.
130         :param table_index: Classify table index.
131         :param skip_n: Number of skip vectors based on mask.
132         :param match_n: Number of match vectors based on mask.
133         :param ip_version: Version of IP protocol.
134         :param direction: Direction of traffic - src/dst.
135         :param address: IPv4 or IPv6 address.
136         :type node: dict
137         :type acl_method: str
138         :type table_index: int
139         :type skip_n: int
140         :type match_n: int
141         :type ip_version: str
142         :type direction: str
143         :type address: str
144         """
145         with VatTerminal(node) as vat:
146             vat.vat_terminal_exec_cmd_from_template("classify_add_session.vat",
147                                                     acl_method=acl_method,
148                                                     table_index=table_index,
149                                                     skip_n=skip_n,
150                                                     match_n=match_n,
151                                                     ip_version=ip_version,
152                                                     direction=direction,
153                                                     address=address)
154
155     @staticmethod
156     def vpp_configures_classify_session_l2(node, acl_method, table_index,
157                                            skip_n, match_n, direction, address):
158         """Configuration of classify session for MAC address filtering.
159
160         :param node: VPP node to setup classify session.
161         :param acl_method: ACL method - deny/permit.
162         :param table_index: Classify table index.
163         :param skip_n: Number of skip vectors based on mask.
164         :param match_n: Number of match vectors based on mask.
165         :param direction: Direction of traffic - src/dst.
166         :param address: IPv4 or IPv6 address.
167         :type node: dict
168         :type acl_method: str
169         :type table_index: int
170         :type skip_n: int
171         :type match_n: int
172         :type direction: str
173         :type address: str
174         """
175         with VatTerminal(node) as vat:
176             vat.vat_terminal_exec_cmd_from_template(
177                 "classify_add_session_l2.vat",
178                 acl_method=acl_method,
179                 table_index=table_index,
180                 skip_n=skip_n,
181                 match_n=match_n,
182                 direction=direction,
183                 address=address)
184
185     @staticmethod
186     def vpp_configures_classify_session_hex(node, acl_method, table_index,
187                                             skip_n, match_n, hex_value):
188         """Configuration of classify session with hex value.
189
190         :param node: VPP node to setup classify session.
191         :param acl_method: ACL method - deny/permit.
192         :param table_index: Classify table index.
193         :param skip_n: Number of skip vectors based on mask.
194         :param match_n: Number of match vectors based on mask.
195         :param hex_value: Classify hex value.
196         :type node: dict
197         :type acl_method: str
198         :type table_index: int
199         :type skip_n: int
200         :type match_n: int
201         :type hex_value: str
202         """
203         with VatTerminal(node) as vat:
204             vat.vat_terminal_exec_cmd_from_template(
205                 "classify_add_session_hex.vat",
206                 acl_method=acl_method,
207                 table_index=table_index,
208                 skip_n=skip_n,
209                 match_n=match_n,
210                 hex_value=hex_value)
211
212     @staticmethod
213     def vpp_configures_classify_session_generic(node, session_type, table_index,
214                                                 skip_n, match_n, match,
215                                                 match2=''):
216         """Configuration of classify session.
217
218         :param node: VPP node to setup classify session.
219         :param session_type: Session type - hit-next, l2-hit-next, acl-hit-next
220         or policer-hit-next, and their respective parameters.
221         :param table_index: Classify table index.
222         :param skip_n: Number of skip vectors based on mask.
223         :param match_n: Number of match vectors based on mask.
224         :param match: Match value - l2, l3, l4 or hex, and their
225         respective parameters.
226         :param match2: Additional match values, to avoid using overly long
227         variables in RobotFramework.
228         :type node: dict
229         :type session_type: str
230         :type table_index: int
231         :type skip_n: int
232         :type match_n: int
233         :type match: str
234         :type match2: str
235         """
236
237         match = ' '.join((match, match2))
238
239         with VatTerminal(node) as vat:
240             vat.vat_terminal_exec_cmd_from_template(
241                 "classify_add_session_generic.vat",
242                 type=session_type,
243                 table_index=table_index,
244                 skip_n=skip_n,
245                 match_n=match_n,
246                 match=match,
247             )
248
249     @staticmethod
250     def compute_classify_hex_mask(ip_version, protocol, direction):
251         """Compute classify hex mask for TCP or UDP packet matching.
252
253         :param ip_version: Version of IP protocol.
254         :param protocol: Type of protocol.
255         :param direction: Traffic direction.
256         :type ip_version: str
257         :type protocol: str
258         :type direction: str
259         :return: Classify hex mask.
260         :rtype : str
261         :raises ValueError: If protocol is not TCP or UDP.
262         :raises ValueError: If direction is not source or destination or
263                             source + destination.
264         """
265         if protocol == 'TCP' or protocol == 'UDP':
266             base_mask = Classify._compute_base_mask(ip_version)
267
268             if direction == 'source':
269                 return base_mask + 'FFFF0000'
270             elif direction == 'destination':
271                 return base_mask + '0000FFFF'
272             elif direction == 'source + destination':
273                 return base_mask + 'FFFFFFFF'
274             else:
275                 raise ValueError("Invalid direction!")
276         else:
277             raise ValueError("Invalid protocol!")
278
279     @staticmethod
280     def compute_classify_hex_value(hex_mask, source_port, destination_port):
281         """Compute classify hex value for TCP or UDP packet matching.
282
283         :param hex_mask: Classify hex mask.
284         :param source_port: Source TCP/UDP port.
285         :param destination_port: Destination TCP/UDP port.
286         :type hex_mask: str
287         :type source_port: str
288         :type destination_port: str
289         :return: Classify hex value.
290         :rtype: str
291         """
292         source_port_hex = Classify._port_convert(source_port)
293         destination_port_hex = Classify._port_convert(destination_port)
294
295         return hex_mask[:-8] + source_port_hex + destination_port_hex
296
297     @staticmethod
298     def _port_convert(port):
299         """Convert port number for classify hex table format.
300
301         :param port: TCP/UDP port number.
302         :type port: str
303         :return: TCP/UDP port number in 4-digit hexadecimal format.
304         :rtype: str
305         """
306         return '{0:04x}'.format(int(port))
307
308     @staticmethod
309     def _compute_base_mask(ip_version):
310         """Compute base classify hex mask based on IP version.
311
312         :param ip_version: Version of IP protocol.
313         :type ip_version: str
314         :return: Base hex mask.
315         :rtype: str
316         """
317         if ip_version == 'ip4':
318             return 68 * '0'
319             # base value of classify hex table for IPv4 TCP/UDP ports
320         elif ip_version == 'ip6':
321             return 108 * '0'
322             # base value of classify hex table for IPv6 TCP/UDP ports
323         else:
324             raise ValueError("Invalid IP version!")
325
326     @staticmethod
327     def get_classify_table_data(node, table_index):
328         """Retrieve settings for classify table by ID.
329
330         :param node: VPP node to retrieve classify data from.
331         :param table_index: Index of a specific classify table.
332         :type node: dict
333         :type table_index: int
334         :return: Classify table settings.
335         :rtype: dict
336         """
337         with VatTerminal(node) as vat:
338             data = vat.vat_terminal_exec_cmd_from_template(
339                 "classify_table_info.vat",
340                 table_id=table_index
341             )
342         return data[0]
343
344     @staticmethod
345     def get_classify_session_data(node, table_index, session_index=None):
346         """Retrieve settings for all classify sessions in a table,
347         or for a specific classify session.
348
349         :param node: VPP node to retrieve classify data from.
350         :param table_index: Index of a classify table.
351         :param session_index: Index of a specific classify session. (Optional)
352         :type node: dict
353         :type table_index: int
354         :type session_index: int
355         :return: List of classify session settings, or a dictionary of settings
356          for a specific classify session.
357         :rtype: list or dict
358         """
359         with VatTerminal(node) as vat:
360             data = vat.vat_terminal_exec_cmd_from_template(
361                 "classify_session_dump.vat",
362                 table_id=table_index
363             )
364         if session_index is not None:
365             return data[0][session_index]
366         else:
367             return data[0]