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 ValueError: If the provided netmask or prefix is not valid.
487 :raises HoneycombError: If the operation fails.
490 interface = InterfaceKeywords.handle_interface_reference(
493 path = "/interface/{0}/ietf-ip:ipv4".format(interface)
494 if isinstance(network, basestring):
497 "address": [{"ip": ip_addr, "netmask": network}, ]}}
498 elif isinstance(network, int) and (0 < network < 33):
501 "address": [{"ip": ip_addr, "prefix-length": network}, ]}}
503 raise ValueError("Value {0} is not a valid netmask or network "
504 "prefix length.".format(network))
505 status_code, _ = HcUtil.put_honeycomb_data(
506 node, "config_vpp_interfaces", data, path)
508 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
509 raise HoneycombError(
510 "Configuring IPv4 address failed. "
511 "Status code:{0}".format(status_code))
514 def add_ipv4_address(node, interface, ip_addr, network):
517 :param node: Honeycomb node.
518 :param interface: The name of interface.
519 :param ip_addr: IPv4 address to be set.
520 :param network: Netmask or length of network prefix.
524 :type network: str or int
525 :returns: Content of response.
527 :raises HoneycombError: If the provided netmask or prefix is not valid.
530 interface = Topology.convert_interface_reference(
531 node, interface, "name")
533 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
535 if isinstance(network, basestring):
536 address = [{"ip": ip_addr, "netmask": network}]
537 elif isinstance(network, int) and (0 < network < 33):
538 address = [{"ip": ip_addr, "prefix-length": network}]
540 raise HoneycombError("Value {0} is not a valid netmask or network "
541 "prefix length.".format(network))
542 return InterfaceKeywords._set_interface_properties(
543 node, interface, path, address)
546 def remove_all_ipv4_addresses(node, interface):
547 """Remove all IPv4 addresses from interface.
549 :param node: Honeycomb node.
550 :param interface: The name of interface.
553 :returns: Content of response.
557 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
559 return InterfaceKeywords._set_interface_properties(
560 node, interface, path, None)
563 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
564 """Add the IPv4 neighbour.
566 :param node: Honeycomb node.
567 :param interface: The name of interface.
568 :param ip_addr: IPv4 address of neighbour to be set.
569 :param link_layer_address: Link layer address.
573 :type link_layer_address: str
574 :returns: Content of response.
578 interface = Topology.convert_interface_reference(
579 node, interface, "name")
581 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
583 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
584 return InterfaceKeywords._set_interface_properties(
585 node, interface, path, neighbor)
588 def remove_all_ipv4_neighbors(node, interface):
589 """Remove all IPv4 neighbours.
591 :param node: Honeycomb node.
592 :param interface: The name of interface.
595 :returns: Content of response.
599 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
601 return InterfaceKeywords._set_interface_properties(
602 node, interface, path, None)
605 def configure_interface_ipv6(node, interface, param, value):
606 """Configure IPv6 parameters of interface
608 :param node: Honeycomb node.
609 :param interface: The name of interface.
610 :param param: Parameter to configure (set, change, remove)
611 :param value: The value of parameter. If None, the parameter will be
617 :returns: Content of response.
619 :raises HoneycombError: If the parameter is not valid.
622 if param in InterfaceKeywords.IPV6_PARAMS:
623 path = ("interfaces", ("interface", "name", interface),
624 "ietf-ip:ipv6", param)
625 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
626 path = ("interfaces", ("interface", "name", interface),
627 "ietf-ip:ipv6", "autoconf", param)
629 raise HoneycombError("The parameter {0} is invalid.".format(param))
631 return InterfaceKeywords._set_interface_properties(
632 node, interface, path, value)
635 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
636 """Add the first IPv6 address.
638 If there are any other addresses configured, they will be removed.
640 :param node: Honeycomb node.
641 :param interface: The name of interface.
642 :param ip_addr: IPv6 address to be set.
643 :param prefix_len: Prefix length.
647 :type prefix_len: str
648 :returns: Content of response.
652 interface = Topology.convert_interface_reference(
653 node, interface, "name")
655 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
656 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
657 return InterfaceKeywords._set_interface_properties(
658 node, interface, path, address)
661 def add_ipv6_address(node, interface, ip_addr, prefix_len):
664 :param node: Honeycomb node.
665 :param interface: The name of interface.
666 :param ip_addr: IPv6 address to be set.
667 :param prefix_len: Prefix length.
671 :type prefix_len: str
672 :returns: Content of response.
676 interface = Topology.convert_interface_reference(
677 node, interface, "name")
679 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
681 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
682 return InterfaceKeywords._set_interface_properties(
683 node, interface, path, address)
686 def remove_all_ipv6_addresses(node, interface):
687 """Remove all IPv6 addresses from interface.
689 :param node: Honeycomb node.
690 :param interface: The name of interface.
693 :returns: Content of response.
697 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
699 return InterfaceKeywords._set_interface_properties(
700 node, interface, path, None)
703 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
704 """Add the IPv6 neighbour.
706 :param node: Honeycomb node.
707 :param interface: The name of interface.
708 :param ip_addr: IPv6 address of neighbour to be set.
709 :param link_layer_address: Link layer address.
713 :type link_layer_address: str
714 :returns: Content of response.
718 interface = Topology.convert_interface_reference(
719 node, interface, "name")
721 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
723 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
724 return InterfaceKeywords._set_interface_properties(
725 node, interface, path, neighbor)
728 def remove_all_ipv6_neighbors(node, interface):
729 """Remove all IPv6 neighbours.
731 :param node: Honeycomb node.
732 :param interface: The name of interface.
735 :returns: Content of response.
739 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
741 return InterfaceKeywords._set_interface_properties(
742 node, interface, path, None)
745 def configure_interface_ethernet(node, interface, param, value):
746 """Configure the ethernet parameters of interface.
748 :param node: Honeycomb node.
749 :param interface: The name of interface.
750 :param param: Parameter to configure (set, change, remove)
751 :param value: The value of parameter. If None, the parameter will be
757 :returns: Content of response.
759 :raises HoneycombError: If the parameter is not valid.
762 if param not in InterfaceKeywords.ETH_PARAMS:
763 raise HoneycombError("The parameter {0} is invalid.".format(param))
764 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
766 return InterfaceKeywords._set_interface_properties(
767 node, interface, path, value)
770 def configure_interface_routing(node, interface, param, value):
771 """Configure the routing parameters of interface.
773 :param node: Honeycomb node.
774 :param interface: The name of interface.
775 :param param: Parameter to configure (set, change, remove)
776 :param value: The value of parameter. If None, the parameter will be
782 :returns: Content of response.
784 :raises HoneycombError: If the parameter is not valid.
787 interface = Topology.convert_interface_reference(
788 node, interface, "name")
790 if param not in InterfaceKeywords.ROUTING_PARAMS:
791 raise HoneycombError("The parameter {0} is invalid.".format(param))
793 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
795 return InterfaceKeywords._set_interface_properties(
796 node, interface, path, value)
799 def create_vxlan_interface(node, interface, **kwargs):
800 """Create a new VxLAN interface.
802 :param node: Honeycomb node.
803 :param interface: The name of interface.
804 :param kwargs: Parameters and their values. The accepted parameters are
805 defined in InterfaceKeywords.VXLAN_PARAMS.
809 :returns: Content of response.
811 :raises HoneycombError: If the parameter is not valid.
816 "type": "v3po:vxlan-tunnel",
819 for param, value in kwargs.items():
820 if param not in InterfaceKeywords.VXLAN_PARAMS:
821 raise HoneycombError("The parameter {0} is invalid.".
823 new_vx_lan["v3po:vxlan"][param] = value
825 path = ("interfaces", "interface")
826 vx_lan_structure = [new_vx_lan, ]
827 return InterfaceKeywords._set_interface_properties(
828 node, interface, path, vx_lan_structure)
831 def delete_interface(node, interface):
832 """Delete an interface.
834 :param node: Honeycomb node.
835 :param interface: The name of interface.
838 :returns: Content of response.
840 :raises HoneycombError: If it is not possible to get information about
841 interfaces or it is not possible to delete the interface.
844 path = ("interfaces", ("interface", "name", interface))
846 status_code, resp = HcUtil.\
847 get_honeycomb_data(node, "config_vpp_interfaces")
848 if status_code != HTTPCodes.OK:
849 raise HoneycombError(
850 "Not possible to get configuration information about the "
851 "interfaces. Status code: {0}.".format(status_code))
853 new_data = HcUtil.remove_item(resp, path)
854 status_code, resp = HcUtil.\
855 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
856 if status_code != HTTPCodes.OK:
857 raise HoneycombError("Not possible to remove interface {0}. "
859 format(interface, status_code))
863 def configure_interface_vxlan(node, interface, **kwargs):
864 """Configure VxLAN on the interface.
866 The keyword configures VxLAN parameters on the given interface. The type
867 of interface must be set to "v3po:vxlan-tunnel".
868 The new VxLAN parameters overwrite the current configuration. If a
869 parameter in new configuration is missing, it is removed from VxLAN
871 If the dictionary kwargs is empty, VxLAN configuration is removed.
873 :param node: Honeycomb node.
874 :param interface: The name of interface.
875 :param kwargs: Parameters and their values. The accepted parameters are
876 defined in InterfaceKeywords.VXLAN_PARAMS.
880 :returns: Content of response.
882 :raises HoneycombError: If the parameter is not valid.
885 vx_lan_structure = dict()
886 for param, value in kwargs.items():
887 if param not in InterfaceKeywords.VXLAN_PARAMS:
888 raise HoneycombError("The parameter {0} is invalid.".
890 vx_lan_structure[param] = value
892 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
893 return InterfaceKeywords._set_interface_properties(
894 node, interface, path, vx_lan_structure)
897 def configure_interface_l2(node, interface, param, value):
898 """Configure the L2 parameters of interface.
900 :param node: Honeycomb node.
901 :param interface: The name of interface.
902 :param param: Parameter to configure (set, change, remove)
903 :param value: The value of parameter. If None, the parameter will be
909 :returns: Content of response.
911 :raises HoneycombError: If the parameter is not valid.
914 if param not in InterfaceKeywords.L2_PARAMS:
915 raise HoneycombError("The parameter {0} is invalid.".format(param))
916 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
918 return InterfaceKeywords._set_interface_properties(
919 node, interface, path, value)
922 def create_tap_interface(node, interface, **kwargs):
923 """Create a new TAP interface.
925 :param node: Honeycomb node.
926 :param interface: The name of interface.
927 :param kwargs: Parameters and their values. The accepted parameters are
928 defined in InterfaceKeywords.TAP_PARAMS.
932 :returns: Content of response.
934 :raises HoneycombError: If the parameter is not valid.
942 for param, value in kwargs.items():
943 if param not in InterfaceKeywords.TAP_PARAMS:
944 raise HoneycombError("The parameter {0} is invalid.".
946 new_tap["v3po:tap"][param] = value
948 path = ("interfaces", "interface")
949 new_tap_structure = [new_tap, ]
950 return InterfaceKeywords._set_interface_properties(
951 node, interface, path, new_tap_structure)
954 def configure_interface_tap(node, interface, **kwargs):
955 """Configure TAP on the interface.
957 The keyword configures TAP parameters on the given interface. The type
958 of interface must be set to "v3po:tap".
959 The new TAP parameters overwrite the current configuration. If a
960 parameter in new configuration is missing, it is removed from TAP
962 If the dictionary kwargs is empty, TAP configuration is removed.
964 :param node: Honeycomb node.
965 :param interface: The name of interface.
966 :param kwargs: Parameters and their values. The accepted parameters are
967 defined in InterfaceKeywords.TAP_PARAMS.
971 :returns: Content of response.
973 :raises HoneycombError: If the parameter is not valid.
976 tap_structure = dict()
977 for param, value in kwargs.items():
978 if param not in InterfaceKeywords.TAP_PARAMS:
979 raise HoneycombError("The parameter {0} is invalid.".
981 tap_structure[param] = value
983 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
984 return InterfaceKeywords._set_interface_properties(
985 node, interface, path, tap_structure)
988 def configure_interface_vhost_user(node, interface, **kwargs):
989 """Configure vhost-user on the interface.
991 The keyword configures vhost-user parameters on the given interface.
992 The type of interface must be set to "v3po:vhost-user".
993 The new vhost-user parameters overwrite the current configuration. If a
994 parameter in new configuration is missing, it is removed from vhost-user
996 If the dictionary kwargs is empty, vhost-user configuration is removed.
998 :param node: Honeycomb node.
999 :param interface: The name of interface.
1000 :param kwargs: Parameters and their values. The accepted parameters are
1001 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1003 :type interface: str
1005 :returns: Content of response.
1007 :raises HoneycombError: If the parameter is not valid.
1010 vhost_structure = dict()
1011 for param, value in kwargs.items():
1012 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1013 raise HoneycombError("The parameter {0} is invalid.".
1015 vhost_structure[param] = value
1017 path = ("interfaces", ("interface", "name", interface),
1019 return InterfaceKeywords._set_interface_properties(
1020 node, interface, path, vhost_structure)
1023 def create_vhost_user_interface(node, interface, **kwargs):
1024 """Create a new vhost-user interface.
1026 :param node: Honeycomb node.
1027 :param interface: The name of interface.
1028 :param kwargs: Parameters and their values. The accepted parameters are
1029 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1031 :type interface: str
1033 :returns: Content of response.
1035 :raises HoneycombError: If the parameter is not valid.
1040 "type": "v3po:vhost-user",
1041 "v3po:vhost-user": {}
1043 for param, value in kwargs.items():
1044 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1045 raise HoneycombError("The parameter {0} is invalid.".
1047 new_vhost["v3po:vhost-user"][param] = value
1049 path = ("interfaces", "interface")
1050 new_vhost_structure = [new_vhost, ]
1051 return InterfaceKeywords._set_interface_properties(
1052 node, interface, path, new_vhost_structure)
1055 def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
1056 """Create a new sub-interface.
1058 :param node: Honeycomb node.
1059 :param super_interface: Super interface.
1060 :param match: Match type. The valid values are defined in
1061 InterfaceKeywords.SUB_IF_MATCH.
1062 :param tags: List of tags.
1063 :param kwargs: Parameters and their values. The accepted parameters are
1064 defined in InterfaceKeywords.SUB_IF_PARAMS.
1066 :type super_interface: str
1070 :returns: Content of response.
1072 :raises HoneycombError: If the parameter is not valid.
1073 :raises KeyError: If the parameter 'match' is invalid.
1082 {"vlan-tagged": {"match-exact-tags": "false"}},
1083 "vlan-tagged-exact-match":
1084 {"vlan-tagged": {"match-exact-tags": "true"}}
1087 new_sub_interface = {
1093 for param, value in kwargs.items():
1094 if param in InterfaceKeywords.SUB_IF_PARAMS:
1095 new_sub_interface[param] = value
1097 raise HoneycombError("The parameter {0} is invalid.".
1100 new_sub_interface["match"] = match_type[match]
1102 raise HoneycombError("The value '{0}' of parameter 'match' is "
1103 "invalid.".format(match))
1106 new_sub_interface["tags"]["tag"].extend(tags)
1108 path = ("interfaces",
1109 ("interface", "name", super_interface),
1110 "vpp-vlan:sub-interfaces",
1112 new_sub_interface_structure = [new_sub_interface, ]
1113 return InterfaceKeywords._set_interface_properties(
1114 node, super_interface, path, new_sub_interface_structure)
1117 def get_sub_interface_oper_data(node, super_interface, identifier):
1118 """Retrieves sub-interface operational data using Honeycomb API.
1120 :param node: Honeycomb node.
1121 :param super_interface: Super interface.
1122 :param identifier: The ID of sub-interface.
1124 :type super_interface: str
1125 :type identifier: int
1126 :returns: Sub-interface operational data.
1128 :raises HoneycombError: If there is no sub-interface with the given ID.
1131 if_data = InterfaceKeywords.get_interface_oper_data(node,
1133 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1134 if str(sub_if["identifier"]) == str(identifier):
1137 raise HoneycombError("The interface {0} does not have sub-interface "
1138 "with ID {1}".format(super_interface, identifier))
1141 def remove_all_sub_interfaces(node, super_interface):
1142 """Remove all sub-interfaces from the given interface.
1144 :param node: Honeycomb node.
1145 :param super_interface: Super interface.
1147 :type super_interface: str
1148 :returns: Content of response.
1152 path = ("interfaces",
1153 ("interface", "name", super_interface),
1154 "vpp-vlan:sub-interfaces")
1156 return InterfaceKeywords._set_interface_properties(
1157 node, super_interface, path, {})
1160 def set_sub_interface_state(node, super_interface, identifier, state):
1161 """Set the administrative state of sub-interface.
1163 :param node: Honeycomb node.
1164 :param super_interface: Super interface.
1165 :param identifier: The ID of sub-interface.
1166 :param state: Required sub-interface state - up or down.
1168 :type super_interface: str
1169 :type identifier: int
1171 :returns: Content of response.
1175 super_interface = Topology.convert_interface_reference(
1176 node, super_interface, "name")
1178 intf_state = {"up": "true",
1181 path = ("interfaces",
1182 ("interface", "name", super_interface),
1183 "vpp-vlan:sub-interfaces",
1184 ("sub-interface", "identifier", int(identifier)),
1187 return InterfaceKeywords._set_interface_properties(
1188 node, super_interface, path, intf_state[state])
1191 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1193 """Add a sub-interface to a bridge domain and set its parameters.
1195 :param node: Honeycomb node.
1196 :param super_interface: Super interface.
1197 :param identifier: The ID of sub-interface.
1198 :param config: Bridge domain configuration.
1200 :type super_interface: str
1201 :type identifier: int
1203 :returns: Content of response.
1207 path = ("interfaces",
1208 ("interface", "name", super_interface),
1209 "vpp-vlan:sub-interfaces",
1210 ("sub-interface", "identifier", int(identifier)),
1213 return InterfaceKeywords._set_interface_properties(
1214 node, super_interface, path, config)
1217 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1218 """Get the operational data about the bridge domain from sub-interface.
1220 :param node: Honeycomb node.
1221 :param super_interface: Super interface.
1222 :param identifier: The ID of sub-interface.
1224 :type super_interface: str
1225 :type identifier: int
1226 :returns: Operational data about the bridge domain.
1228 :raises HoneycombError: If there is no sub-interface with the given ID.
1232 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1233 node, super_interface, identifier)["l2"]
1236 raise HoneycombError("The operational data does not contain "
1237 "information about a bridge domain.")
1240 def configure_tag_rewrite(node, super_interface, identifier, config):
1241 """Add / change / disable vlan tag rewrite on a sub-interface.
1243 :param node: Honeycomb node.
1244 :param super_interface: Super interface.
1245 :param identifier: The ID of sub-interface.
1246 :param config: Rewrite tag configuration.
1248 :type super_interface: str
1249 :type identifier: int
1251 :returns: Content of response.
1255 path = ("interfaces",
1256 ("interface", "name", super_interface),
1257 "vpp-vlan:sub-interfaces",
1258 ("sub-interface", "identifier", int(identifier)),
1262 return InterfaceKeywords._set_interface_properties(
1263 node, super_interface, path, config)
1266 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1267 """Get the operational data about tag rewrite.
1269 :param node: Honeycomb node.
1270 :param super_interface: Super interface.
1271 :param identifier: The ID of sub-interface.
1273 :type super_interface: str
1274 :type identifier: int
1275 :returns: Operational data about tag rewrite.
1277 :raises HoneycombError: If there is no sub-interface with the given ID.
1281 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1282 node, super_interface, identifier)["l2"]["rewrite"]
1285 raise HoneycombError("The operational data does not contain "
1286 "information about the tag-rewrite.")
1289 def add_ip_address_to_sub_interface(node, super_interface, identifier,
1290 ip_addr, network, ip_version):
1291 """Add an ipv4 address to the specified sub-interface, with the provided
1292 netmask or network prefix length. Any existing ipv4 addresses on the
1293 sub-interface will be replaced.
1295 :param node: Honeycomb node.
1296 :param super_interface: Super interface.
1297 :param identifier: The ID of sub-interface.
1298 :param ip_addr: IPv4 address to be set.
1299 :param network: Network mask or network prefix length.
1300 :param ip_version: ipv4 or ipv6
1302 :type super_interface: str
1303 :type identifier: int
1305 :type network: str or int
1306 :type ip_version: string
1307 :returns: Content of response.
1309 :raises HoneycombError: If the provided netmask or prefix is not valid.
1312 path = ("interfaces",
1313 ("interface", "name", super_interface),
1314 "vpp-vlan:sub-interfaces",
1315 ("sub-interface", "identifier", int(identifier)),
1318 if isinstance(network, basestring) and ip_version.lower() == "ipv4":
1319 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1321 elif isinstance(network, int) and 0 < network < 33:
1322 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1325 raise HoneycombError("{0} is not a valid netmask or prefix length."
1328 return InterfaceKeywords._set_interface_properties(
1329 node, super_interface, path, address)
1332 def remove_all_ip_addresses_from_sub_interface(node, super_interface,
1333 identifier, ip_version):
1334 """Remove all ipv4 addresses from the specified sub-interface.
1336 :param node: Honeycomb node.
1337 :param super_interface: Super interface.
1338 :param identifier: The ID of sub-interface.
1339 :param ip_version: ipv4 or ipv6
1341 :type super_interface: str
1342 :type identifier: int
1343 :type ip_version: string
1344 :returns: Content of response.
1348 path = ("interfaces",
1349 ("interface", "name", super_interface),
1350 "vpp-vlan:sub-interfaces",
1351 ("sub-interface", "identifier", int(identifier)),
1352 str(ip_version), "address")
1354 return InterfaceKeywords._set_interface_properties(
1355 node, super_interface, path, None)
1358 def compare_data_structures(data, ref, _path=''):
1359 """Checks if data obtained from UUT is as expected. If it is not,
1360 proceeds down the list/dictionary tree and finds the point of mismatch.
1362 :param data: Data to be checked.
1363 :param ref: Referential data used for comparison.
1364 :param _path: Used in recursive calls, stores the path taken down
1370 :raises HoneycombError: If the data structures do not match in some way,
1371 or if they are not in deserialized JSON format.
1377 elif isinstance(data, dict) and isinstance(ref, dict):
1380 raise HoneycombError(
1381 "Key {key} is not present in path {path}. Keys in path:"
1382 "{data_keys}".format(
1385 data_keys=data.keys()))
1387 if data[key] != ref[key]:
1388 if isinstance(data[key], list) \
1389 or isinstance(data[key], dict):
1390 InterfaceKeywords.compare_data_structures(
1391 data[key], ref[key],
1392 _path + '[{0}]'.format(key))
1394 raise HoneycombError(
1395 "Data mismatch, key {key} in path {path} has value"
1396 " {data}, but should be {ref}".format(
1402 elif isinstance(data, list) and isinstance(ref, list):
1404 if item not in data:
1405 if isinstance(item, dict):
1406 InterfaceKeywords.compare_data_structures(
1408 _path + '[{0}]'.format(ref.index(item)))
1410 raise HoneycombError(
1411 "Data mismatch, list item {index} in path {path}"
1412 " has value {data}, but should be {ref}".format(
1413 index=ref.index(item),
1419 raise HoneycombError(
1420 "Unexpected data type {data_type} in path {path}, reference"
1421 " type is {ref_type}. Must be list or dictionary.".format(
1422 data_type=type(data),
1427 def compare_interface_lists(list1, list2):
1428 """Compare provided lists of interfaces by name.
1430 :param list1: List of interfaces.
1431 :param list2: List of interfaces.
1434 :raises HoneycombError: If an interface exists in only one of the lists.
1437 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1438 # these have no equivalent in config data and no effect on VPP
1440 names1 = [x['name'] for x in list1]
1441 names2 = [x['name'] for x in list2]
1444 if name not in names2 and name not in ignore:
1445 raise HoneycombError("Interface {0} not present in list {1}"
1446 .format(name, list2))
1448 if name not in names1 and name not in ignore:
1449 raise HoneycombError("Interface {0} not present in list {1}"
1450 .format(name, list1))
1453 def create_vxlan_gpe_interface(node, interface, **kwargs):
1454 """Create a new VxLAN GPE interface.
1456 :param node: Honeycomb node.
1457 :param interface: The name of interface to be created.
1458 :param kwargs: Parameters and their values. The accepted parameters are
1459 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1461 :type interface: str
1463 :returns: Content of response.
1465 :raises HoneycombError: If a parameter in kwargs is not valid.
1470 "type": "v3po:vxlan-gpe-tunnel",
1471 "v3po:vxlan-gpe": {}
1473 for param, value in kwargs.items():
1474 if param in InterfaceKeywords.INTF_PARAMS:
1475 new_vxlan_gpe[param] = value
1476 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1477 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1479 raise HoneycombError("The parameter {0} is invalid.".
1481 path = ("interfaces", "interface")
1482 vxlan_gpe_structure = [new_vxlan_gpe, ]
1483 return InterfaceKeywords._set_interface_properties(
1484 node, interface, path, vxlan_gpe_structure)
1487 def enable_acl_on_interface(node, interface, table_name):
1488 """Enable ACL on the given interface.
1490 :param node: Honeycomb node.
1491 :param interface: The interface where the ACL will be enabled.
1492 :param table_name: Name of the classify table.
1494 :type interface: str
1495 :type table_name: str
1496 :returns: Content of response.
1498 :raises HoneycombError: If the configuration of interface is not
1502 interface = interface.replace("/", "%2F")
1505 "vpp-interface-acl:acl": {
1508 "classify-table": table_name
1511 "classify-table": table_name
1517 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1518 status_code, resp = HcUtil.\
1519 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1520 data_representation=DataRepresentation.JSON)
1521 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1522 raise HoneycombError(
1523 "The configuration of interface '{0}' was not successful. "
1524 "Status code: {1}.".format(interface, status_code))
1528 def enable_policer_on_interface(node, interface, table_name):
1529 """Enable Policer on the given interface.
1531 :param node: Honeycomb node.
1532 :param interface: The interface where policer will be enabled.
1533 :param table_name: Name of the classify table.
1535 :type interface: str
1536 :type table_name: str
1537 :returns: Content of response.
1539 :raises HoneycombError: If the configuration of interface is not
1542 interface = Topology.convert_interface_reference(
1543 node, interface, "name")
1544 interface = interface.replace("/", "%2F")
1547 "interface-policer:policer": {
1548 "ip4-table": table_name
1552 path = "/interface/" + interface + "/interface-policer:policer"
1553 status_code, resp = HcUtil.\
1554 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1555 data_representation=DataRepresentation.JSON)
1556 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1557 raise HoneycombError(
1558 "The configuration of interface '{0}' was not successful. "
1559 "Status code: {1}.".format(interface, status_code))
1563 def disable_policer_on_interface(node, interface):
1564 """Disable Policer on the given interface.
1566 :param node: Honeycomb node.
1567 :param interface: The interface where policer will be disabled.
1569 :type interface: str
1570 :returns: Content of response.
1572 :raises HoneycombError: If the configuration of interface is not
1575 interface = Topology.convert_interface_reference(
1576 node, interface, "name")
1577 interface = interface.replace("/", "%2F")
1579 path = "/interface/" + interface + "/interface-policer:policer"
1580 status_code, resp = HcUtil.\
1581 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1582 if status_code != HTTPCodes.OK:
1583 raise HoneycombError(
1584 "The configuration of interface '{0}' was not successful. "
1585 "Status code: {1}.".format(interface, status_code))
1589 def disable_acl_on_interface(node, interface):
1590 """Disable ACL on the given interface.
1592 :param node: Honeycomb node.
1593 :param interface: The interface where the ACL will be disabled.
1595 :type interface: str
1596 :returns: Content of response.
1598 :raises HoneycombError: If the configuration of interface is not
1602 interface = interface.replace("/", "%2F")
1604 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1606 status_code, resp = HcUtil.\
1607 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1609 if status_code != HTTPCodes.OK:
1610 raise HoneycombError(
1611 "The configuration of interface '{0}' was not successful. "
1612 "Status code: {1}.".format(interface, status_code))
1616 def create_pbb_sub_interface(node, intf, params):
1617 """Creates a PBB sub-interface on the given interface and sets its
1620 :param node: Honeycomb node.
1621 :param intf: The interface where PBB sub-interface will be configured.
1622 :param params: Configuration parameters of the sub-interface to be
1627 :returns: Content of response.
1629 :raises HoneycombError: If the configuration of sub-interface is not
1633 interface = intf.replace("/", "%2F")
1634 path = "/interface/{0}/pbb-rewrite".format(interface)
1635 status_code, resp = HcUtil. \
1636 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1637 data_representation=DataRepresentation.JSON)
1638 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1639 raise HoneycombError(
1640 "The configuration of PBB sub-interface '{0}' was not "
1641 "successful. Status code: {1}.".format(intf, status_code))
1645 def delete_pbb_sub_interface(node, intf):
1646 """Deletes the given PBB sub-interface.
1648 :param node: Honeycomb node.
1649 :param intf: The interface where PBB sub-interface will be deleted.
1652 :returns: Content of response.
1654 :raises HoneycombError: If the removal of sub-interface is not
1658 interface = intf.replace("/", "%2F")
1659 path = "/interface/{0}/pbb-rewrite".format(interface)
1661 status_code, resp = HcUtil. \
1662 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1663 if status_code != HTTPCodes.OK:
1664 raise HoneycombError(
1665 "The removal of pbb sub-interface '{0}' was not successful. "
1666 "Status code: {1}.".format(intf, status_code))
1670 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1671 """Retrieves PBB sub-interface operational data from Honeycomb.
1673 :param node: Honeycomb node.
1674 :param intf: The interface where PBB sub-interface is located.
1675 :param sub_if_id: ID of the PBB sub-interface.
1678 :type sub_if_id: str or int
1679 :returns: PBB sub-interface operational data.
1681 :raises HoneycombError: If the removal of sub-interface is not
1685 raise NotImplementedError
1688 def check_disabled_interface(node, interface):
1689 """Retrieves list of disabled interface indices from Honeycomb,
1690 and matches with the provided interface by index.
1692 :param node: Honeycomb node.
1693 :param interface: Index number of an interface on the node.
1695 :type interface: int
1696 :returns: True if the interface exists in disabled interfaces.
1698 :raises HoneycombError: If the interface is not present
1699 in retrieved list of disabled interfaces.
1701 data = InterfaceKeywords.get_disabled_interfaces_oper_data(node)
1702 # decrement by one = conversion from HC if-index to VPP sw_if_index
1706 if item["index"] == interface:
1708 raise HoneycombError("Interface index {0} not present in list"
1709 " of disabled interfaces.".format(interface))
1712 def configure_interface_span(node, dst_interface, src_interfaces=None):
1713 """Configure SPAN port mirroring on the specified interfaces. If no
1714 source interface is provided, SPAN will be disabled.
1716 :param node: Honeycomb node.
1717 :param dst_interface: Interface to mirror packets to.
1718 :param src_interfaces: List of interfaces to mirror packets from.
1720 :type dst_interface: str or int
1721 :type src_interfaces: list of dict
1722 :returns: Content of response.
1724 :raises HoneycombError: If SPAN could not be configured.
1727 interface = Topology.convert_interface_reference(
1728 node, dst_interface, "name")
1729 interface = interface.replace("/", "%2F")
1730 path = "/interface/" + interface + "/span"
1732 if not src_interfaces:
1733 status_code, _ = HcUtil.delete_honeycomb_data(
1734 node, "config_vpp_interfaces", path)
1736 for src_interface in src_interfaces:
1737 src_interface["iface-ref"] = Topology.\
1738 convert_interface_reference(
1739 node, src_interface["iface-ref"], "name")
1742 "mirrored-interfaces": {
1743 "mirrored-interface": src_interfaces
1748 status_code, _ = HcUtil.put_honeycomb_data(
1749 node, "config_vpp_interfaces", data, path)
1751 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1752 raise HoneycombError(
1753 "Configuring SPAN failed. Status code:{0}".format(status_code))
1756 def configure_sub_interface_span(node, super_interface, dst_interface_index,
1757 src_interfaces=None):
1758 """Configure SPAN port mirroring on the specified sub-interface. If no
1759 source interface is provided, SPAN will be disabled.
1761 Note: Does not support source sub-interfaces, only destination.
1763 :param node: Honeycomb node.
1764 :param super_interface: Name, link name or sw_if_index
1765 of the destination interface's super-interface.
1766 :param dst_interface_index: Index of sub-interface to mirror packets to.
1767 :param src_interfaces: List of interfaces to mirror packets from.
1769 :type super_interface: str or int
1770 :type dst_interface_index: int
1771 :type src_interfaces: list of dict
1772 :returns: Content of response.
1774 :raises HoneycombError: If SPAN could not be configured.
1777 super_interface = Topology.convert_interface_reference(
1778 node, super_interface, "name")
1779 super_interface = super_interface.replace("/", "%2F")
1781 path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
1782 .format(super_interface, dst_interface_index)
1784 if not src_interfaces:
1785 status_code, _ = HcUtil.delete_honeycomb_data(
1786 node, "config_vpp_interfaces", path)
1788 for src_interface in src_interfaces:
1789 src_interface["iface-ref"] = Topology. \
1790 convert_interface_reference(
1791 node, src_interface["iface-ref"], "name")
1794 "mirrored-interfaces": {
1795 "mirrored-interface": src_interfaces
1800 status_code, _ = HcUtil.put_honeycomb_data(
1801 node, "config_vpp_interfaces", data, path)
1803 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1804 raise HoneycombError(
1805 "Configuring SPAN failed. Status code:{0}".format(status_code))
1808 def add_interface_local0_to_topology(node):
1809 """Use Topology methods to add interface "local0" to working topology,
1810 if not already present.
1812 :param node: DUT node.
1816 if Topology.get_interface_by_sw_index(node, 0) is None:
1817 local0_key = Topology.add_new_port(node, "localzero")
1818 Topology.update_interface_sw_if_index(node, local0_key, 0)
1819 Topology.update_interface_name(node, local0_key, "local0")
1822 def configure_interface_unnumbered(node, interface, interface_src=None):
1823 """Configure the specified interface as unnumbered. The interface
1824 borrows IP address from the specified source interface. If not source
1825 interface is provided, unnumbered configuration will be removed.
1827 :param node: Honeycomb node.
1828 :param interface: Name, link name or sw_if_index of an interface.
1829 :param interface_src: Name of source interface.
1831 :type interface: str or int
1832 :type interface_src: str
1833 :raises HoneycombError: If the configuration fails.
1836 interface = InterfaceKeywords.handle_interface_reference(
1839 path = "/interface/{0}/unnumbered-interfaces:unnumbered"\
1845 "use": interface_src
1848 status_code, _ = HcUtil.put_honeycomb_data(
1849 node, "config_vpp_interfaces", data, path)
1851 status_code, _ = HcUtil.delete_honeycomb_data(
1852 node, "config_vpp_interfaces", path)
1854 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1855 raise HoneycombError(
1856 "Configuring unnumbered interface failed. "
1857 "Status code:{0}".format(status_code))
1860 def handle_interface_reference(node, interface):
1861 """Convert any interface reference to interface name used by Honeycomb.
1863 :param node: Honeycomb node.
1864 :param interface: Name, link name or sw_if_index of an interface,
1865 name of a custom interface or name of a sub-interface.
1866 :type node: Honeycomb node.
1867 :type interface: str or int
1868 :returns: Name of interface that can be used in Honeycomb requests.
1873 interface = Topology.convert_interface_reference(
1874 node, interface, "name")
1875 interface = interface.replace("/", "%2F")
1876 except RuntimeError:
1877 # interface is not in topology
1878 if "." in interface:
1879 # Assume it's the name of a sub-interface
1880 interface, index = interface.split(".")
1881 interface = interface.replace("/", "%2F")
1882 interface = "{0}/vpp-vlan:sub-interfaces/sub-interface/{1}".\
1883 format(interface, index)
1885 # Assume it's the name of a custom interface (pbb, vxlan, etc.)
1886 interface = interface.replace("/", "%2F")