1 # Copyright (c) 2021 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:
6 # http://www.apache.org/licenses/LICENSE-2.0
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.
14 """Utilities to work with JSON data format from VAT."""
16 from robot.api import logger
18 from resources.libraries.python.parsers.JsonParser import JsonParser
22 """Utilities to work with JSON data format from VAT."""
25 def _convert_mac_to_number_list(mac_address):
26 """Convert MAC address string to list of decimal numbers.
28 Converts a ":" separated MAC address to decimal number list as used
29 in JSON interface dump.
31 :param mac_address: MAC address.
32 :type mac_address: str
33 :returns: List representation of MAC address.
37 for num in mac_address.split(u":"):
38 list_mac.append(int(num, 16))
42 def get_vpp_interface_by_mac(interfaces_list, mac_address):
43 """Return interface dictionary from interface_list by MAC address.
45 Extracts interface dictionary from all of the interfaces in interfaces
46 list parsed from JSON according to mac_address of the interface.
48 :param interfaces_list: Interfaces parsed from JSON.
49 :param mac_address: MAC address of interface we are looking for.
50 :type interfaces_list: dict
51 :type mac_address: str
52 :returns: Interface from JSON.
55 interface_dict = dict()
56 list_mac_address = VatJsonUtil._convert_mac_to_number_list(mac_address)
58 f"MAC address {mac_address} converted to list {list_mac_address}."
60 for interface in interfaces_list:
61 # TODO: create vat json integrity checking and move there
62 if u"l2_address" not in interface:
64 u"key l2_address not found in interface dict."
65 u"Probably input list is not parsed from correct VAT "
68 if u"l2_address_length" not in interface:
70 u"key l2_address_length not found in interface "
71 u"dict. Probably input list is not parsed from correct "
74 mac_from_json = interface[u"l2_address"][:6]
75 if mac_from_json == list_mac_address:
76 if interface[u"l2_address_length"] != 6:
77 raise ValueError(u"l2_address_length value is not 6.")
78 interface_dict = interface
83 def update_vpp_interface_data_from_json(node, interface_dump_json):
84 """Update vpp node data in node__DICT from JSON interface dump.
86 This method updates vpp interface names and sw if indexes according to
87 interface MAC addresses found in interface_dump_json.
89 :param node: Node dictionary.
90 :param interface_dump_json: JSON output from dump_interface_list VAT
93 :type interface_dump_json: str
95 interface_list = JsonParser().parse_data(interface_dump_json)
96 for ifc in node[u"interfaces"].values():
97 if_mac = ifc[u"mac_address"]
98 interface_dict = VatJsonUtil.get_vpp_interface_by_mac(
99 interface_list, if_mac
101 if not interface_dict:
102 logger.trace(f"Interface {ifc} not found by MAC {if_mac}")
103 ifc[u"vpp_sw_index"] = None
105 ifc[u"name"] = interface_dict[u"interface_name"]
106 ifc[u"vpp_sw_index"] = interface_dict[u"sw_if_index"]
107 ifc[u"mtu"] = interface_dict[u"mtu"]
110 def get_interface_sw_index_from_json(interface_dump_json, interface_name):
111 """Get sw_if_index from given JSON output by interface name.
113 :param interface_dump_json: JSON output from dump_interface_list VAT
115 :param interface_name: Interface name.
116 :type interface_dump_json: str
117 :type interface_name: str
118 :returns: SW interface index.
120 :raises ValueError: If interface not found in interface_dump_json.
122 logger.trace(interface_dump_json)
123 interface_list = JsonParser().parse_data(interface_dump_json)
124 for interface in interface_list:
126 if interface[u"interface_name"] == interface_name:
127 index = interface[u"sw_if_index"]
129 f"Interface with name {interface_name} "
130 f"has sw_if_index {index}."
135 raise ValueError(f"Interface with name {interface_name} not found.")
138 def get_interface_name_from_json(interface_dump_json, sw_if_index):
139 """Get interface name from given JSON output by sw_if_index.
141 :param interface_dump_json: JSON output from dump_interface_list VAT
143 :param sw_if_index: SW interface index.
144 :type interface_dump_json: str
145 :type sw_if_index: int
146 :returns: Interface name.
148 :raises ValueError: If interface not found in interface_dump_json.
150 logger.trace(interface_dump_json)
151 interface_list = JsonParser().parse_data(interface_dump_json)
152 for interface in interface_list:
154 if interface[u"sw_if_index"] == sw_if_index:
155 interface_name = interface[u"interface_name"]
157 f"Interface with sw_if_index {sw_if_index} "
158 f"has name {interface_name}."
160 return interface_name
163 raise ValueError(f"Interface with sw_if_index {sw_if_index} not found.")
166 def get_interface_mac_from_json(interface_dump_json, sw_if_index):
167 """Get interface MAC address from given JSON output by sw_if_index.
169 :param interface_dump_json: JSON output from dump_interface_list VAT
171 :param sw_if_index: SW interface index.
172 :type interface_dump_json: str
173 :type sw_if_index: int
174 :returns: Interface MAC address.
176 :raises ValueError: If interface not found in interface_dump_json.
178 logger.trace(interface_dump_json)
179 interface_list = JsonParser().parse_data(interface_dump_json)
180 for interface in interface_list:
182 if interface[u"sw_if_index"] == sw_if_index:
183 mac_from_json = interface[u"l2_address"][:6] \
184 if u"l2_address" in list(interface.keys()) else u""
185 mac_address = u":".join(
186 f"{item:02x}" for item in mac_from_json
189 f"Interface with sw_if_index {sw_if_index} "
190 f"has MAC address {mac_address}."
195 raise ValueError(f"Interface with sw_if_index {sw_if_index} not found.")
198 def verify_vat_retval(vat_out, exp_retval=0, err_msg=u"VAT cmd failed"):
199 """Verify return value of VAT command.
201 VAT command JSON output should be object (dict in python) or array. We
202 are looking for something like this: { "retval": 0 }. Verification is
203 skipped if VAT output does not contain return value element or root
206 :param vat_out: VAT command output in python representation of JSON.
207 :param exp_retval: Expected return value (default 0).
208 :err_msg: Message to be displayed in case of error (optional).
209 :type vat_out: dict or list
210 :type exp_retval: int
212 :raises RuntimeError: If VAT command return value is incorrect.
214 if isinstance(vat_out, dict):
215 retval = vat_out.get(u"retval")
216 if retval is not None:
217 if retval != exp_retval:
218 raise RuntimeError(err_msg)