1 # Copyright (c) 2016 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 # pylint: disable=too-many-public-methods
31 # pylint: disable=too-many-lines
32 class InterfaceKeywords(object):
33 """Keywords for Interface manipulation.
35 Implements keywords which get configuration and operational data about
36 vpp interfaces and set the interface's parameters using Honeycomb REST API.
39 INTF_PARAMS = ("name", "description", "type", "enabled",
40 "link-up-down-trap-enable", "v3po:l2", "v3po:vxlan-gpe",
41 "vpp-vlan:sub-interfaces")
42 IPV4_PARAMS = ("enabled", "forwarding", "mtu")
43 IPV6_PARAMS = ("enabled", "forwarding", "mtu", "dup-addr-detect-transmits")
44 IPV6_AUTOCONF_PARAMS = ("create-global-addresses",
45 "create-temporary-addresses",
46 "temporary-valid-lifetime",
47 "temporary-preferred-lifetime")
48 ETH_PARAMS = ("mtu", )
49 ROUTING_PARAMS = ("vrf-id", )
50 VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
51 L2_PARAMS = ("bridge-domain", "split-horizon-group",
52 "bridged-virtual-interface")
53 TAP_PARAMS = ("tap-name", "mac", "device-instance")
54 VHOST_USER_PARAMS = ("socket", "role")
55 SUB_IF_PARAMS = ("identifier",
58 SUB_IF_MATCH = ("default",
61 "vlan-tagged-exact-match")
62 BD_PARAMS = ("bridge-domain",
63 "split-horizon-group",
64 "bridged-virtual-interface")
65 VXLAN_GPE_PARAMS = ("local",
76 def _configure_interface(node, interface, data,
77 data_representation=DataRepresentation.JSON):
78 """Send interface configuration data and check the response.
80 :param node: Honeycomb node.
81 :param interface: The name of interface.
82 :param data: Configuration data to be sent in PUT request.
83 :param data_representation: How the data is represented.
87 :type data_representation: DataRepresentation
88 :return: Content of response.
90 :raises HoneycombError: If the status code in response on PUT is not
94 status_code, resp = HcUtil.\
95 put_honeycomb_data(node, "config_vpp_interfaces", data,
96 data_representation=data_representation)
97 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
99 "The configuration of interface '{0}' was not successful. "
100 "Status code: {1}.".format(interface, status_code))
104 def get_all_interfaces_cfg_data(node):
105 """Get configuration data about all interfaces from Honeycomb.
107 :param node: Honeycomb node.
109 :return: Configuration data about all interfaces from Honeycomb.
111 :raises HoneycombError: If it is not possible to get configuration data.
114 status_code, resp = HcUtil.\
115 get_honeycomb_data(node, "config_vpp_interfaces")
116 if status_code != HTTPCodes.OK:
117 raise HoneycombError(
118 "Not possible to get configuration information about the "
119 "interfaces. Status code: {0}.".format(status_code))
121 return resp["interfaces"]["interface"]
123 except (KeyError, TypeError):
127 def get_interface_cfg_data(node, interface):
128 """Get configuration data about the given interface from Honeycomb.
130 :param node: Honeycomb node.
131 :param interface: The name of interface.
134 :return: Configuration data about the given interface from Honeycomb.
138 intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
140 if intf["name"] == interface:
145 def get_all_interfaces_oper_data(node):
146 """Get operational data about all interfaces from Honeycomb.
148 :param node: Honeycomb node.
150 :return: Operational data about all interfaces from Honeycomb.
152 :raises HoneycombError: If it is not possible to get operational data.
155 status_code, resp = HcUtil.\
156 get_honeycomb_data(node, "oper_vpp_interfaces")
157 if status_code != HTTPCodes.OK:
158 raise HoneycombError(
159 "Not possible to get operational information about the "
160 "interfaces. Status code: {0}.".format(status_code))
162 return resp["interfaces-state"]["interface"]
164 except (KeyError, TypeError):
168 def get_interface_oper_data(node, interface):
169 """Get operational data about the given interface from Honeycomb.
171 :param node: Honeycomb node.
172 :param interface: The name of interface.
175 :return: Operational data about the given interface from Honeycomb.
179 intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
181 if intf["name"] == interface:
186 def _set_interface_properties(node, interface, path, new_value=None):
187 """Set interface properties.
189 This method reads interface configuration data, creates, changes or
190 removes the requested data and puts it back to Honeycomb.
192 :param node: Honeycomb node.
193 :param interface: The name of interface.
194 :param path: Path to data we want to change / create / remove.
195 :param new_value: The new value to be set. If None, the item will be
200 :type new_value: str, dict or list
201 :return: Content of response.
203 :raises HoneycombError: If it is not possible to get or set the data.
206 status_code, resp = HcUtil.\
207 get_honeycomb_data(node, "config_vpp_interfaces")
208 if status_code != HTTPCodes.OK:
209 raise HoneycombError(
210 "Not possible to get configuration information about the "
211 "interfaces. Status code: {0}.".format(status_code))
214 new_data = HcUtil.set_item_value(resp, path, new_value)
216 new_data = HcUtil.remove_item(resp, path)
217 return InterfaceKeywords._configure_interface(node, interface, new_data)
220 def set_interface_state(node, interface, state="up"):
221 """Set VPP interface state.
223 The keyword changes the administration state of interface to up or down
224 depending on the parameter "state".
226 :param node: Honeycomb node.
227 :param interface: Interface name, key, link name or sw_if_index.
228 :param state: The requested state, only "up" and "down" are valid
233 :return: Content of response.
235 :raises KeyError: If the argument "state" is nor "up" or "down".
236 :raises HoneycombError: If the interface is not present on the node.
239 intf_state = {"up": "true",
242 interface = Topology.convert_interface_reference(
243 node, interface, "name")
245 intf = interface.replace("/", "%2F")
246 path = "/interface/{0}".format(intf)
248 status_code, resp = HcUtil.\
249 get_honeycomb_data(node, "config_vpp_interfaces", path)
250 if status_code != HTTPCodes.OK:
251 raise HoneycombError(
252 "Not possible to get configuration information about the "
253 "interfaces. Status code: {0}.".format(status_code))
255 resp["interface"][0]["enabled"] = intf_state[state.lower()]
257 status_code, resp = HcUtil. \
258 put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
259 data_representation=DataRepresentation.JSON)
260 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
261 raise HoneycombError(
262 "The configuration of interface '{0}' was not successful. "
263 "Status code: {1}.".format(interface, status_code))
267 def set_interface_up(node, interface):
268 """Set the administration state of VPP interface to up.
270 :param node: Honeycomb node.
271 :param interface: The name of interface.
274 :return: Content of response
278 return InterfaceKeywords.set_interface_state(node, interface, "up")
281 def set_interface_down(node, interface):
282 """Set the administration state of VPP interface to down.
284 :param node: Honeycomb node.
285 :param interface: The name of interface.
288 :return: Content of response.
292 return InterfaceKeywords.set_interface_state(node, interface, "down")
295 def add_bridge_domain_to_interface(node, interface, bd_name,
296 split_horizon_group=None, bvi=None):
297 """Add a new bridge domain to an interface and set its parameters.
299 :param node: Honeycomb node.
300 :param interface: Interface name, key, link name or sw_if_index.
301 :param bd_name: Bridge domain name.
302 :param split_horizon_group: Split-horizon group name.
303 :param bvi: The bridged virtual interface.
307 :type split_horizon_group: str
309 :return: Content of response.
311 :raises HoneycombError: If the interface is not present on the node.
314 interface = Topology.convert_interface_reference(
315 node, interface, "name")
317 v3po_l2 = {"bridge-domain": str(bd_name)}
318 if split_horizon_group:
319 v3po_l2["split-horizon-group"] = str(split_horizon_group)
321 v3po_l2["bridged-virtual-interface"] = str(bvi)
323 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
325 return InterfaceKeywords._set_interface_properties(
326 node, interface, path, v3po_l2)
329 def remove_bridge_domain_from_interface(node, interface):
330 """Remove bridge domain assignment from interface.
332 :param node: Honeycomb node.
333 :param interface: Interface name, key, link name or sw_if_index.
335 :type interface: str or int
337 :raises HoneycombError: If the operation fails.
340 interface = Topology.convert_interface_reference(
341 node, interface, "name")
343 intf = interface.replace("/", "%2F")
345 path = "/interface/{0}/v3po:l2".format(intf)
347 status_code, response = HcUtil.delete_honeycomb_data(
348 node, "config_vpp_interfaces", path)
350 if status_code != HTTPCodes.OK:
351 if '"error-tag":"data-missing"' in response:
352 logger.debug("Data does not exist in path.")
354 raise HoneycombError(
355 "Could not remove bridge domain assignment from interface "
356 "'{0}'. Status code: {1}.".format(interface, status_code))
359 def get_bd_oper_data_from_interface(node, interface):
360 """Returns operational data about bridge domain settings in the
363 :param node: Honeycomb node.
364 :param interface: The name of interface.
367 :return: Operational data about bridge domain settings in the
372 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
376 return if_data["v3po:l2"]
382 def configure_interface_base(node, interface, param, value):
383 """Configure the base parameters of interface.
385 :param node: Honeycomb node.
386 :param interface: The name of interface.
387 :param param: Parameter to configure (set, change, remove)
388 :param value: The value of parameter. If None, the parameter will be
394 :return: Content of response.
396 :raises HoneycombError: If the parameter is not valid.
399 if param not in InterfaceKeywords.INTF_PARAMS:
400 raise HoneycombError("The parameter {0} is invalid.".format(param))
402 path = ("interfaces", ("interface", "name", interface), param)
403 return InterfaceKeywords._set_interface_properties(
404 node, interface, path, value)
407 def configure_interface_ipv4(node, interface, param, value):
408 """Configure IPv4 parameters of interface.
410 :param node: Honeycomb node.
411 :param interface: The name of interface.
412 :param param: Parameter to configure (set, change, remove)
413 :param value: The value of parameter. If None, the parameter will be
419 :return: Content of response.
421 :raises HoneycombError: If the parameter is not valid.
424 interface = Topology.convert_interface_reference(
425 node, interface, "name")
427 if param not in InterfaceKeywords.IPV4_PARAMS:
428 raise HoneycombError("The parameter {0} is invalid.".format(param))
430 path = ("interfaces", ("interface", "name", interface),
431 "ietf-ip:ipv4", param)
432 return InterfaceKeywords._set_interface_properties(
433 node, interface, path, value)
436 def add_first_ipv4_address(node, interface, ip_addr, network):
437 """Add the first IPv4 address.
439 If there are any other addresses configured, they will be removed.
441 :param node: Honeycomb node.
442 :param interface: The name of interface.
443 :param ip_addr: IPv4 address to be set.
444 :param network: Netmask or length of network prefix.
448 :type network: str or int
449 :return: Content of response.
451 :raises HoneycombError: If the provided netmask or prefix is not valid.
454 interface = Topology.convert_interface_reference(
455 node, interface, "name")
457 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
458 if isinstance(network, basestring):
459 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
460 elif isinstance(network, int) and (0 < network < 33):
461 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
463 raise HoneycombError("Value {0} is not a valid netmask or network "
464 "prefix length.".format(network))
465 return InterfaceKeywords._set_interface_properties(
466 node, interface, path, address)
469 def add_ipv4_address(node, interface, ip_addr, network):
472 :param node: Honeycomb node.
473 :param interface: The name of interface.
474 :param ip_addr: IPv4 address to be set.
475 :param network: Netmask or length of network prefix.
479 :type network: str or int
480 :return: Content of response.
482 :raises HoneycombError: If the provided netmask or prefix is not valid.
485 interface = Topology.convert_interface_reference(
486 node, interface, "name")
488 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
490 if isinstance(network, basestring):
491 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
492 elif isinstance(network, int) and (0 < network < 33):
493 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
495 raise HoneycombError("Value {0} is not a valid netmask or network "
496 "prefix length.".format(network))
497 return InterfaceKeywords._set_interface_properties(
498 node, interface, path, address)
501 def remove_all_ipv4_addresses(node, interface):
502 """Remove all IPv4 addresses from interface.
504 :param node: Honeycomb node.
505 :param interface: The name of interface.
508 :return: Content of response.
512 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
514 return InterfaceKeywords._set_interface_properties(
515 node, interface, path, None)
518 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
519 """Add the IPv4 neighbour.
521 :param node: Honeycomb node.
522 :param interface: The name of interface.
523 :param ip_addr: IPv4 address of neighbour to be set.
524 :param link_layer_address: Link layer address.
528 :type link_layer_address: str
529 :return: Content of response.
533 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
535 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
536 return InterfaceKeywords._set_interface_properties(
537 node, interface, path, neighbor)
540 def remove_all_ipv4_neighbors(node, interface):
541 """Remove all IPv4 neighbours.
543 :param node: Honeycomb node.
544 :param interface: The name of interface.
547 :return: Content of response.
551 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
553 return InterfaceKeywords._set_interface_properties(
554 node, interface, path, None)
557 def configure_interface_ipv6(node, interface, param, value):
558 """Configure IPv6 parameters of interface
560 :param node: Honeycomb node.
561 :param interface: The name of interface.
562 :param param: Parameter to configure (set, change, remove)
563 :param value: The value of parameter. If None, the parameter will be
569 :return: Content of response.
571 :raises HoneycombError: If the parameter is not valid.
574 if param in InterfaceKeywords.IPV6_PARAMS:
575 path = ("interfaces", ("interface", "name", interface),
576 "ietf-ip:ipv6", param)
577 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
578 path = ("interfaces", ("interface", "name", interface),
579 "ietf-ip:ipv6", "autoconf", param)
581 raise HoneycombError("The parameter {0} is invalid.".format(param))
583 return InterfaceKeywords._set_interface_properties(
584 node, interface, path, value)
587 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
588 """Add the first IPv6 address.
590 If there are any other addresses configured, they will be removed.
592 :param node: Honeycomb node.
593 :param interface: The name of interface.
594 :param ip_addr: IPv6 address to be set.
595 :param prefix_len: Prefix length.
599 :type prefix_len: str
600 :return: Content of response.
604 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
605 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
606 return InterfaceKeywords._set_interface_properties(
607 node, interface, path, address)
610 def add_ipv6_address(node, interface, ip_addr, prefix_len):
613 :param node: Honeycomb node.
614 :param interface: The name of interface.
615 :param ip_addr: IPv6 address to be set.
616 :param prefix_len: Prefix length.
620 :type prefix_len: str
621 :return: Content of response.
625 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
627 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
628 return InterfaceKeywords._set_interface_properties(
629 node, interface, path, address)
632 def remove_all_ipv6_addresses(node, interface):
633 """Remove all IPv6 addresses from interface.
635 :param node: Honeycomb node.
636 :param interface: The name of interface.
639 :return: Content of response.
643 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
645 return InterfaceKeywords._set_interface_properties(
646 node, interface, path, None)
649 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
650 """Add the IPv6 neighbour.
652 :param node: Honeycomb node.
653 :param interface: The name of interface.
654 :param ip_addr: IPv6 address of neighbour to be set.
655 :param link_layer_address: Link layer address.
659 :type link_layer_address: str
660 :return: Content of response.
664 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
666 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
667 return InterfaceKeywords._set_interface_properties(
668 node, interface, path, neighbor)
671 def remove_all_ipv6_neighbors(node, interface):
672 """Remove all IPv6 neighbours.
674 :param node: Honeycomb node.
675 :param interface: The name of interface.
678 :return: Content of response.
682 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
684 return InterfaceKeywords._set_interface_properties(
685 node, interface, path, None)
688 def configure_interface_ethernet(node, interface, param, value):
689 """Configure the ethernet parameters of interface.
691 :param node: Honeycomb node.
692 :param interface: The name of interface.
693 :param param: Parameter to configure (set, change, remove)
694 :param value: The value of parameter. If None, the parameter will be
700 :return: Content of response.
702 :raises HoneycombError: If the parameter is not valid.
705 if param not in InterfaceKeywords.ETH_PARAMS:
706 raise HoneycombError("The parameter {0} is invalid.".format(param))
707 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
709 return InterfaceKeywords._set_interface_properties(
710 node, interface, path, value)
713 def configure_interface_routing(node, interface, param, value):
714 """Configure the routing parameters of interface.
716 :param node: Honeycomb node.
717 :param interface: The name of interface.
718 :param param: Parameter to configure (set, change, remove)
719 :param value: The value of parameter. If None, the parameter will be
725 :return: Content of response.
727 :raises HoneycombError: If the parameter is not valid.
730 if param not in InterfaceKeywords.ROUTING_PARAMS:
731 raise HoneycombError("The parameter {0} is invalid.".format(param))
733 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
735 return InterfaceKeywords._set_interface_properties(
736 node, interface, path, value)
739 def create_vxlan_interface(node, interface, **kwargs):
740 """Create a new VxLAN interface.
742 :param node: Honeycomb node.
743 :param interface: The name of interface.
744 :param kwargs: Parameters and their values. The accepted parameters are
745 defined in InterfaceKeywords.VXLAN_PARAMS.
749 :return: Content of response.
751 :raises HoneycombError: If the parameter is not valid.
756 "type": "v3po:vxlan-tunnel",
759 for param, value in kwargs.items():
760 if param not in InterfaceKeywords.VXLAN_PARAMS:
761 raise HoneycombError("The parameter {0} is invalid.".
763 new_vx_lan["v3po:vxlan"][param] = value
765 path = ("interfaces", "interface")
766 vx_lan_structure = [new_vx_lan, ]
767 return InterfaceKeywords._set_interface_properties(
768 node, interface, path, vx_lan_structure)
771 def delete_interface(node, interface):
772 """Delete an interface.
774 :param node: Honeycomb node.
775 :param interface: The name of interface.
778 :return: Content of response.
780 :raises HoneycombError: If it is not possible to get information about
781 interfaces or it is not possible to delete the interface.
784 path = ("interfaces", ("interface", "name", interface))
786 status_code, resp = HcUtil.\
787 get_honeycomb_data(node, "config_vpp_interfaces")
788 if status_code != HTTPCodes.OK:
789 raise HoneycombError(
790 "Not possible to get configuration information about the "
791 "interfaces. Status code: {0}.".format(status_code))
793 new_data = HcUtil.remove_item(resp, path)
794 status_code, resp = HcUtil.\
795 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
796 if status_code != HTTPCodes.OK:
797 raise HoneycombError("Not possible to remove interface {0}. "
799 format(interface, status_code))
803 def configure_interface_vxlan(node, interface, **kwargs):
804 """Configure VxLAN on the interface.
806 The keyword configures VxLAN parameters on the given interface. The type
807 of interface must be set to "v3po:vxlan-tunnel".
808 The new VxLAN parameters overwrite the current configuration. If a
809 parameter in new configuration is missing, it is removed from VxLAN
811 If the dictionary kwargs is empty, VxLAN configuration is removed.
813 :param node: Honeycomb node.
814 :param interface: The name of interface.
815 :param kwargs: Parameters and their values. The accepted parameters are
816 defined in InterfaceKeywords.VXLAN_PARAMS.
820 :return: Content of response.
822 :raises HoneycombError: If the parameter is not valid.
825 vx_lan_structure = dict()
826 for param, value in kwargs.items():
827 if param not in InterfaceKeywords.VXLAN_PARAMS:
828 raise HoneycombError("The parameter {0} is invalid.".
830 vx_lan_structure[param] = value
832 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
833 return InterfaceKeywords._set_interface_properties(
834 node, interface, path, vx_lan_structure)
837 def configure_interface_l2(node, interface, param, value):
838 """Configure the L2 parameters of interface.
840 :param node: Honeycomb node.
841 :param interface: The name of interface.
842 :param param: Parameter to configure (set, change, remove)
843 :param value: The value of parameter. If None, the parameter will be
849 :return: Content of response.
851 :raises HoneycombError: If the parameter is not valid.
854 if param not in InterfaceKeywords.L2_PARAMS:
855 raise HoneycombError("The parameter {0} is invalid.".format(param))
856 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
858 return InterfaceKeywords._set_interface_properties(
859 node, interface, path, value)
862 def create_tap_interface(node, interface, **kwargs):
863 """Create a new TAP interface.
865 :param node: Honeycomb node.
866 :param interface: The name of interface.
867 :param kwargs: Parameters and their values. The accepted parameters are
868 defined in InterfaceKeywords.TAP_PARAMS.
872 :return: Content of response.
874 :raises HoneycombError: If the parameter is not valid.
882 for param, value in kwargs.items():
883 if param not in InterfaceKeywords.TAP_PARAMS:
884 raise HoneycombError("The parameter {0} is invalid.".
886 new_tap["v3po:tap"][param] = value
888 path = ("interfaces", "interface")
889 new_tap_structure = [new_tap, ]
890 return InterfaceKeywords._set_interface_properties(
891 node, interface, path, new_tap_structure)
894 def configure_interface_tap(node, interface, **kwargs):
895 """Configure TAP on the interface.
897 The keyword configures TAP parameters on the given interface. The type
898 of interface must be set to "v3po:tap".
899 The new TAP parameters overwrite the current configuration. If a
900 parameter in new configuration is missing, it is removed from TAP
902 If the dictionary kwargs is empty, TAP configuration is removed.
904 :param node: Honeycomb node.
905 :param interface: The name of interface.
906 :param kwargs: Parameters and their values. The accepted parameters are
907 defined in InterfaceKeywords.TAP_PARAMS.
911 :return: Content of response.
913 :raises HoneycombError: If the parameter is not valid.
916 tap_structure = dict()
917 for param, value in kwargs.items():
918 if param not in InterfaceKeywords.TAP_PARAMS:
919 raise HoneycombError("The parameter {0} is invalid.".
921 tap_structure[param] = value
923 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
924 return InterfaceKeywords._set_interface_properties(
925 node, interface, path, tap_structure)
928 def configure_interface_vhost_user(node, interface, **kwargs):
929 """Configure vhost-user on the interface.
931 The keyword configures vhost-user parameters on the given interface.
932 The type of interface must be set to "v3po:vhost-user".
933 The new vhost-user parameters overwrite the current configuration. If a
934 parameter in new configuration is missing, it is removed from vhost-user
936 If the dictionary kwargs is empty, vhost-user configuration is removed.
938 :param node: Honeycomb node.
939 :param interface: The name of interface.
940 :param kwargs: Parameters and their values. The accepted parameters are
941 defined in InterfaceKeywords.VHOST_USER_PARAMS.
945 :return: Content of response.
947 :raises HoneycombError: If the parameter is not valid.
950 vhost_structure = dict()
951 for param, value in kwargs.items():
952 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
953 raise HoneycombError("The parameter {0} is invalid.".
955 vhost_structure[param] = value
957 path = ("interfaces", ("interface", "name", interface),
959 return InterfaceKeywords._set_interface_properties(
960 node, interface, path, vhost_structure)
963 def create_vhost_user_interface(node, interface, **kwargs):
964 """Create a new vhost-user interface.
966 :param node: Honeycomb node.
967 :param interface: The name of interface.
968 :param kwargs: Parameters and their values. The accepted parameters are
969 defined in InterfaceKeywords.VHOST_USER_PARAMS.
973 :return: Content of response.
975 :raises HoneycombError: If the parameter is not valid.
980 "type": "v3po:vhost-user",
981 "v3po:vhost-user": {}
983 for param, value in kwargs.items():
984 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
985 raise HoneycombError("The parameter {0} is invalid.".
987 new_vhost["v3po:vhost-user"][param] = value
989 path = ("interfaces", "interface")
990 new_vhost_structure = [new_vhost, ]
991 return InterfaceKeywords._set_interface_properties(
992 node, interface, path, new_vhost_structure)
995 def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
996 """Create a new sub-interface.
998 :param node: Honeycomb node.
999 :param super_interface: Super interface.
1000 :param match: Match type. The valid values are defined in
1001 InterfaceKeywords.SUB_IF_MATCH.
1002 :param tags: List of tags.
1003 :param kwargs: Parameters and their values. The accepted parameters are
1004 defined in InterfaceKeywords.SUB_IF_PARAMS.
1006 :type super_interface: str
1010 :return: Content of response.
1012 :raises HoneycombError: If the parameter is not valid.
1013 :raises KeyError: If the parameter 'match' is invalid.
1022 {"vlan-tagged": {"match-exact-tags": "false"}},
1023 "vlan-tagged-exact-match":
1024 {"vlan-tagged": {"match-exact-tags": "true"}}
1027 new_sub_interface = {
1033 for param, value in kwargs.items():
1034 if param in InterfaceKeywords.SUB_IF_PARAMS:
1035 new_sub_interface[param] = value
1037 raise HoneycombError("The parameter {0} is invalid.".
1040 new_sub_interface["match"] = match_type[match]
1042 raise HoneycombError("The value '{0}' of parameter 'match' is "
1043 "invalid.".format(match))
1046 new_sub_interface["tags"]["tag"].extend(tags)
1048 path = ("interfaces",
1049 ("interface", "name", super_interface),
1050 "vpp-vlan:sub-interfaces",
1052 new_sub_interface_structure = [new_sub_interface, ]
1053 return InterfaceKeywords._set_interface_properties(
1054 node, super_interface, path, new_sub_interface_structure)
1057 def get_sub_interface_oper_data(node, super_interface, identifier):
1058 """Retrieves sub-interface operational data using Honeycomb API.
1060 :param node: Honeycomb node.
1061 :param super_interface: Super interface.
1062 :param identifier: The ID of sub-interface.
1064 :type super_interface: str
1065 :type identifier: int
1066 :return: Sub-interface operational data.
1068 :raises HoneycombError: If there is no sub-interface with the given ID.
1071 if_data = InterfaceKeywords.get_interface_oper_data(node,
1073 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1074 if str(sub_if["identifier"]) == str(identifier):
1077 raise HoneycombError("The interface {0} does not have sub-interface "
1078 "with ID {1}".format(super_interface, identifier))
1081 def remove_all_sub_interfaces(node, super_interface):
1082 """Remove all sub-interfaces from the given interface.
1084 :param node: Honeycomb node.
1085 :param super_interface: Super interface.
1087 :type super_interface: str
1088 :return: Content of response.
1092 path = ("interfaces",
1093 ("interface", "name", super_interface),
1094 "vpp-vlan:sub-interfaces")
1096 return InterfaceKeywords._set_interface_properties(
1097 node, super_interface, path, {})
1100 def set_sub_interface_state(node, super_interface, identifier, state):
1101 """Set the administrative state of sub-interface.
1103 :param node: Honeycomb node.
1104 :param super_interface: Super interface.
1105 :param identifier: The ID of sub-interface.
1106 :param state: Required sub-interface state - up or down.
1108 :type super_interface: str
1109 :type identifier: int
1111 :return: Content of response.
1115 intf_state = {"up": "true",
1118 path = ("interfaces",
1119 ("interface", "name", super_interface),
1120 "vpp-vlan:sub-interfaces",
1121 ("sub-interface", "identifier", identifier),
1124 return InterfaceKeywords._set_interface_properties(
1125 node, super_interface, path, intf_state[state])
1128 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1130 """Add a sub-interface to a bridge domain and set its parameters.
1132 :param node: Honeycomb node.
1133 :param super_interface: Super interface.
1134 :param identifier: The ID of sub-interface.
1135 :param config: Bridge domain configuration.
1137 :type super_interface: str
1138 :type identifier: int
1140 :return: Content of response.
1144 path = ("interfaces",
1145 ("interface", "name", super_interface),
1146 "vpp-vlan:sub-interfaces",
1147 ("sub-interface", "identifier", int(identifier)),
1150 return InterfaceKeywords._set_interface_properties(
1151 node, super_interface, path, config)
1154 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1155 """Get the operational data about the bridge domain from sub-interface.
1157 :param node: Honeycomb node.
1158 :param super_interface: Super interface.
1159 :param identifier: The ID of sub-interface.
1161 :type super_interface: str
1162 :type identifier: int
1163 :return: Operational data about the bridge domain.
1165 :raises HoneycombError: If there is no sub-interface with the given ID.
1169 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1170 node, super_interface, identifier)["l2"]
1173 raise HoneycombError("The operational data does not contain "
1174 "information about a bridge domain.")
1177 def configure_tag_rewrite(node, super_interface, identifier, config):
1178 """Add / change / disable vlan tag rewrite on a sub-interface.
1180 :param node: Honeycomb node.
1181 :param super_interface: Super interface.
1182 :param identifier: The ID of sub-interface.
1183 :param config: Rewrite tag configuration.
1185 :type super_interface: str
1186 :type identifier: int
1188 :return: Content of response.
1192 path = ("interfaces",
1193 ("interface", "name", super_interface),
1194 "vpp-vlan:sub-interfaces",
1195 ("sub-interface", "identifier", int(identifier)),
1199 return InterfaceKeywords._set_interface_properties(
1200 node, super_interface, path, config)
1203 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1204 """Get the operational data about tag rewrite.
1206 :param node: Honeycomb node.
1207 :param super_interface: Super interface.
1208 :param identifier: The ID of sub-interface.
1210 :type super_interface: str
1211 :type identifier: int
1212 :return: Operational data about tag rewrite.
1214 :raises HoneycombError: If there is no sub-interface with the given ID.
1218 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1219 node, super_interface, identifier)["l2"]["rewrite"]
1222 raise HoneycombError("The operational data does not contain "
1223 "information about the tag-rewrite.")
1226 def add_ipv4_address_to_sub_interface(node, super_interface, identifier,
1228 """Add an ipv4 address to the specified sub-interface, with the provided
1229 netmask or network prefix length. Any existing ipv4 addresses on the
1230 sub-interface will be replaced.
1232 :param node: Honeycomb node.
1233 :param super_interface: Super interface.
1234 :param identifier: The ID of sub-interface.
1235 :param ip_addr: IPv4 address to be set.
1236 :param network: Network mask or network prefix length.
1238 :type super_interface: str
1239 :type identifier: int
1241 :type network: str or int
1242 :return: Content of response.
1244 :raises HoneycombError: If the provided netmask or prefix is not valid.
1247 path = ("interfaces",
1248 ("interface", "name", super_interface),
1249 "vpp-vlan:sub-interfaces",
1250 ("sub-interface", "identifier", int(identifier)),
1253 if isinstance(network, basestring):
1254 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1256 elif isinstance(network, int) and 0 < network < 33:
1257 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1260 raise HoneycombError("{0} is not a valid netmask or prefix length."
1263 return InterfaceKeywords._set_interface_properties(
1264 node, super_interface, path, address)
1267 def remove_all_ipv4_addresses_from_sub_interface(node, super_interface, # pylint: disable=invalid-name
1269 """Remove all ipv4 addresses from the specified sub-interface.
1271 :param node: Honeycomb node.
1272 :param super_interface: Super interface.
1273 :param identifier: The ID of sub-interface.
1275 :type super_interface: str
1276 :type identifier: int
1277 :return: Content of response.
1281 path = ("interfaces",
1282 ("interface", "name", super_interface),
1283 "vpp-vlan:sub-interfaces",
1284 ("sub-interface", "identifier", int(identifier)),
1287 return InterfaceKeywords._set_interface_properties(
1288 node, super_interface, path, None)
1291 def compare_data_structures(data, ref, ignore=(), list_order=True):
1292 """Checks if data obtained from UUT is as expected.
1294 :param data: Data to be checked.
1295 :param ref: Referential data used for comparison.
1296 :param ignore: Dictionary keys to be ignored.
1297 :param list_order: Whether to consider the order of list items\
1301 :type ignore: iterable
1302 :type list_order: bool
1304 :raises HoneycombError: If a parameter from referential data is not
1305 present in operational data or if it has different value.
1310 for key, item in ref.items():
1314 if data[key] != item:
1315 if not list_order and sorted(data[key]) == sorted(item):
1318 errors += ("\nThe value of parameter '{0}' is "
1319 "incorrect. It should be "
1320 "'{1}' but it is '{2}'".
1321 format(key, item, data[key]))
1323 errors += ("\nThe parameter '{0}' is not present in "
1324 "operational data".format(key))
1327 raise HoneycombError(errors)
1330 def compare_interface_lists(list1, list2):
1331 """Compare provided lists of interfaces by name.
1333 :param list1: List of interfaces.
1334 :param list2: List of interfaces.
1337 :raises HoneycombError: If an interface exists in only one of the lists.
1340 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1341 # these have no equivalent in config data and no effect on VPP
1343 names1 = [x['name'] for x in list1]
1344 names2 = [x['name'] for x in list2]
1347 if name not in names2 and name not in ignore:
1348 raise HoneycombError("Interface {0} not present in list {1}"
1349 .format(name, list2))
1351 if name not in names1 and name not in ignore:
1352 raise HoneycombError("Interface {0} not present in list {1}"
1353 .format(name, list1))
1356 def create_vxlan_gpe_interface(node, interface, **kwargs):
1357 """Create a new VxLAN GPE interface.
1359 :param node: Honeycomb node.
1360 :param interface: The name of interface to be created.
1361 :param kwargs: Parameters and their values. The accepted parameters are
1362 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1364 :type interface: str
1366 :return: Content of response.
1368 :raises HoneycombError: If a parameter in kwargs is not valid.
1373 "type": "v3po:vxlan-gpe-tunnel",
1374 "v3po:vxlan-gpe": {}
1376 for param, value in kwargs.items():
1377 if param in InterfaceKeywords.INTF_PARAMS:
1378 new_vxlan_gpe[param] = value
1379 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1380 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1382 raise HoneycombError("The parameter {0} is invalid.".
1384 path = ("interfaces", "interface")
1385 vxlan_gpe_structure = [new_vxlan_gpe, ]
1386 return InterfaceKeywords._set_interface_properties(
1387 node, interface, path, vxlan_gpe_structure)
1390 def enable_acl_on_interface(node, interface, table_name):
1391 """Enable ACL on the given interface.
1393 :param node: Honeycomb node.
1394 :param interface: The interface where the ACL will be enabled.
1395 :param table_name: Name of the classify table.
1397 :type interface: str
1398 :type table_name: str
1399 :return: Content of response.
1401 :raises HoneycombError: If the configuration of interface is not
1405 interface = interface.replace("/", "%2F")
1411 "classify-table": table_name
1414 "classify-table": table_name
1420 path = "/interface/" + interface + "/v3po:acl"
1421 status_code, resp = HcUtil.\
1422 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1423 data_representation=DataRepresentation.JSON)
1424 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1425 raise HoneycombError(
1426 "The configuration of interface '{0}' was not successful. "
1427 "Status code: {1}.".format(interface, status_code))
1431 def disable_acl_on_interface(node, interface):
1432 """Disable ACL on the given interface.
1434 :param node: Honeycomb node.
1435 :param interface: The interface where the ACL will be disabled.
1437 :type interface: str
1438 :return: Content of response.
1440 :raises HoneycombError: If the configuration of interface is not
1444 interface = interface.replace("/", "%2F")
1446 path = "/interface/" + interface + "/v3po:acl"
1448 status_code, resp = HcUtil.\
1449 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1451 if status_code != HTTPCodes.OK:
1452 raise HoneycombError(
1453 "The configuration of interface '{0}' was not successful. "
1454 "Status code: {1}.".format(interface, status_code))
1458 def create_pbb_sub_interface(node, intf, sub_if_id, params):
1459 """Creates a PBB sub-interface on the given interface and sets its
1462 :param node: Honeycomb node.
1463 :param intf: The interface where PBB sub-interface will be configured.
1464 :param sub_if_id: Sub-interface ID.
1465 :param params: Configuration parameters of the sub-interface to be
1469 :type sub_if_id: str or int
1471 :return: Content of response.
1473 :raises HoneycombError: If the configuration of sub-interface is not
1477 interface = intf.replace("/", "%2F")
1478 path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1479 "{1}".format(interface, sub_if_id)
1480 status_code, resp = HcUtil. \
1481 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1482 data_representation=DataRepresentation.JSON)
1483 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1484 raise HoneycombError(
1485 "The configuration of PBB sub-interface '{0}' was not "
1486 "successful. Status code: {1}.".format(intf, status_code))
1490 def delete_pbb_sub_interface(node, intf, sub_if_id):
1491 """Deletes the given PBB sub-interface.
1493 :param node: Honeycomb node.
1494 :param intf: The interface where PBB sub-interface will be deleted.
1495 :param sub_if_id: ID of the PBB sub-interface to be deleted.
1498 :type sub_if_id: str or int
1499 :return: Content of response.
1501 :raises HoneycombError: If the removal of sub-interface is not
1505 interface = intf.replace("/", "%2F")
1506 path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1507 "{1}".format(interface, sub_if_id)
1509 status_code, resp = HcUtil. \
1510 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1511 if status_code != HTTPCodes.OK:
1512 raise HoneycombError(
1513 "The removal of pbb sub-interface '{0}' was not successful. "
1514 "Status code: {1}.".format(intf, status_code))
1518 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1519 """Retrieves PBB sub-interface operational data from Honeycomb.
1521 :param node: Honeycomb node.
1522 :param intf: The interface where PBB sub-interface is located.
1523 :param sub_if_id: ID of the PBB sub-interface.
1526 :type sub_if_id: str or int
1527 :return: PBB sub-interface operational data.
1529 :raises HoneycombError: If the removal of sub-interface is not
1533 interface = "{0}.{1}".format(intf, sub_if_id)
1534 return InterfaceKeywords.get_interface_oper_data(node, interface)