X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2Fhoneycomb%2FHcAPIKwInterfaces.py;h=09c9ae9a3b32108bc8bf11355cd23fb84ad37bf7;hp=3351ebf5d34f6426e6bfb8fe03d262adc13c81d8;hb=0513ce5642dcf58b21f9b77d6b50e4e9a7a94f04;hpb=38722703b8ca56a334c6fc77b2cfab9d16c978f9 diff --git a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py index 3351ebf5d3..09c9ae9a3b 100644 --- a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py +++ b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py @@ -201,6 +201,16 @@ class InterfaceKeywords(object): :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: @@ -242,7 +252,7 @@ class InterfaceKeywords(object): 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 @@ -300,7 +310,8 @@ class InterfaceKeywords(object): :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): @@ -314,7 +325,8 @@ class InterfaceKeywords(object): :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, @@ -473,22 +485,32 @@ class InterfaceKeywords(object): :type network: str or int :returns: Content of response. :rtype: bytearray - :raises HoneycombError: If the provided netmask or prefix is not valid. + :raises ValueError: If the provided netmask or prefix is not valid. + :raises HoneycombError: If the operation fails. """ - interface = Topology.convert_interface_reference( - node, interface, "name") + interface = InterfaceKeywords.handle_interface_reference( + node, interface) - path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4") + 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): @@ -534,6 +556,9 @@ class InterfaceKeywords(object): :rtype: bytearray """ + interface = Topology.convert_interface_reference( + node, interface, "name") + path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4", "address") return InterfaceKeywords._set_interface_properties( @@ -576,6 +601,9 @@ class InterfaceKeywords(object): :rtype: bytearray """ + interface = Topology.convert_interface_reference( + node, interface, "name") + path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4", "neighbor") return InterfaceKeywords._set_interface_properties( @@ -653,6 +681,9 @@ class InterfaceKeywords(object): :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}, ] @@ -671,6 +702,9 @@ class InterfaceKeywords(object): :rtype: bytearray """ + interface = Topology.convert_interface_reference( + node, interface, "name") + path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6", "address") return InterfaceKeywords._set_interface_properties( @@ -713,6 +747,9 @@ class InterfaceKeywords(object): :rtype: bytearray """ + interface = Topology.convert_interface_reference( + node, interface, "name") + path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6", "neighbor") return InterfaceKeywords._set_interface_properties( @@ -773,7 +810,7 @@ class InterfaceKeywords(object): 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. @@ -837,7 +874,7 @@ class InterfaceKeywords(object): 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 @@ -1029,7 +1066,8 @@ class InterfaceKeywords(object): node, interface, path, new_vhost_structure) @staticmethod - def create_sub_interface(node, super_interface, match, tags=None, **kwargs): + def honeycomb_create_sub_interface(node, super_interface, match, tags=None, + **kwargs): """Create a new sub-interface. :param node: Honeycomb node. @@ -1050,6 +1088,9 @@ class InterfaceKeywords(object): :raises KeyError: If the parameter 'match' is invalid. """ + super_interface = Topology.convert_interface_reference( + node, super_interface, "name") + match_type = { "default": {"default": {}}, @@ -1149,6 +1190,9 @@ class InterfaceKeywords(object): :rtype: bytearray """ + super_interface = Topology.convert_interface_reference( + node, super_interface, "name") + intf_state = {"up": "true", "down": "false"} @@ -1498,6 +1542,67 @@ class InterfaceKeywords(object): "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. @@ -1544,7 +1649,7 @@ class InterfaceKeywords(object): """ interface = intf.replace("/", "%2F") - path = "/interface/{0}/pbb-rewrite/".format(interface) + path = "/interface/{0}/pbb-rewrite".format(interface) status_code, resp = HcUtil. \ put_honeycomb_data(node, "config_vpp_interfaces", params, path, data_representation=DataRepresentation.JSON) @@ -1622,7 +1727,7 @@ class InterfaceKeywords(object): " of disabled interfaces.".format(interface)) @staticmethod - def configure_interface_span(node, dst_interface, *src_interfaces): + 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. @@ -1630,30 +1735,88 @@ class InterfaceKeywords(object): :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 + :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 = dst_interface.replace("/", "%2F") + 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 + } + } + } - 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) + status_code, _ = HcUtil.put_honeycomb_data( + node, "config_vpp_interfaces", data, path) if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED): raise HoneycombError( @@ -1672,3 +1835,72 @@ class InterfaceKeywords(object): 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