-# Copyright (c) 2016 Cisco and/or its affiliates.
+# Copyright (c) 2018 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
The keywords make possible to put and get configuration data and to get
operational data.
"""
+from robot.api import logger
from resources.libraries.python.HTTPRequest import HTTPCodes
from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
import DataRepresentation
from resources.libraries.python.honeycomb.HoneycombUtil \
import HoneycombUtil as HcUtil
+from resources.libraries.python.topology import Topology
-# pylint: disable=too-many-public-methods
-# pylint: disable=too-many-lines
class InterfaceKeywords(object):
"""Keywords for Interface manipulation.
"""
INTF_PARAMS = ("name", "description", "type", "enabled",
- "link-up-down-trap-enable", "v3po:l2")
+ "link-up-down-trap-enable", "v3po:l2", "v3po:vxlan-gpe",
+ "vpp-vlan:sub-interfaces")
IPV4_PARAMS = ("enabled", "forwarding", "mtu")
IPV6_PARAMS = ("enabled", "forwarding", "mtu", "dup-addr-detect-transmits")
IPV6_AUTOCONF_PARAMS = ("create-global-addresses",
"temporary-valid-lifetime",
"temporary-preferred-lifetime")
ETH_PARAMS = ("mtu", )
- ROUTING_PARAMS = ("vrf-id", )
+ ROUTING_PARAMS = ("ipv4-vrf-id", "ipv6-vrf-id")
VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
L2_PARAMS = ("bridge-domain", "split-horizon-group",
"bridged-virtual-interface")
- L2_REWRITE_TAG_PARAMS = ("rewrite-operation",
- "first-pushed",
- "tag1",
- "tag2")
- TAP_PARAMS = ("tap-name", "mac", "device-instance")
+ TAP_PARAMS = ("id", "tx-ring-size", "rx-ring-size", "host-mac",
+ "host-interface-name", "host-namespace", "host-bridge",
+ "host-ipv4-address", "host-ipv6-address", "tag",
+ "host-ipv4-gateway", "host-ipv6-gateway", "mac")
VHOST_USER_PARAMS = ("socket", "role")
- SUB_INTF_PARAMS = ("super-interface",
- "identifier",
- "vlan-type",
- "number-of-tags",
- "outer-id",
- "inner-id",
- "match-any-outer-id",
- "match-any-inner-id",
- "exact-match",
- "default-subif")
+ SUB_IF_PARAMS = ("identifier",
+ "vlan-type",
+ "enabled")
+ SUB_IF_MATCH = ("default",
+ "untagged",
+ "vlan-tagged",
+ "vlan-tagged-exact-match")
+ BD_PARAMS = ("bridge-domain",
+ "split-horizon-group",
+ "bridged-virtual-interface")
+ VXLAN_GPE_PARAMS = ("local",
+ "remote",
+ "vni",
+ "next-protocol",
+ "encap-vrf-id",
+ "decap-vrf-id")
def __init__(self):
pass
:type interface: str
:type data: dict
:type data_representation: DataRepresentation
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the status code in response on PUT is not
- 200 = OK.
+ 200 = OK.
"""
status_code, resp = HcUtil.\
put_honeycomb_data(node, "config_vpp_interfaces", data,
data_representation=data_representation)
- if status_code != HTTPCodes.OK:
+ 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))
:param node: Honeycomb node.
:type node: dict
- :return: Configuration data about all interfaces from Honeycomb.
+ :returns: Configuration data about all interfaces from Honeycomb.
:rtype: list
:raises HoneycombError: If it is not possible to get configuration data.
"""
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Configuration data about the given interface from Honeycomb.
+ :returns: Configuration data about the given interface from Honeycomb.
:rtype: dict
"""
:param node: Honeycomb node.
:type node: dict
- :return: Operational data about all interfaces from Honeycomb.
+ :returns: Operational data about all interfaces from Honeycomb.
:rtype: list
:raises HoneycombError: If it is not possible to get operational data.
"""
except (KeyError, TypeError):
return []
+ @staticmethod
+ def get_disabled_interfaces_oper_data(node):
+ """Get operational data about all disabled interfaces from Honeycomb.
+
+ :param node: Honeycomb node.
+ :type node: dict
+ :returns: Operational data about disabled interfaces.
+ :rtype: list
+ :raises HoneycombError: If it is not possible to get operational data.
+ """
+
+ status_code, resp = HcUtil. \
+ get_honeycomb_data(node, "oper_disabled_interfaces")
+ if status_code == HTTPCodes.NOT_FOUND:
+ raise HoneycombError(
+ "No disabled interfaces present on node."
+ )
+ if status_code != HTTPCodes.OK:
+ raise HoneycombError(
+ "Not possible to get operational information about the "
+ "interfaces. Status code: {0}.".format(status_code))
+ try:
+ return resp["disabled-interfaces"]["disabled-interface-index"]
+
+ except (KeyError, TypeError):
+ return []
+
@staticmethod
def get_interface_oper_data(node, interface):
"""Get operational data about the given interface from Honeycomb.
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Operational data about the given interface from Honeycomb.
+ :returns: Operational data about the given interface from Honeycomb.
:rtype: dict
"""
+ try:
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+ except RuntimeError:
+ if isinstance(interface, basestring):
+ # Probably name of a custom interface (TAP, VxLAN, Vhost, ...)
+ pass
+ else:
+ raise
+
intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
for intf in intfs:
if intf["name"] == interface:
:param interface: The name of interface.
:param path: Path to data we want to change / create / remove.
:param new_value: The new value to be set. If None, the item will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type path: tuple
:type new_value: str, dict or list
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If it is not possible to get or set the data.
"""
return InterfaceKeywords._configure_interface(node, interface, new_data)
@staticmethod
- def set_interface_state(node, interface, state="up"):
+ def honeycomb_set_interface_state(node, interface, state="up"):
"""Set VPP interface state.
The keyword changes the administration state of interface to up or down
depending on the parameter "state".
:param node: Honeycomb node.
- :param interface: The name of interface.
+ :param interface: Interface name, key, link name or sw_if_index.
:param state: The requested state, only "up" and "down" are valid
- values.
+ values.
:type node: dict
:type interface: str
:type state: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises KeyError: If the argument "state" is nor "up" or "down".
:raises HoneycombError: If the interface is not present on the node.
intf_state = {"up": "true",
"down": "false"}
- path = ("interfaces", ("interface", "name", str(interface)), "enabled")
- return InterfaceKeywords._set_interface_properties(
- node, interface, path, intf_state[state.lower()])
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
+ intf = interface.replace("/", "%2F")
+ path = "/interface/{0}".format(intf)
+
+ status_code, resp = HcUtil.\
+ get_honeycomb_data(node, "config_vpp_interfaces", path)
+ if status_code != HTTPCodes.OK:
+ raise HoneycombError(
+ "Not possible to get configuration information about the "
+ "interfaces. Status code: {0}.".format(status_code))
+
+ resp["interface"][0]["enabled"] = intf_state[state.lower()]
+
+ status_code, resp = HcUtil. \
+ put_honeycomb_data(node, "config_vpp_interfaces", resp, 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 set_interface_up(node, interface):
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response
+ :returns: Content of response
:rtype: bytearray
"""
- return InterfaceKeywords.set_interface_state(node, interface, "up")
+ return InterfaceKeywords.honeycomb_set_interface_state(
+ node, interface, "up")
@staticmethod
def set_interface_down(node, interface):
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
- return InterfaceKeywords.set_interface_state(node, interface, "down")
+ return InterfaceKeywords.honeycomb_set_interface_state(
+ node, interface, "down")
@staticmethod
def add_bridge_domain_to_interface(node, interface, bd_name,
"""Add a new bridge domain to an interface and set its parameters.
:param node: Honeycomb node.
- :param interface: The name of interface.
+ :param interface: Interface name, key, link name or sw_if_index.
:param bd_name: Bridge domain name.
:param split_horizon_group: Split-horizon group name.
:param bvi: The bridged virtual interface.
:type bd_name: str
:type split_horizon_group: str
:type bvi: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the interface is not present on the node.
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
v3po_l2 = {"bridge-domain": str(bd_name)}
if split_horizon_group:
v3po_l2["split-horizon-group"] = str(split_horizon_group)
return InterfaceKeywords._set_interface_properties(
node, interface, path, v3po_l2)
+ @staticmethod
+ def remove_bridge_domain_from_interface(node, interface):
+ """Remove bridge domain assignment from interface.
+
+ :param node: Honeycomb node.
+ :param interface: Interface name, key, link name or sw_if_index.
+ :type node: dict
+ :type interface: str or int
+ :raises HoneycombError: If the operation fails.
+ """
+
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
+ intf = interface.replace("/", "%2F")
+
+ path = "/interface/{0}/v3po:l2".format(intf)
+
+ status_code, response = HcUtil.delete_honeycomb_data(
+ node, "config_vpp_interfaces", path)
+
+ if status_code != HTTPCodes.OK:
+ if '"error-tag":"data-missing"' in response:
+ logger.debug("Data does not exist in path.")
+ else:
+ raise HoneycombError(
+ "Could not remove bridge domain assignment from interface "
+ "'{0}'. Status code: {1}.".format(interface, status_code))
+
+ @staticmethod
+ def get_bd_oper_data_from_interface(node, interface):
+ """Returns operational data about bridge domain settings in the
+ interface.
+
+ :param node: Honeycomb node.
+ :param interface: The name of interface.
+ :type node: dict
+ :type interface: str
+ :returns: Operational data about bridge domain settings in the
+ interface.
+ :rtype: dict
+ """
+
+ if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
+
+ if if_data:
+ try:
+ return if_data["v3po:l2"]
+ except KeyError:
+ return {}
+ return {}
+
@staticmethod
def configure_interface_base(node, interface, param, value):
"""Configure the base parameters of interface.
:param interface: The name of interface.
:param param: Parameter to configure (set, change, remove)
:param value: The value of parameter. If None, the parameter will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type param: str
:type value: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
@staticmethod
def configure_interface_ipv4(node, interface, param, value):
- """Configure IPv4 parameters of interface
+ """Configure IPv4 parameters of interface.
:param node: Honeycomb node.
:param interface: The name of interface.
:param param: Parameter to configure (set, change, remove)
:param value: The value of parameter. If None, the parameter will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type param: str
:type value: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
if param not in InterfaceKeywords.IPV4_PARAMS:
raise HoneycombError("The parameter {0} is invalid.".format(param))
:type interface: str
:type ip_addr: str
:type network: str or int
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
+ :raises ValueError: If the provided netmask or prefix is not valid.
+ :raises HoneycombError: If the operation fails.
"""
- path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
+ interface = InterfaceKeywords.handle_interface_reference(
+ node, interface)
+
+ path = "/interface/{0}/ietf-ip:ipv4".format(interface)
if isinstance(network, basestring):
- address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
+ data = {
+ "ietf-ip:ipv4": {
+ "address": [{"ip": ip_addr, "netmask": network}, ]}}
elif isinstance(network, int) and (0 < network < 33):
- address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
+ data = {
+ "ietf-ip:ipv4": {
+ "address": [{"ip": ip_addr, "prefix-length": network}, ]}}
else:
- raise HoneycombError("Value {0} is not a valid netmask or network "
- "prefix length.".format(network))
- return InterfaceKeywords._set_interface_properties(
- node, interface, path, address)
+ raise ValueError("Value {0} is not a valid netmask or network "
+ "prefix length.".format(network))
+ status_code, _ = HcUtil.put_honeycomb_data(
+ node, "config_vpp_interfaces", data, path)
+
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+ raise HoneycombError(
+ "Configuring IPv4 address failed. "
+ "Status code:{0}".format(status_code))
@staticmethod
def add_ipv4_address(node, interface, ip_addr, network):
:type interface: str
:type ip_addr: str
:type network: str or int
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
+ :raises HoneycombError: If the provided netmask or prefix is not valid.
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
"address")
if isinstance(network, basestring):
- address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
+ address = [{"ip": ip_addr, "netmask": network}]
elif isinstance(network, int) and (0 < network < 33):
- address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
+ address = [{"ip": ip_addr, "prefix-length": network}]
else:
raise HoneycombError("Value {0} is not a valid netmask or network "
"prefix length.".format(network))
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
"address")
return InterfaceKeywords._set_interface_properties(
node, interface, path, None)
- @staticmethod
- def add_first_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
- """Add the first IPv4 neighbour.
-
- If there are any other neighbours configured, they will be removed.
-
- :param node: Honeycomb node.
- :param interface: The name of interface.
- :param ip_addr: IPv4 address of neighbour to be set.
- :param link_layer_address: Link layer address.
- :type node: dict
- :type interface: str
- :type ip_addr: str
- :type link_layer_address: str
- :return: Content of response.
- :rtype: bytearray
- """
-
- path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
- neighbor = {"neighbor": [{"ip": ip_addr,
- "link-layer-address": link_layer_address}, ]}
- return InterfaceKeywords._set_interface_properties(
- node, interface, path, neighbor)
-
@staticmethod
def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
"""Add the IPv4 neighbour.
:type interface: str
:type ip_addr: str
:type link_layer_address: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
"neighbor")
neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
"neighbor")
return InterfaceKeywords._set_interface_properties(
:param interface: The name of interface.
:param param: Parameter to configure (set, change, remove)
:param value: The value of parameter. If None, the parameter will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type param: str
:type value: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
:type interface: str
:type ip_addr: str
:type prefix_len: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
return InterfaceKeywords._set_interface_properties(
:type interface: str
:type ip_addr: str
:type prefix_len: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
"address")
address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
"address")
return InterfaceKeywords._set_interface_properties(
node, interface, path, None)
- @staticmethod
- def add_first_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
- """Add the first IPv6 neighbour.
-
- If there are any other neighbours configured, they will be removed.
-
- :param node: Honeycomb node.
- :param interface: The name of interface.
- :param ip_addr: IPv6 address of neighbour to be set.
- :param link_layer_address: Link layer address.
- :type node: dict
- :type interface: str
- :type ip_addr: str
- :type link_layer_address: str
- :return: Content of response.
- :rtype: bytearray
- """
-
- path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
- neighbor = {"neighbor": [{"ip": ip_addr,
- "link-layer-address": link_layer_address}, ]}
- return InterfaceKeywords._set_interface_properties(
- node, interface, path, neighbor)
-
@staticmethod
def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
"""Add the IPv6 neighbour.
:type interface: str
:type ip_addr: str
:type link_layer_address: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
"neighbor")
neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
"neighbor")
return InterfaceKeywords._set_interface_properties(
:param interface: The name of interface.
:param param: Parameter to configure (set, change, remove)
:param value: The value of parameter. If None, the parameter will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type param: str
:type value: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
:param interface: The name of interface.
:param param: Parameter to configure (set, change, remove)
:param value: The value of parameter. If None, the parameter will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type param: str
:type value: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
+ interface = Topology.convert_interface_reference(
+ node, interface, "name")
+
if param not in InterfaceKeywords.ROUTING_PARAMS:
raise HoneycombError("The parameter {0} is invalid.".format(param))
node, interface, path, value)
@staticmethod
- def create_vxlan_interface(node, interface, **kwargs):
+ def honeycomb_create_vxlan_interface(node, interface, **kwargs):
"""Create a new VxLAN interface.
:param node: Honeycomb node.
:param interface: The name of interface.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.VXLAN_PARAMS.
+ defined in InterfaceKeywords.VXLAN_PARAMS.
:type node: dict
:type interface: str
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
:param interface: The name of interface.
:type node: dict
:type interface: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If it is not possible to get information about
- interfaces or it is not possible to delete the interface.
+ interfaces or it is not possible to delete the interface.
"""
path = ("interfaces", ("interface", "name", interface))
return resp
@staticmethod
- def configure_interface_vxlan(node, interface, **kwargs):
+ def honeycomb_configure_interface_vxlan(node, interface, **kwargs):
"""Configure VxLAN on the interface.
The keyword configures VxLAN parameters on the given interface. The type
:param node: Honeycomb node.
:param interface: The name of interface.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.VXLAN_PARAMS.
+ defined in InterfaceKeywords.VXLAN_PARAMS.
:type node: dict
:type interface: str
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
:param interface: The name of interface.
:param param: Parameter to configure (set, change, remove)
:param value: The value of parameter. If None, the parameter will be
- removed.
+ removed.
:type node: dict
:type interface: str
:type param: str
:type value: str
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
:param node: Honeycomb node.
:param interface: The name of interface.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.TAP_PARAMS.
+ defined in InterfaceKeywords.TAP_PARAMS.
:type node: dict
:type interface: str
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
new_tap = {
"name": interface,
- "type": "v3po:tap",
- "v3po:tap": {}
+ "type": "v3po:tap-v2",
+ "v3po:tap-v2": {}
}
for param, value in kwargs.items():
if param not in InterfaceKeywords.TAP_PARAMS:
- raise HoneycombError("The parameter {0} is invalid.".
- format(param))
- new_tap["v3po:tap"][param] = value
+ raise HoneycombError(
+ "The parameter {0} is invalid.".format(param))
+ new_tap["v3po:tap-v2"][param] = value
path = ("interfaces", "interface")
new_tap_structure = [new_tap, ]
"""Configure TAP on the interface.
The keyword configures TAP parameters on the given interface. The type
- of interface must be set to "v3po:tap".
+ of interface must be set to "v3po:tap-v2".
The new TAP parameters overwrite the current configuration. If a
parameter in new configuration is missing, it is removed from TAP
configuration.
:param node: Honeycomb node.
:param interface: The name of interface.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.TAP_PARAMS.
+ defined in InterfaceKeywords.TAP_PARAMS.
:type node: dict
:type interface: str
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
format(param))
tap_structure[param] = value
- path = ("interfaces", ("interface", "name", interface), "v3po:tap")
+ path = ("interfaces", ("interface", "name", interface), "v3po:tap-v2")
return InterfaceKeywords._set_interface_properties(
node, interface, path, tap_structure)
:param node: Honeycomb node.
:param interface: The name of interface.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.VHOST_USER_PARAMS.
+ defined in InterfaceKeywords.VHOST_USER_PARAMS.
:type node: dict
:type interface: str
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
:param node: Honeycomb node.
:param interface: The name of interface.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.VHOST_USER_PARAMS.
+ defined in InterfaceKeywords.VHOST_USER_PARAMS.
:type node: dict
:type interface: str
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
"""
node, interface, path, new_vhost_structure)
@staticmethod
- def create_sub_interface(node, super_interface, identifier, **kwargs):
+ def honeycomb_create_sub_interface(node, super_interface, match, tags=None,
+ **kwargs):
"""Create a new sub-interface.
:param node: Honeycomb node.
- :param super_interface: The name of super interface.
- :param identifier: sub-interface identifier.
+ :param super_interface: Super interface.
+ :param match: Match type. The valid values are defined in
+ InterfaceKeywords.SUB_IF_MATCH.
+ :param tags: List of tags.
:param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.SUB_INTF_PARAMS.
+ defined in InterfaceKeywords.SUB_IF_PARAMS.
:type node: dict
:type super_interface: str
- :type identifier: int
+ :type match: str
+ :type tags: list
:type kwargs: dict
- :return: Content of response.
+ :returns: Content of response.
:rtype: bytearray
:raises HoneycombError: If the parameter is not valid.
+ :raises KeyError: If the parameter 'match' is invalid.
"""
- # These parameters are empty types (in JSON represented as empty
- # dictionary) but ODL internally represents them as Booleans. If the
- # value is an empty dictionary, it is True, if the parameter is
- # missing, it is False.
- empty_types = ("match-any-outer-id",
- "match-any-inner-id",
- "exact-match",
- "default-subif")
+ super_interface = Topology.convert_interface_reference(
+ node, super_interface, "name")
+
+ match_type = {
+ "default":
+ {"default": {}},
+ "untagged":
+ {"untagged": {}},
+ "vlan-tagged":
+ {"vlan-tagged": {"match-exact-tags": "false"}},
+ "vlan-tagged-exact-match":
+ {"vlan-tagged": {"match-exact-tags": "true"}}
+ }
- sub_interface_name = "{0}.{1}".format(super_interface, str(identifier))
new_sub_interface = {
- "name": sub_interface_name,
- "type": "v3po:sub-interface",
- "enabled": "false",
- "sub-interface": {
- "super-interface": super_interface,
- "identifier": identifier
- }
+ "tags": {
+ "tag": []
+ },
}
+
for param, value in kwargs.items():
- if param in InterfaceKeywords.INTF_PARAMS:
+ if param in InterfaceKeywords.SUB_IF_PARAMS:
new_sub_interface[param] = value
- elif param in InterfaceKeywords.SUB_INTF_PARAMS:
- if param in empty_types:
- if value:
- new_sub_interface["sub-interface"][param] = dict()
- else:
- new_sub_interface["sub-interface"][param] = value
else:
raise HoneycombError("The parameter {0} is invalid.".
format(param))
-
- path = ("interfaces", "interface")
+ try:
+ new_sub_interface["match"] = match_type[match]
+ except KeyError:
+ raise HoneycombError("The value '{0}' of parameter 'match' is "
+ "invalid.".format(match))
+
+ if tags:
+ new_sub_interface["tags"]["tag"].extend(tags)
+
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces",
+ "sub-interface")
new_sub_interface_structure = [new_sub_interface, ]
return InterfaceKeywords._set_interface_properties(
- node, sub_interface_name, path, new_sub_interface_structure)
+ node, super_interface, path, new_sub_interface_structure)
@staticmethod
- def add_vlan_tag_rewrite_to_sub_interface(node, sub_interface, **kwargs):
- """Add vlan tag rewrite to a sub-interface.
+ def get_sub_interface_oper_data(node, super_interface, identifier):
+ """Retrieves sub-interface operational data using Honeycomb API.
:param node: Honeycomb node.
- :param sub_interface: The name of sub-interface.
- :param kwargs: Parameters and their values. The accepted parameters are
- defined in InterfaceKeywords.L2_REWRITE_TAG_PARAMS.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
:type node: dict
- :type sub_interface: str
- :type kwargs: dict
- :return: Content of response.
+ :type super_interface: str
+ :type identifier: int
+ :returns: Sub-interface operational data.
+ :rtype: dict
+ :raises HoneycombError: If there is no sub-interface with the given ID.
+ """
+
+ if_data = InterfaceKeywords.get_interface_oper_data(node,
+ super_interface)
+ for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
+ if str(sub_if["identifier"]) == str(identifier):
+ return sub_if
+
+ raise HoneycombError("The interface {0} does not have sub-interface "
+ "with ID {1}".format(super_interface, identifier))
+
+ @staticmethod
+ def remove_all_sub_interfaces(node, super_interface):
+ """Remove all sub-interfaces from the given interface.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :type node: dict
+ :type super_interface: str
+ :returns: Content of response.
:rtype: bytearray
- :raises HoneycombError: If the parameter is not valid.
"""
- new_rewrite = dict()
- for param, value in kwargs.items():
- if param in InterfaceKeywords.L2_REWRITE_TAG_PARAMS:
- new_rewrite[param] = value
- else:
- raise HoneycombError("The parameter {0} is invalid.".
- format(param))
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces")
- path = ("interfaces", ("interface", "name", sub_interface), "v3po:l2",
- "vlan-tag-rewrite")
return InterfaceKeywords._set_interface_properties(
- node, sub_interface, path, new_rewrite)
+ node, super_interface, path, {})
@staticmethod
- def remove_vlan_tag_rewrite_from_sub_interface(node, sub_interface):
- """Remove vlan tag rewrite from a sub-interface.
+ def set_sub_interface_state(node, super_interface, identifier, state):
+ """Set the administrative state of sub-interface.
:param node: Honeycomb node.
- :param sub_interface: The name of sub-interface.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :param state: Required sub-interface state - up or down.
:type node: dict
- :type sub_interface: str
+ :type super_interface: str
+ :type identifier: int
+ :type state: str
+ :returns: Content of response.
:rtype: bytearray
- :raises HoneycombError: If the parameter is not valid.
"""
- path = ("interfaces", ("interface", "name", sub_interface), "v3po:l2",
- "vlan-tag-rewrite")
+ super_interface = Topology.convert_interface_reference(
+ node, super_interface, "name")
+
+ intf_state = {"up": "true",
+ "down": "false"}
+
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces",
+ ("sub-interface", "identifier", int(identifier)),
+ "enabled")
+
+ return InterfaceKeywords._set_interface_properties(
+ node, super_interface, path, intf_state[state])
+
+ @staticmethod
+ def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
+ config):
+ """Add a sub-interface to a bridge domain and set its parameters.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :param config: Bridge domain configuration.
+ :type node: dict
+ :type super_interface: str
+ :type identifier: int
+ :type config: dict
+ :returns: Content of response.
+ :rtype: bytearray
+ """
+
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces",
+ ("sub-interface", "identifier", int(identifier)),
+ "l2")
+
+ return InterfaceKeywords._set_interface_properties(
+ node, super_interface, path, config)
+
+ @staticmethod
+ def get_bd_data_from_sub_interface(node, super_interface, identifier):
+ """Get the operational data about the bridge domain from sub-interface.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :type node: dict
+ :type super_interface: str
+ :type identifier: int
+ :returns: Operational data about the bridge domain.
+ :rtype: dict
+ :raises HoneycombError: If there is no sub-interface with the given ID.
+ """
+
+ try:
+ bd_data = InterfaceKeywords.get_sub_interface_oper_data(
+ node, super_interface, identifier)["l2"]
+ return bd_data
+ except KeyError:
+ raise HoneycombError("The operational data does not contain "
+ "information about a bridge domain.")
+
+ @staticmethod
+ def configure_tag_rewrite(node, super_interface, identifier, config):
+ """Add / change / disable vlan tag rewrite on a sub-interface.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :param config: Rewrite tag configuration.
+ :type node: dict
+ :type super_interface: str
+ :type identifier: int
+ :type config: dict
+ :returns: Content of response.
+ :rtype: bytearray
+ """
+
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces",
+ ("sub-interface", "identifier", int(identifier)),
+ "l2",
+ "rewrite")
+
+ return InterfaceKeywords._set_interface_properties(
+ node, super_interface, path, config)
+
+ @staticmethod
+ def get_tag_rewrite_oper_data(node, super_interface, identifier):
+ """Get the operational data about tag rewrite.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :type node: dict
+ :type super_interface: str
+ :type identifier: int
+ :returns: Operational data about tag rewrite.
+ :rtype: dict
+ :raises HoneycombError: If there is no sub-interface with the given ID.
+ """
+
+ try:
+ tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
+ node, super_interface, identifier)["l2"]["rewrite"]
+ return tag_rewrite
+ except KeyError:
+ raise HoneycombError("The operational data does not contain "
+ "information about the tag-rewrite.")
+
+ @staticmethod
+ def add_ip_address_to_sub_interface(node, super_interface, identifier,
+ ip_addr, network, ip_version):
+ """Add an ipv4 address to the specified sub-interface, with the provided
+ netmask or network prefix length. Any existing ipv4 addresses on the
+ sub-interface will be replaced.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :param ip_addr: IPv4 address to be set.
+ :param network: Network mask or network prefix length.
+ :param ip_version: ipv4 or ipv6
+ :type node: dict
+ :type super_interface: str
+ :type identifier: int
+ :type ip_addr: str
+ :type network: str or int
+ :type ip_version: string
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If the provided netmask or prefix is not valid.
+ """
+
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces",
+ ("sub-interface", "identifier", int(identifier)),
+ ip_version.lower())
+
+ if isinstance(network, basestring) and ip_version.lower() == "ipv4":
+ address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
+
+ elif isinstance(network, int) and 0 < network < 33:
+ address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
+
+ else:
+ raise HoneycombError("{0} is not a valid netmask or prefix length."
+ .format(network))
+
return InterfaceKeywords._set_interface_properties(
- node, sub_interface, path, None)
+ node, super_interface, path, address)
+
+ @staticmethod
+ def remove_all_ip_addresses_from_sub_interface(node, super_interface,
+ identifier, ip_version):
+ """Remove all ipv4 addresses from the specified sub-interface.
+
+ :param node: Honeycomb node.
+ :param super_interface: Super interface.
+ :param identifier: The ID of sub-interface.
+ :param ip_version: ipv4 or ipv6
+ :type node: dict
+ :type super_interface: str
+ :type identifier: int
+ :type ip_version: string
+ :returns: Content of response.
+ :rtype: bytearray
+ """
+
+ path = ("interfaces",
+ ("interface", "name", super_interface),
+ "vpp-vlan:sub-interfaces",
+ ("sub-interface", "identifier", int(identifier)),
+ str(ip_version), "address")
+
+ return InterfaceKeywords._set_interface_properties(
+ node, super_interface, path, None)
+
+ @staticmethod
+ def compare_data_structures(data, ref, _path=''):
+ """Checks if data obtained from UUT is as expected. If it is not,
+ proceeds down the list/dictionary tree and finds the point of mismatch.
+
+ :param data: Data to be checked.
+ :param ref: Referential data used for comparison.
+ :param _path: Used in recursive calls, stores the path taken down
+ the JSON tree.
+ :type data: dict
+ :type ref: dict
+ :type _path: str
+
+ :raises HoneycombError: If the data structures do not match in some way,
+ or if they are not in deserialized JSON format.
+ """
+
+ if data == ref:
+ return True
+
+ elif isinstance(data, dict) and isinstance(ref, dict):
+ for key in ref:
+ if key not in data:
+ raise HoneycombError(
+ "Key {key} is not present in path {path}. Keys in path:"
+ "{data_keys}".format(
+ key=key,
+ path=_path,
+ data_keys=data.keys()))
+
+ if data[key] != ref[key]:
+ if isinstance(data[key], list) \
+ or isinstance(data[key], dict):
+ InterfaceKeywords.compare_data_structures(
+ data[key], ref[key],
+ _path + '[{0}]'.format(key))
+ else:
+ raise HoneycombError(
+ "Data mismatch, key {key} in path {path} has value"
+ " {data}, but should be {ref}".format(
+ key=key,
+ path=_path,
+ data=data[key],
+ ref=ref[key]))
+
+ elif isinstance(data, list) and isinstance(ref, list):
+ for item in ref:
+ if item not in data:
+ if isinstance(item, dict):
+ InterfaceKeywords.compare_data_structures(
+ data[0], item,
+ _path + '[{0}]'.format(ref.index(item)))
+ else:
+ raise HoneycombError(
+ "Data mismatch, list item {index} in path {path}"
+ " has value {data}, but should be {ref}".format(
+ index=ref.index(item),
+ path=_path,
+ data=data[0],
+ ref=item))
+
+ else:
+ raise HoneycombError(
+ "Unexpected data type {data_type} in path {path}, reference"
+ " type is {ref_type}. Must be list or dictionary.".format(
+ data_type=type(data),
+ ref_type=type(ref),
+ path=_path))
@staticmethod
def compare_interface_lists(list1, list2):
if name not in names1 and name not in ignore:
raise HoneycombError("Interface {0} not present in list {1}"
.format(name, list1))
+
+ @staticmethod
+ def create_vxlan_gpe_interface(node, interface, **kwargs):
+ """Create a new VxLAN GPE interface.
+
+ :param node: Honeycomb node.
+ :param interface: The name of interface to be created.
+ :param kwargs: Parameters and their values. The accepted parameters are
+ defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
+ :type node: dict
+ :type interface: str
+ :type kwargs: dict
+ :returns: Content of response.
+ :rtype: bytearray
+ :raises HoneycombError: If a parameter in kwargs is not valid.
+ """
+
+ new_vxlan_gpe = {
+ "name": interface,
+ "type": "v3po:vxlan-gpe-tunnel",
+ "v3po:vxlan-gpe": {}
+ }
+ for param, value in kwargs.items():
+ if param in InterfaceKeywords.INTF_PARAMS:
+ new_vxlan_gpe[param] = value
+ elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
+ new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
+ else:
+ raise HoneycombError("The parameter {0} is invalid.".
+ format(param))
+ path = ("interfaces", "interface")
+ vxlan_gpe_structure = [new_vxlan_gpe, ]
+ return InterfaceKeywords._set_interface_properties(
+ node, interface, path, vxlan_gpe_structure)
+
+ @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