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 path = ("interfaces", ("interface", "name", str(interface)), "enabled")
241 return InterfaceKeywords._set_interface_properties(
242 node, interface, path, intf_state[state.lower()])
245 def set_interface_up(node, interface):
246 """Set the administration state of VPP interface to up.
248 :param node: Honeycomb node.
249 :param interface: The name of interface.
252 :return: Content of response
256 return InterfaceKeywords.set_interface_state(node, interface, "up")
259 def set_interface_down(node, interface):
260 """Set the administration state of VPP interface to down.
262 :param node: Honeycomb node.
263 :param interface: The name of interface.
266 :return: Content of response.
270 return InterfaceKeywords.set_interface_state(node, interface, "down")
273 def add_bridge_domain_to_interface(node, interface, bd_name,
274 split_horizon_group=None, bvi=None):
275 """Add a new bridge domain to an interface and set its parameters.
277 :param node: Honeycomb node.
278 :param interface: The name of interface.
279 :param bd_name: Bridge domain name.
280 :param split_horizon_group: Split-horizon group name.
281 :param bvi: The bridged virtual interface.
285 :type split_horizon_group: str
287 :return: Content of response.
289 :raises HoneycombError: If the interface is not present on the node.
292 v3po_l2 = {"bridge-domain": str(bd_name)}
293 if split_horizon_group:
294 v3po_l2["split-horizon-group"] = str(split_horizon_group)
296 v3po_l2["bridged-virtual-interface"] = str(bvi)
298 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
300 return InterfaceKeywords._set_interface_properties(
301 node, interface, path, v3po_l2)
304 def get_bd_oper_data_from_interface(node, interface):
305 """Returns operational data about bridge domain settings in the
308 :param node: Honeycomb node.
309 :param interface: The name of interface.
312 :return: Operational data about bridge domain settings in the
317 if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
321 return if_data["v3po:l2"]
327 def configure_interface_base(node, interface, param, value):
328 """Configure the base parameters of interface.
330 :param node: Honeycomb node.
331 :param interface: The name of interface.
332 :param param: Parameter to configure (set, change, remove)
333 :param value: The value of parameter. If None, the parameter will be
339 :return: Content of response.
341 :raises HoneycombError: If the parameter is not valid.
344 if param not in InterfaceKeywords.INTF_PARAMS:
345 raise HoneycombError("The parameter {0} is invalid.".format(param))
347 path = ("interfaces", ("interface", "name", interface), param)
348 return InterfaceKeywords._set_interface_properties(
349 node, interface, path, value)
352 def configure_interface_ipv4(node, interface, param, value):
353 """Configure IPv4 parameters of interface
355 :param node: Honeycomb node.
356 :param interface: The name of interface.
357 :param param: Parameter to configure (set, change, remove)
358 :param value: The value of parameter. If None, the parameter will be
364 :return: Content of response.
366 :raises HoneycombError: If the parameter is not valid.
369 if param not in InterfaceKeywords.IPV4_PARAMS:
370 raise HoneycombError("The parameter {0} is invalid.".format(param))
372 path = ("interfaces", ("interface", "name", interface),
373 "ietf-ip:ipv4", param)
374 return InterfaceKeywords._set_interface_properties(
375 node, interface, path, value)
378 def add_first_ipv4_address(node, interface, ip_addr, network):
379 """Add the first IPv4 address.
381 If there are any other addresses configured, they will be removed.
383 :param node: Honeycomb node.
384 :param interface: The name of interface.
385 :param ip_addr: IPv4 address to be set.
386 :param network: Netmask or length of network prefix.
390 :type network: str or int
391 :return: Content of response.
393 :raises HoneycombError: If the provided netmask or prefix is not valid.
396 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
397 if isinstance(network, basestring):
398 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
399 elif isinstance(network, int) and (0 < network < 33):
400 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
402 raise HoneycombError("Value {0} is not a valid netmask or network "
403 "prefix length.".format(network))
404 return InterfaceKeywords._set_interface_properties(
405 node, interface, path, address)
408 def add_ipv4_address(node, interface, ip_addr, network):
411 :param node: Honeycomb node.
412 :param interface: The name of interface.
413 :param ip_addr: IPv4 address to be set.
414 :param network: Netmask or length of network prefix.
418 :type network: str or int
419 :return: Content of response.
421 :raises HoneycombError: If the provided netmask or prefix is not valid.
424 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
426 if isinstance(network, basestring):
427 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
428 elif isinstance(network, int) and (0 < network < 33):
429 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
431 raise HoneycombError("Value {0} is not a valid netmask or network "
432 "prefix length.".format(network))
433 return InterfaceKeywords._set_interface_properties(
434 node, interface, path, address)
437 def remove_all_ipv4_addresses(node, interface):
438 """Remove all IPv4 addresses from interface.
440 :param node: Honeycomb node.
441 :param interface: The name of interface.
444 :return: Content of response.
448 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
450 return InterfaceKeywords._set_interface_properties(
451 node, interface, path, None)
454 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
455 """Add the IPv4 neighbour.
457 :param node: Honeycomb node.
458 :param interface: The name of interface.
459 :param ip_addr: IPv4 address of neighbour to be set.
460 :param link_layer_address: Link layer address.
464 :type link_layer_address: str
465 :return: Content of response.
469 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
471 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
472 return InterfaceKeywords._set_interface_properties(
473 node, interface, path, neighbor)
476 def remove_all_ipv4_neighbors(node, interface):
477 """Remove all IPv4 neighbours.
479 :param node: Honeycomb node.
480 :param interface: The name of interface.
483 :return: Content of response.
487 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
489 return InterfaceKeywords._set_interface_properties(
490 node, interface, path, None)
493 def configure_interface_ipv6(node, interface, param, value):
494 """Configure IPv6 parameters of interface
496 :param node: Honeycomb node.
497 :param interface: The name of interface.
498 :param param: Parameter to configure (set, change, remove)
499 :param value: The value of parameter. If None, the parameter will be
505 :return: Content of response.
507 :raises HoneycombError: If the parameter is not valid.
510 if param in InterfaceKeywords.IPV6_PARAMS:
511 path = ("interfaces", ("interface", "name", interface),
512 "ietf-ip:ipv6", param)
513 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
514 path = ("interfaces", ("interface", "name", interface),
515 "ietf-ip:ipv6", "autoconf", param)
517 raise HoneycombError("The parameter {0} is invalid.".format(param))
519 return InterfaceKeywords._set_interface_properties(
520 node, interface, path, value)
523 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
524 """Add the first IPv6 address.
526 If there are any other addresses configured, they will be removed.
528 :param node: Honeycomb node.
529 :param interface: The name of interface.
530 :param ip_addr: IPv6 address to be set.
531 :param prefix_len: Prefix length.
535 :type prefix_len: str
536 :return: Content of response.
540 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
541 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
542 return InterfaceKeywords._set_interface_properties(
543 node, interface, path, address)
546 def add_ipv6_address(node, interface, ip_addr, prefix_len):
549 :param node: Honeycomb node.
550 :param interface: The name of interface.
551 :param ip_addr: IPv6 address to be set.
552 :param prefix_len: Prefix length.
556 :type prefix_len: str
557 :return: Content of response.
561 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
563 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
564 return InterfaceKeywords._set_interface_properties(
565 node, interface, path, address)
568 def remove_all_ipv6_addresses(node, interface):
569 """Remove all IPv6 addresses from interface.
571 :param node: Honeycomb node.
572 :param interface: The name of interface.
575 :return: Content of response.
579 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
581 return InterfaceKeywords._set_interface_properties(
582 node, interface, path, None)
585 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
586 """Add the IPv6 neighbour.
588 :param node: Honeycomb node.
589 :param interface: The name of interface.
590 :param ip_addr: IPv6 address of neighbour to be set.
591 :param link_layer_address: Link layer address.
595 :type link_layer_address: str
596 :return: Content of response.
600 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
602 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
603 return InterfaceKeywords._set_interface_properties(
604 node, interface, path, neighbor)
607 def remove_all_ipv6_neighbors(node, interface):
608 """Remove all IPv6 neighbours.
610 :param node: Honeycomb node.
611 :param interface: The name of interface.
614 :return: Content of response.
618 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
620 return InterfaceKeywords._set_interface_properties(
621 node, interface, path, None)
624 def configure_interface_ethernet(node, interface, param, value):
625 """Configure the ethernet parameters of interface.
627 :param node: Honeycomb node.
628 :param interface: The name of interface.
629 :param param: Parameter to configure (set, change, remove)
630 :param value: The value of parameter. If None, the parameter will be
636 :return: Content of response.
638 :raises HoneycombError: If the parameter is not valid.
641 if param not in InterfaceKeywords.ETH_PARAMS:
642 raise HoneycombError("The parameter {0} is invalid.".format(param))
643 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
645 return InterfaceKeywords._set_interface_properties(
646 node, interface, path, value)
649 def configure_interface_routing(node, interface, param, value):
650 """Configure the routing parameters of interface.
652 :param node: Honeycomb node.
653 :param interface: The name of interface.
654 :param param: Parameter to configure (set, change, remove)
655 :param value: The value of parameter. If None, the parameter will be
661 :return: Content of response.
663 :raises HoneycombError: If the parameter is not valid.
666 if param not in InterfaceKeywords.ROUTING_PARAMS:
667 raise HoneycombError("The parameter {0} is invalid.".format(param))
669 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
671 return InterfaceKeywords._set_interface_properties(
672 node, interface, path, value)
675 def create_vxlan_interface(node, interface, **kwargs):
676 """Create a new VxLAN interface.
678 :param node: Honeycomb node.
679 :param interface: The name of interface.
680 :param kwargs: Parameters and their values. The accepted parameters are
681 defined in InterfaceKeywords.VXLAN_PARAMS.
685 :return: Content of response.
687 :raises HoneycombError: If the parameter is not valid.
692 "type": "v3po:vxlan-tunnel",
695 for param, value in kwargs.items():
696 if param not in InterfaceKeywords.VXLAN_PARAMS:
697 raise HoneycombError("The parameter {0} is invalid.".
699 new_vx_lan["v3po:vxlan"][param] = value
701 path = ("interfaces", "interface")
702 vx_lan_structure = [new_vx_lan, ]
703 return InterfaceKeywords._set_interface_properties(
704 node, interface, path, vx_lan_structure)
707 def delete_interface(node, interface):
708 """Delete an interface.
710 :param node: Honeycomb node.
711 :param interface: The name of interface.
714 :return: Content of response.
716 :raises HoneycombError: If it is not possible to get information about
717 interfaces or it is not possible to delete the interface.
720 path = ("interfaces", ("interface", "name", interface))
722 status_code, resp = HcUtil.\
723 get_honeycomb_data(node, "config_vpp_interfaces")
724 if status_code != HTTPCodes.OK:
725 raise HoneycombError(
726 "Not possible to get configuration information about the "
727 "interfaces. Status code: {0}.".format(status_code))
729 new_data = HcUtil.remove_item(resp, path)
730 status_code, resp = HcUtil.\
731 put_honeycomb_data(node, "config_vpp_interfaces", new_data)
732 if status_code != HTTPCodes.OK:
733 raise HoneycombError("Not possible to remove interface {0}. "
735 format(interface, status_code))
739 def configure_interface_vxlan(node, interface, **kwargs):
740 """Configure VxLAN on the interface.
742 The keyword configures VxLAN parameters on the given interface. The type
743 of interface must be set to "v3po:vxlan-tunnel".
744 The new VxLAN parameters overwrite the current configuration. If a
745 parameter in new configuration is missing, it is removed from VxLAN
747 If the dictionary kwargs is empty, VxLAN configuration is removed.
749 :param node: Honeycomb node.
750 :param interface: The name of interface.
751 :param kwargs: Parameters and their values. The accepted parameters are
752 defined in InterfaceKeywords.VXLAN_PARAMS.
756 :return: Content of response.
758 :raises HoneycombError: If the parameter is not valid.
761 vx_lan_structure = dict()
762 for param, value in kwargs.items():
763 if param not in InterfaceKeywords.VXLAN_PARAMS:
764 raise HoneycombError("The parameter {0} is invalid.".
766 vx_lan_structure[param] = value
768 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
769 return InterfaceKeywords._set_interface_properties(
770 node, interface, path, vx_lan_structure)
773 def configure_interface_l2(node, interface, param, value):
774 """Configure the L2 parameters of interface.
776 :param node: Honeycomb node.
777 :param interface: The name of interface.
778 :param param: Parameter to configure (set, change, remove)
779 :param value: The value of parameter. If None, the parameter will be
785 :return: Content of response.
787 :raises HoneycombError: If the parameter is not valid.
790 if param not in InterfaceKeywords.L2_PARAMS:
791 raise HoneycombError("The parameter {0} is invalid.".format(param))
792 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
794 return InterfaceKeywords._set_interface_properties(
795 node, interface, path, value)
798 def create_tap_interface(node, interface, **kwargs):
799 """Create a new TAP interface.
801 :param node: Honeycomb node.
802 :param interface: The name of interface.
803 :param kwargs: Parameters and their values. The accepted parameters are
804 defined in InterfaceKeywords.TAP_PARAMS.
808 :return: Content of response.
810 :raises HoneycombError: If the parameter is not valid.
818 for param, value in kwargs.items():
819 if param not in InterfaceKeywords.TAP_PARAMS:
820 raise HoneycombError("The parameter {0} is invalid.".
822 new_tap["v3po:tap"][param] = value
824 path = ("interfaces", "interface")
825 new_tap_structure = [new_tap, ]
826 return InterfaceKeywords._set_interface_properties(
827 node, interface, path, new_tap_structure)
830 def configure_interface_tap(node, interface, **kwargs):
831 """Configure TAP on the interface.
833 The keyword configures TAP parameters on the given interface. The type
834 of interface must be set to "v3po:tap".
835 The new TAP parameters overwrite the current configuration. If a
836 parameter in new configuration is missing, it is removed from TAP
838 If the dictionary kwargs is empty, TAP configuration is removed.
840 :param node: Honeycomb node.
841 :param interface: The name of interface.
842 :param kwargs: Parameters and their values. The accepted parameters are
843 defined in InterfaceKeywords.TAP_PARAMS.
847 :return: Content of response.
849 :raises HoneycombError: If the parameter is not valid.
852 tap_structure = dict()
853 for param, value in kwargs.items():
854 if param not in InterfaceKeywords.TAP_PARAMS:
855 raise HoneycombError("The parameter {0} is invalid.".
857 tap_structure[param] = value
859 path = ("interfaces", ("interface", "name", interface), "v3po:tap")
860 return InterfaceKeywords._set_interface_properties(
861 node, interface, path, tap_structure)
864 def configure_interface_vhost_user(node, interface, **kwargs):
865 """Configure vhost-user on the interface.
867 The keyword configures vhost-user parameters on the given interface.
868 The type of interface must be set to "v3po:vhost-user".
869 The new vhost-user parameters overwrite the current configuration. If a
870 parameter in new configuration is missing, it is removed from vhost-user
872 If the dictionary kwargs is empty, vhost-user configuration is removed.
874 :param node: Honeycomb node.
875 :param interface: The name of interface.
876 :param kwargs: Parameters and their values. The accepted parameters are
877 defined in InterfaceKeywords.VHOST_USER_PARAMS.
881 :return: Content of response.
883 :raises HoneycombError: If the parameter is not valid.
886 vhost_structure = dict()
887 for param, value in kwargs.items():
888 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
889 raise HoneycombError("The parameter {0} is invalid.".
891 vhost_structure[param] = value
893 path = ("interfaces", ("interface", "name", interface),
895 return InterfaceKeywords._set_interface_properties(
896 node, interface, path, vhost_structure)
899 def create_vhost_user_interface(node, interface, **kwargs):
900 """Create a new vhost-user interface.
902 :param node: Honeycomb node.
903 :param interface: The name of interface.
904 :param kwargs: Parameters and their values. The accepted parameters are
905 defined in InterfaceKeywords.VHOST_USER_PARAMS.
909 :return: Content of response.
911 :raises HoneycombError: If the parameter is not valid.
916 "type": "v3po:vhost-user",
917 "v3po:vhost-user": {}
919 for param, value in kwargs.items():
920 if param not in InterfaceKeywords.VHOST_USER_PARAMS:
921 raise HoneycombError("The parameter {0} is invalid.".
923 new_vhost["v3po:vhost-user"][param] = value
925 path = ("interfaces", "interface")
926 new_vhost_structure = [new_vhost, ]
927 return InterfaceKeywords._set_interface_properties(
928 node, interface, path, new_vhost_structure)
931 def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
932 """Create a new sub-interface.
934 :param node: Honeycomb node.
935 :param super_interface: Super interface.
936 :param match: Match type. The valid values are defined in
937 InterfaceKeywords.SUB_IF_MATCH.
938 :param tags: List of tags.
939 :param kwargs: Parameters and their values. The accepted parameters are
940 defined in InterfaceKeywords.SUB_IF_PARAMS.
942 :type super_interface: str
946 :return: Content of response.
948 :raises HoneycombError: If the parameter is not valid.
949 :raises KeyError: If the parameter 'match' is invalid.
958 {"vlan-tagged": {"match-exact-tags": "false"}},
959 "vlan-tagged-exact-match":
960 {"vlan-tagged": {"match-exact-tags": "true"}}
963 new_sub_interface = {
969 for param, value in kwargs.items():
970 if param in InterfaceKeywords.SUB_IF_PARAMS:
971 new_sub_interface[param] = value
973 raise HoneycombError("The parameter {0} is invalid.".
976 new_sub_interface["match"] = match_type[match]
978 raise HoneycombError("The value '{0}' of parameter 'match' is "
979 "invalid.".format(match))
982 new_sub_interface["tags"]["tag"].extend(tags)
984 path = ("interfaces",
985 ("interface", "name", super_interface),
986 "vpp-vlan:sub-interfaces",
988 new_sub_interface_structure = [new_sub_interface, ]
989 return InterfaceKeywords._set_interface_properties(
990 node, super_interface, path, new_sub_interface_structure)
993 def get_sub_interface_oper_data(node, super_interface, identifier):
994 """Retrieves sub-interface operational data using Honeycomb API.
996 :param node: Honeycomb node.
997 :param super_interface: Super interface.
998 :param identifier: The ID of sub-interface.
1000 :type super_interface: str
1001 :type identifier: int
1002 :return: Sub-interface operational data.
1004 :raises HoneycombError: If there is no sub-interface with the given ID.
1007 if_data = InterfaceKeywords.get_interface_oper_data(node,
1009 for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1010 if str(sub_if["identifier"]) == str(identifier):
1013 raise HoneycombError("The interface {0} does not have sub-interface "
1014 "with ID {1}".format(super_interface, identifier))
1017 def remove_all_sub_interfaces(node, super_interface):
1018 """Remove all sub-interfaces from the given interface.
1020 :param node: Honeycomb node.
1021 :param super_interface: Super interface.
1023 :type super_interface: str
1024 :return: Content of response.
1028 path = ("interfaces",
1029 ("interface", "name", super_interface),
1030 "vpp-vlan:sub-interfaces")
1032 return InterfaceKeywords._set_interface_properties(
1033 node, super_interface, path, {})
1036 def set_sub_interface_state(node, super_interface, identifier, state):
1037 """Set the administrative state of sub-interface.
1039 :param node: Honeycomb node.
1040 :param super_interface: Super interface.
1041 :param identifier: The ID of sub-interface.
1042 :param state: Required sub-interface state - up or down.
1044 :type super_interface: str
1045 :type identifier: int
1047 :return: Content of response.
1051 intf_state = {"up": "true",
1054 path = ("interfaces",
1055 ("interface", "name", super_interface),
1056 "vpp-vlan:sub-interfaces",
1057 ("sub-interface", "identifier", identifier),
1060 return InterfaceKeywords._set_interface_properties(
1061 node, super_interface, path, intf_state[state])
1064 def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1066 """Add a sub-interface to a bridge domain and set its parameters.
1068 :param node: Honeycomb node.
1069 :param super_interface: Super interface.
1070 :param identifier: The ID of sub-interface.
1071 :param config: Bridge domain configuration.
1073 :type super_interface: str
1074 :type identifier: int
1076 :return: Content of response.
1080 path = ("interfaces",
1081 ("interface", "name", super_interface),
1082 "vpp-vlan:sub-interfaces",
1083 ("sub-interface", "identifier", int(identifier)),
1086 return InterfaceKeywords._set_interface_properties(
1087 node, super_interface, path, config)
1090 def get_bd_data_from_sub_interface(node, super_interface, identifier):
1091 """Get the operational data about the bridge domain from sub-interface.
1093 :param node: Honeycomb node.
1094 :param super_interface: Super interface.
1095 :param identifier: The ID of sub-interface.
1097 :type super_interface: str
1098 :type identifier: int
1099 :return: Operational data about the bridge domain.
1101 :raises HoneycombError: If there is no sub-interface with the given ID.
1105 bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1106 node, super_interface, identifier)["l2"]
1109 raise HoneycombError("The operational data does not contain "
1110 "information about a bridge domain.")
1113 def configure_tag_rewrite(node, super_interface, identifier, config):
1114 """Add / change / disable vlan tag rewrite on a sub-interface.
1116 :param node: Honeycomb node.
1117 :param super_interface: Super interface.
1118 :param identifier: The ID of sub-interface.
1119 :param config: Rewrite tag configuration.
1121 :type super_interface: str
1122 :type identifier: int
1124 :return: Content of response.
1128 path = ("interfaces",
1129 ("interface", "name", super_interface),
1130 "vpp-vlan:sub-interfaces",
1131 ("sub-interface", "identifier", int(identifier)),
1135 return InterfaceKeywords._set_interface_properties(
1136 node, super_interface, path, config)
1139 def get_tag_rewrite_oper_data(node, super_interface, identifier):
1140 """Get the operational data about tag rewrite.
1142 :param node: Honeycomb node.
1143 :param super_interface: Super interface.
1144 :param identifier: The ID of sub-interface.
1146 :type super_interface: str
1147 :type identifier: int
1148 :return: Operational data about tag rewrite.
1150 :raises HoneycombError: If there is no sub-interface with the given ID.
1154 tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1155 node, super_interface, identifier)["l2"]["rewrite"]
1158 raise HoneycombError("The operational data does not contain "
1159 "information about the tag-rewrite.")
1162 def add_ipv4_address_to_sub_interface(node, super_interface, identifier,
1164 """Add an ipv4 address to the specified sub-interface, with the provided
1165 netmask or network prefix length. Any existing ipv4 addresses on the
1166 sub-interface will be replaced.
1168 :param node: Honeycomb node.
1169 :param super_interface: Super interface.
1170 :param identifier: The ID of sub-interface.
1171 :param ip_addr: IPv4 address to be set.
1172 :param network: Network mask or network prefix length.
1174 :type super_interface: str
1175 :type identifier: int
1177 :type network: str or int
1178 :return: Content of response.
1180 :raises HoneycombError: If the provided netmask or prefix is not valid.
1183 path = ("interfaces",
1184 ("interface", "name", super_interface),
1185 "vpp-vlan:sub-interfaces",
1186 ("sub-interface", "identifier", int(identifier)),
1189 if isinstance(network, basestring):
1190 address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1192 elif isinstance(network, int) and 0 < network < 33:
1193 address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1196 raise HoneycombError("{0} is not a valid netmask or prefix length."
1199 return InterfaceKeywords._set_interface_properties(
1200 node, super_interface, path, address)
1203 def remove_all_ipv4_addresses_from_sub_interface(node, super_interface, # pylint: disable=invalid-name
1205 """Remove all ipv4 addresses from the specified sub-interface.
1207 :param node: Honeycomb node.
1208 :param super_interface: Super interface.
1209 :param identifier: The ID of sub-interface.
1211 :type super_interface: str
1212 :type identifier: int
1213 :return: Content of response.
1217 path = ("interfaces",
1218 ("interface", "name", super_interface),
1219 "vpp-vlan:sub-interfaces",
1220 ("sub-interface", "identifier", int(identifier)),
1223 return InterfaceKeywords._set_interface_properties(
1224 node, super_interface, path, None)
1227 def compare_data_structures(data, ref, ignore=()):
1228 """Checks if data obtained from UUT is as expected.
1230 :param data: Data to be checked.
1231 :param ref: Referential data used for comparison.
1232 :param ignore: Dictionary keys to be ignored.
1235 :type ignore: iterable
1236 :raises HoneycombError: If a parameter from referential data is not
1237 present in operational data or if it has different value.
1242 for key, item in ref.items():
1246 if data[key] != item:
1247 errors += ("\nThe value of parameter '{0}' is "
1248 "incorrect. It should be "
1249 "'{1}' but it is '{2}'".
1250 format(key, item, data[key]))
1252 errors += ("\nThe parameter '{0}' is not present in "
1253 "operational data".format(key))
1256 raise HoneycombError(errors)
1259 def compare_interface_lists(list1, list2):
1260 """Compare provided lists of interfaces by name.
1262 :param list1: List of interfaces.
1263 :param list2: List of interfaces.
1266 :raises HoneycombError: If an interface exists in only one of the lists.
1269 ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1270 # these have no equivalent in config data and no effect on VPP
1272 names1 = [x['name'] for x in list1]
1273 names2 = [x['name'] for x in list2]
1276 if name not in names2 and name not in ignore:
1277 raise HoneycombError("Interface {0} not present in list {1}"
1278 .format(name, list2))
1280 if name not in names1 and name not in ignore:
1281 raise HoneycombError("Interface {0} not present in list {1}"
1282 .format(name, list1))
1285 def create_vxlan_gpe_interface(node, interface, **kwargs):
1286 """Create a new VxLAN GPE interface.
1288 :param node: Honeycomb node.
1289 :param interface: The name of interface to be created.
1290 :param kwargs: Parameters and their values. The accepted parameters are
1291 defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1293 :type interface: str
1295 :return: Content of response.
1297 :raises HoneycombError: If a parameter in kwargs is not valid.
1302 "type": "v3po:vxlan-gpe-tunnel",
1303 "v3po:vxlan-gpe": {}
1305 for param, value in kwargs.items():
1306 if param in InterfaceKeywords.INTF_PARAMS:
1307 new_vxlan_gpe[param] = value
1308 elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1309 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1311 raise HoneycombError("The parameter {0} is invalid.".
1313 path = ("interfaces", "interface")
1314 vxlan_gpe_structure = [new_vxlan_gpe, ]
1315 return InterfaceKeywords._set_interface_properties(
1316 node, interface, path, vxlan_gpe_structure)
1319 def enable_acl_on_interface(node, interface, table_name):
1320 """Enable ACL on the given interface.
1322 :param node: Honeycomb node.
1323 :param interface: The interface where the ACL will be enabled.
1324 :param table_name: Name of the classify table.
1326 :type interface: str
1327 :type table_name: str
1328 :return: Content of response.
1330 :raises HoneycombError: If the configuration of interface is not
1334 interface = interface.replace("/", "%2F")
1339 "classify-table": table_name
1342 "classify-table": table_name
1347 path = "/interface/" + interface + "/v3po:acl"
1348 status_code, resp = HcUtil.\
1349 put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1350 data_representation=DataRepresentation.JSON)
1351 if status_code != HTTPCodes.OK:
1352 raise HoneycombError(
1353 "The configuration of interface '{0}' was not successful. "
1354 "Status code: {1}.".format(interface, status_code))
1358 def disable_acl_on_interface(node, interface):
1359 """Disable ACL on the given interface.
1361 :param node: Honeycomb node.
1362 :param interface: The interface where the ACL will be disabled.
1364 :type interface: str
1365 :return: Content of response.
1367 :raises HoneycombError: If the configuration of interface is not
1371 interface = interface.replace("/", "%2F")
1373 path = "/interface/" + interface + "/v3po:acl"
1375 status_code, resp = HcUtil.\
1376 delete_honeycomb_data(node, "config_vpp_interfaces", path)
1378 if status_code != HTTPCodes.OK:
1379 raise HoneycombError(
1380 "The configuration of interface '{0}' was not successful. "
1381 "Status code: {1}.".format(interface, status_code))