1 # Copyright (c) 2017 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Keywords to manipulate interface configuration using Honeycomb REST API.
16 The keywords make possible to put and get configuration data and to get
19 from robot.api import logger
21 from resources.libraries.python.topology import Topology
22 from resources.libraries.python.HTTPRequest import HTTPCodes
23 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
24 from resources.libraries.python.honeycomb.HoneycombUtil \
25 import DataRepresentation
26 from resources.libraries.python.honeycomb.HoneycombUtil \
27 import HoneycombUtil as HcUtil
30 class InterfaceKeywords(object):
31 """Keywords for Interface manipulation.
33 Implements keywords which get configuration and operational data about
34 vpp interfaces and set the interface's parameters using Honeycomb REST API.
37 INTF_PARAMS = ("name", "description", "type", "enabled",
38 "link-up-down-trap-enable", "v3po:l2", "v3po:vxlan-gpe",
39 "vpp-vlan:sub-interfaces")
40 IPV4_PARAMS = ("enabled", "forwarding", "mtu")
41 IPV6_PARAMS = ("enabled", "forwarding", "mtu", "dup-addr-detect-transmits")
42 IPV6_AUTOCONF_PARAMS = ("create-global-addresses",
43 "create-temporary-addresses",
44 "temporary-valid-lifetime",
45 "temporary-preferred-lifetime")
46 ETH_PARAMS = ("mtu", )
47 ROUTING_PARAMS = ("ipv4-vrf-id", "ipv6-vrf-id")
48 VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
49 L2_PARAMS = ("bridge-domain", "split-horizon-group",
50 "bridged-virtual-interface")
51 TAP_PARAMS = ("tap-name", "mac", "device-instance")
52 VHOST_USER_PARAMS = ("socket", "role")
53 SUB_IF_PARAMS = ("identifier",
56 SUB_IF_MATCH = ("default",
59 "vlan-tagged-exact-match")
60 BD_PARAMS = ("bridge-domain",
61 "split-horizon-group",
62 "bridged-virtual-interface")
63 VXLAN_GPE_PARAMS = ("local",
74 def _configure_interface(node, interface, data,
75 data_representation=DataRepresentation.JSON):
76 """Send interface configuration data and check the response.
78 :param node: Honeycomb node.
79 :param interface: The name of interface.
80 :param data: Configuration data to be sent in PUT request.
81 :param data_representation: How the data is represented.
85 :type data_representation: DataRepresentation
86 :returns: Content of response.
88 :raises HoneycombError: If the status code in response on PUT is not
92 status_code, resp = HcUtil.\
93 put_honeycomb_data(node, "config_vpp_interfaces", data,
94 data_representation=data_representation)
95 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
97 "The configuration of interface '{0}' was not successful. "
98 "Status code: {1}.".format(interface, status_code))
102 def get_all_interfaces_cfg_data(node):
103 """Get configuration data about all interfaces from Honeycomb.
105 :param node: Honeycomb node.
107 :returns: Configuration data about all interfaces from Honeycomb.
109 :raises HoneycombError: If it is not possible to get configuration data.
112 status_code, resp = HcUtil.\
113 get_honeycomb_data(node, "config_vpp_interfaces")
114 if status_code != HTTPCodes.OK:
115 raise HoneycombError(
116 "Not possible to get configuration information about the "
117 "interfaces. Status code: {0}.".format(status_code))
119 return resp["interfaces"]["interface"]
121 except (KeyError, TypeError):
125 def get_interface_cfg_data(node, interface):
126 """Get configuration data about the given interface from Honeycomb.
128 :param node: Honeycomb node.
129 :param interface: The name of interface.
132 :returns: Configuration data about the given interface from Honeycomb.
136 intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
138 if intf["name"] == interface:
143 def get_all_interfaces_oper_data(node):
144 """Get operational data about all interfaces from Honeycomb.
146 :param node: Honeycomb node.
148 :returns: Operational data about all interfaces from Honeycomb.
150 :raises HoneycombError: If it is not possible to get operational data.
153 status_code, resp = HcUtil.\
154 get_honeycomb_data(node, "oper_vpp_interfaces")
155 if status_code != HTTPCodes.OK:
156 raise HoneycombError(
157 "Not possible to get operational information about the "
158 "interfaces. Status code: {0}.".format(status_code))
160 return resp["interfaces-state"]["interface"]
162 except (KeyError, TypeError):
166 def get_disabled_interfaces_oper_data(node):
167 """Get operational data about all disabled interfaces from Honeycomb.
169 :param node: Honeycomb node.
171 :returns: Operational data about disabled interfaces.
173 :raises HoneycombError: If it is not possible to get operational data.
176 status_code, resp = HcUtil. \
177 get_honeycomb_data(node, "oper_disabled_interfaces")
178 if status_code == HTTPCodes.NOT_FOUND:
179 raise HoneycombError(
180 "No disabled interfaces present on node."
182 if status_code != HTTPCodes.OK:
183 raise HoneycombError(
184 "Not possible to get operational information about the "
185 "interfaces. Status code: {0}.".format(status_code))
187 return resp["disabled-interfaces"]["disabled-interface-index"]
189 except (KeyError, TypeError):
193 def get_interface_oper_data(node, interface):
194 """Get operational data about the given interface from Honeycomb.
196 :param node: Honeycomb node.
197 :param interface: The name of interface.
200 :returns: Operational data about the given interface from Honeycomb.
205 interface = Topology.convert_interface_reference(
206 node, interface, "name")
208 if isinstance(interface, basestring):
209 # Probably name of a custom interface (TAP, VxLAN, Vhost, ...)
214 intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
216 if intf["name"] == interface:
221 def _set_interface_properties(node, interface, path, new_value=None):
222 """Set interface properties.
224 This method reads interface configuration data, creates, changes or
225 removes the requested data and puts it back to Honeycomb.
227 :param node: Honeycomb node.
228 :param interface: The name of interface.
229 :param path: Path to data we want to change / create / remove.
230 :param new_value: The new value to be set. If None, the item will be
235 :type new_value: str, dict or list
236 :returns: Content of response.
238 :raises HoneycombError: If it is not possible to get or set the data.
241 status_code, resp = HcUtil.\
242 get_honeycomb_data(node, "config_vpp_interfaces")
243 if status_code != HTTPCodes.OK:
244 raise HoneycombError(
245 "Not possible to get configuration information about the "
246 "interfaces. Status code: {0}.".format(status_code))
249 new_data = HcUtil.set_item_value(resp, path, new_value)
251 new_data = HcUtil.remove_item(resp, path)
252 return InterfaceKeywords._configure_interface(node, interface, new_data)
255 def set_interface_state(node, interface, state="up"):
256 """Set VPP interface state.
258 The keyword changes the administration state of interface to up or down
259 depending on the parameter "state".
261 :param node: Honeycomb node.
262 :param interface: Interface name, key, link name or sw_if_index.
263 :param state: The requested state, only "up" and "down" are valid
268 :returns: Content of response.
270 :raises KeyError: If the argument "state" is nor "up" or "down".
271 :raises HoneycombError: If the interface is not present on the node.
274 intf_state = {"up": "true",
277 interface = Topology.convert_interface_reference(
278 node, interface, "name")
280 intf = interface.replace("/", "%2F")
281 path = "/interface/{0}".format(intf)
283 status_code, resp = HcUtil.\
284 get_honeycomb_data(node, "config_vpp_interfaces", path)
285 if status_code != HTTPCodes.OK:
286 raise HoneycombError(
287 "Not possible to get configuration information about the "
288 "interfaces. Status code: {0}.".format(status_code))
290 resp["interface"][0]["enabled"] = intf_state[state.lower()]
292 status_code, resp = HcUtil. \
293 put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
294 data_representation=DataRepresentation.JSON)
295 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
296 raise HoneycombError(
297 "The configuration of interface '{0}' was not successful. "
298 "Status code: {1}.".format(interface, status_code))
302 def set_interface_up(node, interface):
303 """Set the administration state of VPP interface to up.
305 :param node: Honeycomb node.
306 :param interface: The name of interface.
309 :returns: Content of response
313 return InterfaceKeywords.set_interface_state(node, interface, "up")
316 def set_interface_down(node, interface):
317 """Set the administration state of VPP interface to down.
319 :param node: Honeycomb node.
320 :param interface: The name of interface.
323 :returns: Content of response.
327 return InterfaceKeywords.set_interface_state(node, interface, "down")
330 def add_bridge_domain_to_interface(node, interface, bd_name,
331 split_horizon_group=None, bvi=None):
332 """Add a new bridge domain to an interface and set its parameters.
334 :param node: Honeycomb node.
335 :param interface: Interface name, key, link name or sw_if_index.
336 :param bd_name: Bridge domain name.
337 :param split_horizon_group: Split-horizon group name.
338 :param bvi: The bridged virtual interface.
342 :type split_horizon_group: str
344 :returns: Content of response.
346 :raises HoneycombError: If the interface is not present on the node.
349 interface = Topology.convert_interface_reference(
350 node, interface, "name")
352 v3po_l2 = {"bridge-domain": str(bd_name)}
353 if split_horizon_group:
354 v3po_l2["split-horizon-group"] = str(split_horizon_group)
356 v3po_l2["bridged-virtual-interface"] = str(bvi)
358 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
360 return InterfaceKeywords._set_interface_properties(
361 node, interface, path, v3po_l2)
364 def remove_bridge_domain_from_interface(node, interface):
365 """Remove bridge domain assignment from interface.
367 :param node: Honeycomb node.
368 :param interface: Interface name, key, link name or sw_if_index.
370 :type interface: str or int
372 :raises HoneycombError: If the operation fails.
375 interface = Topology.convert_interface_reference(
376 node, interface, "name")
378 intf = interface.replace("/", "%2F")
380 path = "/interface/{0}/v3po:l2".format(intf)
382 status_code, response = HcUtil.delete_honeycomb_data(
383 node, "config_vpp_interfaces", path)
385 if status_code != HTTPCodes.OK:
386 if '"error-tag":"data-missing"' in response:
387 logger.debug("Data does not exist in path.")
389 raise HoneycombError(
390 "Could not remove bridge domain assignment from interface "
391 "'{0}'. Status code: {1}.".format(interface, status_code))
394 def get_bd_oper_data_from_interface(node, interface):
395 """Returns operational data about bridge domain settings in the
398 :param node: Honeycomb node.
399 :param interface: The name of interface.
402 :returns: Operational data about bridge domain settings in the
407 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
411 return if_data["v3po:l2"]
417 def configure_interface_base(node, interface, param, value):
418 """Configure the base parameters of interface.
420 :param node: Honeycomb node.
421 :param interface: The name of interface.
422 :param param: Parameter to configure (set, change, remove)
423 :param value: The value of parameter. If None, the parameter will be
429 :returns: Content of response.
431 :raises HoneycombError: If the parameter is not valid.
434 if param not in InterfaceKeywords.INTF_PARAMS:
435 raise HoneycombError("The parameter {0} is invalid.".format(param))
437 path = ("interfaces", ("interface", "name", interface), param)
438 return InterfaceKeywords._set_interface_properties(
439 node, interface, path, value)
442 def configure_interface_ipv4(node, interface, param, value):
443 """Configure IPv4 parameters of interface.
445 :param node: Honeycomb node.
446 :param interface: The name of interface.
447 :param param: Parameter to configure (set, change, remove)
448 :param value: The value of parameter. If None, the parameter will be
454 :returns: Content of response.
456 :raises HoneycombError: If the parameter is not valid.
459 interface = Topology.convert_interface_reference(
460 node, interface, "name")
462 if param not in InterfaceKeywords.IPV4_PARAMS:
463 raise HoneycombError("The parameter {0} is invalid.".format(param))
465 path = ("interfaces", ("interface", "name", interface),
466 "ietf-ip:ipv4", param)
467 return InterfaceKeywords._set_interface_properties(
468 node, interface, path, value)
471 def add_first_ipv4_address(node, interface, ip_addr, network):
472 """Add the first IPv4 address.
474 If there are any other addresses configured, they will be removed.
476 :param node: Honeycomb node.
477 :param interface: The name of interface.
478 :param ip_addr: IPv4 address to be set.
479 :param network: Netmask or length of network prefix.
483 :type network: str or int
484 :returns: Content of response.
486 :raises HoneycombError: If the provided netmask or prefix is not valid.
489 interface = Topology.convert_interface_reference(
490 node, interface, "name")
492 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
493 if isinstance(network, basestring):
494 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
495 elif isinstance(network, int) and (0 < network < 33):
496 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
498 raise HoneycombError("Value {0} is not a valid netmask or network "
499 "prefix length.".format(network))
500 return InterfaceKeywords._set_interface_properties(
501 node, interface, path, address)
504 def add_ipv4_address(node, interface, ip_addr, network):
507 :param node: Honeycomb node.
508 :param interface: The name of interface.
509 :param ip_addr: IPv4 address to be set.
510 :param network: Netmask or length of network prefix.
514 :type network: str or int
515 :returns: Content of response.
517 :raises HoneycombError: If the provided netmask or prefix is not valid.
520 interface = Topology.convert_interface_reference(
521 node, interface, "name")
523 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
525 if isinstance(network, basestring):
526 address = [{"ip": ip_addr, "netmask": network}]
527 elif isinstance(network, int) and (0 < network < 33):
528 address = [{"ip": ip_addr, "prefix-length": network}]
530 raise HoneycombError("Value {0} is not a valid netmask or network "
531 "prefix length.".format(network))
532 return InterfaceKeywords._set_interface_properties(
533 node, interface, path, address)
536 def remove_all_ipv4_addresses(node, interface):
537 """Remove all IPv4 addresses from interface.
539 :param node: Honeycomb node.
540 :param interface: The name of interface.
543 :returns: Content of response.
547 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
549 return InterfaceKeywords._set_interface_properties(
550 node, interface, path, None)
553 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
554 """Add the IPv4 neighbour.
556 :param node: Honeycomb node.
557 :param interface: The name of interface.
558 :param ip_addr: IPv4 address of neighbour to be set.
559 :param link_layer_address: Link layer address.
563 :type link_layer_address: str
564 :returns: Content of response.
568 interface = Topology.convert_interface_reference(
569 node, interface, "name")
571 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
573 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
574 return InterfaceKeywords._set_interface_properties(
575 node, interface, path, neighbor)
578 def remove_all_ipv4_neighbors(node, interface):
579 """Remove all IPv4 neighbours.
581 :param node: Honeycomb node.
582 :param interface: The name of interface.
585 :returns: Content of response.
589 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
591 return InterfaceKeywords._set_interface_properties(
592 node, interface, path, None)
595 def configure_interface_ipv6(node, interface, param, value):
596 """Configure IPv6 parameters of interface
598 :param node: Honeycomb node.
599 :param interface: The name of interface.
600 :param param: Parameter to configure (set, change, remove)
601 :param value: The value of parameter. If None, the parameter will be
607 :returns: Content of response.
609 :raises HoneycombError: If the parameter is not valid.
612 if param in InterfaceKeywords.IPV6_PARAMS:
613 path = ("interfaces", ("interface", "name", interface),
614 "ietf-ip:ipv6", param)
615 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
616 path = ("interfaces", ("interface", "name", interface),
617 "ietf-ip:ipv6", "autoconf", param)
619 raise HoneycombError("The parameter {0} is invalid.".format(param))
621 return InterfaceKeywords._set_interface_properties(
622 node, interface, path, value)
625 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
626 """Add the first IPv6 address.
628 If there are any other addresses configured, they will be removed.
630 :param node: Honeycomb node.
631 :param interface: The name of interface.
632 :param ip_addr: IPv6 address to be set.
633 :param prefix_len: Prefix length.
637 :type prefix_len: str
638 :returns: Content of response.
642 interface = Topology.convert_interface_reference(
643 node, interface, "name")
645 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
646 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
647 return InterfaceKeywords._set_interface_properties(
648 node, interface, path, address)
651 def add_ipv6_address(node, interface, ip_addr, prefix_len):
654 :param node: Honeycomb node.
655 :param interface: The name of interface.
656 :param ip_addr: IPv6 address to be set.
657 :param prefix_len: Prefix length.
661 :type prefix_len: str
662 :returns: Content of response.
666 interface = Topology.convert_interface_reference(
667 node, interface, "name")
669 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
671 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
672 return InterfaceKeywords._set_interface_properties(
673 node, interface, path, address)
676 def remove_all_ipv6_addresses(node, interface):
677 """Remove all IPv6 addresses from interface.
679 :param node: Honeycomb node.
680 :param interface: The name of interface.
683 :returns: Content of response.
687 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
689 return InterfaceKeywords._set_interface_properties(
690 node, interface, path, None)
693 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
694 """Add the IPv6 neighbour.
696 :param node: Honeycomb node.
697 :param interface: The name of interface.
698 :param ip_addr: IPv6 address of neighbour to be set.
699 :param link_layer_address: Link layer address.
703 :type link_layer_address: str
704 :returns: Content of response.
708 interface = Topology.convert_interface_reference(
709 node, interface, "name")
711 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
713 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
714 return InterfaceKeywords._set_interface_properties(
715 node, interface, path, neighbor)
718 def remove_all_ipv6_neighbors(node, interface):
719 """Remove all IPv6 neighbours.
721 :param node: Honeycomb node.
722 :param interface: The name of interface.
725 :returns: Content of response.
729 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
731 return InterfaceKeywords._set_interface_properties(
732 node, interface, path, None)
735 def configure_interface_ethernet(node, interface, param, value):
736 """Configure the ethernet parameters of interface.
738 :param node: Honeycomb node.
739 :param interface: The name of interface.
740 :param param: Parameter to configure (set, change, remove)
741 :param value: The value of parameter. If None, the parameter will be
747 :returns: Content of response.
749 :raises HoneycombError: If the parameter is not valid.
752 if param not in InterfaceKeywords.ETH_PARAMS:
753 raise HoneycombError("The parameter {0} is invalid.".format(param))
754 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
756 return InterfaceKeywords._set_interface_properties(
757 node, interface, path, value)
760 def configure_interface_routing(node, interface, param, value):
761 """Configure the routing parameters of interface.
763 :param node: Honeycomb node.
764 :param interface: The name of interface.
765 :param param: Parameter to configure (set, change, remove)
766 :param value: The value of parameter. If None, the parameter will be
772 :returns: Content of response.
774 :raises HoneycombError: If the parameter is not valid.
777 interface = Topology.convert_interface_reference(
778 node, interface, "name")
780 if param not in InterfaceKeywords.ROUTING_PARAMS:
781 raise HoneycombError("The parameter {0} is invalid.".format(param))
783 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
785 return InterfaceKeywords._set_interface_properties(
786 node, interface, path, value)
789 def create_vxlan_interface(node, interface, **kwargs):
790 """Create a new VxLAN interface.
792 :param node: Honeycomb node.
793 :param interface: The name of interface.
794 :param kwargs: Parameters and their values. The accepted parameters are
795 defined in InterfaceKeywords.VXLAN_PARAMS.
799 :returns: Content of response.
801 :raises HoneycombError: If the parameter is not valid.
806 "type": "v3po:vxlan-tunnel",
809 for param, value in kwargs.items():
810 if param not in InterfaceKeywords.VXLAN_PARAMS:
811 raise HoneycombError("The parameter {0} is invalid.".
813 new_vx_lan["v3po:vxlan"][param] = value
815 path = ("interfaces", "interface")
816 vx_lan_structure = [new_vx_lan, ]
817 return InterfaceKeywords._set_interface_properties(
818 node, interface, path, vx_lan_structure)
821 def delete_interface(node, interface):
822 """Delete an interface.
824 :param node: Honeycomb node.
825 :param interface: The name of interface.
828 :returns: Content of response.
830 :raises HoneycombError: If it is not possible to get information about
831 interfaces or it is not possible to delete the interface.
834 path = ("interfaces", ("interface", "name", interface))
836 status_code, resp = HcUtil.\
837 get_honeycomb_data(node, "config_vpp_interfaces")
838 if status_code != HTTPCodes.OK:
839 raise HoneycombError(
840 "Not possible to get configuration information about the "
841 "interfaces. Status code: {0}.".format(status_code))
843 new_data = HcUtil.remove_item(resp, path)
844 status_code, resp = HcUtil.\
845 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
846 if status_code != HTTPCodes.OK:
847 raise HoneycombError("Not possible to remove interface {0}. "
849 format(interface, status_code))
853 def configure_interface_vxlan(node, interface, **kwargs):
854 """Configure VxLAN on the interface.
856 The keyword configures VxLAN parameters on the given interface. The type
857 of interface must be set to "v3po:vxlan-tunnel".
858 The new VxLAN parameters overwrite the current configuration. If a
859 parameter in new configuration is missing, it is removed from VxLAN
861 If the dictionary kwargs is empty, VxLAN configuration is removed.
863 :param node: Honeycomb node.
864 :param interface: The name of interface.
865 :param kwargs: Parameters and their values. The accepted parameters are
866 defined in InterfaceKeywords.VXLAN_PARAMS.
870 :returns: Content of response.
872 :raises HoneycombError: If the parameter is not valid.
875 vx_lan_structure = dict()
876 for param, value in kwargs.items():
877 if param not in InterfaceKeywords.VXLAN_PARAMS:
878 raise HoneycombError("The parameter {0} is invalid.".
880 vx_lan_structure[param] = value
882 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
883 return InterfaceKeywords._set_interface_properties(
884 node, interface, path, vx_lan_structure)
887 def configure_interface_l2(node, interface, param, value):
888 """Configure the L2 parameters of interface.
890 :param node: Honeycomb node.
891 :param interface: The name of interface.
892 :param param: Parameter to configure (set, change, remove)
893 :param value: The value of parameter. If None, the parameter will be
899 :returns: Content of response.
901 :raises HoneycombError: If the parameter is not valid.
904 if param not in InterfaceKeywords.L2_PARAMS:
905 raise HoneycombError("The parameter {0} is invalid.".format(param))
906 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
908 return InterfaceKeywords._set_interface_properties(
909 node, interface, path, value)
912 def create_tap_interface(node, interface, **kwargs):
913 """Create a new TAP interface.
915 :param node: Honeycomb node.
916 :param interface: The name of interface.
917 :param kwargs: Parameters and their values. The accepted parameters are
918 defined in InterfaceKeywords.TAP_PARAMS.
922 :returns: Content of response.
924 :raises HoneycombError: If the parameter is not valid.
932 for param, value in kwargs.items():
933 if param not in InterfaceKeywords.TAP_PARAMS:
934 raise HoneycombError("The parameter {0} is invalid.".
936 new_tap["v3po:tap"][param] = value
938 path = ("interfaces", "interface")
939 new_tap_structure = [new_tap, ]
940 return InterfaceKeywords._set_interface_properties(
941 node, interface, path, new_tap_structure)
944 def configure_interface_tap(node, interface, **kwargs):
945 """Configure TAP on the interface.
947 The keyword configures TAP parameters on the given interface. The type
948 of interface must be set to "v3po:tap".
949 The new TAP parameters overwrite the current configuration. If a
950 parameter in new configuration is missing, it is removed from TAP
952 If the dictionary kwargs is empty, TAP configuration is removed.
954 :param node: Honeycomb node.
955 :param interface: The name of interface.
956 :param kwargs: Parameters and their values. The accepted parameters are
957 defined in InterfaceKeywords.TAP_PARAMS.
961 :returns: Content of response.
963 :raises HoneycombError: If the parameter is not valid.
966 tap_structure = dict()
967 for param, value in kwargs.items():
968 if param not in InterfaceKeywords.TAP_PARAMS:
969 raise HoneycombError("The parameter {0} is invalid.".
971 tap_structure[param] = value
973 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
974 return InterfaceKeywords._set_interface_properties(
975 node, interface, path, tap_structure)
978 def configure_interface_vhost_user(node, interface, **kwargs):
979 """Configure vhost-user on the interface.
981 The keyword configures vhost-user parameters on the given interface.
982 The type of interface must be set to "v3po:vhost-user".
983 The new vhost-user parameters overwrite the current configuration. If a
984 parameter in new configuration is missing, it is removed from vhost-user
986 If the dictionary kwargs is empty, vhost-user configuration is removed.
988 :param node: Honeycomb node.
989 :param interface: The name of interface.
990 :param kwargs: Parameters and their values. The accepted parameters are
991 defined in InterfaceKeywords.VHOST_USER_PARAMS.
995 :returns: Content of response.
997 :raises HoneycombError: If the parameter is not valid.
1000 vhost_structure = dict()
1001 for param, value in kwargs.items():
1002 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1003 raise HoneycombError("The parameter {0} is invalid.".
1005 vhost_structure[param] = value
1007 path = ("interfaces", ("interface", "name", interface),
1009 return InterfaceKeywords._set_interface_properties(
1010 node, interface, path, vhost_structure)
1013 def create_vhost_user_interface(node, interface, **kwargs):
1014 """Create a new vhost-user interface.
1016 :param node: Honeycomb node.
1017 :param interface: The name of interface.
1018 :param kwargs: Parameters and their values. The accepted parameters are
1019 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1021 :type interface: str
1023 :returns: Content of response.
1025 :raises HoneycombError: If the parameter is not valid.
1030 "type": "v3po:vhost-user",
1031 "v3po:vhost-user": {}
1033 for param, value in kwargs.items():
1034 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1035 raise HoneycombError("The parameter {0} is invalid.".
1037 new_vhost["v3po:vhost-user"][param] = value
1039 path = ("interfaces", "interface")
1040 new_vhost_structure = [new_vhost, ]
1041 return InterfaceKeywords._set_interface_properties(
1042 node, interface, path, new_vhost_structure)
1045 def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
1046 """Create a new sub-interface.
1048 :param node: Honeycomb node.
1049 :param super_interface: Super interface.
1050 :param match: Match type. The valid values are defined in
1051 InterfaceKeywords.SUB_IF_MATCH.
1052 :param tags: List of tags.
1053 :param kwargs: Parameters and their values. The accepted parameters are
1054 defined in InterfaceKeywords.SUB_IF_PARAMS.
1056 :type super_interface: str
1060 :returns: Content of response.
1062 :raises HoneycombError: If the parameter is not valid.
1063 :raises KeyError: If the parameter 'match' is invalid.
1072 {"vlan-tagged": {"match-exact-tags": "false"}},
1073 "vlan-tagged-exact-match":
1074 {"vlan-tagged": {"match-exact-tags": "true"}}
1077 new_sub_interface = {
1083 for param, value in kwargs.items():
1084 if param in InterfaceKeywords.SUB_IF_PARAMS:
1085 new_sub_interface[param] = value
1087 raise HoneycombError("The parameter {0} is invalid.".
1090 new_sub_interface["match"] = match_type[match]
1092 raise HoneycombError("The value '{0}' of parameter 'match' is "
1093 "invalid.".format(match))
1096 new_sub_interface["tags"]["tag"].extend(tags)
1098 path = ("interfaces",
1099 ("interface", "name", super_interface),
1100 "vpp-vlan:sub-interfaces",
1102 new_sub_interface_structure = [new_sub_interface, ]
1103 return InterfaceKeywords._set_interface_properties(
1104 node, super_interface, path, new_sub_interface_structure)
1107 def get_sub_interface_oper_data(node, super_interface, identifier):
1108 """Retrieves sub-interface operational data using Honeycomb API.
1110 :param node: Honeycomb node.
1111 :param super_interface: Super interface.
1112 :param identifier: The ID of sub-interface.
1114 :type super_interface: str
1115 :type identifier: int
1116 :returns: Sub-interface operational data.
1118 :raises HoneycombError: If there is no sub-interface with the given ID.
1121 if_data = InterfaceKeywords.get_interface_oper_data(node,
1123 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1124 if str(sub_if["identifier"]) == str(identifier):
1127 raise HoneycombError("The interface {0} does not have sub-interface "
1128 "with ID {1}".format(super_interface, identifier))
1131 def remove_all_sub_interfaces(node, super_interface):
1132 """Remove all sub-interfaces from the given interface.
1134 :param node: Honeycomb node.
1135 :param super_interface: Super interface.
1137 :type super_interface: str
1138 :returns: Content of response.
1142 path = ("interfaces",
1143 ("interface", "name", super_interface),
1144 "vpp-vlan:sub-interfaces")
1146 return InterfaceKeywords._set_interface_properties(
1147 node, super_interface, path, {})
1150 def set_sub_interface_state(node, super_interface, identifier, state):
1151 """Set the administrative state of sub-interface.
1153 :param node: Honeycomb node.
1154 :param super_interface: Super interface.
1155 :param identifier: The ID of sub-interface.
1156 :param state: Required sub-interface state - up or down.
1158 :type super_interface: str
1159 :type identifier: int
1161 :returns: Content of response.
1165 super_interface = Topology.convert_interface_reference(
1166 node, super_interface, "name")
1168 intf_state = {"up": "true",
1171 path = ("interfaces",
1172 ("interface", "name", super_interface),
1173 "vpp-vlan:sub-interfaces",
1174 ("sub-interface", "identifier", int(identifier)),
1177 return InterfaceKeywords._set_interface_properties(
1178 node, super_interface, path, intf_state[state])
1181 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1183 """Add a sub-interface to a bridge domain and set its parameters.
1185 :param node: Honeycomb node.
1186 :param super_interface: Super interface.
1187 :param identifier: The ID of sub-interface.
1188 :param config: Bridge domain configuration.
1190 :type super_interface: str
1191 :type identifier: int
1193 :returns: Content of response.
1197 path = ("interfaces",
1198 ("interface", "name", super_interface),
1199 "vpp-vlan:sub-interfaces",
1200 ("sub-interface", "identifier", int(identifier)),
1203 return InterfaceKeywords._set_interface_properties(
1204 node, super_interface, path, config)
1207 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1208 """Get the operational data about the bridge domain from sub-interface.
1210 :param node: Honeycomb node.
1211 :param super_interface: Super interface.
1212 :param identifier: The ID of sub-interface.
1214 :type super_interface: str
1215 :type identifier: int
1216 :returns: Operational data about the bridge domain.
1218 :raises HoneycombError: If there is no sub-interface with the given ID.
1222 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1223 node, super_interface, identifier)["l2"]
1226 raise HoneycombError("The operational data does not contain "
1227 "information about a bridge domain.")
1230 def configure_tag_rewrite(node, super_interface, identifier, config):
1231 """Add / change / disable vlan tag rewrite on a sub-interface.
1233 :param node: Honeycomb node.
1234 :param super_interface: Super interface.
1235 :param identifier: The ID of sub-interface.
1236 :param config: Rewrite tag configuration.
1238 :type super_interface: str
1239 :type identifier: int
1241 :returns: Content of response.
1245 path = ("interfaces",
1246 ("interface", "name", super_interface),
1247 "vpp-vlan:sub-interfaces",
1248 ("sub-interface", "identifier", int(identifier)),
1252 return InterfaceKeywords._set_interface_properties(
1253 node, super_interface, path, config)
1256 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1257 """Get the operational data about tag rewrite.
1259 :param node: Honeycomb node.
1260 :param super_interface: Super interface.
1261 :param identifier: The ID of sub-interface.
1263 :type super_interface: str
1264 :type identifier: int
1265 :returns: Operational data about tag rewrite.
1267 :raises HoneycombError: If there is no sub-interface with the given ID.
1271 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1272 node, super_interface, identifier)["l2"]["rewrite"]
1275 raise HoneycombError("The operational data does not contain "
1276 "information about the tag-rewrite.")
1279 def add_ip_address_to_sub_interface(node, super_interface, identifier,
1280 ip_addr, network, ip_version):
1281 """Add an ipv4 address to the specified sub-interface, with the provided
1282 netmask or network prefix length. Any existing ipv4 addresses on the
1283 sub-interface will be replaced.
1285 :param node: Honeycomb node.
1286 :param super_interface: Super interface.
1287 :param identifier: The ID of sub-interface.
1288 :param ip_addr: IPv4 address to be set.
1289 :param network: Network mask or network prefix length.
1290 :param ip_version: ipv4 or ipv6
1292 :type super_interface: str
1293 :type identifier: int
1295 :type network: str or int
1296 :type ip_version: string
1297 :returns: Content of response.
1299 :raises HoneycombError: If the provided netmask or prefix is not valid.
1302 path = ("interfaces",
1303 ("interface", "name", super_interface),
1304 "vpp-vlan:sub-interfaces",
1305 ("sub-interface", "identifier", int(identifier)),
1308 if isinstance(network, basestring) and ip_version.lower() == "ipv4":
1309 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1311 elif isinstance(network, int) and 0 < network < 33:
1312 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1315 raise HoneycombError("{0} is not a valid netmask or prefix length."
1318 return InterfaceKeywords._set_interface_properties(
1319 node, super_interface, path, address)
1322 def remove_all_ip_addresses_from_sub_interface(node, super_interface,
1323 identifier, ip_version):
1324 """Remove all ipv4 addresses from the specified sub-interface.
1326 :param node: Honeycomb node.
1327 :param super_interface: Super interface.
1328 :param identifier: The ID of sub-interface.
1329 :param ip_version: ipv4 or ipv6
1331 :type super_interface: str
1332 :type identifier: int
1333 :type ip_version: string
1334 :returns: Content of response.
1338 path = ("interfaces",
1339 ("interface", "name", super_interface),
1340 "vpp-vlan:sub-interfaces",
1341 ("sub-interface", "identifier", int(identifier)),
1342 str(ip_version), "address")
1344 return InterfaceKeywords._set_interface_properties(
1345 node, super_interface, path, None)
1348 def compare_data_structures(data, ref, _path=''):
1349 """Checks if data obtained from UUT is as expected. If it is not,
1350 proceeds down the list/dictionary tree and finds the point of mismatch.
1352 :param data: Data to be checked.
1353 :param ref: Referential data used for comparison.
1354 :param _path: Used in recursive calls, stores the path taken down
1360 :raises HoneycombError: If the data structures do not match in some way,
1361 or if they are not in deserialized JSON format.
1367 elif isinstance(data, dict) and isinstance(ref, dict):
1370 raise HoneycombError(
1371 "Key {key} is not present in path {path}. Keys in path:"
1372 "{data_keys}".format(
1375 data_keys=data.keys()))
1377 if data[key] != ref[key]:
1378 if isinstance(data[key], list) \
1379 or isinstance(data[key], dict):
1380 InterfaceKeywords.compare_data_structures(
1381 data[key], ref[key],
1382 _path + '[{0}]'.format(key))
1384 raise HoneycombError(
1385 "Data mismatch, key {key} in path {path} has value"
1386 " {data}, but should be {ref}".format(
1392 elif isinstance(data, list) and isinstance(ref, list):
1394 if item not in data:
1395 if isinstance(item, dict):
1396 InterfaceKeywords.compare_data_structures(
1398 _path + '[{0}]'.format(ref.index(item)))
1400 raise HoneycombError(
1401 "Data mismatch, list item {index} in path {path}"
1402 " has value {data}, but should be {ref}".format(
1403 index=ref.index(item),
1409 raise HoneycombError(
1410 "Unexpected data type {data_type} in path {path}, reference"
1411 " type is {ref_type}. Must be list or dictionary.".format(
1412 data_type=type(data),
1417 def compare_interface_lists(list1, list2):
1418 """Compare provided lists of interfaces by name.
1420 :param list1: List of interfaces.
1421 :param list2: List of interfaces.
1424 :raises HoneycombError: If an interface exists in only one of the lists.
1427 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1428 # these have no equivalent in config data and no effect on VPP
1430 names1 = [x['name'] for x in list1]
1431 names2 = [x['name'] for x in list2]
1434 if name not in names2 and name not in ignore:
1435 raise HoneycombError("Interface {0} not present in list {1}"
1436 .format(name, list2))
1438 if name not in names1 and name not in ignore:
1439 raise HoneycombError("Interface {0} not present in list {1}"
1440 .format(name, list1))
1443 def create_vxlan_gpe_interface(node, interface, **kwargs):
1444 """Create a new VxLAN GPE interface.
1446 :param node: Honeycomb node.
1447 :param interface: The name of interface to be created.
1448 :param kwargs: Parameters and their values. The accepted parameters are
1449 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1451 :type interface: str
1453 :returns: Content of response.
1455 :raises HoneycombError: If a parameter in kwargs is not valid.
1460 "type": "v3po:vxlan-gpe-tunnel",
1461 "v3po:vxlan-gpe": {}
1463 for param, value in kwargs.items():
1464 if param in InterfaceKeywords.INTF_PARAMS:
1465 new_vxlan_gpe[param] = value
1466 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1467 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1469 raise HoneycombError("The parameter {0} is invalid.".
1471 path = ("interfaces", "interface")
1472 vxlan_gpe_structure = [new_vxlan_gpe, ]
1473 return InterfaceKeywords._set_interface_properties(
1474 node, interface, path, vxlan_gpe_structure)
1477 def enable_acl_on_interface(node, interface, table_name):
1478 """Enable ACL on the given interface.
1480 :param node: Honeycomb node.
1481 :param interface: The interface where the ACL will be enabled.
1482 :param table_name: Name of the classify table.
1484 :type interface: str
1485 :type table_name: str
1486 :returns: Content of response.
1488 :raises HoneycombError: If the configuration of interface is not
1492 interface = interface.replace("/", "%2F")
1495 "vpp-interface-acl:acl": {
1498 "classify-table": table_name
1501 "classify-table": table_name
1507 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1508 status_code, resp = HcUtil.\
1509 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1510 data_representation=DataRepresentation.JSON)
1511 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1512 raise HoneycombError(
1513 "The configuration of interface '{0}' was not successful. "
1514 "Status code: {1}.".format(interface, status_code))
1518 def enable_policer_on_interface(node, interface, table_name):
1519 """Enable Policer on the given interface.
1521 :param node: Honeycomb node.
1522 :param interface: The interface where policer will be enabled.
1523 :param table_name: Name of the classify table.
1525 :type interface: str
1526 :type table_name: str
1527 :returns: Content of response.
1529 :raises HoneycombError: If the configuration of interface is not
1532 interface = Topology.convert_interface_reference(
1533 node, interface, "name")
1534 interface = interface.replace("/", "%2F")
1537 "interface-policer:policer": {
1538 "ip4-table": table_name
1542 path = "/interface/" + interface + "/interface-policer:policer"
1543 status_code, resp = HcUtil.\
1544 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1545 data_representation=DataRepresentation.JSON)
1546 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1547 raise HoneycombError(
1548 "The configuration of interface '{0}' was not successful. "
1549 "Status code: {1}.".format(interface, status_code))
1553 def disable_policer_on_interface(node, interface):
1554 """Disable Policer on the given interface.
1556 :param node: Honeycomb node.
1557 :param interface: The interface where policer will be disabled.
1558 :param table_name: Name of the classify table.
1560 :type interface: str
1561 :type table_name: str
1562 :returns: Content of response.
1564 :raises HoneycombError: If the configuration of interface is not
1567 interface = Topology.convert_interface_reference(
1568 node, interface, "name")
1569 interface = interface.replace("/", "%2F")
1571 path = "/interface/" + interface + "/interface-policer:policer"
1572 status_code, resp = HcUtil.\
1573 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1574 if status_code != HTTPCodes.OK:
1575 raise HoneycombError(
1576 "The configuration of interface '{0}' was not successful. "
1577 "Status code: {1}.".format(interface, status_code))
1581 def disable_acl_on_interface(node, interface):
1582 """Disable ACL on the given interface.
1584 :param node: Honeycomb node.
1585 :param interface: The interface where the ACL will be disabled.
1587 :type interface: str
1588 :returns: Content of response.
1590 :raises HoneycombError: If the configuration of interface is not
1594 interface = interface.replace("/", "%2F")
1596 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1598 status_code, resp = HcUtil.\
1599 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1601 if status_code != HTTPCodes.OK:
1602 raise HoneycombError(
1603 "The configuration of interface '{0}' was not successful. "
1604 "Status code: {1}.".format(interface, status_code))
1608 def create_pbb_sub_interface(node, intf, params):
1609 """Creates a PBB sub-interface on the given interface and sets its
1612 :param node: Honeycomb node.
1613 :param intf: The interface where PBB sub-interface will be configured.
1614 :param params: Configuration parameters of the sub-interface to be
1619 :returns: Content of response.
1621 :raises HoneycombError: If the configuration of sub-interface is not
1625 interface = intf.replace("/", "%2F")
1626 path = "/interface/{0}/pbb-rewrite".format(interface)
1627 status_code, resp = HcUtil. \
1628 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1629 data_representation=DataRepresentation.JSON)
1630 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1631 raise HoneycombError(
1632 "The configuration of PBB sub-interface '{0}' was not "
1633 "successful. Status code: {1}.".format(intf, status_code))
1637 def delete_pbb_sub_interface(node, intf):
1638 """Deletes the given PBB sub-interface.
1640 :param node: Honeycomb node.
1641 :param intf: The interface where PBB sub-interface will be deleted.
1644 :returns: Content of response.
1646 :raises HoneycombError: If the removal of sub-interface is not
1650 interface = intf.replace("/", "%2F")
1651 path = "/interface/{0}/pbb-rewrite".format(interface)
1653 status_code, resp = HcUtil. \
1654 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1655 if status_code != HTTPCodes.OK:
1656 raise HoneycombError(
1657 "The removal of pbb sub-interface '{0}' was not successful. "
1658 "Status code: {1}.".format(intf, status_code))
1662 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1663 """Retrieves PBB sub-interface operational data from Honeycomb.
1665 :param node: Honeycomb node.
1666 :param intf: The interface where PBB sub-interface is located.
1667 :param sub_if_id: ID of the PBB sub-interface.
1670 :type sub_if_id: str or int
1671 :returns: PBB sub-interface operational data.
1673 :raises HoneycombError: If the removal of sub-interface is not
1677 raise NotImplementedError
1680 def check_disabled_interface(node, interface):
1681 """Retrieves list of disabled interface indices from Honeycomb,
1682 and matches with the provided interface by index.
1684 :param node: Honeycomb node.
1685 :param interface: Index number of an interface on the node.
1687 :type interface: int
1688 :returns: True if the interface exists in disabled interfaces.
1690 :raises HoneycombError: If the interface is not present
1691 in retrieved list of disabled interfaces.
1693 data = InterfaceKeywords.get_disabled_interfaces_oper_data(node)
1694 # decrement by one = conversion from HC if-index to VPP sw_if_index
1698 if item["index"] == interface:
1700 raise HoneycombError("Interface index {0} not present in list"
1701 " of disabled interfaces.".format(interface))
1704 def configure_interface_span(node, dst_interface, src_interfaces=None):
1705 """Configure SPAN port mirroring on the specified interfaces. If no
1706 source interface is provided, SPAN will be disabled.
1708 :param node: Honeycomb node.
1709 :param dst_interface: Interface to mirror packets to.
1710 :param src_interfaces: List of interfaces to mirror packets from.
1712 :type dst_interface: str or int
1713 :type src_interfaces: list of dict
1714 :returns: Content of response.
1716 :raises HoneycombError: If SPAN could not be configured.
1719 interface = Topology.convert_interface_reference(
1720 node, dst_interface, "name")
1721 interface = interface.replace("/", "%2F")
1722 path = "/interface/" + interface + "/span"
1724 if not src_interfaces:
1725 status_code, _ = HcUtil.delete_honeycomb_data(
1726 node, "config_vpp_interfaces", path)
1728 for src_interface in src_interfaces:
1729 src_interface["iface-ref"] = Topology.\
1730 convert_interface_reference(
1731 node, src_interface["iface-ref"], "name")
1734 "mirrored-interfaces": {
1735 "mirrored-interface": src_interfaces
1740 status_code, _ = HcUtil.put_honeycomb_data(
1741 node, "config_vpp_interfaces", data, path)
1743 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1744 raise HoneycombError(
1745 "Configuring SPAN failed. Status code:{0}".format(status_code))
1748 def configure_sub_interface_span(node, super_interface, dst_interface_index,
1749 src_interfaces=None):
1750 """Configure SPAN port mirroring on the specified sub-interface. If no
1751 source interface is provided, SPAN will be disabled.
1753 Note: Does not support source sub-interfaces, only destination.
1755 :param node: Honeycomb node.
1756 :param super_interface: Name, link name or sw_if_index
1757 of the destination interface's super-interface.
1758 :param dst_interface_index: Index of sub-interface to mirror packets to.
1759 :param src_interfaces: List of interfaces to mirror packets from.
1761 :type super_interface: str or int
1762 :type dst_interface_index: int
1763 :type src_interfaces: list of dict
1764 :returns: Content of response.
1766 :raises HoneycombError: If SPAN could not be configured.
1769 super_interface = Topology.convert_interface_reference(
1770 node, super_interface, "name")
1771 super_interface = super_interface.replace("/", "%2F")
1773 path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
1774 .format(super_interface, dst_interface_index)
1776 if not src_interfaces:
1777 status_code, _ = HcUtil.delete_honeycomb_data(
1778 node, "config_vpp_interfaces", path)
1780 for src_interface in src_interfaces:
1781 src_interface["iface-ref"] = Topology. \
1782 convert_interface_reference(
1783 node, src_interface["iface-ref"], "name")
1786 "mirrored-interfaces": {
1787 "mirrored-interface": src_interfaces
1792 status_code, _ = HcUtil.put_honeycomb_data(
1793 node, "config_vpp_interfaces", data, path)
1795 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1796 raise HoneycombError(
1797 "Configuring SPAN failed. Status code:{0}".format(status_code))
1800 def add_interface_local0_to_topology(node):
1801 """Use Topology methods to add interface "local0" to working topology,
1802 if not already present.
1804 :param node: DUT node.
1808 if Topology.get_interface_by_sw_index(node, 0) is None:
1809 local0_key = Topology.add_new_port(node, "localzero")
1810 Topology.update_interface_sw_if_index(node, local0_key, 0)
1811 Topology.update_interface_name(node, local0_key, "local0")