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 class InterfaceKeywords(object):
29 """Keywords for Interface manipulation.
31 Implements keywords which get configuration and operational data about
32 vpp interfaces and set the interface's parameters using Honeycomb REST API.
35 INTF_PARAMS = ("name", "description", "type", "enabled",
36 "link-up-down-trap-enable")
37 IPV4_PARAMS = ("enabled", "forwarding", "mtu")
38 IPV6_PARAMS = ("enabled", "forwarding", "mtu", "dup-addr-detect-transmits")
39 IPV6_AUTOCONF_PARAMS = ("create-global-addresses",
40 "create-temporary-addresses",
41 "temporary-valid-lifetime",
42 "temporary-preferred-lifetime")
43 ETH_PARAMS = ("mtu", )
44 ROUTING_PARAMS = ("vrf-id", )
45 VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
46 L2_PARAMS = ("bridge-domain", "split-horizon-group",
47 "bridged-virtual-interface")
53 def _configure_interface(node, interface, data,
54 data_representation=DataRepresentation.JSON):
55 """Send interface configuration data and check the response.
57 :param node: Honeycomb node.
58 :param interface: The name of interface.
59 :param data: Configuration data to be sent in PUT request.
60 :param data_representation: How the data is represented.
64 :type data_representation: DataRepresentation
65 :return: Content of response.
67 :raises HoneycombError: If the status code in response on PUT is not
71 status_code, resp = HcUtil.\
72 put_honeycomb_data(node, "config_vpp_interfaces", data,
73 data_representation=data_representation)
74 if status_code != HTTPCodes.OK:
76 "The configuration of interface '{0}' was not successful. "
77 "Status code: {1}.".format(interface, status_code))
81 def get_all_interfaces_cfg_data(node):
82 """Get configuration data about all interfaces from Honeycomb.
84 :param node: Honeycomb node.
86 :return: Configuration data about all interfaces from Honeycomb.
88 :raises HoneycombError: If it is not possible to get configuration data.
91 status_code, resp = HcUtil.\
92 get_honeycomb_data(node, "config_vpp_interfaces")
93 if status_code != HTTPCodes.OK:
95 "Not possible to get configuration information about the "
96 "interfaces. Status code: {0}.".format(status_code))
98 return resp["interfaces"]["interface"]
100 except (KeyError, TypeError):
104 def get_interface_cfg_data(node, interface):
105 """Get configuration data about the given interface from Honeycomb.
107 :param node: Honeycomb node.
108 :param interface: The name of interface.
111 :return: Configuration data about the given interface from Honeycomb.
115 intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
117 if intf["name"] == interface:
122 def get_all_interfaces_oper_data(node):
123 """Get operational data about all interfaces from Honeycomb.
125 :param node: Honeycomb node.
127 :return: Operational data about all interfaces from Honeycomb.
129 :raises HoneycombError: If it is not possible to get operational data.
132 status_code, resp = HcUtil.\
133 get_honeycomb_data(node, "oper_vpp_interfaces")
134 if status_code != HTTPCodes.OK:
135 raise HoneycombError(
136 "Not possible to get operational information about the "
137 "interfaces. Status code: {0}.".format(status_code))
139 return resp["interfaces-state"]["interface"]
141 except (KeyError, TypeError):
145 def get_interface_oper_data(node, interface):
146 """Get operational data about the given interface from Honeycomb.
148 :param node: Honeycomb node.
149 :param interface: The name of interface.
152 :return: Operational data about the given interface from Honeycomb.
156 intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
158 if intf["name"] == interface:
163 def _set_interface_properties(node, interface, path, new_value=None):
164 """Set interface properties.
166 This method reads interface configuration data, creates, changes or
167 removes the requested data and puts it back to Honeycomb.
169 :param node: Honeycomb node.
170 :param interface: The name of interface.
171 :param path: Path to data we want to change / create / remove.
172 :param new_value: The new value to be set. If None, the item will be
177 :type new_value: str, dict or list
178 :return: Content of response.
180 :raises HoneycombError: If it is not possible to get or set the data.
183 status_code, resp = HcUtil.\
184 get_honeycomb_data(node, "config_vpp_interfaces")
185 if status_code != HTTPCodes.OK:
186 raise HoneycombError(
187 "Not possible to get configuration information about the "
188 "interfaces. Status code: {0}.".format(status_code))
191 new_data = HcUtil.set_item_value(resp, path, new_value)
193 new_data = HcUtil.remove_item(resp, path)
194 return InterfaceKeywords._configure_interface(node, interface, new_data)
197 def set_interface_state(node, interface, state="up"):
198 """Set VPP interface state.
200 The keyword changes the administration state of interface to up or down
201 depending on the parameter "state".
203 :param node: Honeycomb node.
204 :param interface: The name of interface.
205 :param state: The requested state, only "up" and "down" are valid
210 :return: Content of response.
212 :raises KeyError: If the argument "state" is nor "up" or "down".
213 :raises HoneycombError: If the interface is not present on the node.
216 intf_state = {"up": "true",
219 path = ("interfaces", ("interface", "name", str(interface)), "enabled")
220 return InterfaceKeywords._set_interface_properties(
221 node, interface, path, intf_state[state.lower()])
224 def set_interface_up(node, interface):
225 """Set the administration state of VPP interface to up.
227 :param node: Honeycomb node.
228 :param interface: The name of interface.
231 :return: Content of response
235 return InterfaceKeywords.set_interface_state(node, interface, "up")
238 def set_interface_down(node, interface):
239 """Set the administration state of VPP interface to down.
241 :param node: Honeycomb node.
242 :param interface: The name of interface.
245 :return: Content of response.
249 return InterfaceKeywords.set_interface_state(node, interface, "down")
252 def add_bridge_domain_to_interface(node, interface, bd_name,
253 split_horizon_group=None, bvi=None):
254 """Add a new bridge domain to an interface and set its parameters.
256 :param node: Honeycomb node.
257 :param interface: The name of interface.
258 :param bd_name: Bridge domain name.
259 :param split_horizon_group: Split-horizon group name.
260 :param bvi: The bridged virtual interface.
264 :type split_horizon_group: str
266 :return: Content of response.
268 :raises HoneycombError: If the interface is not present on the node.
271 v3po_l2 = {"bridge-domain": str(bd_name)}
272 if split_horizon_group:
273 v3po_l2["split-horizon-group"] = str(split_horizon_group)
275 v3po_l2["bridged-virtual-interface"] = str(bvi)
277 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
279 return InterfaceKeywords._set_interface_properties(
280 node, interface, path, v3po_l2)
283 def configure_interface_base(node, interface, param, value):
284 """Configure the base parameters of interface.
286 :param node: Honeycomb node.
287 :param interface: The name of interface.
288 :param param: Parameter to configure (set, change, remove)
289 :param value: The value of parameter. If None, the parameter will be
295 :return: Content of response.
297 :raises HoneycombError: If the parameter is not valid.
300 if param not in InterfaceKeywords.INTF_PARAMS:
301 raise HoneycombError("The parameter {0} is invalid.".format(param))
303 path = ("interfaces", ("interface", "name", interface), param)
304 return InterfaceKeywords._set_interface_properties(
305 node, interface, path, value)
308 def configure_interface_ipv4(node, interface, param, value):
309 """Configure IPv4 parameters of interface
311 :param node: Honeycomb node.
312 :param interface: The name of interface.
313 :param param: Parameter to configure (set, change, remove)
314 :param value: The value of parameter. If None, the parameter will be
320 :return: Content of response.
322 :raises HoneycombError: If the parameter is not valid.
325 if param not in InterfaceKeywords.IPV4_PARAMS:
326 raise HoneycombError("The parameter {0} is invalid.".format(param))
328 path = ("interfaces", ("interface", "name", interface),
329 "ietf-ip:ipv4", param)
330 return InterfaceKeywords._set_interface_properties(
331 node, interface, path, value)
334 def add_first_ipv4_address(node, interface, ip_addr, netmask):
335 """Add the first IPv4 address.
337 If there are any other addresses configured, they will be removed.
339 :param node: Honeycomb node.
340 :param interface: The name of interface.
341 :param ip_addr: IPv4 address to be set.
342 :param netmask: Netmask.
347 :return: Content of response.
351 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
352 address = {"address": [{"ip": ip_addr, "netmask": netmask}, ]}
353 return InterfaceKeywords._set_interface_properties(
354 node, interface, path, address)
357 def add_ipv4_address(node, interface, ip_addr, netmask):
360 :param node: Honeycomb node.
361 :param interface: The name of interface.
362 :param ip_addr: IPv4 address to be set.
363 :param netmask: Netmask.
368 :return: Content of response.
372 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
374 address = [{"ip": ip_addr, "prefix-length": netmask}, ]
375 return InterfaceKeywords._set_interface_properties(
376 node, interface, path, address)
379 def remove_all_ipv4_addresses(node, interface):
380 """Remove all IPv4 addresses from interface.
382 :param node: Honeycomb node.
383 :param interface: The name of interface.
386 :return: Content of response.
390 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
392 return InterfaceKeywords._set_interface_properties(
393 node, interface, path, None)
396 def add_first_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
397 """Add the first IPv4 neighbour.
399 If there are any other neighbours configured, they will be removed.
401 :param node: Honeycomb node.
402 :param interface: The name of interface.
403 :param ip_addr: IPv4 address of neighbour to be set.
404 :param link_layer_address: Link layer address.
408 :type link_layer_address: str
409 :return: Content of response.
413 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
414 neighbor = {"neighbor": [{"ip": ip_addr,
415 "link-layer-address": link_layer_address}, ]}
416 return InterfaceKeywords._set_interface_properties(
417 node, interface, path, neighbor)
420 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
421 """Add the IPv4 neighbour.
423 :param node: Honeycomb node.
424 :param interface: The name of interface.
425 :param ip_addr: IPv4 address of neighbour to be set.
426 :param link_layer_address: Link layer address.
430 :type link_layer_address: str
431 :return: Content of response.
435 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
437 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
438 return InterfaceKeywords._set_interface_properties(
439 node, interface, path, neighbor)
442 def remove_all_ipv4_neighbors(node, interface):
443 """Remove all IPv4 neighbours.
445 :param node: Honeycomb node.
446 :param interface: The name of interface.
449 :return: Content of response.
453 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
455 return InterfaceKeywords._set_interface_properties(
456 node, interface, path, None)
459 def configure_interface_ipv6(node, interface, param, value):
460 """Configure IPv6 parameters of interface
462 :param node: Honeycomb node.
463 :param interface: The name of interface.
464 :param param: Parameter to configure (set, change, remove)
465 :param value: The value of parameter. If None, the parameter will be
471 :return: Content of response.
473 :raises HoneycombError: If the parameter is not valid.
476 if param in InterfaceKeywords.IPV6_PARAMS:
477 path = ("interfaces", ("interface", "name", interface),
478 "ietf-ip:ipv6", param)
479 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
480 path = ("interfaces", ("interface", "name", interface),
481 "ietf-ip:ipv6", "autoconf", param)
483 raise HoneycombError("The parameter {0} is invalid.".format(param))
485 return InterfaceKeywords._set_interface_properties(
486 node, interface, path, value)
489 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
490 """Add the first IPv6 address.
492 If there are any other addresses configured, they will be removed.
494 :param node: Honeycomb node.
495 :param interface: The name of interface.
496 :param ip_addr: IPv6 address to be set.
497 :param prefix_len: Prefix length.
501 :type prefix_len: str
502 :return: Content of response.
506 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
507 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
508 return InterfaceKeywords._set_interface_properties(
509 node, interface, path, address)
512 def add_ipv6_address(node, interface, ip_addr, prefix_len):
515 :param node: Honeycomb node.
516 :param interface: The name of interface.
517 :param ip_addr: IPv6 address to be set.
518 :param prefix_len: Prefix length.
522 :type prefix_len: str
523 :return: Content of response.
527 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
529 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
530 return InterfaceKeywords._set_interface_properties(
531 node, interface, path, address)
534 def remove_all_ipv6_addresses(node, interface):
535 """Remove all IPv6 addresses from interface.
537 :param node: Honeycomb node.
538 :param interface: The name of interface.
541 :return: Content of response.
545 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
547 return InterfaceKeywords._set_interface_properties(
548 node, interface, path, None)
551 def add_first_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
552 """Add the first IPv6 neighbour.
554 If there are any other neighbours configured, they will be removed.
556 :param node: Honeycomb node.
557 :param interface: The name of interface.
558 :param ip_addr: IPv6 address of neighbour to be set.
559 :param link_layer_address: Link layer address.
563 :type link_layer_address: str
564 :return: Content of response.
568 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
569 neighbor = {"neighbor": [{"ip": ip_addr,
570 "link-layer-address": link_layer_address}, ]}
571 return InterfaceKeywords._set_interface_properties(
572 node, interface, path, neighbor)
575 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
576 """Add the IPv6 neighbour.
578 :param node: Honeycomb node.
579 :param interface: The name of interface.
580 :param ip_addr: IPv6 address of neighbour to be set.
581 :param link_layer_address: Link layer address.
585 :type link_layer_address: str
586 :return: Content of response.
590 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
592 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
593 return InterfaceKeywords._set_interface_properties(
594 node, interface, path, neighbor)
597 def remove_all_ipv6_neighbors(node, interface):
598 """Remove all IPv6 neighbours.
600 :param node: Honeycomb node.
601 :param interface: The name of interface.
604 :return: Content of response.
608 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
610 return InterfaceKeywords._set_interface_properties(
611 node, interface, path, None)
614 def configure_interface_ethernet(node, interface, param, value):
615 """Configure the ethernet parameters of interface.
617 :param node: Honeycomb node.
618 :param interface: The name of interface.
619 :param param: Parameter to configure (set, change, remove)
620 :param value: The value of parameter. If None, the parameter will be
626 :return: Content of response.
628 :raises HoneycombError: If the parameter is not valid.
631 if param not in InterfaceKeywords.ETH_PARAMS:
632 raise HoneycombError("The parameter {0} is invalid.".format(param))
633 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
635 return InterfaceKeywords._set_interface_properties(
636 node, interface, path, value)
639 def configure_interface_routing(node, interface, param, value):
640 """Configure the routing parameters of interface.
642 :param node: Honeycomb node.
643 :param interface: The name of interface.
644 :param param: Parameter to configure (set, change, remove)
645 :param value: The value of parameter. If None, the parameter will be
651 :return: Content of response.
653 :raises HoneycombError: If the parameter is not valid.
656 if param not in InterfaceKeywords.ROUTING_PARAMS:
657 raise HoneycombError("The parameter {0} is invalid.".format(param))
659 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
661 return InterfaceKeywords._set_interface_properties(
662 node, interface, path, value)
665 def configure_interface_vxlan(node, interface, param, value):
666 """Configure the VxLAN parameters of interface.
668 :param node: Honeycomb node.
669 :param interface: The name of interface.
670 :param param: Parameter to configure (set, change, remove)
671 :param value: The value of parameter. If None, the parameter will be
677 :return: Content of response.
679 :raises HoneycombError: If the parameter is not valid.
682 if param not in InterfaceKeywords.VXLAN_PARAMS:
683 raise HoneycombError("The parameter {0} is invalid.".format(param))
685 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan",
687 return InterfaceKeywords._set_interface_properties(
688 node, interface, path, value)
691 def configure_interface_l2(node, interface, param, value):
692 """Configure the L2 parameters of interface.
694 :param node: Honeycomb node.
695 :param interface: The name of interface.
696 :param param: Parameter to configure (set, change, remove)
697 :param value: The value of parameter. If None, the parameter will be
703 :return: Content of response.
705 :raises HoneycombError: If the parameter is not valid.
708 if param not in InterfaceKeywords.L2_PARAMS:
709 raise HoneycombError("The parameter {0} is invalid.".format(param))
710 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
712 return InterfaceKeywords._set_interface_properties(
713 node, interface, path, value)