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
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 != HTTPCodes.OK:
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: The name of interface.
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 intf = interface.replace("/", "%2F")
241 path = "/interface/{0}".format(intf)
243 status_code, resp = HcUtil.\
244 get_honeycomb_data(node, "config_vpp_interfaces", path)
245 if status_code != HTTPCodes.OK:
246 raise HoneycombError(
247 "Not possible to get configuration information about the "
248 "interfaces. Status code: {0}.".format(status_code))
250 resp["interface"][0]["enabled"] = intf_state[state.lower()]
252 status_code, resp = HcUtil. \
253 put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
254 data_representation=DataRepresentation.JSON)
255 if status_code != HTTPCodes.OK:
256 raise HoneycombError(
257 "The configuration of interface '{0}' was not successful. "
258 "Status code: {1}.".format(interface, status_code))
262 def set_interface_up(node, interface):
263 """Set the administration state of VPP interface to up.
265 :param node: Honeycomb node.
266 :param interface: The name of interface.
269 :return: Content of response
273 return InterfaceKeywords.set_interface_state(node, interface, "up")
276 def set_interface_down(node, interface):
277 """Set the administration state of VPP interface to down.
279 :param node: Honeycomb node.
280 :param interface: The name of interface.
283 :return: Content of response.
287 return InterfaceKeywords.set_interface_state(node, interface, "down")
290 def add_bridge_domain_to_interface(node, interface, bd_name,
291 split_horizon_group=None, bvi=None):
292 """Add a new bridge domain to an interface and set its parameters.
294 :param node: Honeycomb node.
295 :param interface: The name of interface.
296 :param bd_name: Bridge domain name.
297 :param split_horizon_group: Split-horizon group name.
298 :param bvi: The bridged virtual interface.
302 :type split_horizon_group: str
304 :return: Content of response.
306 :raises HoneycombError: If the interface is not present on the node.
309 v3po_l2 = {"bridge-domain": str(bd_name)}
310 if split_horizon_group:
311 v3po_l2["split-horizon-group"] = str(split_horizon_group)
313 v3po_l2["bridged-virtual-interface"] = str(bvi)
315 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
317 return InterfaceKeywords._set_interface_properties(
318 node, interface, path, v3po_l2)
321 def get_bd_oper_data_from_interface(node, interface):
322 """Returns operational data about bridge domain settings in the
325 :param node: Honeycomb node.
326 :param interface: The name of interface.
329 :return: Operational data about bridge domain settings in the
334 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
338 return if_data["v3po:l2"]
344 def configure_interface_base(node, interface, param, value):
345 """Configure the base parameters of interface.
347 :param node: Honeycomb node.
348 :param interface: The name of interface.
349 :param param: Parameter to configure (set, change, remove)
350 :param value: The value of parameter. If None, the parameter will be
356 :return: Content of response.
358 :raises HoneycombError: If the parameter is not valid.
361 if param not in InterfaceKeywords.INTF_PARAMS:
362 raise HoneycombError("The parameter {0} is invalid.".format(param))
364 path = ("interfaces", ("interface", "name", interface), param)
365 return InterfaceKeywords._set_interface_properties(
366 node, interface, path, value)
369 def configure_interface_ipv4(node, interface, param, value):
370 """Configure IPv4 parameters of interface
372 :param node: Honeycomb node.
373 :param interface: The name of interface.
374 :param param: Parameter to configure (set, change, remove)
375 :param value: The value of parameter. If None, the parameter will be
381 :return: Content of response.
383 :raises HoneycombError: If the parameter is not valid.
386 if param not in InterfaceKeywords.IPV4_PARAMS:
387 raise HoneycombError("The parameter {0} is invalid.".format(param))
389 path = ("interfaces", ("interface", "name", interface),
390 "ietf-ip:ipv4", param)
391 return InterfaceKeywords._set_interface_properties(
392 node, interface, path, value)
395 def add_first_ipv4_address(node, interface, ip_addr, network):
396 """Add the first IPv4 address.
398 If there are any other addresses configured, they will be removed.
400 :param node: Honeycomb node.
401 :param interface: The name of interface.
402 :param ip_addr: IPv4 address to be set.
403 :param network: Netmask or length of network prefix.
407 :type network: str or int
408 :return: Content of response.
410 :raises HoneycombError: If the provided netmask or prefix is not valid.
413 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
414 if isinstance(network, basestring):
415 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
416 elif isinstance(network, int) and (0 < network < 33):
417 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
419 raise HoneycombError("Value {0} is not a valid netmask or network "
420 "prefix length.".format(network))
421 return InterfaceKeywords._set_interface_properties(
422 node, interface, path, address)
425 def add_ipv4_address(node, interface, ip_addr, network):
428 :param node: Honeycomb node.
429 :param interface: The name of interface.
430 :param ip_addr: IPv4 address to be set.
431 :param network: Netmask or length of network prefix.
435 :type network: str or int
436 :return: Content of response.
438 :raises HoneycombError: If the provided netmask or prefix is not valid.
441 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
443 if isinstance(network, basestring):
444 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
445 elif isinstance(network, int) and (0 < network < 33):
446 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
448 raise HoneycombError("Value {0} is not a valid netmask or network "
449 "prefix length.".format(network))
450 return InterfaceKeywords._set_interface_properties(
451 node, interface, path, address)
454 def remove_all_ipv4_addresses(node, interface):
455 """Remove all IPv4 addresses from interface.
457 :param node: Honeycomb node.
458 :param interface: The name of interface.
461 :return: Content of response.
465 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
467 return InterfaceKeywords._set_interface_properties(
468 node, interface, path, None)
471 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
472 """Add the IPv4 neighbour.
474 :param node: Honeycomb node.
475 :param interface: The name of interface.
476 :param ip_addr: IPv4 address of neighbour to be set.
477 :param link_layer_address: Link layer address.
481 :type link_layer_address: str
482 :return: Content of response.
486 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
488 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
489 return InterfaceKeywords._set_interface_properties(
490 node, interface, path, neighbor)
493 def remove_all_ipv4_neighbors(node, interface):
494 """Remove all IPv4 neighbours.
496 :param node: Honeycomb node.
497 :param interface: The name of interface.
500 :return: Content of response.
504 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
506 return InterfaceKeywords._set_interface_properties(
507 node, interface, path, None)
510 def configure_interface_ipv6(node, interface, param, value):
511 """Configure IPv6 parameters of interface
513 :param node: Honeycomb node.
514 :param interface: The name of interface.
515 :param param: Parameter to configure (set, change, remove)
516 :param value: The value of parameter. If None, the parameter will be
522 :return: Content of response.
524 :raises HoneycombError: If the parameter is not valid.
527 if param in InterfaceKeywords.IPV6_PARAMS:
528 path = ("interfaces", ("interface", "name", interface),
529 "ietf-ip:ipv6", param)
530 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
531 path = ("interfaces", ("interface", "name", interface),
532 "ietf-ip:ipv6", "autoconf", param)
534 raise HoneycombError("The parameter {0} is invalid.".format(param))
536 return InterfaceKeywords._set_interface_properties(
537 node, interface, path, value)
540 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
541 """Add the first IPv6 address.
543 If there are any other addresses configured, they will be removed.
545 :param node: Honeycomb node.
546 :param interface: The name of interface.
547 :param ip_addr: IPv6 address to be set.
548 :param prefix_len: Prefix length.
552 :type prefix_len: str
553 :return: Content of response.
557 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
558 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
559 return InterfaceKeywords._set_interface_properties(
560 node, interface, path, address)
563 def add_ipv6_address(node, interface, ip_addr, prefix_len):
566 :param node: Honeycomb node.
567 :param interface: The name of interface.
568 :param ip_addr: IPv6 address to be set.
569 :param prefix_len: Prefix length.
573 :type prefix_len: str
574 :return: Content of response.
578 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
580 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
581 return InterfaceKeywords._set_interface_properties(
582 node, interface, path, address)
585 def remove_all_ipv6_addresses(node, interface):
586 """Remove all IPv6 addresses from interface.
588 :param node: Honeycomb node.
589 :param interface: The name of interface.
592 :return: Content of response.
596 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
598 return InterfaceKeywords._set_interface_properties(
599 node, interface, path, None)
602 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
603 """Add the IPv6 neighbour.
605 :param node: Honeycomb node.
606 :param interface: The name of interface.
607 :param ip_addr: IPv6 address of neighbour to be set.
608 :param link_layer_address: Link layer address.
612 :type link_layer_address: str
613 :return: Content of response.
617 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
619 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
620 return InterfaceKeywords._set_interface_properties(
621 node, interface, path, neighbor)
624 def remove_all_ipv6_neighbors(node, interface):
625 """Remove all IPv6 neighbours.
627 :param node: Honeycomb node.
628 :param interface: The name of interface.
631 :return: Content of response.
635 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
637 return InterfaceKeywords._set_interface_properties(
638 node, interface, path, None)
641 def configure_interface_ethernet(node, interface, param, value):
642 """Configure the ethernet parameters of interface.
644 :param node: Honeycomb node.
645 :param interface: The name of interface.
646 :param param: Parameter to configure (set, change, remove)
647 :param value: The value of parameter. If None, the parameter will be
653 :return: Content of response.
655 :raises HoneycombError: If the parameter is not valid.
658 if param not in InterfaceKeywords.ETH_PARAMS:
659 raise HoneycombError("The parameter {0} is invalid.".format(param))
660 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
662 return InterfaceKeywords._set_interface_properties(
663 node, interface, path, value)
666 def configure_interface_routing(node, interface, param, value):
667 """Configure the routing parameters of interface.
669 :param node: Honeycomb node.
670 :param interface: The name of interface.
671 :param param: Parameter to configure (set, change, remove)
672 :param value: The value of parameter. If None, the parameter will be
678 :return: Content of response.
680 :raises HoneycombError: If the parameter is not valid.
683 if param not in InterfaceKeywords.ROUTING_PARAMS:
684 raise HoneycombError("The parameter {0} is invalid.".format(param))
686 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
688 return InterfaceKeywords._set_interface_properties(
689 node, interface, path, value)
692 def create_vxlan_interface(node, interface, **kwargs):
693 """Create a new VxLAN interface.
695 :param node: Honeycomb node.
696 :param interface: The name of interface.
697 :param kwargs: Parameters and their values. The accepted parameters are
698 defined in InterfaceKeywords.VXLAN_PARAMS.
702 :return: Content of response.
704 :raises HoneycombError: If the parameter is not valid.
709 "type": "v3po:vxlan-tunnel",
712 for param, value in kwargs.items():
713 if param not in InterfaceKeywords.VXLAN_PARAMS:
714 raise HoneycombError("The parameter {0} is invalid.".
716 new_vx_lan["v3po:vxlan"][param] = value
718 path = ("interfaces", "interface")
719 vx_lan_structure = [new_vx_lan, ]
720 return InterfaceKeywords._set_interface_properties(
721 node, interface, path, vx_lan_structure)
724 def delete_interface(node, interface):
725 """Delete an interface.
727 :param node: Honeycomb node.
728 :param interface: The name of interface.
731 :return: Content of response.
733 :raises HoneycombError: If it is not possible to get information about
734 interfaces or it is not possible to delete the interface.
737 path = ("interfaces", ("interface", "name", interface))
739 status_code, resp = HcUtil.\
740 get_honeycomb_data(node, "config_vpp_interfaces")
741 if status_code != HTTPCodes.OK:
742 raise HoneycombError(
743 "Not possible to get configuration information about the "
744 "interfaces. Status code: {0}.".format(status_code))
746 new_data = HcUtil.remove_item(resp, path)
747 status_code, resp = HcUtil.\
748 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
749 if status_code != HTTPCodes.OK:
750 raise HoneycombError("Not possible to remove interface {0}. "
752 format(interface, status_code))
756 def configure_interface_vxlan(node, interface, **kwargs):
757 """Configure VxLAN on the interface.
759 The keyword configures VxLAN parameters on the given interface. The type
760 of interface must be set to "v3po:vxlan-tunnel".
761 The new VxLAN parameters overwrite the current configuration. If a
762 parameter in new configuration is missing, it is removed from VxLAN
764 If the dictionary kwargs is empty, VxLAN configuration is removed.
766 :param node: Honeycomb node.
767 :param interface: The name of interface.
768 :param kwargs: Parameters and their values. The accepted parameters are
769 defined in InterfaceKeywords.VXLAN_PARAMS.
773 :return: Content of response.
775 :raises HoneycombError: If the parameter is not valid.
778 vx_lan_structure = dict()
779 for param, value in kwargs.items():
780 if param not in InterfaceKeywords.VXLAN_PARAMS:
781 raise HoneycombError("The parameter {0} is invalid.".
783 vx_lan_structure[param] = value
785 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
786 return InterfaceKeywords._set_interface_properties(
787 node, interface, path, vx_lan_structure)
790 def configure_interface_l2(node, interface, param, value):
791 """Configure the L2 parameters of interface.
793 :param node: Honeycomb node.
794 :param interface: The name of interface.
795 :param param: Parameter to configure (set, change, remove)
796 :param value: The value of parameter. If None, the parameter will be
802 :return: Content of response.
804 :raises HoneycombError: If the parameter is not valid.
807 if param not in InterfaceKeywords.L2_PARAMS:
808 raise HoneycombError("The parameter {0} is invalid.".format(param))
809 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
811 return InterfaceKeywords._set_interface_properties(
812 node, interface, path, value)
815 def create_tap_interface(node, interface, **kwargs):
816 """Create a new TAP 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.TAP_PARAMS.
825 :return: Content of response.
827 :raises HoneycombError: If the parameter is not valid.
835 for param, value in kwargs.items():
836 if param not in InterfaceKeywords.TAP_PARAMS:
837 raise HoneycombError("The parameter {0} is invalid.".
839 new_tap["v3po:tap"][param] = value
841 path = ("interfaces", "interface")
842 new_tap_structure = [new_tap, ]
843 return InterfaceKeywords._set_interface_properties(
844 node, interface, path, new_tap_structure)
847 def configure_interface_tap(node, interface, **kwargs):
848 """Configure TAP on the interface.
850 The keyword configures TAP parameters on the given interface. The type
851 of interface must be set to "v3po:tap".
852 The new TAP parameters overwrite the current configuration. If a
853 parameter in new configuration is missing, it is removed from TAP
855 If the dictionary kwargs is empty, TAP configuration is removed.
857 :param node: Honeycomb node.
858 :param interface: The name of interface.
859 :param kwargs: Parameters and their values. The accepted parameters are
860 defined in InterfaceKeywords.TAP_PARAMS.
864 :return: Content of response.
866 :raises HoneycombError: If the parameter is not valid.
869 tap_structure = dict()
870 for param, value in kwargs.items():
871 if param not in InterfaceKeywords.TAP_PARAMS:
872 raise HoneycombError("The parameter {0} is invalid.".
874 tap_structure[param] = value
876 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
877 return InterfaceKeywords._set_interface_properties(
878 node, interface, path, tap_structure)
881 def configure_interface_vhost_user(node, interface, **kwargs):
882 """Configure vhost-user on the interface.
884 The keyword configures vhost-user parameters on the given interface.
885 The type of interface must be set to "v3po:vhost-user".
886 The new vhost-user parameters overwrite the current configuration. If a
887 parameter in new configuration is missing, it is removed from vhost-user
889 If the dictionary kwargs is empty, vhost-user configuration is removed.
891 :param node: Honeycomb node.
892 :param interface: The name of interface.
893 :param kwargs: Parameters and their values. The accepted parameters are
894 defined in InterfaceKeywords.VHOST_USER_PARAMS.
898 :return: Content of response.
900 :raises HoneycombError: If the parameter is not valid.
903 vhost_structure = dict()
904 for param, value in kwargs.items():
905 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
906 raise HoneycombError("The parameter {0} is invalid.".
908 vhost_structure[param] = value
910 path = ("interfaces", ("interface", "name", interface),
912 return InterfaceKeywords._set_interface_properties(
913 node, interface, path, vhost_structure)
916 def create_vhost_user_interface(node, interface, **kwargs):
917 """Create a new vhost-user interface.
919 :param node: Honeycomb node.
920 :param interface: The name of interface.
921 :param kwargs: Parameters and their values. The accepted parameters are
922 defined in InterfaceKeywords.VHOST_USER_PARAMS.
926 :return: Content of response.
928 :raises HoneycombError: If the parameter is not valid.
933 "type": "v3po:vhost-user",
934 "v3po:vhost-user": {}
936 for param, value in kwargs.items():
937 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
938 raise HoneycombError("The parameter {0} is invalid.".
940 new_vhost["v3po:vhost-user"][param] = value
942 path = ("interfaces", "interface")
943 new_vhost_structure = [new_vhost, ]
944 return InterfaceKeywords._set_interface_properties(
945 node, interface, path, new_vhost_structure)
948 def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
949 """Create a new sub-interface.
951 :param node: Honeycomb node.
952 :param super_interface: Super interface.
953 :param match: Match type. The valid values are defined in
954 InterfaceKeywords.SUB_IF_MATCH.
955 :param tags: List of tags.
956 :param kwargs: Parameters and their values. The accepted parameters are
957 defined in InterfaceKeywords.SUB_IF_PARAMS.
959 :type super_interface: str
963 :return: Content of response.
965 :raises HoneycombError: If the parameter is not valid.
966 :raises KeyError: If the parameter 'match' is invalid.
975 {"vlan-tagged": {"match-exact-tags": "false"}},
976 "vlan-tagged-exact-match":
977 {"vlan-tagged": {"match-exact-tags": "true"}}
980 new_sub_interface = {
986 for param, value in kwargs.items():
987 if param in InterfaceKeywords.SUB_IF_PARAMS:
988 new_sub_interface[param] = value
990 raise HoneycombError("The parameter {0} is invalid.".
993 new_sub_interface["match"] = match_type[match]
995 raise HoneycombError("The value '{0}' of parameter 'match' is "
996 "invalid.".format(match))
999 new_sub_interface["tags"]["tag"].extend(tags)
1001 path = ("interfaces",
1002 ("interface", "name", super_interface),
1003 "vpp-vlan:sub-interfaces",
1005 new_sub_interface_structure = [new_sub_interface, ]
1006 return InterfaceKeywords._set_interface_properties(
1007 node, super_interface, path, new_sub_interface_structure)
1010 def get_sub_interface_oper_data(node, super_interface, identifier):
1011 """Retrieves sub-interface operational data using Honeycomb API.
1013 :param node: Honeycomb node.
1014 :param super_interface: Super interface.
1015 :param identifier: The ID of sub-interface.
1017 :type super_interface: str
1018 :type identifier: int
1019 :return: Sub-interface operational data.
1021 :raises HoneycombError: If there is no sub-interface with the given ID.
1024 if_data = InterfaceKeywords.get_interface_oper_data(node,
1026 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1027 if str(sub_if["identifier"]) == str(identifier):
1030 raise HoneycombError("The interface {0} does not have sub-interface "
1031 "with ID {1}".format(super_interface, identifier))
1034 def remove_all_sub_interfaces(node, super_interface):
1035 """Remove all sub-interfaces from the given interface.
1037 :param node: Honeycomb node.
1038 :param super_interface: Super interface.
1040 :type super_interface: str
1041 :return: Content of response.
1045 path = ("interfaces",
1046 ("interface", "name", super_interface),
1047 "vpp-vlan:sub-interfaces")
1049 return InterfaceKeywords._set_interface_properties(
1050 node, super_interface, path, {})
1053 def set_sub_interface_state(node, super_interface, identifier, state):
1054 """Set the administrative state of sub-interface.
1056 :param node: Honeycomb node.
1057 :param super_interface: Super interface.
1058 :param identifier: The ID of sub-interface.
1059 :param state: Required sub-interface state - up or down.
1061 :type super_interface: str
1062 :type identifier: int
1064 :return: Content of response.
1068 intf_state = {"up": "true",
1071 path = ("interfaces",
1072 ("interface", "name", super_interface),
1073 "vpp-vlan:sub-interfaces",
1074 ("sub-interface", "identifier", identifier),
1077 return InterfaceKeywords._set_interface_properties(
1078 node, super_interface, path, intf_state[state])
1081 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1083 """Add a sub-interface to a bridge domain and set its parameters.
1085 :param node: Honeycomb node.
1086 :param super_interface: Super interface.
1087 :param identifier: The ID of sub-interface.
1088 :param config: Bridge domain configuration.
1090 :type super_interface: str
1091 :type identifier: int
1093 :return: Content of response.
1097 path = ("interfaces",
1098 ("interface", "name", super_interface),
1099 "vpp-vlan:sub-interfaces",
1100 ("sub-interface", "identifier", int(identifier)),
1103 return InterfaceKeywords._set_interface_properties(
1104 node, super_interface, path, config)
1107 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1108 """Get the operational data about the bridge domain from sub-interface.
1110 :param node: Honeycomb node.
1111 :param super_interface: Super interface.
1112 :param identifier: The ID of sub-interface.
1114 :type super_interface: str
1115 :type identifier: int
1116 :return: Operational data about the bridge domain.
1118 :raises HoneycombError: If there is no sub-interface with the given ID.
1122 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1123 node, super_interface, identifier)["l2"]
1126 raise HoneycombError("The operational data does not contain "
1127 "information about a bridge domain.")
1130 def configure_tag_rewrite(node, super_interface, identifier, config):
1131 """Add / change / disable vlan tag rewrite on a sub-interface.
1133 :param node: Honeycomb node.
1134 :param super_interface: Super interface.
1135 :param identifier: The ID of sub-interface.
1136 :param config: Rewrite tag configuration.
1138 :type super_interface: str
1139 :type identifier: int
1141 :return: Content of response.
1145 path = ("interfaces",
1146 ("interface", "name", super_interface),
1147 "vpp-vlan:sub-interfaces",
1148 ("sub-interface", "identifier", int(identifier)),
1152 return InterfaceKeywords._set_interface_properties(
1153 node, super_interface, path, config)
1156 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1157 """Get the operational data about tag rewrite.
1159 :param node: Honeycomb node.
1160 :param super_interface: Super interface.
1161 :param identifier: The ID of sub-interface.
1163 :type super_interface: str
1164 :type identifier: int
1165 :return: Operational data about tag rewrite.
1167 :raises HoneycombError: If there is no sub-interface with the given ID.
1171 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1172 node, super_interface, identifier)["l2"]["rewrite"]
1175 raise HoneycombError("The operational data does not contain "
1176 "information about the tag-rewrite.")
1179 def add_ipv4_address_to_sub_interface(node, super_interface, identifier,
1181 """Add an ipv4 address to the specified sub-interface, with the provided
1182 netmask or network prefix length. Any existing ipv4 addresses on the
1183 sub-interface will be replaced.
1185 :param node: Honeycomb node.
1186 :param super_interface: Super interface.
1187 :param identifier: The ID of sub-interface.
1188 :param ip_addr: IPv4 address to be set.
1189 :param network: Network mask or network prefix length.
1191 :type super_interface: str
1192 :type identifier: int
1194 :type network: str or int
1195 :return: Content of response.
1197 :raises HoneycombError: If the provided netmask or prefix is not valid.
1200 path = ("interfaces",
1201 ("interface", "name", super_interface),
1202 "vpp-vlan:sub-interfaces",
1203 ("sub-interface", "identifier", int(identifier)),
1206 if isinstance(network, basestring):
1207 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1209 elif isinstance(network, int) and 0 < network < 33:
1210 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1213 raise HoneycombError("{0} is not a valid netmask or prefix length."
1216 return InterfaceKeywords._set_interface_properties(
1217 node, super_interface, path, address)
1220 def remove_all_ipv4_addresses_from_sub_interface(node, super_interface, # pylint: disable=invalid-name
1222 """Remove all ipv4 addresses from the specified sub-interface.
1224 :param node: Honeycomb node.
1225 :param super_interface: Super interface.
1226 :param identifier: The ID of sub-interface.
1228 :type super_interface: str
1229 :type identifier: int
1230 :return: Content of response.
1234 path = ("interfaces",
1235 ("interface", "name", super_interface),
1236 "vpp-vlan:sub-interfaces",
1237 ("sub-interface", "identifier", int(identifier)),
1240 return InterfaceKeywords._set_interface_properties(
1241 node, super_interface, path, None)
1244 def compare_data_structures(data, ref, ignore=()):
1245 """Checks if data obtained from UUT is as expected.
1247 :param data: Data to be checked.
1248 :param ref: Referential data used for comparison.
1249 :param ignore: Dictionary keys to be ignored.
1252 :type ignore: iterable
1253 :raises HoneycombError: If a parameter from referential data is not
1254 present in operational data or if it has different value.
1259 for key, item in ref.items():
1263 if data[key] != item:
1264 errors += ("\nThe value of parameter '{0}' is "
1265 "incorrect. It should be "
1266 "'{1}' but it is '{2}'".
1267 format(key, item, data[key]))
1269 errors += ("\nThe parameter '{0}' is not present in "
1270 "operational data".format(key))
1273 raise HoneycombError(errors)
1276 def compare_interface_lists(list1, list2):
1277 """Compare provided lists of interfaces by name.
1279 :param list1: List of interfaces.
1280 :param list2: List of interfaces.
1283 :raises HoneycombError: If an interface exists in only one of the lists.
1286 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1287 # these have no equivalent in config data and no effect on VPP
1289 names1 = [x['name'] for x in list1]
1290 names2 = [x['name'] for x in list2]
1293 if name not in names2 and name not in ignore:
1294 raise HoneycombError("Interface {0} not present in list {1}"
1295 .format(name, list2))
1297 if name not in names1 and name not in ignore:
1298 raise HoneycombError("Interface {0} not present in list {1}"
1299 .format(name, list1))
1302 def create_vxlan_gpe_interface(node, interface, **kwargs):
1303 """Create a new VxLAN GPE interface.
1305 :param node: Honeycomb node.
1306 :param interface: The name of interface to be created.
1307 :param kwargs: Parameters and their values. The accepted parameters are
1308 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1310 :type interface: str
1312 :return: Content of response.
1314 :raises HoneycombError: If a parameter in kwargs is not valid.
1319 "type": "v3po:vxlan-gpe-tunnel",
1320 "v3po:vxlan-gpe": {}
1322 for param, value in kwargs.items():
1323 if param in InterfaceKeywords.INTF_PARAMS:
1324 new_vxlan_gpe[param] = value
1325 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1326 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1328 raise HoneycombError("The parameter {0} is invalid.".
1330 path = ("interfaces", "interface")
1331 vxlan_gpe_structure = [new_vxlan_gpe, ]
1332 return InterfaceKeywords._set_interface_properties(
1333 node, interface, path, vxlan_gpe_structure)
1336 def enable_acl_on_interface(node, interface, table_name):
1337 """Enable ACL on the given interface.
1339 :param node: Honeycomb node.
1340 :param interface: The interface where the ACL will be enabled.
1341 :param table_name: Name of the classify table.
1343 :type interface: str
1344 :type table_name: str
1345 :return: Content of response.
1347 :raises HoneycombError: If the configuration of interface is not
1351 interface = interface.replace("/", "%2F")
1356 "classify-table": table_name
1359 "classify-table": table_name
1364 path = "/interface/" + interface + "/v3po:acl"
1365 status_code, resp = HcUtil.\
1366 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1367 data_representation=DataRepresentation.JSON)
1368 if status_code != HTTPCodes.OK:
1369 raise HoneycombError(
1370 "The configuration of interface '{0}' was not successful. "
1371 "Status code: {1}.".format(interface, status_code))
1375 def disable_acl_on_interface(node, interface):
1376 """Disable ACL on the given interface.
1378 :param node: Honeycomb node.
1379 :param interface: The interface where the ACL will be disabled.
1381 :type interface: str
1382 :return: Content of response.
1384 :raises HoneycombError: If the configuration of interface is not
1388 interface = interface.replace("/", "%2F")
1390 path = "/interface/" + interface + "/v3po:acl"
1392 status_code, resp = HcUtil.\
1393 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1395 if status_code != HTTPCodes.OK:
1396 raise HoneycombError(
1397 "The configuration of interface '{0}' was not successful. "
1398 "Status code: {1}.".format(interface, status_code))
1402 def create_pbb_sub_interface(node, intf, sub_if_id, params):
1403 """Creates a PBB sub-interface on the given interface and sets its
1406 :param node: Honeycomb node.
1407 :param intf: The interface where PBB sub-interface will be configured.
1408 :param sub_if_id: Sub-interface ID.
1409 :param params: Configuration parameters of the sub-interface to be
1413 :type sub_if_id: str or int
1415 :return: Content of response.
1417 :raises HoneycombError: If the configuration of sub-interface is not
1421 interface = intf.replace("/", "%2F")
1422 path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1423 "{1}".format(interface, sub_if_id)
1424 status_code, resp = HcUtil. \
1425 put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1426 data_representation=DataRepresentation.JSON)
1427 if status_code != HTTPCodes.OK:
1428 raise HoneycombError(
1429 "The configuration of PBB sub-interface '{0}' was not "
1430 "successful. Status code: {1}.".format(intf, status_code))
1434 def delete_pbb_sub_interface(node, intf, sub_if_id):
1435 """Deletes the given PBB sub-interface.
1437 :param node: Honeycomb node.
1438 :param intf: The interface where PBB sub-interface will be deleted.
1439 :param sub_if_id: ID of the PBB sub-interface to be deleted.
1442 :type sub_if_id: str or int
1443 :return: Content of response.
1445 :raises HoneycombError: If the removal of sub-interface is not
1449 interface = intf.replace("/", "%2F")
1450 path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1451 "{1}".format(interface, sub_if_id)
1453 status_code, resp = HcUtil. \
1454 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1455 if status_code != HTTPCodes.OK:
1456 raise HoneycombError(
1457 "The removal of pbb sub-interface '{0}' was not successful. "
1458 "Status code: {1}.".format(intf, status_code))
1462 def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1463 """Retrieves PBB sub-interface operational data from Honeycomb.
1465 :param node: Honeycomb node.
1466 :param intf: The interface where PBB sub-interface is located.
1467 :param sub_if_id: ID of the PBB sub-interface.
1470 :type sub_if_id: str or int
1471 :return: PBB sub-interface operational data.
1473 :raises HoneycombError: If the removal of sub-interface is not
1477 interface = "{0}.{1}".format(intf, sub_if_id)
1478 return InterfaceKeywords.get_interface_oper_data(node, interface)