INMARSAT-54 Honeycomb configures PBB
[csit.git] / resources / libraries / python / honeycomb / HcAPIKwInterfaces.py
index afd6076..fdb9b90 100644 (file)
@@ -237,9 +237,26 @@ class InterfaceKeywords(object):
         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()])
+        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 != HTTPCodes.OK:
+            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):
@@ -307,8 +324,8 @@ class InterfaceKeywords(object):
 
         :param node: Honeycomb node.
         :param interface: The name of interface.
+        :type node: dict
         :type interface: str
-        :type param: str
         :return: Operational data about bridge domain settings in the
         interface.
         :rtype: dict
@@ -390,6 +407,7 @@ class InterfaceKeywords(object):
         :type network: str or int
         :return: Content of response.
         :rtype: bytearray
+        :raises HoneycombError: If the provided netmask or prefix is not valid.
         """
 
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
@@ -417,6 +435,7 @@ class InterfaceKeywords(object):
         :type network: str or int
         :return: Content of response.
         :rtype: bytearray
+        :raises HoneycombError: If the provided netmask or prefix is not valid.
         """
 
         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
@@ -448,30 +467,6 @@ class InterfaceKeywords(object):
         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.
@@ -603,30 +598,6 @@ class InterfaceKeywords(object):
         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.
@@ -1205,27 +1176,101 @@ class InterfaceKeywords(object):
                                  "information about the tag-rewrite.")
 
     @staticmethod
-    def compare_data_structures(data, ref):
+    def add_ipv4_address_to_sub_interface(node, super_interface, identifier,
+                                          ip_addr, network):
+        """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.
+        :type node: dict
+        :type super_interface: str
+        :type identifier: int
+        :type ip_addr: str
+        :type network: str or int
+        :return: 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)),
+                "ipv4")
+
+        if isinstance(network, basestring):
+            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, super_interface, path, address)
+
+    @staticmethod
+    def remove_all_ipv4_addresses_from_sub_interface(node, super_interface, # pylint: disable=invalid-name
+                                                     identifier):
+        """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.
+        :type node: dict
+        :type super_interface: str
+        :type identifier: int
+        :return: Content of response.
+        :rtype: bytearray
+        """
+
+        path = ("interfaces",
+                ("interface", "name", super_interface),
+                "vpp-vlan:sub-interfaces",
+                ("sub-interface", "identifier", int(identifier)),
+                "ipv4", "address")
+
+        return InterfaceKeywords._set_interface_properties(
+            node, super_interface, path, None)
+
+    @staticmethod
+    def compare_data_structures(data, ref, ignore=()):
         """Checks if data obtained from UUT is as expected.
 
         :param data: Data to be checked.
         :param ref: Referential data used for comparison.
+        :param ignore: Dictionary keys to be ignored.
         :type data: dict
         :type ref: dict
+        :type ignore: iterable
         :raises HoneycombError: If a parameter from referential data is not
         present in operational data or if it has different value.
         """
 
+        errors = ""
+
         for key, item in ref.items():
+            if key in ignore:
+                continue
             try:
                 if data[key] != item:
-                    raise HoneycombError("The value of parameter '{0}' is "
-                                         "incorrect. It should be "
-                                         "'{1}' but it is '{2}'".
-                                         format(key, item, data[key]))
+                    errors += ("\nThe value of parameter '{0}' is "
+                               "incorrect. It should be "
+                               "'{1}' but it is '{2}'".
+                               format(key, item, data[key]))
             except KeyError:
-                raise HoneycombError("The parameter '{0}' is not present in "
-                                     "operational data".format(key))
+                errors += ("\nThe parameter '{0}' is not present in "
+                           "operational data".format(key))
+
+        if errors:
+            raise HoneycombError(errors)
 
     @staticmethod
     def compare_interface_lists(list1, list2):
@@ -1286,3 +1331,148 @@ class InterfaceKeywords(object):
         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
+        :return: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+        successful.
+        """
+
+        interface = interface.replace("/", "%2F")
+
+        data = {
+            "v3po:acl": {
+                "l2-acl": {
+                    "classify-table": table_name
+                },
+                "ip4-acl": {
+                    "classify-table": table_name
+                }
+            }
+        }
+
+        path = "/interface/" + interface + "/v3po:acl"
+        status_code, resp = HcUtil.\
+            put_honeycomb_data(node, "config_vpp_interfaces", data, path,
+                               data_representation=DataRepresentation.JSON)
+        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
+        :return: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of interface is not
+        successful.
+        """
+
+        interface = interface.replace("/", "%2F")
+
+        path = "/interface/" + interface + "/v3po: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, sub_if_id, 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 sub_if_id: Sub-interface ID.
+        :param params: Configuration parameters of the sub-interface to be
+        created.
+        :type node: dict
+        :type intf: str
+        :type sub_if_id: str or int
+        :type params: dict
+        :return: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the configuration of sub-interface is not
+        successful.
+        """
+
+        interface = intf.replace("/", "%2F")
+        path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
+               "{1}".format(interface, sub_if_id)
+        status_code, resp = HcUtil. \
+            put_honeycomb_data(node, "config_vpp_interfaces", params, path,
+                               data_representation=DataRepresentation.JSON)
+        if status_code != HTTPCodes.OK:
+            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, sub_if_id):
+        """Deletes the given PBB sub-interface.
+
+        :param node: Honeycomb node.
+        :param intf: The interface where PBB sub-interface will be deleted.
+        :param sub_if_id: ID of the PBB sub-interface to be deleted.
+        :type node: dict
+        :type intf: str
+        :type sub_if_id: str or int
+        :return: Content of response.
+        :rtype: bytearray
+        :raises HoneycombError: If the removal of sub-interface is not
+        successful.
+        """
+
+        interface = intf.replace("/", "%2F")
+        path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
+               "{1}".format(interface, sub_if_id)
+
+        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
+        :return: PBB sub-interface operational data.
+        :rtype: dict
+        :raises HoneycombError: If the removal of sub-interface is not
+        successful.
+        """
+
+        interface = "{0}.{1}".format(intf, sub_if_id)
+        return InterfaceKeywords.get_interface_oper_data(node, interface)