X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2Fhoneycomb%2FHcAPIKwInterfaces.py;h=e9ef13352bf08311a56adecc1afd0a179985a94f;hp=e78696cd1516b9344de59111c66d22c392709292;hb=67f247b4015b76641c6fab7c49e7d9862043c856;hpb=fa14d9f454a7248a71135375bfb0758cdb532ca7 diff --git a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py index e78696cd15..e9ef13352b 100644 --- a/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py +++ b/resources/libraries/python/honeycomb/HcAPIKwInterfaces.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 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: @@ -18,13 +18,13 @@ operational data. """ from robot.api import logger -from resources.libraries.python.topology import Topology from resources.libraries.python.HTTPRequest import HTTPCodes from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError from resources.libraries.python.honeycomb.HoneycombUtil \ import DataRepresentation from resources.libraries.python.honeycomb.HoneycombUtil \ import HoneycombUtil as HcUtil +from resources.libraries.python.topology import Topology class InterfaceKeywords(object): @@ -48,7 +48,10 @@ class InterfaceKeywords(object): VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id") L2_PARAMS = ("bridge-domain", "split-horizon-group", "bridged-virtual-interface") - 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_IF_PARAMS = ("identifier", "vlan-type", @@ -86,7 +89,7 @@ class InterfaceKeywords(object): :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.\ @@ -228,7 +231,7 @@ class InterfaceKeywords(object): :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 @@ -252,7 +255,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 @@ -261,7 +264,7 @@ class InterfaceKeywords(object): :param node: Honeycomb node. :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 @@ -310,7 +313,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): @@ -324,7 +328,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, @@ -368,7 +373,6 @@ class InterfaceKeywords(object): :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. """ @@ -400,7 +404,7 @@ class InterfaceKeywords(object): :type node: dict :type interface: str :returns: Operational data about bridge domain settings in the - interface. + interface. :rtype: dict """ @@ -421,7 +425,7 @@ class InterfaceKeywords(object): :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 @@ -446,7 +450,7 @@ class InterfaceKeywords(object): :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 @@ -483,22 +487,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): @@ -544,6 +558,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( @@ -586,6 +603,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( @@ -599,7 +619,7 @@ class InterfaceKeywords(object): :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 @@ -684,6 +704,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( @@ -726,6 +749,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( @@ -739,7 +765,7 @@ class InterfaceKeywords(object): :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 @@ -764,7 +790,7 @@ class InterfaceKeywords(object): :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 @@ -786,13 +812,13 @@ 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. :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 @@ -828,7 +854,7 @@ class InterfaceKeywords(object): :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)) @@ -850,7 +876,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 @@ -863,7 +889,7 @@ class InterfaceKeywords(object): :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 @@ -891,7 +917,7 @@ class InterfaceKeywords(object): :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 @@ -915,7 +941,7 @@ class InterfaceKeywords(object): :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 @@ -926,14 +952,14 @@ class InterfaceKeywords(object): 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, ] @@ -945,7 +971,7 @@ class InterfaceKeywords(object): """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. @@ -954,7 +980,7 @@ class InterfaceKeywords(object): :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 @@ -970,7 +996,7 @@ class InterfaceKeywords(object): 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) @@ -988,7 +1014,7 @@ class InterfaceKeywords(object): :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 @@ -1016,7 +1042,7 @@ class InterfaceKeywords(object): :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 @@ -1042,16 +1068,17 @@ 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. :param super_interface: Super interface. :param match: Match type. The valid values are defined in - InterfaceKeywords.SUB_IF_MATCH. + InterfaceKeywords.SUB_IF_MATCH. :param tags: List of tags. :param kwargs: Parameters and their values. The accepted parameters are - defined in InterfaceKeywords.SUB_IF_PARAMS. + defined in InterfaceKeywords.SUB_IF_PARAMS. :type node: dict :type super_interface: str :type match: str @@ -1063,6 +1090,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": {}}, @@ -1352,13 +1382,13 @@ class InterfaceKeywords(object): :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. + 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. + or if they are not in deserialized JSON format. """ if data == ref: @@ -1446,7 +1476,7 @@ class InterfaceKeywords(object): :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. + defined in InterfaceKeywords.VXLAN_GPE_PARAMS. :type node: dict :type interface: str :type kwargs: dict @@ -1486,7 +1516,7 @@ class InterfaceKeywords(object): :returns: Content of response. :rtype: bytearray :raises HoneycombError: If the configuration of interface is not - successful. + successful. """ interface = interface.replace("/", "%2F") @@ -1527,7 +1557,7 @@ class InterfaceKeywords(object): :returns: Content of response. :rtype: bytearray :raises HoneycombError: If the configuration of interface is not - successful. + successful. """ interface = Topology.convert_interface_reference( node, interface, "name") @@ -1555,14 +1585,12 @@ class InterfaceKeywords(object): :param node: Honeycomb node. :param interface: The interface where policer will be disabled. - :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. + successful. """ interface = Topology.convert_interface_reference( node, interface, "name") @@ -1588,7 +1616,7 @@ class InterfaceKeywords(object): :returns: Content of response. :rtype: bytearray :raises HoneycombError: If the configuration of interface is not - successful. + successful. """ interface = interface.replace("/", "%2F") @@ -1612,14 +1640,14 @@ class InterfaceKeywords(object): :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. + 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. + successful. """ interface = intf.replace("/", "%2F") @@ -1644,7 +1672,7 @@ class InterfaceKeywords(object): :returns: Content of response. :rtype: bytearray :raises HoneycombError: If the removal of sub-interface is not - successful. + successful. """ interface = intf.replace("/", "%2F") @@ -1671,7 +1699,7 @@ class InterfaceKeywords(object): :returns: PBB sub-interface operational data. :rtype: dict :raises HoneycombError: If the removal of sub-interface is not - successful. + successful. """ raise NotImplementedError @@ -1688,8 +1716,8 @@ class InterfaceKeywords(object): :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. - """ + 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 @@ -1754,7 +1782,7 @@ class InterfaceKeywords(object): :param node: Honeycomb node. :param super_interface: Name, link name or sw_if_index - of the destination interface's super-interface. + 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 @@ -1780,7 +1808,7 @@ class InterfaceKeywords(object): for src_interface in src_interfaces: src_interface["iface-ref"] = Topology. \ convert_interface_reference( - node, src_interface["iface-ref"], "name") + node, src_interface["iface-ref"], "name") data = { "span": { "mirrored-interfaces": { @@ -1809,3 +1837,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