"""This module implements keywords to manipulate ACL data structures using
Honeycomb REST API."""
+from robot.api import logger
from resources.libraries.python.topology import Topology
from resources.libraries.python.HTTPRequest import HTTPCodes
status_code, resp = HcUtil.\
delete_honeycomb_data(node, "config_classify_table", path)
- if status_code != HTTPCodes.OK:
- raise HoneycombError(
- "The configuration of classify table was not successful. "
- "Status code: {0}.".format(status_code))
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
+ if data is None and '"error-tag":"data-missing"' in resp:
+ logger.debug("data does not exist in path.")
+ else:
+ raise HoneycombError(
+ "The configuration of classify table was not successful. "
+ "Status code: {0}.".format(status_code))
return resp
@staticmethod
:rtype: bytearray
:raises HoneycombError: If the operation fails.
"""
- if layer.lower() == "l2":
- suffix = "eth"
- elif layer.lower() in ("l3_ip4", "l3_ip6", "l4"):
- raise NotImplementedError
- else:
+ layer = layer.lower()
+ suffix_dict = {"l2": "eth",
+ "l3_ip4": "ipv4",
+ "l3_ip6": "ipv6",
+ "mixed": "mixed"}
+ try:
+ suffix = suffix_dict[layer]
+ except KeyError:
raise ValueError("Unexpected value of layer argument {0}."
- "Valid options are: L2, L3_IP4, L3_IP6, L4."
- .format(layer))
+ "Valid options are: {1}"
+ .format(layer, suffix_dict.keys()))
+
+ if layer == "mixed":
+ path = "/acl/vpp-acl:{0}-acl/{1}"
+ else:
+ path = "/acl/ietf-access-control-list:{0}-acl/{1}"
- path = "/acl/ietf-access-control-list:{0}-acl/{1}".format(
- suffix, list_name)
+ path = path.format(suffix, list_name)
status_code, resp = HcUtil.put_honeycomb_data(
node, "config_ietf_classify_chain", data, path)
- if status_code != HTTPCodes.OK:
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
raise HoneycombError(
"Could not create classify chain."
"Status code: {0}.".format(status_code))
@staticmethod
def set_ietf_interface_acl(node, interface, layer, direction, list_name,
- default_action):
+ default_action, mode=None):
"""Assign an interface to an ietf-acl classify chain.
:param node: Honeycomb node.
Valid options are: ingress, egress
:param list_name: Name of an ietf-acl classify chain.
:param default_action: Default classifier action: permit or deny.
+ :param mode: When using mixed layers, this specifies operational mode
+ of the interface - L2 or L3. If layer is not "mixed", this argument
+ will be ignored.
:type node: dict
:type interface: str or int
:type layer: str
:type direction: str
:type list_name: str
:type default_action: str
+ :type mode: str
:return: Content of response.
:rtype: bytearray
:raises HoneycombError: If the operation fails.
"""
+ layer = layer.lower()
+ if mode is not None:
+ mode = mode.lower()
interface = Topology.convert_interface_reference(
node, interface, "name")
path = "/interface/{0}/ietf-acl/{1}/access-lists".format(
interface, direction)
- data = {
+ types = {
+ "ietf": "ietf-access-control-list:{0}-acl",
+ "vpp": "vpp-acl:{0}-acl"}
+ layers = {
+ "l2": {"mode": "l2", "acl_type": types['ietf'].format("eth")},
+ "l3_ip4": {"mode": "l3", "acl_type": types['ietf'].format("ipv4")},
+ "l3_ip6": {"mode": "l3", "acl_type": types['ietf'].format("ipv6")},
+ "mixed": {"mode": mode, "acl_type": types['vpp'].format("mixed")}
+ }
+
+ try:
+ data = {
"access-lists": {
- "acl": [{
- "type": None,
- "name": list_name
- }],
+ "acl": [
+ {
+ "type": layers[layer]['acl_type'],
+ "name": list_name
+ }
+ ],
"default-action": default_action,
- "mode": None
- }
+ "mode": layers[layer]['mode']
}
-
- acl_type = "ietf-access-control-list:{suffix}-acl"
-
- if layer.lower() == "l2":
- data["access-lists"]["mode"] = "l2"
- data["access-lists"]["acl"][0]["type"] = \
- acl_type.format(suffix="eth")
-
- elif layer.lower() in ("l3_ip4", "l3_ip6", "L4"):
- raise NotImplementedError
- else:
+ }
+ except KeyError:
raise ValueError("Unknown network layer {0}. "
- "Valid options are: "
- "L2, L3_IP4, L3_IP6, L4.".format(layer))
+ "Valid options are: {1}".
+ format(layer, layers.keys()))
status_code, resp = HcUtil.put_honeycomb_data(
node, "config_vpp_interfaces", data, path)
- if status_code != HTTPCodes.OK:
+ if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
raise HoneycombError(
"Could not configure ACL on interface. "
"Status code: {0}.".format(status_code))