From 4f70ebf481d496f91d2b1ec27361c9898b19c451 Mon Sep 17 00:00:00 2001 From: selias Date: Fri, 25 Nov 2016 10:50:29 +0100 Subject: CSIT-481: HC Test: Port mirroring (SPAN) - add port mirroring test suite - add relevant keywords Change-Id: I4ff398dd2ab4323e2a53af2812bf07cbb7043252 Signed-off-by: selias --- .../python/honeycomb/HcAPIKwInterfaces.py | 52 +++++++++++++++++++ resources/libraries/python/telemetry/SPAN.py | 58 ++++++++++++++++++++-- resources/libraries/python/topology.py | 13 +++++ 3 files changed, 118 insertions(+), 5 deletions(-) (limited to 'resources/libraries/python') diff --git a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py index 3271413d1c..01a2eba0ad 100644 --- a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py +++ b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py @@ -1576,3 +1576,55 @@ class InterfaceKeywords(object): return True raise HoneycombError("Interface index {0} not present in list" " of disabled interfaces.".format(interface)) + + @staticmethod + def configure_interface_span(node, dst_interface, *src_interfaces): + """Configure SPAN port mirroring on the specified interfaces. If no + source interface is provided, SPAN will be disabled. + + :param node: Honeycomb node. + :param dst_interface: Interface to mirror packets to. + :param src_interfaces: List of interfaces to mirror packets from. + :type node: dict + :type dst_interface: str + :type src_interfaces: list of str + :returns: Content of response. + :rtype: bytearray + :raises HoneycombError: If SPAN could not be configured. + """ + + interface = dst_interface.replace("/", "%2F") + path = "/interface/" + interface + "/span" + + if not src_interfaces: + status_code, _ = HcUtil.delete_honeycomb_data( + node, "config_vpp_interfaces", path) + + data = { + "span": { + "mirrored-interfaces": { + "mirrored-interface": src_interfaces + } + } + } + + status_code, _ = HcUtil.put_honeycomb_data( + node, "config_vpp_interfaces", data, path) + + if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED): + raise HoneycombError( + "Configuring SPAN failed. Status code:{0}".format(status_code)) + + @staticmethod + def add_interface_local0_to_topology(node): + """Use Topology methods to add interface "local0" to working topology, + if not already present. + + :param node: DUT node. + :type node: dict + """ + + if Topology.get_interface_by_sw_index(node, 0) is None: + local0_key = Topology.add_new_port(node, "localzero") + Topology.update_interface_sw_if_index(node, local0_key, 0) + Topology.update_interface_name(node, local0_key, "local0") diff --git a/resources/libraries/python/telemetry/SPAN.py b/resources/libraries/python/telemetry/SPAN.py index 7933898c02..aff465c0ea 100644 --- a/resources/libraries/python/telemetry/SPAN.py +++ b/resources/libraries/python/telemetry/SPAN.py @@ -37,12 +37,60 @@ class SPAN(object): :type dst_if: str """ - src_if = Topology.get_interface_name(node, src_if) - dst_if = Topology.get_interface_name(node, dst_if) + src_if = Topology.get_interface_sw_index(node, src_if) + dst_if = Topology.get_interface_sw_index(node, dst_if) with VatTerminal(node, json_param=False) as vat: vat.vat_terminal_exec_cmd_from_template('span_create.vat', - src_if=src_if, - dst_if=dst_if, + src_sw_if_index=src_if, + dst_sw_if_index=dst_if, ) - # TODO: Update "span_create.vat" to use VAT command, once available + + @staticmethod + def vpp_get_span_configuration(node): + """Get full SPAN configuration from VPP node. + + :param node: DUT node. + :type node: dict + :returns: Full SPAN configuration as list. One list entry for every + source/destination interface pair. + :rtype: list of dict + """ + + with VatTerminal(node, json_param=True) as vat: + data = vat.vat_terminal_exec_cmd_from_template('span_dump.vat') + return data[0] + + @staticmethod + def vpp_get_span_configuration_by_interface(node, dst_interface, + ret_format="sw_if_index"): + """Get a list of all interfaces currently being mirrored + to the specified interface. + + :param node: DUT node. + :param dst_interface: Name, sw_if_index or key of interface. + :param ret_format: Optional. Desired format of returned interfaces. + :type node: dict + :type dst_interface: str or int + :type ret_format: string + :returns: List of SPAN source interfaces for the provided destination + interface. + :rtype: list + """ + + data = SPAN.vpp_get_span_configuration(node) + + dst_interface = Topology.convert_interface_reference( + node, dst_interface, "sw_if_index") + src_interfaces = [] + for item in data: + if item["dst-if-index"] == dst_interface: + src_interfaces.append(item["src-if-index"]) + + if ret_format != "sw_if_index": + src_interfaces = [ + Topology.convert_interface_reference( + node, interface, ret_format + ) for interface in src_interfaces] + + return src_interfaces diff --git a/resources/libraries/python/topology.py b/resources/libraries/python/topology.py index 3c903e5c94..0214cc9c02 100644 --- a/resources/libraries/python/topology.py +++ b/resources/libraries/python/topology.py @@ -125,6 +125,19 @@ class Topology(object): """ node['interfaces'][iface_key]['vpp_sw_index'] = int(sw_if_index) + @staticmethod + def update_interface_name(node, iface_key, name): + """Update name on the interface from the node. + + :param node: Node to update name on. + :param iface_key: Topology key of the interface. + :param name: Interface name to store. + :type node: dict + :type iface_key: str + :type name: str + """ + node['interfaces'][iface_key]['name'] = str(name) + @staticmethod def update_interface_mac_address(node, iface_key, mac_address): """Update mac_address on the interface from the node. -- cgit 1.2.3-korg