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 honeycomb_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.honeycomb_set_interface_state(
314 node, interface, "up")
317 def set_interface_down(node, interface):
318 """Set the administration state of VPP interface to down.
320 :param node: Honeycomb node.
321 :param interface: The name of interface.
324 :returns: Content of response.
328 return InterfaceKeywords.honeycomb_set_interface_state(
329 node, interface, "down")
332 def add_bridge_domain_to_interface(node, interface, bd_name,
333 split_horizon_group=None, bvi=None):
334 """Add a new bridge domain to an interface and set its parameters.
336 :param node: Honeycomb node.
337 :param interface: Interface name, key, link name or sw_if_index.
338 :param bd_name: Bridge domain name.
339 :param split_horizon_group: Split-horizon group name.
340 :param bvi: The bridged virtual interface.
344 :type split_horizon_group: str
346 :returns: Content of response.
348 :raises HoneycombError: If the interface is not present on the node.
351 interface = Topology.convert_interface_reference(
352 node, interface, "name")
354 v3po_l2 = {"bridge-domain": str(bd_name)}
355 if split_horizon_group:
356 v3po_l2["split-horizon-group"] = str(split_horizon_group)
358 v3po_l2["bridged-virtual-interface"] = str(bvi)
360 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
362 return InterfaceKeywords._set_interface_properties(
363 node, interface, path, v3po_l2)
366 def remove_bridge_domain_from_interface(node, interface):
367 """Remove bridge domain assignment from interface.
369 :param node: Honeycomb node.
370 :param interface: Interface name, key, link name or sw_if_index.
372 :type interface: str or int
374 :raises HoneycombError: If the operation fails.
377 interface = Topology.convert_interface_reference(
378 node, interface, "name")
380 intf = interface.replace("/", "%2F")
382 path = "/interface/{0}/v3po:l2".format(intf)
384 status_code, response = HcUtil.delete_honeycomb_data(
385 node, "config_vpp_interfaces", path)
387 if status_code != HTTPCodes.OK:
388 if '"error-tag":"data-missing"' in response:
389 logger.debug("Data does not exist in path.")
391 raise HoneycombError(
392 "Could not remove bridge domain assignment from interface "
393 "'{0}'. Status code: {1}.".format(interface, status_code))
396 def get_bd_oper_data_from_interface(node, interface):
397 """Returns operational data about bridge domain settings in the
400 :param node: Honeycomb node.
401 :param interface: The name of interface.
404 :returns: Operational data about bridge domain settings in the
409 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
413 return if_data["v3po:l2"]
419 def configure_interface_base(node, interface, param, value):
420 """Configure the base parameters of interface.
422 :param node: Honeycomb node.
423 :param interface: The name of interface.
424 :param param: Parameter to configure (set, change, remove)
425 :param value: The value of parameter. If None, the parameter will be
431 :returns: Content of response.
433 :raises HoneycombError: If the parameter is not valid.
436 if param not in InterfaceKeywords.INTF_PARAMS:
437 raise HoneycombError("The parameter {0} is invalid.".format(param))
439 path = ("interfaces", ("interface", "name", interface), param)
440 return InterfaceKeywords._set_interface_properties(
441 node, interface, path, value)
444 def configure_interface_ipv4(node, interface, param, value):
445 """Configure IPv4 parameters of interface.
447 :param node: Honeycomb node.
448 :param interface: The name of interface.
449 :param param: Parameter to configure (set, change, remove)
450 :param value: The value of parameter. If None, the parameter will be
456 :returns: Content of response.
458 :raises HoneycombError: If the parameter is not valid.
461 interface = Topology.convert_interface_reference(
462 node, interface, "name")
464 if param not in InterfaceKeywords.IPV4_PARAMS:
465 raise HoneycombError("The parameter {0} is invalid.".format(param))
467 path = ("interfaces", ("interface", "name", interface),
468 "ietf-ip:ipv4", param)
469 return InterfaceKeywords._set_interface_properties(
470 node, interface, path, value)
473 def add_first_ipv4_address(node, interface, ip_addr, network):
474 """Add the first IPv4 address.
476 If there are any other addresses configured, they will be removed.
478 :param node: Honeycomb node.
479 :param interface: The name of interface.
480 :param ip_addr: IPv4 address to be set.
481 :param network: Netmask or length of network prefix.
485 :type network: str or int
486 :returns: Content of response.
488 :raises ValueError: If the provided netmask or prefix is not valid.
489 :raises HoneycombError: If the operation fails.
492 interface = InterfaceKeywords.handle_interface_reference(
495 path = "/interface/{0}/ietf-ip:ipv4".format(interface)
496 if isinstance(network, basestring):
499 "address": [{"ip": ip_addr, "netmask": network}, ]}}
500 elif isinstance(network, int) and (0 < network < 33):
503 "address": [{"ip": ip_addr, "prefix-length": network}, ]}}
505 raise ValueError("Value {0} is not a valid netmask or network "
506 "prefix length.".format(network))
507 status_code, _ = HcUtil.put_honeycomb_data(
508 node, "config_vpp_interfaces", data, path)
510 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
511 raise HoneycombError(
512 "Configuring IPv4 address failed. "
513 "Status code:{0}".format(status_code))
516 def add_ipv4_address(node, interface, ip_addr, network):
519 :param node: Honeycomb node.
520 :param interface: The name of interface.
521 :param ip_addr: IPv4 address to be set.
522 :param network: Netmask or length of network prefix.
526 :type network: str or int
527 :returns: Content of response.
529 :raises HoneycombError: If the provided netmask or prefix is not valid.
532 interface = Topology.convert_interface_reference(
533 node, interface, "name")
535 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
537 if isinstance(network, basestring):
538 address = [{"ip": ip_addr, "netmask": network}]
539 elif isinstance(network, int) and (0 < network < 33):
540 address = [{"ip": ip_addr, "prefix-length": network}]
542 raise HoneycombError("Value {0} is not a valid netmask or network "
543 "prefix length.".format(network))
544 return InterfaceKeywords._set_interface_properties(
545 node, interface, path, address)
548 def remove_all_ipv4_addresses(node, interface):
549 """Remove all IPv4 addresses from interface.
551 :param node: Honeycomb node.
552 :param interface: The name of interface.
555 :returns: Content of response.
559 interface = Topology.convert_interface_reference(
560 node, interface, "name")
562 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
564 return InterfaceKeywords._set_interface_properties(
565 node, interface, path, None)
568 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
569 """Add the IPv4 neighbour.
571 :param node: Honeycomb node.
572 :param interface: The name of interface.
573 :param ip_addr: IPv4 address of neighbour to be set.
574 :param link_layer_address: Link layer address.
578 :type link_layer_address: str
579 :returns: Content of response.
583 interface = Topology.convert_interface_reference(
584 node, interface, "name")
586 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
588 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
589 return InterfaceKeywords._set_interface_properties(
590 node, interface, path, neighbor)
593 def remove_all_ipv4_neighbors(node, interface):
594 """Remove all IPv4 neighbours.
596 :param node: Honeycomb node.
597 :param interface: The name of interface.
600 :returns: Content of response.
604 interface = Topology.convert_interface_reference(
605 node, interface, "name")
607 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
609 return InterfaceKeywords._set_interface_properties(
610 node, interface, path, None)
613 def configure_interface_ipv6(node, interface, param, value):
614 """Configure IPv6 parameters of interface
616 :param node: Honeycomb node.
617 :param interface: The name of interface.
618 :param param: Parameter to configure (set, change, remove)
619 :param value: The value of parameter. If None, the parameter will be
625 :returns: Content of response.
627 :raises HoneycombError: If the parameter is not valid.
630 if param in InterfaceKeywords.IPV6_PARAMS:
631 path = ("interfaces", ("interface", "name", interface),
632 "ietf-ip:ipv6", param)
633 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
634 path = ("interfaces", ("interface", "name", interface),
635 "ietf-ip:ipv6", "autoconf", param)
637 raise HoneycombError("The parameter {0} is invalid.".format(param))
639 return InterfaceKeywords._set_interface_properties(
640 node, interface, path, value)
643 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
644 """Add the first IPv6 address.
646 If there are any other addresses configured, they will be removed.
648 :param node: Honeycomb node.
649 :param interface: The name of interface.
650 :param ip_addr: IPv6 address to be set.
651 :param prefix_len: Prefix length.
655 :type prefix_len: str
656 :returns: Content of response.
660 interface = Topology.convert_interface_reference(
661 node, interface, "name")
663 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
664 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
665 return InterfaceKeywords._set_interface_properties(
666 node, interface, path, address)
669 def add_ipv6_address(node, interface, ip_addr, prefix_len):
672 :param node: Honeycomb node.
673 :param interface: The name of interface.
674 :param ip_addr: IPv6 address to be set.
675 :param prefix_len: Prefix length.
679 :type prefix_len: str
680 :returns: Content of response.
684 interface = Topology.convert_interface_reference(
685 node, interface, "name")
687 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
689 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
690 return InterfaceKeywords._set_interface_properties(
691 node, interface, path, address)
694 def remove_all_ipv6_addresses(node, interface):
695 """Remove all IPv6 addresses from interface.
697 :param node: Honeycomb node.
698 :param interface: The name of interface.
701 :returns: Content of response.
705 interface = Topology.convert_interface_reference(
706 node, interface, "name")
708 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
710 return InterfaceKeywords._set_interface_properties(
711 node, interface, path, None)
714 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
715 """Add the IPv6 neighbour.
717 :param node: Honeycomb node.
718 :param interface: The name of interface.
719 :param ip_addr: IPv6 address of neighbour to be set.
720 :param link_layer_address: Link layer address.
724 :type link_layer_address: str
725 :returns: Content of response.
729 interface = Topology.convert_interface_reference(
730 node, interface, "name")
732 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
734 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
735 return InterfaceKeywords._set_interface_properties(
736 node, interface, path, neighbor)
739 def remove_all_ipv6_neighbors(node, interface):
740 """Remove all IPv6 neighbours.
742 :param node: Honeycomb node.
743 :param interface: The name of interface.
746 :returns: Content of response.
750 interface = Topology.convert_interface_reference(
751 node, interface, "name")
753 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
755 return InterfaceKeywords._set_interface_properties(
756 node, interface, path, None)
759 def configure_interface_ethernet(node, interface, param, value):
760 """Configure the ethernet parameters of interface.
762 :param node: Honeycomb node.
763 :param interface: The name of interface.
764 :param param: Parameter to configure (set, change, remove)
765 :param value: The value of parameter. If None, the parameter will be
771 :returns: Content of response.
773 :raises HoneycombError: If the parameter is not valid.
776 if param not in InterfaceKeywords.ETH_PARAMS:
777 raise HoneycombError("The parameter {0} is invalid.".format(param))
778 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
780 return InterfaceKeywords._set_interface_properties(
781 node, interface, path, value)
784 def configure_interface_routing(node, interface, param, value):
785 """Configure the routing parameters of interface.
787 :param node: Honeycomb node.
788 :param interface: The name of interface.
789 :param param: Parameter to configure (set, change, remove)
790 :param value: The value of parameter. If None, the parameter will be
796 :returns: Content of response.
798 :raises HoneycombError: If the parameter is not valid.
801 interface = Topology.convert_interface_reference(
802 node, interface, "name")
804 if param not in InterfaceKeywords.ROUTING_PARAMS:
805 raise HoneycombError("The parameter {0} is invalid.".format(param))
807 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
809 return InterfaceKeywords._set_interface_properties(
810 node, interface, path, value)
813 def honeycomb_create_vxlan_interface(node, interface, **kwargs):
814 """Create a new VxLAN interface.
816 :param node: Honeycomb node.
817 :param interface: The name of interface.
818 :param kwargs: Parameters and their values. The accepted parameters are
819 defined in InterfaceKeywords.VXLAN_PARAMS.
823 :returns: Content of response.
825 :raises HoneycombError: If the parameter is not valid.
830 "type": "v3po:vxlan-tunnel",
833 for param, value in kwargs.items():
834 if param not in InterfaceKeywords.VXLAN_PARAMS:
835 raise HoneycombError("The parameter {0} is invalid.".
837 new_vx_lan["v3po:vxlan"][param] = value
839 path = ("interfaces", "interface")
840 vx_lan_structure = [new_vx_lan, ]
841 return InterfaceKeywords._set_interface_properties(
842 node, interface, path, vx_lan_structure)
845 def delete_interface(node, interface):
846 """Delete an interface.
848 :param node: Honeycomb node.
849 :param interface: The name of interface.
852 :returns: Content of response.
854 :raises HoneycombError: If it is not possible to get information about
855 interfaces or it is not possible to delete the interface.
858 path = ("interfaces", ("interface", "name", interface))
860 status_code, resp = HcUtil.\
861 get_honeycomb_data(node, "config_vpp_interfaces")
862 if status_code != HTTPCodes.OK:
863 raise HoneycombError(
864 "Not possible to get configuration information about the "
865 "interfaces. Status code: {0}.".format(status_code))
867 new_data = HcUtil.remove_item(resp, path)
868 status_code, resp = HcUtil.\
869 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
870 if status_code != HTTPCodes.OK:
871 raise HoneycombError("Not possible to remove interface {0}. "
873 format(interface, status_code))
877 def honeycomb_configure_interface_vxlan(node, interface, **kwargs):
878 """Configure VxLAN on the interface.
880 The keyword configures VxLAN parameters on the given interface. The type
881 of interface must be set to "v3po:vxlan-tunnel".
882 The new VxLAN parameters overwrite the current configuration. If a
883 parameter in new configuration is missing, it is removed from VxLAN
885 If the dictionary kwargs is empty, VxLAN configuration is removed.
887 :param node: Honeycomb node.
888 :param interface: The name of interface.
889 :param kwargs: Parameters and their values. The accepted parameters are
890 defined in InterfaceKeywords.VXLAN_PARAMS.
894 :returns: Content of response.
896 :raises HoneycombError: If the parameter is not valid.
899 vx_lan_structure = dict()
900 for param, value in kwargs.items():
901 if param not in InterfaceKeywords.VXLAN_PARAMS:
902 raise HoneycombError("The parameter {0} is invalid.".
904 vx_lan_structure[param] = value
906 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
907 return InterfaceKeywords._set_interface_properties(
908 node, interface, path, vx_lan_structure)
911 def configure_interface_l2(node, interface, param, value):
912 """Configure the L2 parameters of interface.
914 :param node: Honeycomb node.
915 :param interface: The name of interface.
916 :param param: Parameter to configure (set, change, remove)
917 :param value: The value of parameter. If None, the parameter will be
923 :returns: Content of response.
925 :raises HoneycombError: If the parameter is not valid.
928 if param not in InterfaceKeywords.L2_PARAMS:
929 raise HoneycombError("The parameter {0} is invalid.".format(param))
930 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
932 return InterfaceKeywords._set_interface_properties(
933 node, interface, path, value)
936 def create_tap_interface(node, interface, **kwargs):
937 """Create a new TAP interface.
939 :param node: Honeycomb node.
940 :param interface: The name of interface.
941 :param kwargs: Parameters and their values. The accepted parameters are
942 defined in InterfaceKeywords.TAP_PARAMS.
946 :returns: Content of response.
948 :raises HoneycombError: If the parameter is not valid.
956 for param, value in kwargs.items():
957 if param not in InterfaceKeywords.TAP_PARAMS:
958 raise HoneycombError("The parameter {0} is invalid.".
960 new_tap["v3po:tap"][param] = value
962 path = ("interfaces", "interface")
963 new_tap_structure = [new_tap, ]
964 return InterfaceKeywords._set_interface_properties(
965 node, interface, path, new_tap_structure)
968 def configure_interface_tap(node, interface, **kwargs):
969 """Configure TAP on the interface.
971 The keyword configures TAP parameters on the given interface. The type
972 of interface must be set to "v3po:tap".
973 The new TAP parameters overwrite the current configuration. If a
974 parameter in new configuration is missing, it is removed from TAP
976 If the dictionary kwargs is empty, TAP configuration is removed.
978 :param node: Honeycomb node.
979 :param interface: The name of interface.
980 :param kwargs: Parameters and their values. The accepted parameters are
981 defined in InterfaceKeywords.TAP_PARAMS.
985 :returns: Content of response.
987 :raises HoneycombError: If the parameter is not valid.
990 tap_structure = dict()
991 for param, value in kwargs.items():
992 if param not in InterfaceKeywords.TAP_PARAMS:
993 raise HoneycombError("The parameter {0} is invalid.".
995 tap_structure[param] = value
997 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
998 return InterfaceKeywords._set_interface_properties(
999 node, interface, path, tap_structure)
1002 def configure_interface_vhost_user(node, interface, **kwargs):
1003 """Configure vhost-user on the interface.
1005 The keyword configures vhost-user parameters on the given interface.
1006 The type of interface must be set to "v3po:vhost-user".
1007 The new vhost-user parameters overwrite the current configuration. If a
1008 parameter in new configuration is missing, it is removed from vhost-user
1010 If the dictionary kwargs is empty, vhost-user configuration is removed.
1012 :param node: Honeycomb node.
1013 :param interface: The name of interface.
1014 :param kwargs: Parameters and their values. The accepted parameters are
1015 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1017 :type interface: str
1019 :returns: Content of response.
1021 :raises HoneycombError: If the parameter is not valid.
1024 vhost_structure = dict()
1025 for param, value in kwargs.items():
1026 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1027 raise HoneycombError("The parameter {0} is invalid.".
1029 vhost_structure[param] = value
1031 path = ("interfaces", ("interface", "name", interface),
1033 return InterfaceKeywords._set_interface_properties(
1034 node, interface, path, vhost_structure)
1037 def create_vhost_user_interface(node, interface, **kwargs):
1038 """Create a new vhost-user interface.
1040 :param node: Honeycomb node.
1041 :param interface: The name of interface.
1042 :param kwargs: Parameters and their values. The accepted parameters are
1043 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1045 :type interface: str
1047 :returns: Content of response.
1049 :raises HoneycombError: If the parameter is not valid.
1054 "type": "v3po:vhost-user",
1055 "v3po:vhost-user": {}
1057 for param, value in kwargs.items():
1058 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1059 raise HoneycombError("The parameter {0} is invalid.".
1061 new_vhost["v3po:vhost-user"][param] = value
1063 path = ("interfaces", "interface")
1064 new_vhost_structure = [new_vhost, ]
1065 return InterfaceKeywords._set_interface_properties(
1066 node, interface, path, new_vhost_structure)
1069 def honeycomb_create_sub_interface(node, super_interface, match, tags=None,
1071 """Create a new sub-interface.
1073 :param node: Honeycomb node.
1074 :param super_interface: Super interface.
1075 :param match: Match type. The valid values are defined in
1076 InterfaceKeywords.SUB_IF_MATCH.
1077 :param tags: List of tags.
1078 :param kwargs: Parameters and their values. The accepted parameters are
1079 defined in InterfaceKeywords.SUB_IF_PARAMS.
1081 :type super_interface: str
1085 :returns: Content of response.
1087 :raises HoneycombError: If the parameter is not valid.
1088 :raises KeyError: If the parameter 'match' is invalid.
1097 {"vlan-tagged": {"match-exact-tags": "false"}},
1098 "vlan-tagged-exact-match":
1099 {"vlan-tagged": {"match-exact-tags": "true"}}
1102 new_sub_interface = {
1108 for param, value in kwargs.items():
1109 if param in InterfaceKeywords.SUB_IF_PARAMS:
1110 new_sub_interface[param] = value
1112 raise HoneycombError("The parameter {0} is invalid.".
1115 new_sub_interface["match"] = match_type[match]
1117 raise HoneycombError("The value '{0}' of parameter 'match' is "
1118 "invalid.".format(match))
1121 new_sub_interface["tags"]["tag"].extend(tags)
1123 path = ("interfaces",
1124 ("interface", "name", super_interface),
1125 "vpp-vlan:sub-interfaces",
1127 new_sub_interface_structure = [new_sub_interface, ]
1128 return InterfaceKeywords._set_interface_properties(
1129 node, super_interface, path, new_sub_interface_structure)
1132 def get_sub_interface_oper_data(node, super_interface, identifier):
1133 """Retrieves sub-interface operational data using Honeycomb API.
1135 :param node: Honeycomb node.
1136 :param super_interface: Super interface.
1137 :param identifier: The ID of sub-interface.
1139 :type super_interface: str
1140 :type identifier: int
1141 :returns: Sub-interface operational data.
1143 :raises HoneycombError: If there is no sub-interface with the given ID.
1146 if_data = InterfaceKeywords.get_interface_oper_data(node,
1148 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1149 if str(sub_if["identifier"]) == str(identifier):
1152 raise HoneycombError("The interface {0} does not have sub-interface "
1153 "with ID {1}".format(super_interface, identifier))
1156 def remove_all_sub_interfaces(node, super_interface):
1157 """Remove all sub-interfaces from the given interface.
1159 :param node: Honeycomb node.
1160 :param super_interface: Super interface.
1162 :type super_interface: str
1163 :returns: Content of response.
1167 path = ("interfaces",
1168 ("interface", "name", super_interface),
1169 "vpp-vlan:sub-interfaces")
1171 return InterfaceKeywords._set_interface_properties(
1172 node, super_interface, path, {})
1175 def set_sub_interface_state(node, super_interface, identifier, state):
1176 """Set the administrative state of sub-interface.
1178 :param node: Honeycomb node.
1179 :param super_interface: Super interface.
1180 :param identifier: The ID of sub-interface.
1181 :param state: Required sub-interface state - up or down.
1183 :type super_interface: str
1184 :type identifier: int
1186 :returns: Content of response.
1190 super_interface = Topology.convert_interface_reference(
1191 node, super_interface, "name")
1193 intf_state = {"up": "true",
1196 path = ("interfaces",
1197 ("interface", "name", super_interface),
1198 "vpp-vlan:sub-interfaces",
1199 ("sub-interface", "identifier", int(identifier)),
1202 return InterfaceKeywords._set_interface_properties(
1203 node, super_interface, path, intf_state[state])
1206 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1208 """Add a sub-interface to a bridge domain and set its parameters.
1210 :param node: Honeycomb node.
1211 :param super_interface: Super interface.
1212 :param identifier: The ID of sub-interface.
1213 :param config: Bridge domain configuration.
1215 :type super_interface: str
1216 :type identifier: int
1218 :returns: Content of response.
1222 path = ("interfaces",
1223 ("interface", "name", super_interface),
1224 "vpp-vlan:sub-interfaces",
1225 ("sub-interface", "identifier", int(identifier)),
1228 return InterfaceKeywords._set_interface_properties(
1229 node, super_interface, path, config)
1232 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1233 """Get the operational data about the bridge domain from sub-interface.
1235 :param node: Honeycomb node.
1236 :param super_interface: Super interface.
1237 :param identifier: The ID of sub-interface.
1239 :type super_interface: str
1240 :type identifier: int
1241 :returns: Operational data about the bridge domain.
1243 :raises HoneycombError: If there is no sub-interface with the given ID.
1247 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1248 node, super_interface, identifier)["l2"]
1251 raise HoneycombError("The operational data does not contain "
1252 "information about a bridge domain.")
1255 def configure_tag_rewrite(node, super_interface, identifier, config):
1256 """Add / change / disable vlan tag rewrite on a sub-interface.
1258 :param node: Honeycomb node.
1259 :param super_interface: Super interface.
1260 :param identifier: The ID of sub-interface.
1261 :param config: Rewrite tag configuration.
1263 :type super_interface: str
1264 :type identifier: int
1266 :returns: Content of response.
1270 path = ("interfaces",
1271 ("interface", "name", super_interface),
1272 "vpp-vlan:sub-interfaces",
1273 ("sub-interface", "identifier", int(identifier)),
1277 return InterfaceKeywords._set_interface_properties(
1278 node, super_interface, path, config)
1281 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1282 """Get the operational data about tag rewrite.
1284 :param node: Honeycomb node.
1285 :param super_interface: Super interface.
1286 :param identifier: The ID of sub-interface.
1288 :type super_interface: str
1289 :type identifier: int
1290 :returns: Operational data about tag rewrite.
1292 :raises HoneycombError: If there is no sub-interface with the given ID.
1296 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1297 node, super_interface, identifier)["l2"]["rewrite"]
1300 raise HoneycombError("The operational data does not contain "
1301 "information about the tag-rewrite.")
1304 def add_ip_address_to_sub_interface(node, super_interface, identifier,
1305 ip_addr, network, ip_version):
1306 """Add an ipv4 address to the specified sub-interface, with the provided
1307 netmask or network prefix length. Any existing ipv4 addresses on the
1308 sub-interface will be replaced.
1310 :param node: Honeycomb node.
1311 :param super_interface: Super interface.
1312 :param identifier: The ID of sub-interface.
1313 :param ip_addr: IPv4 address to be set.
1314 :param network: Network mask or network prefix length.
1315 :param ip_version: ipv4 or ipv6
1317 :type super_interface: str
1318 :type identifier: int
1320 :type network: str or int
1321 :type ip_version: string
1322 :returns: Content of response.
1324 :raises HoneycombError: If the provided netmask or prefix is not valid.
1327 path = ("interfaces",
1328 ("interface", "name", super_interface),
1329 "vpp-vlan:sub-interfaces",
1330 ("sub-interface", "identifier", int(identifier)),
1333 if isinstance(network, basestring) and ip_version.lower() == "ipv4":
1334 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1336 elif isinstance(network, int) and 0 < network < 33:
1337 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1340 raise HoneycombError("{0} is not a valid netmask or prefix length."
1343 return InterfaceKeywords._set_interface_properties(
1344 node, super_interface, path, address)
1347 def remove_all_ip_addresses_from_sub_interface(node, super_interface,
1348 identifier, ip_version):
1349 """Remove all ipv4 addresses from the specified sub-interface.
1351 :param node: Honeycomb node.
1352 :param super_interface: Super interface.
1353 :param identifier: The ID of sub-interface.
1354 :param ip_version: ipv4 or ipv6
1356 :type super_interface: str
1357 :type identifier: int
1358 :type ip_version: string
1359 :returns: Content of response.
1363 path = ("interfaces",
1364 ("interface", "name", super_interface),
1365 "vpp-vlan:sub-interfaces",
1366 ("sub-interface", "identifier", int(identifier)),
1367 str(ip_version), "address")
1369 return InterfaceKeywords._set_interface_properties(
1370 node, super_interface, path, None)
1373 def compare_data_structures(data, ref, _path=''):
1374 """Checks if data obtained from UUT is as expected. If it is not,
1375 proceeds down the list/dictionary tree and finds the point of mismatch.
1377 :param data: Data to be checked.
1378 :param ref: Referential data used for comparison.
1379 :param _path: Used in recursive calls, stores the path taken down
1385 :raises HoneycombError: If the data structures do not match in some way,
1386 or if they are not in deserialized JSON format.
1392 elif isinstance(data, dict) and isinstance(ref, dict):
1395 raise HoneycombError(
1396 "Key {key} is not present in path {path}. Keys in path:"
1397 "{data_keys}".format(
1400 data_keys=data.keys()))
1402 if data[key] != ref[key]:
1403 if isinstance(data[key], list) \
1404 or isinstance(data[key], dict):
1405 InterfaceKeywords.compare_data_structures(
1406 data[key], ref[key],
1407 _path + '[{0}]'.format(key))
1409 raise HoneycombError(
1410 "Data mismatch, key {key} in path {path} has value"
1411 " {data}, but should be {ref}".format(
1417 elif isinstance(data, list) and isinstance(ref, list):
1419 if item not in data:
1420 if isinstance(item, dict):
1421 InterfaceKeywords.compare_data_structures(
1423 _path + '[{0}]'.format(ref.index(item)))
1425 raise HoneycombError(
1426 "Data mismatch, list item {index} in path {path}"
1427 " has value {data}, but should be {ref}".format(
1428 index=ref.index(item),
1434 raise HoneycombError(
1435 "Unexpected data type {data_type} in path {path}, reference"
1436 " type is {ref_type}. Must be list or dictionary.".format(
1437 data_type=type(data),
1442 def compare_interface_lists(list1, list2):
1443 """Compare provided lists of interfaces by name.
1445 :param list1: List of interfaces.
1446 :param list2: List of interfaces.
1449 :raises HoneycombError: If an interface exists in only one of the lists.
1452 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1453 # these have no equivalent in config data and no effect on VPP
1455 names1 = [x['name'] for x in list1]
1456 names2 = [x['name'] for x in list2]
1459 if name not in names2 and name not in ignore:
1460 raise HoneycombError("Interface {0} not present in list {1}"
1461 .format(name, list2))
1463 if name not in names1 and name not in ignore:
1464 raise HoneycombError("Interface {0} not present in list {1}"
1465 .format(name, list1))
1468 def create_vxlan_gpe_interface(node, interface, **kwargs):
1469 """Create a new VxLAN GPE interface.
1471 :param node: Honeycomb node.
1472 :param interface: The name of interface to be created.
1473 :param kwargs: Parameters and their values. The accepted parameters are
1474 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1476 :type interface: str
1478 :returns: Content of response.
1480 :raises HoneycombError: If a parameter in kwargs is not valid.
1485 "type": "v3po:vxlan-gpe-tunnel",
1486 "v3po:vxlan-gpe": {}
1488 for param, value in kwargs.items():
1489 if param in InterfaceKeywords.INTF_PARAMS:
1490 new_vxlan_gpe[param] = value
1491 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1492 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1494 raise HoneycombError("The parameter {0} is invalid.".
1496 path = ("interfaces", "interface")
1497 vxlan_gpe_structure = [new_vxlan_gpe, ]
1498 return InterfaceKeywords._set_interface_properties(
1499 node, interface, path, vxlan_gpe_structure)
1502 def enable_acl_on_interface(node, interface, table_name):
1503 """Enable ACL on the given interface.
1505 :param node: Honeycomb node.
1506 :param interface: The interface where the ACL will be enabled.
1507 :param table_name: Name of the classify table.
1509 :type interface: str
1510 :type table_name: str
1511 :returns: Content of response.
1513 :raises HoneycombError: If the configuration of interface is not
1517 interface = interface.replace("/", "%2F")
1520 "vpp-interface-acl:acl": {
1523 "classify-table": table_name
1526 "classify-table": table_name
1532 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1533 status_code, resp = HcUtil.\
1534 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1535 data_representation=DataRepresentation.JSON)
1536 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1537 raise HoneycombError(
1538 "The configuration of interface '{0}' was not successful. "
1539 "Status code: {1}.".format(interface, status_code))
1543 def enable_policer_on_interface(node, interface, table_name):
1544 """Enable Policer on the given interface.
1546 :param node: Honeycomb node.
1547 :param interface: The interface where policer will be enabled.
1548 :param table_name: Name of the classify table.
1550 :type interface: str
1551 :type table_name: str
1552 :returns: Content of response.
1554 :raises HoneycombError: If the configuration of interface is not
1557 interface = Topology.convert_interface_reference(
1558 node, interface, "name")
1559 interface = interface.replace("/", "%2F")
1562 "interface-policer:policer": {
1563 "ip4-table": table_name
1567 path = "/interface/" + interface + "/interface-policer:policer"
1568 status_code, resp = HcUtil.\
1569 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1570 data_representation=DataRepresentation.JSON)
1571 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1572 raise HoneycombError(
1573 "The configuration of interface '{0}' was not successful. "
1574 "Status code: {1}.".format(interface, status_code))
1578 def disable_policer_on_interface(node, interface):
1579 """Disable Policer on the given interface.
1581 :param node: Honeycomb node.
1582 :param interface: The interface where policer will be disabled.
1584 :type interface: str
1585 :returns: Content of response.
1587 :raises HoneycombError: If the configuration of interface is not
1590 interface = Topology.convert_interface_reference(
1591 node, interface, "name")
1592 interface = interface.replace("/", "%2F")
1594 path = "/interface/" + interface + "/interface-policer:policer"
1595 status_code, resp = HcUtil.\
1596 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1597 if status_code != HTTPCodes.OK:
1598 raise HoneycombError(
1599 "The configuration of interface '{0}' was not successful. "
1600 "Status code: {1}.".format(interface, status_code))
1604 def disable_acl_on_interface(node, interface):
1605 """Disable ACL on the given interface.
1607 :param node: Honeycomb node.
1608 :param interface: The interface where the ACL will be disabled.
1610 :type interface: str
1611 :returns: Content of response.
1613 :raises HoneycombError: If the configuration of interface is not
1617 interface = interface.replace("/", "%2F")
1619 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1621 status_code, resp = HcUtil.\
1622 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1624 if status_code != HTTPCodes.OK:
1625 raise HoneycombError(
1626 "The configuration of interface '{0}' was not successful. "
1627 "Status code: {1}.".format(interface, status_code))
1631 def create_pbb_sub_interface(node, intf, params):
1632 """Creates a PBB sub-interface on the given interface and sets its
1635 :param node: Honeycomb node.
1636 :param intf: The interface where PBB sub-interface will be configured.
1637 :param params: Configuration parameters of the sub-interface to be
1642 :returns: Content of response.
1644 :raises HoneycombError: If the configuration of sub-interface is not
1648 interface = intf.replace("/", "%2F")
1649 path = "/interface/{0}/pbb-rewrite".format(interface)
1650 status_code, resp = HcUtil. \
1651 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1652 data_representation=DataRepresentation.JSON)
1653 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1654 raise HoneycombError(
1655 "The configuration of PBB sub-interface '{0}' was not "
1656 "successful. Status code: {1}.".format(intf, status_code))
1660 def delete_pbb_sub_interface(node, intf):
1661 """Deletes the given PBB sub-interface.
1663 :param node: Honeycomb node.
1664 :param intf: The interface where PBB sub-interface will be deleted.
1667 :returns: Content of response.
1669 :raises HoneycombError: If the removal of sub-interface is not
1673 interface = intf.replace("/", "%2F")
1674 path = "/interface/{0}/pbb-rewrite".format(interface)
1676 status_code, resp = HcUtil. \
1677 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1678 if status_code != HTTPCodes.OK:
1679 raise HoneycombError(
1680 "The removal of pbb sub-interface '{0}' was not successful. "
1681 "Status code: {1}.".format(intf, status_code))
1685 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1686 """Retrieves PBB sub-interface operational data from Honeycomb.
1688 :param node: Honeycomb node.
1689 :param intf: The interface where PBB sub-interface is located.
1690 :param sub_if_id: ID of the PBB sub-interface.
1693 :type sub_if_id: str or int
1694 :returns: PBB sub-interface operational data.
1696 :raises HoneycombError: If the removal of sub-interface is not
1700 raise NotImplementedError
1703 def check_disabled_interface(node, interface):
1704 """Retrieves list of disabled interface indices from Honeycomb,
1705 and matches with the provided interface by index.
1707 :param node: Honeycomb node.
1708 :param interface: Index number of an interface on the node.
1710 :type interface: int
1711 :returns: True if the interface exists in disabled interfaces.
1713 :raises HoneycombError: If the interface is not present
1714 in retrieved list of disabled interfaces.
1716 data = InterfaceKeywords.get_disabled_interfaces_oper_data(node)
1717 # decrement by one = conversion from HC if-index to VPP sw_if_index
1721 if item["index"] == interface:
1723 raise HoneycombError("Interface index {0} not present in list"
1724 " of disabled interfaces.".format(interface))
1727 def configure_interface_span(node, dst_interface, src_interfaces=None):
1728 """Configure SPAN port mirroring on the specified interfaces. If no
1729 source interface is provided, SPAN will be disabled.
1731 :param node: Honeycomb node.
1732 :param dst_interface: Interface to mirror packets to.
1733 :param src_interfaces: List of interfaces to mirror packets from.
1735 :type dst_interface: str or int
1736 :type src_interfaces: list of dict
1737 :returns: Content of response.
1739 :raises HoneycombError: If SPAN could not be configured.
1742 interface = Topology.convert_interface_reference(
1743 node, dst_interface, "name")
1744 interface = interface.replace("/", "%2F")
1745 path = "/interface/" + interface + "/span"
1747 if not src_interfaces:
1748 status_code, _ = HcUtil.delete_honeycomb_data(
1749 node, "config_vpp_interfaces", path)
1751 for src_interface in src_interfaces:
1752 src_interface["iface-ref"] = Topology.\
1753 convert_interface_reference(
1754 node, src_interface["iface-ref"], "name")
1757 "mirrored-interfaces": {
1758 "mirrored-interface": src_interfaces
1763 status_code, _ = HcUtil.put_honeycomb_data(
1764 node, "config_vpp_interfaces", data, path)
1766 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1767 raise HoneycombError(
1768 "Configuring SPAN failed. Status code:{0}".format(status_code))
1771 def configure_sub_interface_span(node, super_interface, dst_interface_index,
1772 src_interfaces=None):
1773 """Configure SPAN port mirroring on the specified sub-interface. If no
1774 source interface is provided, SPAN will be disabled.
1776 Note: Does not support source sub-interfaces, only destination.
1778 :param node: Honeycomb node.
1779 :param super_interface: Name, link name or sw_if_index
1780 of the destination interface's super-interface.
1781 :param dst_interface_index: Index of sub-interface to mirror packets to.
1782 :param src_interfaces: List of interfaces to mirror packets from.
1784 :type super_interface: str or int
1785 :type dst_interface_index: int
1786 :type src_interfaces: list of dict
1787 :returns: Content of response.
1789 :raises HoneycombError: If SPAN could not be configured.
1792 super_interface = Topology.convert_interface_reference(
1793 node, super_interface, "name")
1794 super_interface = super_interface.replace("/", "%2F")
1796 path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
1797 .format(super_interface, dst_interface_index)
1799 if not src_interfaces:
1800 status_code, _ = HcUtil.delete_honeycomb_data(
1801 node, "config_vpp_interfaces", path)
1803 for src_interface in src_interfaces:
1804 src_interface["iface-ref"] = Topology. \
1805 convert_interface_reference(
1806 node, src_interface["iface-ref"], "name")
1809 "mirrored-interfaces": {
1810 "mirrored-interface": src_interfaces
1815 status_code, _ = HcUtil.put_honeycomb_data(
1816 node, "config_vpp_interfaces", data, path)
1818 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1819 raise HoneycombError(
1820 "Configuring SPAN failed. Status code:{0}".format(status_code))
1823 def add_interface_local0_to_topology(node):
1824 """Use Topology methods to add interface "local0" to working topology,
1825 if not already present.
1827 :param node: DUT node.
1831 if Topology.get_interface_by_sw_index(node, 0) is None:
1832 local0_key = Topology.add_new_port(node, "localzero")
1833 Topology.update_interface_sw_if_index(node, local0_key, 0)
1834 Topology.update_interface_name(node, local0_key, "local0")
1837 def configure_interface_unnumbered(node, interface, interface_src=None):
1838 """Configure the specified interface as unnumbered. The interface
1839 borrows IP address from the specified source interface. If not source
1840 interface is provided, unnumbered configuration will be removed.
1842 :param node: Honeycomb node.
1843 :param interface: Name, link name or sw_if_index of an interface.
1844 :param interface_src: Name of source interface.
1846 :type interface: str or int
1847 :type interface_src: str
1848 :raises HoneycombError: If the configuration fails.
1851 interface = InterfaceKeywords.handle_interface_reference(
1854 path = "/interface/{0}/unnumbered-interfaces:unnumbered"\
1860 "use": interface_src
1863 status_code, _ = HcUtil.put_honeycomb_data(
1864 node, "config_vpp_interfaces", data, path)
1866 status_code, _ = HcUtil.delete_honeycomb_data(
1867 node, "config_vpp_interfaces", path)
1869 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1870 raise HoneycombError(
1871 "Configuring unnumbered interface failed. "
1872 "Status code:{0}".format(status_code))
1875 def handle_interface_reference(node, interface):
1876 """Convert any interface reference to interface name used by Honeycomb.
1878 :param node: Honeycomb node.
1879 :param interface: Name, link name or sw_if_index of an interface,
1880 name of a custom interface or name of a sub-interface.
1881 :type node: Honeycomb node.
1882 :type interface: str or int
1883 :returns: Name of interface that can be used in Honeycomb requests.
1888 interface = Topology.convert_interface_reference(
1889 node, interface, "name")
1890 interface = interface.replace("/", "%2F")
1891 except RuntimeError:
1892 # interface is not in topology
1893 if "." in interface:
1894 # Assume it's the name of a sub-interface
1895 interface, index = interface.split(".")
1896 interface = interface.replace("/", "%2F")
1897 interface = "{0}/vpp-vlan:sub-interfaces/sub-interface/{1}".\
1898 format(interface, index)
1900 # Assume it's the name of a custom interface (pbb, vxlan, etc.)
1901 interface = interface.replace("/", "%2F")