1 # Copyright (c) 2018 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.HTTPRequest import HTTPCodes
22 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
23 from resources.libraries.python.honeycomb.HoneycombUtil \
24 import DataRepresentation
25 from resources.libraries.python.honeycomb.HoneycombUtil \
26 import HoneycombUtil as HcUtil
27 from resources.libraries.python.topology import Topology
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 = ("id", "tx-ring-size", "rx-ring-size", "host-mac",
52 "host-interface-name", "host-namespace", "host-bridge",
53 "host-ipv4-address", "host-ipv6-address", "tag",
54 "host-ipv4-gateway", "host-ipv6-gateway", "mac")
55 VHOST_USER_PARAMS = ("socket", "role")
56 SUB_IF_PARAMS = ("identifier",
59 SUB_IF_MATCH = ("default",
62 "vlan-tagged-exact-match")
63 BD_PARAMS = ("bridge-domain",
64 "split-horizon-group",
65 "bridged-virtual-interface")
66 VXLAN_GPE_PARAMS = ("local",
77 def _configure_interface(node, interface, data,
78 data_representation=DataRepresentation.JSON):
79 """Send interface configuration data and check the response.
81 :param node: Honeycomb node.
82 :param interface: The name of interface.
83 :param data: Configuration data to be sent in PUT request.
84 :param data_representation: How the data is represented.
88 :type data_representation: DataRepresentation
89 :returns: Content of response.
91 :raises HoneycombError: If the status code in response on PUT is not
95 status_code, resp = HcUtil.\
96 put_honeycomb_data(node, "config_vpp_interfaces", data,
97 data_representation=data_representation)
98 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
100 "The configuration of interface '{0}' was not successful. "
101 "Status code: {1}.".format(interface, status_code))
105 def get_all_interfaces_cfg_data(node):
106 """Get configuration data about all interfaces from Honeycomb.
108 :param node: Honeycomb node.
110 :returns: Configuration data about all interfaces from Honeycomb.
112 :raises HoneycombError: If it is not possible to get configuration data.
115 status_code, resp = HcUtil.\
116 get_honeycomb_data(node, "config_vpp_interfaces")
117 if status_code != HTTPCodes.OK:
118 raise HoneycombError(
119 "Not possible to get configuration information about the "
120 "interfaces. Status code: {0}.".format(status_code))
122 return resp["interfaces"]["interface"]
124 except (KeyError, TypeError):
128 def get_interface_cfg_data(node, interface):
129 """Get configuration data about the given interface from Honeycomb.
131 :param node: Honeycomb node.
132 :param interface: The name of interface.
135 :returns: Configuration data about the given interface from Honeycomb.
139 intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
141 if intf["name"] == interface:
146 def get_all_interfaces_oper_data(node):
147 """Get operational data about all interfaces from Honeycomb.
149 :param node: Honeycomb node.
151 :returns: Operational data about all interfaces from Honeycomb.
153 :raises HoneycombError: If it is not possible to get operational data.
156 status_code, resp = HcUtil.\
157 get_honeycomb_data(node, "oper_vpp_interfaces")
158 if status_code != HTTPCodes.OK:
159 raise HoneycombError(
160 "Not possible to get operational information about the "
161 "interfaces. Status code: {0}.".format(status_code))
163 return resp["interfaces"]["interface"]
165 except (KeyError, TypeError):
169 def get_disabled_interfaces_oper_data(node):
170 """Get operational data about all disabled interfaces from Honeycomb.
172 :param node: Honeycomb node.
174 :returns: Operational data about disabled interfaces.
176 :raises HoneycombError: If it is not possible to get operational data.
179 status_code, resp = HcUtil. \
180 get_honeycomb_data(node, "oper_disabled_interfaces")
181 if status_code == HTTPCodes.NOT_FOUND:
182 raise HoneycombError(
183 "No disabled interfaces present on node."
185 if status_code != HTTPCodes.OK:
186 raise HoneycombError(
187 "Not possible to get operational information about the "
188 "interfaces. Status code: {0}.".format(status_code))
190 return resp["disabled-interfaces"]["disabled-interface-index"]
192 except (KeyError, TypeError):
196 def get_interface_oper_data(node, interface):
197 """Get operational data about the given interface from Honeycomb.
199 :param node: Honeycomb node.
200 :param interface: The name of interface.
203 :returns: Operational data about the given interface from Honeycomb.
208 interface = Topology.convert_interface_reference(
209 node, interface, "name")
211 if isinstance(interface, basestring):
212 # Probably name of a custom interface (TAP, VxLAN, Vhost, ...)
217 intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
219 if intf["name"] == interface:
224 def _set_interface_properties(node, interface, path, new_value=None):
225 """Set interface properties.
227 This method reads interface configuration data, creates, changes or
228 removes the requested data and puts it back to Honeycomb.
230 :param node: Honeycomb node.
231 :param interface: The name of interface.
232 :param path: Path to data we want to change / create / remove.
233 :param new_value: The new value to be set. If None, the item will be
238 :type new_value: str, dict or list
239 :returns: Content of response.
241 :raises HoneycombError: If it is not possible to get or set the data.
244 status_code, resp = HcUtil.\
245 get_honeycomb_data(node, "config_vpp_interfaces")
246 if status_code != HTTPCodes.OK:
247 raise HoneycombError(
248 "Not possible to get configuration information about the "
249 "interfaces. Status code: {0}.".format(status_code))
252 new_data = HcUtil.set_item_value(resp, path, new_value)
254 new_data = HcUtil.remove_item(resp, path)
255 return InterfaceKeywords._configure_interface(node, interface, new_data)
258 def honeycomb_set_interface_state(node, interface, state="up"):
259 """Set VPP interface state.
261 The keyword changes the administration state of interface to up or down
262 depending on the parameter "state".
264 :param node: Honeycomb node.
265 :param interface: Interface name, key, link name or sw_if_index.
266 :param state: The requested state, only "up" and "down" are valid
271 :returns: Content of response.
273 :raises KeyError: If the argument "state" is nor "up" or "down".
274 :raises HoneycombError: If the interface is not present on the node.
277 intf_state = {"up": "true",
280 interface = Topology.convert_interface_reference(
281 node, interface, "name")
283 intf = interface.replace("/", "%2F")
284 path = "/interface/{0}".format(intf)
286 status_code, resp = HcUtil.\
287 get_honeycomb_data(node, "config_vpp_interfaces", path)
288 if status_code != HTTPCodes.OK:
289 raise HoneycombError(
290 "Not possible to get configuration information about the "
291 "interfaces. Status code: {0}.".format(status_code))
293 resp["interface"][0]["enabled"] = intf_state[state.lower()]
295 status_code, resp = HcUtil. \
296 put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
297 data_representation=DataRepresentation.JSON)
298 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
299 raise HoneycombError(
300 "The configuration of interface '{0}' was not successful. "
301 "Status code: {1}.".format(interface, status_code))
305 def set_interface_up(node, interface):
306 """Set the administration state of VPP interface to up.
308 :param node: Honeycomb node.
309 :param interface: The name of interface.
312 :returns: Content of response
316 return InterfaceKeywords.honeycomb_set_interface_state(
317 node, interface, "up")
320 def set_interface_down(node, interface):
321 """Set the administration state of VPP interface to down.
323 :param node: Honeycomb node.
324 :param interface: The name of interface.
327 :returns: Content of response.
331 return InterfaceKeywords.honeycomb_set_interface_state(
332 node, interface, "down")
335 def add_bridge_domain_to_interface(node, interface, bd_name,
336 split_horizon_group=None, bvi=None):
337 """Add a new bridge domain to an interface and set its parameters.
339 :param node: Honeycomb node.
340 :param interface: Interface name, key, link name or sw_if_index.
341 :param bd_name: Bridge domain name.
342 :param split_horizon_group: Split-horizon group name.
343 :param bvi: The bridged virtual interface.
347 :type split_horizon_group: str
349 :returns: Content of response.
351 :raises HoneycombError: If the interface is not present on the node.
354 interface = Topology.convert_interface_reference(
355 node, interface, "name")
357 v3po_l2 = {"bridge-domain": str(bd_name)}
358 if split_horizon_group:
359 v3po_l2["split-horizon-group"] = str(split_horizon_group)
361 v3po_l2["bridged-virtual-interface"] = str(bvi)
363 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
365 return InterfaceKeywords._set_interface_properties(
366 node, interface, path, v3po_l2)
369 def remove_bridge_domain_from_interface(node, interface):
370 """Remove bridge domain assignment from interface.
372 :param node: Honeycomb node.
373 :param interface: Interface name, key, link name or sw_if_index.
375 :type interface: str or int
376 :raises HoneycombError: If the operation fails.
379 interface = Topology.convert_interface_reference(
380 node, interface, "name")
382 intf = interface.replace("/", "%2F")
384 path = "/interface/{0}/v3po:l2".format(intf)
386 status_code, response = HcUtil.delete_honeycomb_data(
387 node, "config_vpp_interfaces", path)
389 if status_code != HTTPCodes.OK:
390 if '"error-tag":"data-missing"' in response:
391 logger.debug("Data does not exist in path.")
393 raise HoneycombError(
394 "Could not remove bridge domain assignment from interface "
395 "'{0}'. Status code: {1}.".format(interface, status_code))
398 def get_bd_oper_data_from_interface(node, interface):
399 """Returns operational data about bridge domain settings in the
402 :param node: Honeycomb node.
403 :param interface: The name of interface.
406 :returns: Operational data about bridge domain settings in the
411 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
415 return if_data["v3po:l2"]
421 def configure_interface_base(node, interface, param, value):
422 """Configure the base parameters of interface.
424 :param node: Honeycomb node.
425 :param interface: The name of interface.
426 :param param: Parameter to configure (set, change, remove)
427 :param value: The value of parameter. If None, the parameter will be
433 :returns: Content of response.
435 :raises HoneycombError: If the parameter is not valid.
438 if param not in InterfaceKeywords.INTF_PARAMS:
439 raise HoneycombError("The parameter {0} is invalid.".format(param))
441 path = ("interfaces", ("interface", "name", interface), param)
442 return InterfaceKeywords._set_interface_properties(
443 node, interface, path, value)
446 def configure_interface_ipv4(node, interface, param, value):
447 """Configure IPv4 parameters of interface.
449 :param node: Honeycomb node.
450 :param interface: The name of interface.
451 :param param: Parameter to configure (set, change, remove)
452 :param value: The value of parameter. If None, the parameter will be
458 :returns: Content of response.
460 :raises HoneycombError: If the parameter is not valid.
463 interface = Topology.convert_interface_reference(
464 node, interface, "name")
466 if param not in InterfaceKeywords.IPV4_PARAMS:
467 raise HoneycombError("The parameter {0} is invalid.".format(param))
469 path = ("interfaces", ("interface", "name", interface),
470 "ietf-ip:ipv4", param)
471 return InterfaceKeywords._set_interface_properties(
472 node, interface, path, value)
475 def add_first_ipv4_address(node, interface, ip_addr, network):
476 """Add the first IPv4 address.
478 If there are any other addresses configured, they will be removed.
480 :param node: Honeycomb node.
481 :param interface: The name of interface.
482 :param ip_addr: IPv4 address to be set.
483 :param network: Netmask or length of network prefix.
487 :type network: str or int
488 :returns: Content of response.
490 :raises ValueError: If the provided netmask or prefix is not valid.
491 :raises HoneycombError: If the operation fails.
494 interface = InterfaceKeywords.handle_interface_reference(
497 path = "/interface/{0}/ietf-ip:ipv4".format(interface)
498 if isinstance(network, basestring):
501 "address": [{"ip": ip_addr, "netmask": network}, ]}}
502 elif isinstance(network, int) and (0 < network < 33):
505 "address": [{"ip": ip_addr, "prefix-length": network}, ]}}
507 raise ValueError("Value {0} is not a valid netmask or network "
508 "prefix length.".format(network))
509 status_code, _ = HcUtil.put_honeycomb_data(
510 node, "config_vpp_interfaces", data, path)
512 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
513 raise HoneycombError(
514 "Configuring IPv4 address failed. "
515 "Status code:{0}".format(status_code))
518 def add_ipv4_address(node, interface, ip_addr, network):
521 :param node: Honeycomb node.
522 :param interface: The name of interface.
523 :param ip_addr: IPv4 address to be set.
524 :param network: Netmask or length of network prefix.
528 :type network: str or int
529 :returns: Content of response.
531 :raises HoneycombError: If the provided netmask or prefix is not valid.
534 interface = Topology.convert_interface_reference(
535 node, interface, "name")
537 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
539 if isinstance(network, basestring):
540 address = [{"ip": ip_addr, "netmask": network}]
541 elif isinstance(network, int) and (0 < network < 33):
542 address = [{"ip": ip_addr, "prefix-length": network}]
544 raise HoneycombError("Value {0} is not a valid netmask or network "
545 "prefix length.".format(network))
546 return InterfaceKeywords._set_interface_properties(
547 node, interface, path, address)
550 def remove_all_ipv4_addresses(node, interface):
551 """Remove all IPv4 addresses from interface.
553 :param node: Honeycomb node.
554 :param interface: The name of interface.
557 :returns: Content of response.
561 interface = Topology.convert_interface_reference(
562 node, interface, "name")
564 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
566 return InterfaceKeywords._set_interface_properties(
567 node, interface, path, None)
570 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
571 """Add the IPv4 neighbour.
573 :param node: Honeycomb node.
574 :param interface: The name of interface.
575 :param ip_addr: IPv4 address of neighbour to be set.
576 :param link_layer_address: Link layer address.
580 :type link_layer_address: str
581 :returns: Content of response.
585 interface = Topology.convert_interface_reference(
586 node, interface, "name")
588 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
590 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
591 return InterfaceKeywords._set_interface_properties(
592 node, interface, path, neighbor)
595 def remove_all_ipv4_neighbors(node, interface):
596 """Remove all IPv4 neighbours.
598 :param node: Honeycomb node.
599 :param interface: The name of interface.
602 :returns: Content of response.
606 interface = Topology.convert_interface_reference(
607 node, interface, "name")
609 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
611 return InterfaceKeywords._set_interface_properties(
612 node, interface, path, None)
615 def configure_interface_ipv6(node, interface, param, value):
616 """Configure IPv6 parameters of interface
618 :param node: Honeycomb node.
619 :param interface: The name of interface.
620 :param param: Parameter to configure (set, change, remove)
621 :param value: The value of parameter. If None, the parameter will be
627 :returns: Content of response.
629 :raises HoneycombError: If the parameter is not valid.
632 if param in InterfaceKeywords.IPV6_PARAMS:
633 path = ("interfaces", ("interface", "name", interface),
634 "ietf-ip:ipv6", param)
635 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
636 path = ("interfaces", ("interface", "name", interface),
637 "ietf-ip:ipv6", "autoconf", param)
639 raise HoneycombError("The parameter {0} is invalid.".format(param))
641 return InterfaceKeywords._set_interface_properties(
642 node, interface, path, value)
645 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
646 """Add the first IPv6 address.
648 If there are any other addresses configured, they will be removed.
650 :param node: Honeycomb node.
651 :param interface: The name of interface.
652 :param ip_addr: IPv6 address to be set.
653 :param prefix_len: Prefix length.
657 :type prefix_len: str
658 :returns: Content of response.
662 interface = Topology.convert_interface_reference(
663 node, interface, "name")
665 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
666 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
667 return InterfaceKeywords._set_interface_properties(
668 node, interface, path, address)
671 def add_ipv6_address(node, interface, ip_addr, prefix_len):
674 :param node: Honeycomb node.
675 :param interface: The name of interface.
676 :param ip_addr: IPv6 address to be set.
677 :param prefix_len: Prefix length.
681 :type prefix_len: str
682 :returns: Content of response.
686 interface = Topology.convert_interface_reference(
687 node, interface, "name")
689 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
691 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
692 return InterfaceKeywords._set_interface_properties(
693 node, interface, path, address)
696 def remove_all_ipv6_addresses(node, interface):
697 """Remove all IPv6 addresses from interface.
699 :param node: Honeycomb node.
700 :param interface: The name of interface.
703 :returns: Content of response.
707 interface = Topology.convert_interface_reference(
708 node, interface, "name")
710 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
712 return InterfaceKeywords._set_interface_properties(
713 node, interface, path, None)
716 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
717 """Add the IPv6 neighbour.
719 :param node: Honeycomb node.
720 :param interface: The name of interface.
721 :param ip_addr: IPv6 address of neighbour to be set.
722 :param link_layer_address: Link layer address.
726 :type link_layer_address: str
727 :returns: Content of response.
731 interface = Topology.convert_interface_reference(
732 node, interface, "name")
734 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
736 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
737 return InterfaceKeywords._set_interface_properties(
738 node, interface, path, neighbor)
741 def remove_all_ipv6_neighbors(node, interface):
742 """Remove all IPv6 neighbours.
744 :param node: Honeycomb node.
745 :param interface: The name of interface.
748 :returns: Content of response.
752 interface = Topology.convert_interface_reference(
753 node, interface, "name")
755 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
757 return InterfaceKeywords._set_interface_properties(
758 node, interface, path, None)
761 def configure_interface_ethernet(node, interface, param, value):
762 """Configure the ethernet parameters of interface.
764 :param node: Honeycomb node.
765 :param interface: The name of interface.
766 :param param: Parameter to configure (set, change, remove)
767 :param value: The value of parameter. If None, the parameter will be
773 :returns: Content of response.
775 :raises HoneycombError: If the parameter is not valid.
778 if param not in InterfaceKeywords.ETH_PARAMS:
779 raise HoneycombError("The parameter {0} is invalid.".format(param))
780 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
782 return InterfaceKeywords._set_interface_properties(
783 node, interface, path, value)
786 def configure_interface_routing(node, interface, param, value):
787 """Configure the routing parameters of interface.
789 :param node: Honeycomb node.
790 :param interface: The name of interface.
791 :param param: Parameter to configure (set, change, remove)
792 :param value: The value of parameter. If None, the parameter will be
798 :returns: Content of response.
800 :raises HoneycombError: If the parameter is not valid.
803 interface = Topology.convert_interface_reference(
804 node, interface, "name")
806 if param not in InterfaceKeywords.ROUTING_PARAMS:
807 raise HoneycombError("The parameter {0} is invalid.".format(param))
809 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
811 return InterfaceKeywords._set_interface_properties(
812 node, interface, path, value)
815 def honeycomb_create_vxlan_interface(node, interface, **kwargs):
816 """Create a new VxLAN interface.
818 :param node: Honeycomb node.
819 :param interface: The name of interface.
820 :param kwargs: Parameters and their values. The accepted parameters are
821 defined in InterfaceKeywords.VXLAN_PARAMS.
825 :returns: Content of response.
827 :raises HoneycombError: If the parameter is not valid.
832 "type": "v3po:vxlan-tunnel",
835 for param, value in kwargs.items():
836 if param not in InterfaceKeywords.VXLAN_PARAMS:
837 raise HoneycombError("The parameter {0} is invalid.".
839 new_vx_lan["v3po:vxlan"][param] = value
841 path = ("interfaces", "interface")
842 vx_lan_structure = [new_vx_lan, ]
843 return InterfaceKeywords._set_interface_properties(
844 node, interface, path, vx_lan_structure)
847 def delete_interface(node, interface):
848 """Delete an interface.
850 :param node: Honeycomb node.
851 :param interface: The name of interface.
854 :returns: Content of response.
856 :raises HoneycombError: If it is not possible to get information about
857 interfaces or it is not possible to delete the interface.
860 path = ("interfaces", ("interface", "name", interface))
862 status_code, resp = HcUtil.\
863 get_honeycomb_data(node, "config_vpp_interfaces")
864 if status_code != HTTPCodes.OK:
865 raise HoneycombError(
866 "Not possible to get configuration information about the "
867 "interfaces. Status code: {0}.".format(status_code))
869 new_data = HcUtil.remove_item(resp, path)
870 status_code, resp = HcUtil.\
871 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
872 if status_code != HTTPCodes.OK:
873 raise HoneycombError("Not possible to remove interface {0}. "
875 format(interface, status_code))
879 def honeycomb_configure_interface_vxlan(node, interface, **kwargs):
880 """Configure VxLAN on the interface.
882 The keyword configures VxLAN parameters on the given interface. The type
883 of interface must be set to "v3po:vxlan-tunnel".
884 The new VxLAN parameters overwrite the current configuration. If a
885 parameter in new configuration is missing, it is removed from VxLAN
887 If the dictionary kwargs is empty, VxLAN configuration is removed.
889 :param node: Honeycomb node.
890 :param interface: The name of interface.
891 :param kwargs: Parameters and their values. The accepted parameters are
892 defined in InterfaceKeywords.VXLAN_PARAMS.
896 :returns: Content of response.
898 :raises HoneycombError: If the parameter is not valid.
901 vx_lan_structure = dict()
902 for param, value in kwargs.items():
903 if param not in InterfaceKeywords.VXLAN_PARAMS:
904 raise HoneycombError("The parameter {0} is invalid.".
906 vx_lan_structure[param] = value
908 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
909 return InterfaceKeywords._set_interface_properties(
910 node, interface, path, vx_lan_structure)
913 def configure_interface_l2(node, interface, param, value):
914 """Configure the L2 parameters of interface.
916 :param node: Honeycomb node.
917 :param interface: The name of interface.
918 :param param: Parameter to configure (set, change, remove)
919 :param value: The value of parameter. If None, the parameter will be
925 :returns: Content of response.
927 :raises HoneycombError: If the parameter is not valid.
930 if param not in InterfaceKeywords.L2_PARAMS:
931 raise HoneycombError("The parameter {0} is invalid.".format(param))
932 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
934 return InterfaceKeywords._set_interface_properties(
935 node, interface, path, value)
938 def create_tap_interface(node, interface, **kwargs):
939 """Create a new TAP interface.
941 :param node: Honeycomb node.
942 :param interface: The name of interface.
943 :param kwargs: Parameters and their values. The accepted parameters are
944 defined in InterfaceKeywords.TAP_PARAMS.
948 :returns: Content of response.
950 :raises HoneycombError: If the parameter is not valid.
955 "type": "v3po:tap-v2",
958 for param, value in kwargs.items():
959 if param not in InterfaceKeywords.TAP_PARAMS:
960 raise HoneycombError(
961 "The parameter {0} is invalid.".format(param))
962 new_tap["v3po:tap-v2"][param] = value
964 path = ("interfaces", "interface")
965 new_tap_structure = [new_tap, ]
966 return InterfaceKeywords._set_interface_properties(
967 node, interface, path, new_tap_structure)
970 def configure_interface_tap(node, interface, **kwargs):
971 """Configure TAP on the interface.
973 The keyword configures TAP parameters on the given interface. The type
974 of interface must be set to "v3po:tap-v2".
975 The new TAP parameters overwrite the current configuration. If a
976 parameter in new configuration is missing, it is removed from TAP
978 If the dictionary kwargs is empty, TAP configuration is removed.
980 :param node: Honeycomb node.
981 :param interface: The name of interface.
982 :param kwargs: Parameters and their values. The accepted parameters are
983 defined in InterfaceKeywords.TAP_PARAMS.
987 :returns: Content of response.
989 :raises HoneycombError: If the parameter is not valid.
992 tap_structure = dict()
993 for param, value in kwargs.items():
994 if param not in InterfaceKeywords.TAP_PARAMS:
995 raise HoneycombError("The parameter {0} is invalid.".
997 tap_structure[param] = value
999 path = ("interfaces", ("interface", "name", interface), "v3po:tap-v2")
1000 return InterfaceKeywords._set_interface_properties(
1001 node, interface, path, tap_structure)
1004 def configure_interface_vhost_user(node, interface, **kwargs):
1005 """Configure vhost-user on the interface.
1007 The keyword configures vhost-user parameters on the given interface.
1008 The type of interface must be set to "v3po:vhost-user".
1009 The new vhost-user parameters overwrite the current configuration. If a
1010 parameter in new configuration is missing, it is removed from vhost-user
1012 If the dictionary kwargs is empty, vhost-user configuration is removed.
1014 :param node: Honeycomb node.
1015 :param interface: The name of interface.
1016 :param kwargs: Parameters and their values. The accepted parameters are
1017 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1019 :type interface: str
1021 :returns: Content of response.
1023 :raises HoneycombError: If the parameter is not valid.
1026 vhost_structure = dict()
1027 for param, value in kwargs.items():
1028 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1029 raise HoneycombError("The parameter {0} is invalid.".
1031 vhost_structure[param] = value
1033 path = ("interfaces", ("interface", "name", interface),
1035 return InterfaceKeywords._set_interface_properties(
1036 node, interface, path, vhost_structure)
1039 def create_vhost_user_interface(node, interface, **kwargs):
1040 """Create a new vhost-user interface.
1042 :param node: Honeycomb node.
1043 :param interface: The name of interface.
1044 :param kwargs: Parameters and their values. The accepted parameters are
1045 defined in InterfaceKeywords.VHOST_USER_PARAMS.
1047 :type interface: str
1049 :returns: Content of response.
1051 :raises HoneycombError: If the parameter is not valid.
1056 "type": "v3po:vhost-user",
1057 "v3po:vhost-user": {}
1059 for param, value in kwargs.items():
1060 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
1061 raise HoneycombError("The parameter {0} is invalid.".
1063 new_vhost["v3po:vhost-user"][param] = value
1065 path = ("interfaces", "interface")
1066 new_vhost_structure = [new_vhost, ]
1067 return InterfaceKeywords._set_interface_properties(
1068 node, interface, path, new_vhost_structure)
1071 def honeycomb_create_sub_interface(node, super_interface, match, tags=None,
1073 """Create a new sub-interface.
1075 :param node: Honeycomb node.
1076 :param super_interface: Super interface.
1077 :param match: Match type. The valid values are defined in
1078 InterfaceKeywords.SUB_IF_MATCH.
1079 :param tags: List of tags.
1080 :param kwargs: Parameters and their values. The accepted parameters are
1081 defined in InterfaceKeywords.SUB_IF_PARAMS.
1083 :type super_interface: str
1087 :returns: Content of response.
1089 :raises HoneycombError: If the parameter is not valid.
1090 :raises KeyError: If the parameter 'match' is invalid.
1093 super_interface = Topology.convert_interface_reference(
1094 node, super_interface, "name")
1102 {"vlan-tagged": {"match-exact-tags": "false"}},
1103 "vlan-tagged-exact-match":
1104 {"vlan-tagged": {"match-exact-tags": "true"}}
1107 new_sub_interface = {
1113 for param, value in kwargs.items():
1114 if param in InterfaceKeywords.SUB_IF_PARAMS:
1115 new_sub_interface[param] = value
1117 raise HoneycombError("The parameter {0} is invalid.".
1120 new_sub_interface["match"] = match_type[match]
1122 raise HoneycombError("The value '{0}' of parameter 'match' is "
1123 "invalid.".format(match))
1126 new_sub_interface["tags"]["tag"].extend(tags)
1128 path = ("interfaces",
1129 ("interface", "name", super_interface),
1130 "vpp-vlan:sub-interfaces",
1132 new_sub_interface_structure = [new_sub_interface, ]
1133 return InterfaceKeywords._set_interface_properties(
1134 node, super_interface, path, new_sub_interface_structure)
1137 def get_sub_interface_oper_data(node, super_interface, identifier):
1138 """Retrieves sub-interface operational data using Honeycomb API.
1140 :param node: Honeycomb node.
1141 :param super_interface: Super interface.
1142 :param identifier: The ID of sub-interface.
1144 :type super_interface: str
1145 :type identifier: int
1146 :returns: Sub-interface operational data.
1148 :raises HoneycombError: If there is no sub-interface with the given ID.
1151 if_data = InterfaceKeywords.get_interface_oper_data(node,
1153 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1154 if str(sub_if["identifier"]) == str(identifier):
1157 raise HoneycombError("The interface {0} does not have sub-interface "
1158 "with ID {1}".format(super_interface, identifier))
1161 def remove_all_sub_interfaces(node, super_interface):
1162 """Remove all sub-interfaces from the given interface.
1164 :param node: Honeycomb node.
1165 :param super_interface: Super interface.
1167 :type super_interface: str
1168 :returns: Content of response.
1172 path = ("interfaces",
1173 ("interface", "name", super_interface),
1174 "vpp-vlan:sub-interfaces")
1176 return InterfaceKeywords._set_interface_properties(
1177 node, super_interface, path, {})
1180 def set_sub_interface_state(node, super_interface, identifier, state):
1181 """Set the administrative state of sub-interface.
1183 :param node: Honeycomb node.
1184 :param super_interface: Super interface.
1185 :param identifier: The ID of sub-interface.
1186 :param state: Required sub-interface state - up or down.
1188 :type super_interface: str
1189 :type identifier: int
1191 :returns: Content of response.
1195 super_interface = Topology.convert_interface_reference(
1196 node, super_interface, "name")
1198 intf_state = {"up": "true",
1201 path = ("interfaces",
1202 ("interface", "name", super_interface),
1203 "vpp-vlan:sub-interfaces",
1204 ("sub-interface", "identifier", int(identifier)),
1207 return InterfaceKeywords._set_interface_properties(
1208 node, super_interface, path, intf_state[state])
1211 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1213 """Add a sub-interface to a bridge domain and set its parameters.
1215 :param node: Honeycomb node.
1216 :param super_interface: Super interface.
1217 :param identifier: The ID of sub-interface.
1218 :param config: Bridge domain configuration.
1220 :type super_interface: str
1221 :type identifier: int
1223 :returns: Content of response.
1227 path = ("interfaces",
1228 ("interface", "name", super_interface),
1229 "vpp-vlan:sub-interfaces",
1230 ("sub-interface", "identifier", int(identifier)),
1233 return InterfaceKeywords._set_interface_properties(
1234 node, super_interface, path, config)
1237 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1238 """Get the operational data about the bridge domain from sub-interface.
1240 :param node: Honeycomb node.
1241 :param super_interface: Super interface.
1242 :param identifier: The ID of sub-interface.
1244 :type super_interface: str
1245 :type identifier: int
1246 :returns: Operational data about the bridge domain.
1248 :raises HoneycombError: If there is no sub-interface with the given ID.
1252 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1253 node, super_interface, identifier)["l2"]
1256 raise HoneycombError("The operational data does not contain "
1257 "information about a bridge domain.")
1260 def configure_tag_rewrite(node, super_interface, identifier, config):
1261 """Add / change / disable vlan tag rewrite on a sub-interface.
1263 :param node: Honeycomb node.
1264 :param super_interface: Super interface.
1265 :param identifier: The ID of sub-interface.
1266 :param config: Rewrite tag configuration.
1268 :type super_interface: str
1269 :type identifier: int
1271 :returns: Content of response.
1275 path = ("interfaces",
1276 ("interface", "name", super_interface),
1277 "vpp-vlan:sub-interfaces",
1278 ("sub-interface", "identifier", int(identifier)),
1282 return InterfaceKeywords._set_interface_properties(
1283 node, super_interface, path, config)
1286 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1287 """Get the operational data about tag rewrite.
1289 :param node: Honeycomb node.
1290 :param super_interface: Super interface.
1291 :param identifier: The ID of sub-interface.
1293 :type super_interface: str
1294 :type identifier: int
1295 :returns: Operational data about tag rewrite.
1297 :raises HoneycombError: If there is no sub-interface with the given ID.
1301 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1302 node, super_interface, identifier)["l2"]["rewrite"]
1305 raise HoneycombError("The operational data does not contain "
1306 "information about the tag-rewrite.")
1309 def add_ip_address_to_sub_interface(node, super_interface, identifier,
1310 ip_addr, network, ip_version):
1311 """Add an ipv4 address to the specified sub-interface, with the provided
1312 netmask or network prefix length. Any existing ipv4 addresses on the
1313 sub-interface will be replaced.
1315 :param node: Honeycomb node.
1316 :param super_interface: Super interface.
1317 :param identifier: The ID of sub-interface.
1318 :param ip_addr: IPv4 address to be set.
1319 :param network: Network mask or network prefix length.
1320 :param ip_version: ipv4 or ipv6
1322 :type super_interface: str
1323 :type identifier: int
1325 :type network: str or int
1326 :type ip_version: string
1327 :returns: Content of response.
1329 :raises HoneycombError: If the provided netmask or prefix is not valid.
1332 path = ("interfaces",
1333 ("interface", "name", super_interface),
1334 "vpp-vlan:sub-interfaces",
1335 ("sub-interface", "identifier", int(identifier)),
1338 if isinstance(network, basestring) and ip_version.lower() == "ipv4":
1339 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1341 elif isinstance(network, int) and 0 < network < 33:
1342 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1345 raise HoneycombError("{0} is not a valid netmask or prefix length."
1348 return InterfaceKeywords._set_interface_properties(
1349 node, super_interface, path, address)
1352 def remove_all_ip_addresses_from_sub_interface(node, super_interface,
1353 identifier, ip_version):
1354 """Remove all ipv4 addresses from the specified sub-interface.
1356 :param node: Honeycomb node.
1357 :param super_interface: Super interface.
1358 :param identifier: The ID of sub-interface.
1359 :param ip_version: ipv4 or ipv6
1361 :type super_interface: str
1362 :type identifier: int
1363 :type ip_version: string
1364 :returns: Content of response.
1368 path = ("interfaces",
1369 ("interface", "name", super_interface),
1370 "vpp-vlan:sub-interfaces",
1371 ("sub-interface", "identifier", int(identifier)),
1372 str(ip_version), "address")
1374 return InterfaceKeywords._set_interface_properties(
1375 node, super_interface, path, None)
1378 def compare_data_structures(data, ref, _path=''):
1379 """Checks if data obtained from UUT is as expected. If it is not,
1380 proceeds down the list/dictionary tree and finds the point of mismatch.
1382 :param data: Data to be checked.
1383 :param ref: Referential data used for comparison.
1384 :param _path: Used in recursive calls, stores the path taken down
1390 :raises HoneycombError: If the data structures do not match in some way,
1391 or if they are not in deserialized JSON format.
1397 elif isinstance(data, dict) and isinstance(ref, dict):
1400 raise HoneycombError(
1401 "Key {key} is not present in path {path}. Keys in path:"
1402 "{data_keys}".format(
1405 data_keys=data.keys()))
1407 if data[key] != ref[key]:
1408 if isinstance(data[key], list) \
1409 or isinstance(data[key], dict):
1410 InterfaceKeywords.compare_data_structures(
1411 data[key], ref[key],
1412 _path + '[{0}]'.format(key))
1414 raise HoneycombError(
1415 "Data mismatch, key {key} in path {path} has value"
1416 " {data}, but should be {ref}".format(
1422 elif isinstance(data, list) and isinstance(ref, list):
1424 if item not in data:
1425 if isinstance(item, dict):
1426 InterfaceKeywords.compare_data_structures(
1428 _path + '[{0}]'.format(ref.index(item)))
1430 raise HoneycombError(
1431 "Data mismatch, list item {index} in path {path}"
1432 " has value {data}, but should be {ref}".format(
1433 index=ref.index(item),
1439 raise HoneycombError(
1440 "Unexpected data type {data_type} in path {path}, reference"
1441 " type is {ref_type}. Must be list or dictionary.".format(
1442 data_type=type(data),
1447 def compare_interface_lists(list1, list2):
1448 """Compare provided lists of interfaces by name.
1450 :param list1: List of interfaces.
1451 :param list2: List of interfaces.
1454 :raises HoneycombError: If an interface exists in only one of the lists.
1457 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1458 # these have no equivalent in config data and no effect on VPP
1460 names1 = [x['name'] for x in list1]
1461 names2 = [x['name'] for x in list2]
1464 if name not in names2 and name not in ignore:
1465 raise HoneycombError("Interface {0} not present in list {1}"
1466 .format(name, list2))
1468 if name not in names1 and name not in ignore:
1469 raise HoneycombError("Interface {0} not present in list {1}"
1470 .format(name, list1))
1473 def create_vxlan_gpe_interface(node, interface, **kwargs):
1474 """Create a new VxLAN GPE interface.
1476 :param node: Honeycomb node.
1477 :param interface: The name of interface to be created.
1478 :param kwargs: Parameters and their values. The accepted parameters are
1479 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1481 :type interface: str
1483 :returns: Content of response.
1485 :raises HoneycombError: If a parameter in kwargs is not valid.
1490 "type": "v3po:vxlan-gpe-tunnel",
1491 "v3po:vxlan-gpe": {}
1493 for param, value in kwargs.items():
1494 if param in InterfaceKeywords.INTF_PARAMS:
1495 new_vxlan_gpe[param] = value
1496 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1497 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1499 raise HoneycombError("The parameter {0} is invalid.".
1501 path = ("interfaces", "interface")
1502 vxlan_gpe_structure = [new_vxlan_gpe, ]
1503 return InterfaceKeywords._set_interface_properties(
1504 node, interface, path, vxlan_gpe_structure)
1507 def enable_acl_on_interface(node, interface, table_name):
1508 """Enable ACL on the given interface.
1510 :param node: Honeycomb node.
1511 :param interface: The interface where the ACL will be enabled.
1512 :param table_name: Name of the classify table.
1514 :type interface: str
1515 :type table_name: str
1516 :returns: Content of response.
1518 :raises HoneycombError: If the configuration of interface is not
1522 interface = interface.replace("/", "%2F")
1525 "vpp-interface-acl:acl": {
1528 "classify-table": table_name
1531 "classify-table": table_name
1537 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1538 status_code, resp = HcUtil.\
1539 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1540 data_representation=DataRepresentation.JSON)
1541 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1542 raise HoneycombError(
1543 "The configuration of interface '{0}' was not successful. "
1544 "Status code: {1}.".format(interface, status_code))
1548 def enable_policer_on_interface(node, interface, table_name):
1549 """Enable Policer on the given interface.
1551 :param node: Honeycomb node.
1552 :param interface: The interface where policer will be enabled.
1553 :param table_name: Name of the classify table.
1555 :type interface: str
1556 :type table_name: str
1557 :returns: Content of response.
1559 :raises HoneycombError: If the configuration of interface is not
1562 interface = Topology.convert_interface_reference(
1563 node, interface, "name")
1564 interface = interface.replace("/", "%2F")
1567 "interface-policer:policer": {
1568 "ip4-table": table_name
1572 path = "/interface/" + interface + "/interface-policer:policer"
1573 status_code, resp = HcUtil.\
1574 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1575 data_representation=DataRepresentation.JSON)
1576 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1577 raise HoneycombError(
1578 "The configuration of interface '{0}' was not successful. "
1579 "Status code: {1}.".format(interface, status_code))
1583 def disable_policer_on_interface(node, interface):
1584 """Disable Policer on the given interface.
1586 :param node: Honeycomb node.
1587 :param interface: The interface where policer will be disabled.
1589 :type interface: str
1590 :returns: Content of response.
1592 :raises HoneycombError: If the configuration of interface is not
1595 interface = Topology.convert_interface_reference(
1596 node, interface, "name")
1597 interface = interface.replace("/", "%2F")
1599 path = "/interface/" + interface + "/interface-policer:policer"
1600 status_code, resp = HcUtil.\
1601 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1602 if status_code != HTTPCodes.OK:
1603 raise HoneycombError(
1604 "The configuration of interface '{0}' was not successful. "
1605 "Status code: {1}.".format(interface, status_code))
1609 def disable_acl_on_interface(node, interface):
1610 """Disable ACL on the given interface.
1612 :param node: Honeycomb node.
1613 :param interface: The interface where the ACL will be disabled.
1615 :type interface: str
1616 :returns: Content of response.
1618 :raises HoneycombError: If the configuration of interface is not
1622 interface = interface.replace("/", "%2F")
1624 path = "/interface/" + interface + "/vpp-interface-acl:acl"
1626 status_code, resp = HcUtil.\
1627 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1629 if status_code != HTTPCodes.OK:
1630 raise HoneycombError(
1631 "The configuration of interface '{0}' was not successful. "
1632 "Status code: {1}.".format(interface, status_code))
1636 def create_pbb_sub_interface(node, intf, params):
1637 """Creates a PBB sub-interface on the given interface and sets its
1640 :param node: Honeycomb node.
1641 :param intf: The interface where PBB sub-interface will be configured.
1642 :param params: Configuration parameters of the sub-interface to be
1647 :returns: Content of response.
1649 :raises HoneycombError: If the configuration of sub-interface is not
1653 interface = intf.replace("/", "%2F")
1654 path = "/interface/{0}/pbb-rewrite".format(interface)
1655 status_code, resp = HcUtil. \
1656 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1657 data_representation=DataRepresentation.JSON)
1658 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1659 raise HoneycombError(
1660 "The configuration of PBB sub-interface '{0}' was not "
1661 "successful. Status code: {1}.".format(intf, status_code))
1665 def delete_pbb_sub_interface(node, intf):
1666 """Deletes the given PBB sub-interface.
1668 :param node: Honeycomb node.
1669 :param intf: The interface where PBB sub-interface will be deleted.
1672 :returns: Content of response.
1674 :raises HoneycombError: If the removal of sub-interface is not
1678 interface = intf.replace("/", "%2F")
1679 path = "/interface/{0}/pbb-rewrite".format(interface)
1681 status_code, resp = HcUtil. \
1682 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1683 if status_code != HTTPCodes.OK:
1684 raise HoneycombError(
1685 "The removal of pbb sub-interface '{0}' was not successful. "
1686 "Status code: {1}.".format(intf, status_code))
1690 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1691 """Retrieves PBB sub-interface operational data from Honeycomb.
1693 :param node: Honeycomb node.
1694 :param intf: The interface where PBB sub-interface is located.
1695 :param sub_if_id: ID of the PBB sub-interface.
1698 :type sub_if_id: str or int
1699 :returns: PBB sub-interface operational data.
1701 :raises HoneycombError: If the removal of sub-interface is not
1705 raise NotImplementedError
1708 def check_disabled_interface(node, interface):
1709 """Retrieves list of disabled interface indices from Honeycomb,
1710 and matches with the provided interface by index.
1712 :param node: Honeycomb node.
1713 :param interface: Index number of an interface on the node.
1715 :type interface: int
1716 :returns: True if the interface exists in disabled interfaces.
1718 :raises HoneycombError: If the interface is not present
1719 in retrieved list of disabled interfaces.
1721 data = InterfaceKeywords.get_disabled_interfaces_oper_data(node)
1722 # decrement by one = conversion from HC if-index to VPP sw_if_index
1726 if item["index"] == interface:
1728 raise HoneycombError("Interface index {0} not present in list"
1729 " of disabled interfaces.".format(interface))
1732 def configure_interface_span(node, dst_interface, src_interfaces=None):
1733 """Configure SPAN port mirroring on the specified interfaces. If no
1734 source interface is provided, SPAN will be disabled.
1736 :param node: Honeycomb node.
1737 :param dst_interface: Interface to mirror packets to.
1738 :param src_interfaces: List of interfaces to mirror packets from.
1740 :type dst_interface: str or int
1741 :type src_interfaces: list of dict
1742 :returns: Content of response.
1744 :raises HoneycombError: If SPAN could not be configured.
1747 interface = Topology.convert_interface_reference(
1748 node, dst_interface, "name")
1749 interface = interface.replace("/", "%2F")
1750 path = "/interface/" + interface + "/span"
1752 if not src_interfaces:
1753 status_code, _ = HcUtil.delete_honeycomb_data(
1754 node, "config_vpp_interfaces", path)
1756 for src_interface in src_interfaces:
1757 src_interface["iface-ref"] = Topology.\
1758 convert_interface_reference(
1759 node, src_interface["iface-ref"], "name")
1762 "mirrored-interfaces": {
1763 "mirrored-interface": src_interfaces
1768 status_code, _ = HcUtil.put_honeycomb_data(
1769 node, "config_vpp_interfaces", data, path)
1771 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1772 raise HoneycombError(
1773 "Configuring SPAN failed. Status code:{0}".format(status_code))
1776 def configure_sub_interface_span(node, super_interface, dst_interface_index,
1777 src_interfaces=None):
1778 """Configure SPAN port mirroring on the specified sub-interface. If no
1779 source interface is provided, SPAN will be disabled.
1781 Note: Does not support source sub-interfaces, only destination.
1783 :param node: Honeycomb node.
1784 :param super_interface: Name, link name or sw_if_index
1785 of the destination interface's super-interface.
1786 :param dst_interface_index: Index of sub-interface to mirror packets to.
1787 :param src_interfaces: List of interfaces to mirror packets from.
1789 :type super_interface: str or int
1790 :type dst_interface_index: int
1791 :type src_interfaces: list of dict
1792 :returns: Content of response.
1794 :raises HoneycombError: If SPAN could not be configured.
1797 super_interface = Topology.convert_interface_reference(
1798 node, super_interface, "name")
1799 super_interface = super_interface.replace("/", "%2F")
1801 path = "/interface/{0}/vpp-vlan:sub-interfaces/sub-interface/{1}/span"\
1802 .format(super_interface, dst_interface_index)
1804 if not src_interfaces:
1805 status_code, _ = HcUtil.delete_honeycomb_data(
1806 node, "config_vpp_interfaces", path)
1808 for src_interface in src_interfaces:
1809 src_interface["iface-ref"] = Topology. \
1810 convert_interface_reference(
1811 node, src_interface["iface-ref"], "name")
1814 "mirrored-interfaces": {
1815 "mirrored-interface": src_interfaces
1820 status_code, _ = HcUtil.put_honeycomb_data(
1821 node, "config_vpp_interfaces", data, path)
1823 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1824 raise HoneycombError(
1825 "Configuring SPAN failed. Status code:{0}".format(status_code))
1828 def add_interface_local0_to_topology(node):
1829 """Use Topology methods to add interface "local0" to working topology,
1830 if not already present.
1832 :param node: DUT node.
1836 if Topology.get_interface_by_sw_index(node, 0) is None:
1837 local0_key = Topology.add_new_port(node, "localzero")
1838 Topology.update_interface_sw_if_index(node, local0_key, 0)
1839 Topology.update_interface_name(node, local0_key, "local0")
1842 def configure_interface_unnumbered(node, interface, interface_src=None):
1843 """Configure the specified interface as unnumbered. The interface
1844 borrows IP address from the specified source interface. If not source
1845 interface is provided, unnumbered configuration will be removed.
1847 :param node: Honeycomb node.
1848 :param interface: Name, link name or sw_if_index of an interface.
1849 :param interface_src: Name of source interface.
1851 :type interface: str or int
1852 :type interface_src: str
1853 :raises HoneycombError: If the configuration fails.
1856 interface = InterfaceKeywords.handle_interface_reference(
1859 path = "/interface/{0}/unnumbered-interfaces:unnumbered"\
1865 "use": interface_src
1868 status_code, _ = HcUtil.put_honeycomb_data(
1869 node, "config_vpp_interfaces", data, path)
1871 status_code, _ = HcUtil.delete_honeycomb_data(
1872 node, "config_vpp_interfaces", path)
1874 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1875 raise HoneycombError(
1876 "Configuring unnumbered interface failed. "
1877 "Status code:{0}".format(status_code))
1880 def handle_interface_reference(node, interface):
1881 """Convert any interface reference to interface name used by Honeycomb.
1883 :param node: Honeycomb node.
1884 :param interface: Name, link name or sw_if_index of an interface,
1885 name of a custom interface or name of a sub-interface.
1886 :type node: Honeycomb node.
1887 :type interface: str or int
1888 :returns: Name of interface that can be used in Honeycomb requests.
1893 interface = Topology.convert_interface_reference(
1894 node, interface, "name")
1895 interface = interface.replace("/", "%2F")
1896 except RuntimeError:
1897 # interface is not in topology
1898 if "." in interface:
1899 # Assume it's the name of a sub-interface
1900 interface, index = interface.split(".")
1901 interface = interface.replace("/", "%2F")
1902 interface = "{0}/vpp-vlan:sub-interfaces/sub-interface/{1}".\
1903 format(interface, index)
1905 # Assume it's the name of a custom interface (pbb, vxlan, etc.)
1906 interface = interface.replace("/", "%2F")