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 resources.libraries.python.topology import Topology
20 from resources.libraries.python.HTTPRequest import HTTPCodes
21 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
22 from resources.libraries.python.honeycomb.HoneycombUtil \
23 import DataRepresentation
24 from resources.libraries.python.honeycomb.HoneycombUtil \
25 import HoneycombUtil as HcUtil
28 # pylint: disable=too-many-public-methods
29 # pylint: disable=too-many-lines
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 = ("vrf-id", )
48 VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
49 L2_PARAMS = ("bridge-domain", "split-horizon-group",
50 "bridged-virtual-interface")
51 TAP_PARAMS = ("tap-name", "mac", "device-instance")
52 VHOST_USER_PARAMS = ("socket", "role")
53 SUB_IF_PARAMS = ("identifier",
56 SUB_IF_MATCH = ("default",
59 "vlan-tagged-exact-match")
60 BD_PARAMS = ("bridge-domain",
61 "split-horizon-group",
62 "bridged-virtual-interface")
63 VXLAN_GPE_PARAMS = ("local",
74 def _configure_interface(node, interface, data,
75 data_representation=DataRepresentation.JSON):
76 """Send interface configuration data and check the response.
78 :param node: Honeycomb node.
79 :param interface: The name of interface.
80 :param data: Configuration data to be sent in PUT request.
81 :param data_representation: How the data is represented.
85 :type data_representation: DataRepresentation
86 :return: Content of response.
88 :raises HoneycombError: If the status code in response on PUT is not
92 status_code, resp = HcUtil.\
93 put_honeycomb_data(node, "config_vpp_interfaces", data,
94 data_representation=data_representation)
95 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
97 "The configuration of interface '{0}' was not successful. "
98 "Status code: {1}.".format(interface, status_code))
102 def get_all_interfaces_cfg_data(node):
103 """Get configuration data about all interfaces from Honeycomb.
105 :param node: Honeycomb node.
107 :return: Configuration data about all interfaces from Honeycomb.
109 :raises HoneycombError: If it is not possible to get configuration data.
112 status_code, resp = HcUtil.\
113 get_honeycomb_data(node, "config_vpp_interfaces")
114 if status_code != HTTPCodes.OK:
115 raise HoneycombError(
116 "Not possible to get configuration information about the "
117 "interfaces. Status code: {0}.".format(status_code))
119 return resp["interfaces"]["interface"]
121 except (KeyError, TypeError):
125 def get_interface_cfg_data(node, interface):
126 """Get configuration data about the given interface from Honeycomb.
128 :param node: Honeycomb node.
129 :param interface: The name of interface.
132 :return: Configuration data about the given interface from Honeycomb.
136 intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
138 if intf["name"] == interface:
143 def get_all_interfaces_oper_data(node):
144 """Get operational data about all interfaces from Honeycomb.
146 :param node: Honeycomb node.
148 :return: Operational data about all interfaces from Honeycomb.
150 :raises HoneycombError: If it is not possible to get operational data.
153 status_code, resp = HcUtil.\
154 get_honeycomb_data(node, "oper_vpp_interfaces")
155 if status_code != HTTPCodes.OK:
156 raise HoneycombError(
157 "Not possible to get operational information about the "
158 "interfaces. Status code: {0}.".format(status_code))
160 return resp["interfaces-state"]["interface"]
162 except (KeyError, TypeError):
166 def get_interface_oper_data(node, interface):
167 """Get operational data about the given interface from Honeycomb.
169 :param node: Honeycomb node.
170 :param interface: The name of interface.
173 :return: Operational data about the given interface from Honeycomb.
177 intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
179 if intf["name"] == interface:
184 def _set_interface_properties(node, interface, path, new_value=None):
185 """Set interface properties.
187 This method reads interface configuration data, creates, changes or
188 removes the requested data and puts it back to Honeycomb.
190 :param node: Honeycomb node.
191 :param interface: The name of interface.
192 :param path: Path to data we want to change / create / remove.
193 :param new_value: The new value to be set. If None, the item will be
198 :type new_value: str, dict or list
199 :return: Content of response.
201 :raises HoneycombError: If it is not possible to get or set the data.
204 status_code, resp = HcUtil.\
205 get_honeycomb_data(node, "config_vpp_interfaces")
206 if status_code != HTTPCodes.OK:
207 raise HoneycombError(
208 "Not possible to get configuration information about the "
209 "interfaces. Status code: {0}.".format(status_code))
212 new_data = HcUtil.set_item_value(resp, path, new_value)
214 new_data = HcUtil.remove_item(resp, path)
215 return InterfaceKeywords._configure_interface(node, interface, new_data)
218 def set_interface_state(node, interface, state="up"):
219 """Set VPP interface state.
221 The keyword changes the administration state of interface to up or down
222 depending on the parameter "state".
224 :param node: Honeycomb node.
225 :param interface: Interface name, key, link name or sw_if_index.
226 :param state: The requested state, only "up" and "down" are valid
231 :return: Content of response.
233 :raises KeyError: If the argument "state" is nor "up" or "down".
234 :raises HoneycombError: If the interface is not present on the node.
237 intf_state = {"up": "true",
240 interface = Topology.convert_interface_reference(
241 node, interface, "name")
243 intf = interface.replace("/", "%2F")
244 path = "/interface/{0}".format(intf)
246 status_code, resp = HcUtil.\
247 get_honeycomb_data(node, "config_vpp_interfaces", path)
248 if status_code != HTTPCodes.OK:
249 raise HoneycombError(
250 "Not possible to get configuration information about the "
251 "interfaces. Status code: {0}.".format(status_code))
253 resp["interface"][0]["enabled"] = intf_state[state.lower()]
255 status_code, resp = HcUtil. \
256 put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
257 data_representation=DataRepresentation.JSON)
258 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
259 raise HoneycombError(
260 "The configuration of interface '{0}' was not successful. "
261 "Status code: {1}.".format(interface, status_code))
265 def set_interface_up(node, interface):
266 """Set the administration state of VPP interface to up.
268 :param node: Honeycomb node.
269 :param interface: The name of interface.
272 :return: Content of response
276 return InterfaceKeywords.set_interface_state(node, interface, "up")
279 def set_interface_down(node, interface):
280 """Set the administration state of VPP interface to down.
282 :param node: Honeycomb node.
283 :param interface: The name of interface.
286 :return: Content of response.
290 return InterfaceKeywords.set_interface_state(node, interface, "down")
293 def add_bridge_domain_to_interface(node, interface, bd_name,
294 split_horizon_group=None, bvi=None):
295 """Add a new bridge domain to an interface and set its parameters.
297 :param node: Honeycomb node.
298 :param interface: Interface name, key, link name or sw_if_index.
299 :param bd_name: Bridge domain name.
300 :param split_horizon_group: Split-horizon group name.
301 :param bvi: The bridged virtual interface.
305 :type split_horizon_group: str
307 :return: Content of response.
309 :raises HoneycombError: If the interface is not present on the node.
312 interface = Topology.convert_interface_reference(
313 node, interface, "name")
315 v3po_l2 = {"bridge-domain": str(bd_name)}
316 if split_horizon_group:
317 v3po_l2["split-horizon-group"] = str(split_horizon_group)
319 v3po_l2["bridged-virtual-interface"] = str(bvi)
321 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
323 return InterfaceKeywords._set_interface_properties(
324 node, interface, path, v3po_l2)
327 def remove_bridge_domain_from_interface(node, interface):
328 """Remove bridge domain assignment from interface.
330 :param node: Honeycomb node.
331 :param interface: Interface name, key, link name or sw_if_index.
333 :type interface: str or int
335 :raises HoneycombError: If the operation fails.
338 interface = Topology.convert_interface_reference(
339 node, interface, "name")
341 intf = interface.replace("/", "%2F")
343 path = "/interface/{0}/v3po:l2".format(intf)
345 status_code, _ = HcUtil.delete_honeycomb_data(
346 node, "config_vpp_interfaces", path)
348 if status_code != HTTPCodes.OK:
349 raise HoneycombError(
350 "Could not remove bridge domain assignment from interface "
351 "'{0}'. Status code: {1}.".format(interface, status_code))
354 def get_bd_oper_data_from_interface(node, interface):
355 """Returns operational data about bridge domain settings in the
358 :param node: Honeycomb node.
359 :param interface: The name of interface.
362 :return: Operational data about bridge domain settings in the
367 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
371 return if_data["v3po:l2"]
377 def configure_interface_base(node, interface, param, value):
378 """Configure the base parameters of interface.
380 :param node: Honeycomb node.
381 :param interface: The name of interface.
382 :param param: Parameter to configure (set, change, remove)
383 :param value: The value of parameter. If None, the parameter will be
389 :return: Content of response.
391 :raises HoneycombError: If the parameter is not valid.
394 if param not in InterfaceKeywords.INTF_PARAMS:
395 raise HoneycombError("The parameter {0} is invalid.".format(param))
397 path = ("interfaces", ("interface", "name", interface), param)
398 return InterfaceKeywords._set_interface_properties(
399 node, interface, path, value)
402 def configure_interface_ipv4(node, interface, param, value):
403 """Configure IPv4 parameters of interface.
405 :param node: Honeycomb node.
406 :param interface: The name of interface.
407 :param param: Parameter to configure (set, change, remove)
408 :param value: The value of parameter. If None, the parameter will be
414 :return: Content of response.
416 :raises HoneycombError: If the parameter is not valid.
419 interface = Topology.convert_interface_reference(
420 node, interface, "name")
422 if param not in InterfaceKeywords.IPV4_PARAMS:
423 raise HoneycombError("The parameter {0} is invalid.".format(param))
425 path = ("interfaces", ("interface", "name", interface),
426 "ietf-ip:ipv4", param)
427 return InterfaceKeywords._set_interface_properties(
428 node, interface, path, value)
431 def add_first_ipv4_address(node, interface, ip_addr, network):
432 """Add the first IPv4 address.
434 If there are any other addresses configured, they will be removed.
436 :param node: Honeycomb node.
437 :param interface: The name of interface.
438 :param ip_addr: IPv4 address to be set.
439 :param network: Netmask or length of network prefix.
443 :type network: str or int
444 :return: Content of response.
446 :raises HoneycombError: If the provided netmask or prefix is not valid.
449 interface = Topology.convert_interface_reference(
450 node, interface, "name")
452 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
453 if isinstance(network, basestring):
454 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
455 elif isinstance(network, int) and (0 < network < 33):
456 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
458 raise HoneycombError("Value {0} is not a valid netmask or network "
459 "prefix length.".format(network))
460 return InterfaceKeywords._set_interface_properties(
461 node, interface, path, address)
464 def add_ipv4_address(node, interface, ip_addr, network):
467 :param node: Honeycomb node.
468 :param interface: The name of interface.
469 :param ip_addr: IPv4 address to be set.
470 :param network: Netmask or length of network prefix.
474 :type network: str or int
475 :return: Content of response.
477 :raises HoneycombError: If the provided netmask or prefix is not valid.
480 interface = Topology.convert_interface_reference(
481 node, interface, "name")
483 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
485 if isinstance(network, basestring):
486 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
487 elif isinstance(network, int) and (0 < network < 33):
488 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
490 raise HoneycombError("Value {0} is not a valid netmask or network "
491 "prefix length.".format(network))
492 return InterfaceKeywords._set_interface_properties(
493 node, interface, path, address)
496 def remove_all_ipv4_addresses(node, interface):
497 """Remove all IPv4 addresses from interface.
499 :param node: Honeycomb node.
500 :param interface: The name of interface.
503 :return: Content of response.
507 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
509 return InterfaceKeywords._set_interface_properties(
510 node, interface, path, None)
513 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
514 """Add the IPv4 neighbour.
516 :param node: Honeycomb node.
517 :param interface: The name of interface.
518 :param ip_addr: IPv4 address of neighbour to be set.
519 :param link_layer_address: Link layer address.
523 :type link_layer_address: str
524 :return: Content of response.
528 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
530 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
531 return InterfaceKeywords._set_interface_properties(
532 node, interface, path, neighbor)
535 def remove_all_ipv4_neighbors(node, interface):
536 """Remove all IPv4 neighbours.
538 :param node: Honeycomb node.
539 :param interface: The name of interface.
542 :return: Content of response.
546 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
548 return InterfaceKeywords._set_interface_properties(
549 node, interface, path, None)
552 def configure_interface_ipv6(node, interface, param, value):
553 """Configure IPv6 parameters of interface
555 :param node: Honeycomb node.
556 :param interface: The name of interface.
557 :param param: Parameter to configure (set, change, remove)
558 :param value: The value of parameter. If None, the parameter will be
564 :return: Content of response.
566 :raises HoneycombError: If the parameter is not valid.
569 if param in InterfaceKeywords.IPV6_PARAMS:
570 path = ("interfaces", ("interface", "name", interface),
571 "ietf-ip:ipv6", param)
572 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
573 path = ("interfaces", ("interface", "name", interface),
574 "ietf-ip:ipv6", "autoconf", param)
576 raise HoneycombError("The parameter {0} is invalid.".format(param))
578 return InterfaceKeywords._set_interface_properties(
579 node, interface, path, value)
582 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
583 """Add the first IPv6 address.
585 If there are any other addresses configured, they will be removed.
587 :param node: Honeycomb node.
588 :param interface: The name of interface.
589 :param ip_addr: IPv6 address to be set.
590 :param prefix_len: Prefix length.
594 :type prefix_len: str
595 :return: Content of response.
599 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
600 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
601 return InterfaceKeywords._set_interface_properties(
602 node, interface, path, address)
605 def add_ipv6_address(node, interface, ip_addr, prefix_len):
608 :param node: Honeycomb node.
609 :param interface: The name of interface.
610 :param ip_addr: IPv6 address to be set.
611 :param prefix_len: Prefix length.
615 :type prefix_len: str
616 :return: Content of response.
620 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
622 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
623 return InterfaceKeywords._set_interface_properties(
624 node, interface, path, address)
627 def remove_all_ipv6_addresses(node, interface):
628 """Remove all IPv6 addresses from interface.
630 :param node: Honeycomb node.
631 :param interface: The name of interface.
634 :return: Content of response.
638 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
640 return InterfaceKeywords._set_interface_properties(
641 node, interface, path, None)
644 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
645 """Add the IPv6 neighbour.
647 :param node: Honeycomb node.
648 :param interface: The name of interface.
649 :param ip_addr: IPv6 address of neighbour to be set.
650 :param link_layer_address: Link layer address.
654 :type link_layer_address: str
655 :return: Content of response.
659 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
661 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
662 return InterfaceKeywords._set_interface_properties(
663 node, interface, path, neighbor)
666 def remove_all_ipv6_neighbors(node, interface):
667 """Remove all IPv6 neighbours.
669 :param node: Honeycomb node.
670 :param interface: The name of interface.
673 :return: Content of response.
677 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
679 return InterfaceKeywords._set_interface_properties(
680 node, interface, path, None)
683 def configure_interface_ethernet(node, interface, param, value):
684 """Configure the ethernet parameters of interface.
686 :param node: Honeycomb node.
687 :param interface: The name of interface.
688 :param param: Parameter to configure (set, change, remove)
689 :param value: The value of parameter. If None, the parameter will be
695 :return: Content of response.
697 :raises HoneycombError: If the parameter is not valid.
700 if param not in InterfaceKeywords.ETH_PARAMS:
701 raise HoneycombError("The parameter {0} is invalid.".format(param))
702 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
704 return InterfaceKeywords._set_interface_properties(
705 node, interface, path, value)
708 def configure_interface_routing(node, interface, param, value):
709 """Configure the routing parameters of interface.
711 :param node: Honeycomb node.
712 :param interface: The name of interface.
713 :param param: Parameter to configure (set, change, remove)
714 :param value: The value of parameter. If None, the parameter will be
720 :return: Content of response.
722 :raises HoneycombError: If the parameter is not valid.
725 if param not in InterfaceKeywords.ROUTING_PARAMS:
726 raise HoneycombError("The parameter {0} is invalid.".format(param))
728 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
730 return InterfaceKeywords._set_interface_properties(
731 node, interface, path, value)
734 def create_vxlan_interface(node, interface, **kwargs):
735 """Create a new VxLAN interface.
737 :param node: Honeycomb node.
738 :param interface: The name of interface.
739 :param kwargs: Parameters and their values. The accepted parameters are
740 defined in InterfaceKeywords.VXLAN_PARAMS.
744 :return: Content of response.
746 :raises HoneycombError: If the parameter is not valid.
751 "type": "v3po:vxlan-tunnel",
754 for param, value in kwargs.items():
755 if param not in InterfaceKeywords.VXLAN_PARAMS:
756 raise HoneycombError("The parameter {0} is invalid.".
758 new_vx_lan["v3po:vxlan"][param] = value
760 path = ("interfaces", "interface")
761 vx_lan_structure = [new_vx_lan, ]
762 return InterfaceKeywords._set_interface_properties(
763 node, interface, path, vx_lan_structure)
766 def delete_interface(node, interface):
767 """Delete an interface.
769 :param node: Honeycomb node.
770 :param interface: The name of interface.
773 :return: Content of response.
775 :raises HoneycombError: If it is not possible to get information about
776 interfaces or it is not possible to delete the interface.
779 path = ("interfaces", ("interface", "name", interface))
781 status_code, resp = HcUtil.\
782 get_honeycomb_data(node, "config_vpp_interfaces")
783 if status_code != HTTPCodes.OK:
784 raise HoneycombError(
785 "Not possible to get configuration information about the "
786 "interfaces. Status code: {0}.".format(status_code))
788 new_data = HcUtil.remove_item(resp, path)
789 status_code, resp = HcUtil.\
790 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
791 if status_code != HTTPCodes.OK:
792 raise HoneycombError("Not possible to remove interface {0}. "
794 format(interface, status_code))
798 def configure_interface_vxlan(node, interface, **kwargs):
799 """Configure VxLAN on the interface.
801 The keyword configures VxLAN parameters on the given interface. The type
802 of interface must be set to "v3po:vxlan-tunnel".
803 The new VxLAN parameters overwrite the current configuration. If a
804 parameter in new configuration is missing, it is removed from VxLAN
806 If the dictionary kwargs is empty, VxLAN configuration is removed.
808 :param node: Honeycomb node.
809 :param interface: The name of interface.
810 :param kwargs: Parameters and their values. The accepted parameters are
811 defined in InterfaceKeywords.VXLAN_PARAMS.
815 :return: Content of response.
817 :raises HoneycombError: If the parameter is not valid.
820 vx_lan_structure = dict()
821 for param, value in kwargs.items():
822 if param not in InterfaceKeywords.VXLAN_PARAMS:
823 raise HoneycombError("The parameter {0} is invalid.".
825 vx_lan_structure[param] = value
827 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
828 return InterfaceKeywords._set_interface_properties(
829 node, interface, path, vx_lan_structure)
832 def configure_interface_l2(node, interface, param, value):
833 """Configure the L2 parameters of interface.
835 :param node: Honeycomb node.
836 :param interface: The name of interface.
837 :param param: Parameter to configure (set, change, remove)
838 :param value: The value of parameter. If None, the parameter will be
844 :return: Content of response.
846 :raises HoneycombError: If the parameter is not valid.
849 if param not in InterfaceKeywords.L2_PARAMS:
850 raise HoneycombError("The parameter {0} is invalid.".format(param))
851 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
853 return InterfaceKeywords._set_interface_properties(
854 node, interface, path, value)
857 def create_tap_interface(node, interface, **kwargs):
858 """Create a new TAP interface.
860 :param node: Honeycomb node.
861 :param interface: The name of interface.
862 :param kwargs: Parameters and their values. The accepted parameters are
863 defined in InterfaceKeywords.TAP_PARAMS.
867 :return: Content of response.
869 :raises HoneycombError: If the parameter is not valid.
877 for param, value in kwargs.items():
878 if param not in InterfaceKeywords.TAP_PARAMS:
879 raise HoneycombError("The parameter {0} is invalid.".
881 new_tap["v3po:tap"][param] = value
883 path = ("interfaces", "interface")
884 new_tap_structure = [new_tap, ]
885 return InterfaceKeywords._set_interface_properties(
886 node, interface, path, new_tap_structure)
889 def configure_interface_tap(node, interface, **kwargs):
890 """Configure TAP on the interface.
892 The keyword configures TAP parameters on the given interface. The type
893 of interface must be set to "v3po:tap".
894 The new TAP parameters overwrite the current configuration. If a
895 parameter in new configuration is missing, it is removed from TAP
897 If the dictionary kwargs is empty, TAP configuration is removed.
899 :param node: Honeycomb node.
900 :param interface: The name of interface.
901 :param kwargs: Parameters and their values. The accepted parameters are
902 defined in InterfaceKeywords.TAP_PARAMS.
906 :return: Content of response.
908 :raises HoneycombError: If the parameter is not valid.
911 tap_structure = dict()
912 for param, value in kwargs.items():
913 if param not in InterfaceKeywords.TAP_PARAMS:
914 raise HoneycombError("The parameter {0} is invalid.".
916 tap_structure[param] = value
918 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
919 return InterfaceKeywords._set_interface_properties(
920 node, interface, path, tap_structure)
923 def configure_interface_vhost_user(node, interface, **kwargs):
924 """Configure vhost-user on the interface.
926 The keyword configures vhost-user parameters on the given interface.
927 The type of interface must be set to "v3po:vhost-user".
928 The new vhost-user parameters overwrite the current configuration. If a
929 parameter in new configuration is missing, it is removed from vhost-user
931 If the dictionary kwargs is empty, vhost-user configuration is removed.
933 :param node: Honeycomb node.
934 :param interface: The name of interface.
935 :param kwargs: Parameters and their values. The accepted parameters are
936 defined in InterfaceKeywords.VHOST_USER_PARAMS.
940 :return: Content of response.
942 :raises HoneycombError: If the parameter is not valid.
945 vhost_structure = dict()
946 for param, value in kwargs.items():
947 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
948 raise HoneycombError("The parameter {0} is invalid.".
950 vhost_structure[param] = value
952 path = ("interfaces", ("interface", "name", interface),
954 return InterfaceKeywords._set_interface_properties(
955 node, interface, path, vhost_structure)
958 def create_vhost_user_interface(node, interface, **kwargs):
959 """Create a new vhost-user interface.
961 :param node: Honeycomb node.
962 :param interface: The name of interface.
963 :param kwargs: Parameters and their values. The accepted parameters are
964 defined in InterfaceKeywords.VHOST_USER_PARAMS.
968 :return: Content of response.
970 :raises HoneycombError: If the parameter is not valid.
975 "type": "v3po:vhost-user",
976 "v3po:vhost-user": {}
978 for param, value in kwargs.items():
979 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
980 raise HoneycombError("The parameter {0} is invalid.".
982 new_vhost["v3po:vhost-user"][param] = value
984 path = ("interfaces", "interface")
985 new_vhost_structure = [new_vhost, ]
986 return InterfaceKeywords._set_interface_properties(
987 node, interface, path, new_vhost_structure)
990 def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
991 """Create a new sub-interface.
993 :param node: Honeycomb node.
994 :param super_interface: Super interface.
995 :param match: Match type. The valid values are defined in
996 InterfaceKeywords.SUB_IF_MATCH.
997 :param tags: List of tags.
998 :param kwargs: Parameters and their values. The accepted parameters are
999 defined in InterfaceKeywords.SUB_IF_PARAMS.
1001 :type super_interface: str
1005 :return: Content of response.
1007 :raises HoneycombError: If the parameter is not valid.
1008 :raises KeyError: If the parameter 'match' is invalid.
1017 {"vlan-tagged": {"match-exact-tags": "false"}},
1018 "vlan-tagged-exact-match":
1019 {"vlan-tagged": {"match-exact-tags": "true"}}
1022 new_sub_interface = {
1028 for param, value in kwargs.items():
1029 if param in InterfaceKeywords.SUB_IF_PARAMS:
1030 new_sub_interface[param] = value
1032 raise HoneycombError("The parameter {0} is invalid.".
1035 new_sub_interface["match"] = match_type[match]
1037 raise HoneycombError("The value '{0}' of parameter 'match' is "
1038 "invalid.".format(match))
1041 new_sub_interface["tags"]["tag"].extend(tags)
1043 path = ("interfaces",
1044 ("interface", "name", super_interface),
1045 "vpp-vlan:sub-interfaces",
1047 new_sub_interface_structure = [new_sub_interface, ]
1048 return InterfaceKeywords._set_interface_properties(
1049 node, super_interface, path, new_sub_interface_structure)
1052 def get_sub_interface_oper_data(node, super_interface, identifier):
1053 """Retrieves sub-interface operational data using Honeycomb API.
1055 :param node: Honeycomb node.
1056 :param super_interface: Super interface.
1057 :param identifier: The ID of sub-interface.
1059 :type super_interface: str
1060 :type identifier: int
1061 :return: Sub-interface operational data.
1063 :raises HoneycombError: If there is no sub-interface with the given ID.
1066 if_data = InterfaceKeywords.get_interface_oper_data(node,
1068 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1069 if str(sub_if["identifier"]) == str(identifier):
1072 raise HoneycombError("The interface {0} does not have sub-interface "
1073 "with ID {1}".format(super_interface, identifier))
1076 def remove_all_sub_interfaces(node, super_interface):
1077 """Remove all sub-interfaces from the given interface.
1079 :param node: Honeycomb node.
1080 :param super_interface: Super interface.
1082 :type super_interface: str
1083 :return: Content of response.
1087 path = ("interfaces",
1088 ("interface", "name", super_interface),
1089 "vpp-vlan:sub-interfaces")
1091 return InterfaceKeywords._set_interface_properties(
1092 node, super_interface, path, {})
1095 def set_sub_interface_state(node, super_interface, identifier, state):
1096 """Set the administrative state of sub-interface.
1098 :param node: Honeycomb node.
1099 :param super_interface: Super interface.
1100 :param identifier: The ID of sub-interface.
1101 :param state: Required sub-interface state - up or down.
1103 :type super_interface: str
1104 :type identifier: int
1106 :return: Content of response.
1110 intf_state = {"up": "true",
1113 path = ("interfaces",
1114 ("interface", "name", super_interface),
1115 "vpp-vlan:sub-interfaces",
1116 ("sub-interface", "identifier", identifier),
1119 return InterfaceKeywords._set_interface_properties(
1120 node, super_interface, path, intf_state[state])
1123 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1125 """Add a sub-interface to a bridge domain and set its parameters.
1127 :param node: Honeycomb node.
1128 :param super_interface: Super interface.
1129 :param identifier: The ID of sub-interface.
1130 :param config: Bridge domain configuration.
1132 :type super_interface: str
1133 :type identifier: int
1135 :return: Content of response.
1139 path = ("interfaces",
1140 ("interface", "name", super_interface),
1141 "vpp-vlan:sub-interfaces",
1142 ("sub-interface", "identifier", int(identifier)),
1145 return InterfaceKeywords._set_interface_properties(
1146 node, super_interface, path, config)
1149 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1150 """Get the operational data about the bridge domain from sub-interface.
1152 :param node: Honeycomb node.
1153 :param super_interface: Super interface.
1154 :param identifier: The ID of sub-interface.
1156 :type super_interface: str
1157 :type identifier: int
1158 :return: Operational data about the bridge domain.
1160 :raises HoneycombError: If there is no sub-interface with the given ID.
1164 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1165 node, super_interface, identifier)["l2"]
1168 raise HoneycombError("The operational data does not contain "
1169 "information about a bridge domain.")
1172 def configure_tag_rewrite(node, super_interface, identifier, config):
1173 """Add / change / disable vlan tag rewrite on a sub-interface.
1175 :param node: Honeycomb node.
1176 :param super_interface: Super interface.
1177 :param identifier: The ID of sub-interface.
1178 :param config: Rewrite tag configuration.
1180 :type super_interface: str
1181 :type identifier: int
1183 :return: Content of response.
1187 path = ("interfaces",
1188 ("interface", "name", super_interface),
1189 "vpp-vlan:sub-interfaces",
1190 ("sub-interface", "identifier", int(identifier)),
1194 return InterfaceKeywords._set_interface_properties(
1195 node, super_interface, path, config)
1198 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1199 """Get the operational data about tag rewrite.
1201 :param node: Honeycomb node.
1202 :param super_interface: Super interface.
1203 :param identifier: The ID of sub-interface.
1205 :type super_interface: str
1206 :type identifier: int
1207 :return: Operational data about tag rewrite.
1209 :raises HoneycombError: If there is no sub-interface with the given ID.
1213 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1214 node, super_interface, identifier)["l2"]["rewrite"]
1217 raise HoneycombError("The operational data does not contain "
1218 "information about the tag-rewrite.")
1221 def add_ipv4_address_to_sub_interface(node, super_interface, identifier,
1223 """Add an ipv4 address to the specified sub-interface, with the provided
1224 netmask or network prefix length. Any existing ipv4 addresses on the
1225 sub-interface will be replaced.
1227 :param node: Honeycomb node.
1228 :param super_interface: Super interface.
1229 :param identifier: The ID of sub-interface.
1230 :param ip_addr: IPv4 address to be set.
1231 :param network: Network mask or network prefix length.
1233 :type super_interface: str
1234 :type identifier: int
1236 :type network: str or int
1237 :return: Content of response.
1239 :raises HoneycombError: If the provided netmask or prefix is not valid.
1242 path = ("interfaces",
1243 ("interface", "name", super_interface),
1244 "vpp-vlan:sub-interfaces",
1245 ("sub-interface", "identifier", int(identifier)),
1248 if isinstance(network, basestring):
1249 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1251 elif isinstance(network, int) and 0 < network < 33:
1252 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1255 raise HoneycombError("{0} is not a valid netmask or prefix length."
1258 return InterfaceKeywords._set_interface_properties(
1259 node, super_interface, path, address)
1262 def remove_all_ipv4_addresses_from_sub_interface(node, super_interface, # pylint: disable=invalid-name
1264 """Remove all ipv4 addresses from the specified sub-interface.
1266 :param node: Honeycomb node.
1267 :param super_interface: Super interface.
1268 :param identifier: The ID of sub-interface.
1270 :type super_interface: str
1271 :type identifier: int
1272 :return: Content of response.
1276 path = ("interfaces",
1277 ("interface", "name", super_interface),
1278 "vpp-vlan:sub-interfaces",
1279 ("sub-interface", "identifier", int(identifier)),
1282 return InterfaceKeywords._set_interface_properties(
1283 node, super_interface, path, None)
1286 def compare_data_structures(data, ref, ignore=()):
1287 """Checks if data obtained from UUT is as expected.
1289 :param data: Data to be checked.
1290 :param ref: Referential data used for comparison.
1291 :param ignore: Dictionary keys to be ignored.
1294 :type ignore: iterable
1295 :raises HoneycombError: If a parameter from referential data is not
1296 present in operational data or if it has different value.
1301 for key, item in ref.items():
1305 if data[key] != item:
1306 errors += ("\nThe value of parameter '{0}' is "
1307 "incorrect. It should be "
1308 "'{1}' but it is '{2}'".
1309 format(key, item, data[key]))
1311 errors += ("\nThe parameter '{0}' is not present in "
1312 "operational data".format(key))
1315 raise HoneycombError(errors)
1318 def compare_interface_lists(list1, list2):
1319 """Compare provided lists of interfaces by name.
1321 :param list1: List of interfaces.
1322 :param list2: List of interfaces.
1325 :raises HoneycombError: If an interface exists in only one of the lists.
1328 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1329 # these have no equivalent in config data and no effect on VPP
1331 names1 = [x['name'] for x in list1]
1332 names2 = [x['name'] for x in list2]
1335 if name not in names2 and name not in ignore:
1336 raise HoneycombError("Interface {0} not present in list {1}"
1337 .format(name, list2))
1339 if name not in names1 and name not in ignore:
1340 raise HoneycombError("Interface {0} not present in list {1}"
1341 .format(name, list1))
1344 def create_vxlan_gpe_interface(node, interface, **kwargs):
1345 """Create a new VxLAN GPE interface.
1347 :param node: Honeycomb node.
1348 :param interface: The name of interface to be created.
1349 :param kwargs: Parameters and their values. The accepted parameters are
1350 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1352 :type interface: str
1354 :return: Content of response.
1356 :raises HoneycombError: If a parameter in kwargs is not valid.
1361 "type": "v3po:vxlan-gpe-tunnel",
1362 "v3po:vxlan-gpe": {}
1364 for param, value in kwargs.items():
1365 if param in InterfaceKeywords.INTF_PARAMS:
1366 new_vxlan_gpe[param] = value
1367 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1368 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1370 raise HoneycombError("The parameter {0} is invalid.".
1372 path = ("interfaces", "interface")
1373 vxlan_gpe_structure = [new_vxlan_gpe, ]
1374 return InterfaceKeywords._set_interface_properties(
1375 node, interface, path, vxlan_gpe_structure)
1378 def enable_acl_on_interface(node, interface, table_name):
1379 """Enable ACL on the given interface.
1381 :param node: Honeycomb node.
1382 :param interface: The interface where the ACL will be enabled.
1383 :param table_name: Name of the classify table.
1385 :type interface: str
1386 :type table_name: str
1387 :return: Content of response.
1389 :raises HoneycombError: If the configuration of interface is not
1393 interface = interface.replace("/", "%2F")
1398 "classify-table": table_name
1401 "classify-table": table_name
1406 path = "/interface/" + interface + "/v3po:acl"
1407 status_code, resp = HcUtil.\
1408 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1409 data_representation=DataRepresentation.JSON)
1410 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1411 raise HoneycombError(
1412 "The configuration of interface '{0}' was not successful. "
1413 "Status code: {1}.".format(interface, status_code))
1417 def disable_acl_on_interface(node, interface):
1418 """Disable ACL on the given interface.
1420 :param node: Honeycomb node.
1421 :param interface: The interface where the ACL will be disabled.
1423 :type interface: str
1424 :return: Content of response.
1426 :raises HoneycombError: If the configuration of interface is not
1430 interface = interface.replace("/", "%2F")
1432 path = "/interface/" + interface + "/v3po:acl"
1434 status_code, resp = HcUtil.\
1435 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1437 if status_code != HTTPCodes.OK:
1438 raise HoneycombError(
1439 "The configuration of interface '{0}' was not successful. "
1440 "Status code: {1}.".format(interface, status_code))
1444 def create_pbb_sub_interface(node, intf, sub_if_id, params):
1445 """Creates a PBB sub-interface on the given interface and sets its
1448 :param node: Honeycomb node.
1449 :param intf: The interface where PBB sub-interface will be configured.
1450 :param sub_if_id: Sub-interface ID.
1451 :param params: Configuration parameters of the sub-interface to be
1455 :type sub_if_id: str or int
1457 :return: Content of response.
1459 :raises HoneycombError: If the configuration of sub-interface is not
1463 interface = intf.replace("/", "%2F")
1464 path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1465 "{1}".format(interface, sub_if_id)
1466 status_code, resp = HcUtil. \
1467 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1468 data_representation=DataRepresentation.JSON)
1469 if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
1470 raise HoneycombError(
1471 "The configuration of PBB sub-interface '{0}' was not "
1472 "successful. Status code: {1}.".format(intf, status_code))
1476 def delete_pbb_sub_interface(node, intf, sub_if_id):
1477 """Deletes the given PBB sub-interface.
1479 :param node: Honeycomb node.
1480 :param intf: The interface where PBB sub-interface will be deleted.
1481 :param sub_if_id: ID of the PBB sub-interface to be deleted.
1484 :type sub_if_id: str or int
1485 :return: Content of response.
1487 :raises HoneycombError: If the removal of sub-interface is not
1491 interface = intf.replace("/", "%2F")
1492 path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1493 "{1}".format(interface, sub_if_id)
1495 status_code, resp = HcUtil. \
1496 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1497 if status_code != HTTPCodes.OK:
1498 raise HoneycombError(
1499 "The removal of pbb sub-interface '{0}' was not successful. "
1500 "Status code: {1}.".format(intf, status_code))
1504 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1505 """Retrieves PBB sub-interface operational data from Honeycomb.
1507 :param node: Honeycomb node.
1508 :param intf: The interface where PBB sub-interface is located.
1509 :param sub_if_id: ID of the PBB sub-interface.
1512 :type sub_if_id: str or int
1513 :return: PBB sub-interface operational data.
1515 :raises HoneycombError: If the removal of sub-interface is not
1519 interface = "{0}.{1}".format(intf, sub_if_id)
1520 return InterfaceKeywords.get_interface_oper_data(node, interface)