+
+ @staticmethod
+ def enable_acl_on_interface(node, interface, table_name):
+ """Enable ACL on the given interface.
+
+ :param node: Honeycomb node.
+ :param interface: The interface where the ACL will be enabled.
+ :param table_name: Name of the classify table.
+ :type node: dict
+ :type interface: str
+ :type table_name: str
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the configuration of interface is not
+ successful.
+ """
+
+ interface = interface.replace("/", "%2F")
+
+ data = {
+ "vpp-interface-acl:acl": {
+ "ingress": {
+ "ip4-acl": {
+ "classify-table": table_name
+ },
+ "l2-acl": {
+ "classify-table": table_name
+ }
+ }
+ }
+ }
+
+ path = "/interface/" + interface + "/vpp-interface-acl:acl"
+ status_code, resp = HcUtil.\
+ put_honeycomb_data(node, "config_vpp_interfaces", data, path,
+ data_representation=DataRepresentation.JSON)
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+ raise HoneycombError(
+ "The configuration of interface '{0}' was not successful. "
+ "Status code: {1}.".format(interface, status_code))
+ return resp
+
+ @staticmethod
+ def enable_policer_on_interface(node, interface, table_name):
+ """Enable Policer on the given interface.
+
+ :param node: Honeycomb node.
+ :param interface: The interface where policer will be enabled.
+ :param table_name: Name of the classify table.
+ :type node: dict
+ :type interface: str
+ :type table_name: str
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the configuration of interface is not
+ successful.
+ """
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+ interface = interface.replace("/", "%2F")
+
+ data = {
+ "interface-policer:policer": {
+ "ip4-table": table_name
+ }
+ }
+
+ path = "/interface/" + interface + "/interface-policer:policer"
+ status_code, resp = HcUtil.\
+ put_honeycomb_data(node, "config_vpp_interfaces", data, path,
+ data_representation=DataRepresentation.JSON)
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+ raise HoneycombError(
+ "The configuration of interface '{0}' was not successful. "
+ "Status code: {1}.".format(interface, status_code))
+ return resp
+
+ @staticmethod
+ def disable_policer_on_interface(node, interface):
+ """Disable Policer on the given interface.
+
+ :param node: Honeycomb node.
+ :param interface: The interface where policer will be disabled.
+ :type node: dict
+ :type interface: str
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the configuration of interface is not
+ successful.
+ """
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+ interface = interface.replace("/", "%2F")
+
+ path = "/interface/" + interface + "/interface-policer:policer"
+ status_code, resp = HcUtil.\
+ delete_honeycomb_data(node, "config_vpp_interfaces", path)
+ if status_code != HTTPCodes.OK:
+ raise HoneycombError(
+ "The configuration of interface '{0}' was not successful. "
+ "Status code: {1}.".format(interface, status_code))
+ return resp
+
+ @staticmethod
+ def disable_acl_on_interface(node, interface):
+ """Disable ACL on the given interface.
+
+ :param node: Honeycomb node.
+ :param interface: The interface where the ACL will be disabled.
+ :type node: dict
+ :type interface: str
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the configuration of interface is not
+ successful.
+ """
+
+ interface = interface.replace("/", "%2F")
+
+ path = "/interface/" + interface + "/vpp-interface-acl:acl"
+
+ status_code, resp = HcUtil.\
+ delete_honeycomb_data(node, "config_vpp_interfaces", path)
+
+ if status_code != HTTPCodes.OK:
+ raise HoneycombError(
+ "The configuration of interface '{0}' was not successful. "
+ "Status code: {1}.".format(interface, status_code))
+ return resp
+
+ @staticmethod
+ def create_pbb_sub_interface(node, intf, params):
+ """Creates a PBB sub-interface on the given interface and sets its
+ parameters.
+
+ :param node: Honeycomb node.
+ :param intf: The interface where PBB sub-interface will be configured.
+ :param params: Configuration parameters of the sub-interface to be
+ created.
+ :type node: dict
+ :type intf: str
+ :type params: dict
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the configuration of sub-interface is not
+ successful.
+ """
+
+ interface = intf.replace("/", "%2F")
+ path = "/interface/{0}/pbb-rewrite".format(interface)
+ status_code, resp = HcUtil. \
+ put_honeycomb_data(node, "config_vpp_interfaces", params, path,
+ data_representation=DataRepresentation.JSON)
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+ raise HoneycombError(
+ "The configuration of PBB sub-interface '{0}' was not "
+ "successful. Status code: {1}.".format(intf, status_code))
+ return resp
+
+ @staticmethod
+ def delete_pbb_sub_interface(node, intf):
+ """Deletes the given PBB sub-interface.
+
+ :param node: Honeycomb node.
+ :param intf: The interface where PBB sub-interface will be deleted.
+ :type node: dict
+ :type intf: str
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the removal of sub-interface is not
+ successful.
+ """
+
+ interface = intf.replace("/", "%2F")
+ path = "/interface/{0}/pbb-rewrite".format(interface)
+
+ status_code, resp = HcUtil. \
+ delete_honeycomb_data(node, "config_vpp_interfaces", path)
+ if status_code != HTTPCodes.OK:
+ raise HoneycombError(
+ "The removal of pbb sub-interface '{0}' was not successful. "
+ "Status code: {1}.".format(intf, status_code))
+ return resp
+
+ @staticmethod
+ def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
+ """Retrieves PBB sub-interface operational data from Honeycomb.
+
+ :param node: Honeycomb node.
+ :param intf: The interface where PBB sub-interface is located.
+ :param sub_if_id: ID of the PBB sub-interface.
+ :type node: dict
+ :type intf: str
+ :type sub_if_id: str or int
+ :returns: PBB sub-interface operational data.
+ :rtype: dict
+ :raises HoneycombError: If the removal of sub-interface is not
+ successful.
+ """
+
+ raise NotImplementedError
+
+ @staticmethod
+ def check_disabled_interface(node, interface):
+ """Retrieves list of disabled interface indices from Honeycomb,
+ and matches with the provided interface by index.
+
+ :param node: Honeycomb node.
+ :param interface: Index number of an interface on the node.
+ :type node: dict
+ :type interface: int
+ :returns: True if the interface exists in disabled interfaces.
+ :rtype: bool
+ :raises HoneycombError: If the interface is not present
+ in retrieved list of disabled interfaces.
+ """
+ data = InterfaceKeywords.get_disabled_interfaces_oper_data(node)
+ # decrement by one = conversion from HC if-index to VPP sw_if_index
+ interface -= 1
+
+ for item in data:
+ if item["index"] == interface:
+ 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=None):
+ """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 or int
+ :type src_interfaces: list of dict
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If SPAN could not be configured.
+ """
+
+ interface = Topology.convert_interface_reference(
+ node, dst_interface, "name")
+ interface = interface.replace("/", "%2F")
+ path = "/interface/" + interface + "/span"
+
+ if not src_interfaces:
+ status_code, _ = HcUtil.delete_honeycomb_data(
+ node, "config_vpp_interfaces", path)
+ else:
+ for src_interface in src_interfaces:
+ src_interface["iface-ref"] = Topology.\
+ convert_interface_reference(
+ node, src_interface["iface-ref"], "name")
+ 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 configure_sub_interface_span(node, super_interface, dst_interface_index,
+ src_interfaces=None):
+ """Configure SPAN port mirroring on the specified sub-interface. If no
+ source interface is provided, SPAN will be disabled.
+
+ Note: Does not support source sub-interfaces, only destination.
+
+ :param node: Honeycomb node.
+ :param super_interface: Name, link name or sw_if_index
+ of the destination interface's super-interface.
+ :param dst_interface_index: Index of sub-interface to mirror packets to.
+ :param src_interfaces: List of interfaces to mirror packets from.
+ :type node: dict
+ :type super_interface: str or int
+ :type dst_interface_index: int
+ :type src_interfaces: list of dict
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If SPAN could not be configured.
+ """
+
+ super_interface = Topology.convert_interface_reference(
+ node, super_interface, "name")
+ super_interface = super_interface.replace("/", "%2F")
+
+ path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
+ .format(super_interface, dst_interface_index)
+
+ if not src_interfaces:
+ status_code, _ = HcUtil.delete_honeycomb_data(
+ node, "config_vpp_interfaces", path)
+ else:
+ for src_interface in src_interfaces:
+ src_interface["iface-ref"] = Topology. \
+ convert_interface_reference(
+ node, src_interface["iface-ref"], "name")
+ 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")
+
+ @staticmethod
+ def configure_interface_unnumbered(node, interface, interface_src=None):
+ """Configure the specified interface as unnumbered. The interface
+ borrows IP address from the specified source interface. If not source
+ interface is provided, unnumbered configuration will be removed.
+
+ :param node: Honeycomb node.
+ :param interface: Name, link name or sw_if_index of an interface.
+ :param interface_src: Name of source interface.
+ :type node: dict
+ :type interface: str or int
+ :type interface_src: str
+ :raises HoneycombError: If the configuration fails.
+ """
+
+ interface = InterfaceKeywords.handle_interface_reference(
+ node, interface)
+
+ path = "/interface/{0}/unnumbered-interfaces:unnumbered"\
+ .format(interface)
+
+ if interface_src:
+ data = {
+ "unnumbered": {
+ "use": interface_src
+ }
+ }
+ status_code, _ = HcUtil.put_honeycomb_data(
+ node, "config_vpp_interfaces", data, path)
+ else:
+ status_code, _ = HcUtil.delete_honeycomb_data(
+ node, "config_vpp_interfaces", path)
+
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+ raise HoneycombError(
+ "Configuring unnumbered interface failed. "
+ "Status code:{0}".format(status_code))
+
+ @staticmethod
+ def handle_interface_reference(node, interface):
+ """Convert any interface reference to interface name used by Honeycomb.
+
+ :param node: Honeycomb node.
+ :param interface: Name, link name or sw_if_index of an interface,
+ name of a custom interface or name of a sub-interface.
+ :type node: Honeycomb node.
+ :type interface: str or int
+ :returns: Name of interface that can be used in Honeycomb requests.
+ :rtype: str
+ """
+
+ try:
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+ interface = interface.replace("/", "%2F")
+ except RuntimeError:
+ # interface is not in topology
+ if "." in interface:
+ # Assume it's the name of a sub-interface
+ interface, index = interface.split(".")
+ interface = interface.replace("/", "%2F")
+ interface = "{0}/vpp-vlan:sub-interfaces/sub-interface/{1}".\
+ format(interface, index)
+ else:
+ # Assume it's the name of a custom interface (pbb, vxlan, etc.)
+ interface = interface.replace("/", "%2F")
+
+ return interface