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
21 from resources.libraries.python.HTTPRequest import HTTPCodes
22 from resources.libraries.python.HoneycombSetup import HoneycombError
23 from resources.libraries.python.HoneycombUtil import HoneycombUtil as HcUtil
24 from resources.libraries.python.HoneycombUtil import DataRepresentation
27 class InterfaceKeywords(object):
28 """Keywords for Interface manipulation.
30 Implements keywords which get configuration and operational data about
31 vpp interfaces and set the interface's parameters using Honeycomb REST API.
34 INTF_PARAMS = ("name", "description", "type", "enabled",
35 "link-up-down-trap-enable")
36 IPV4_PARAMS = ("enabled", "forwarding", "mtu")
37 IPV6_PARAMS = ("enabled", "forwarding", "mtu", "dup-addr-detect-transmits")
38 IPV6_AUTOCONF_PARAMS = ("create-global-addresses",
39 "create-temporary-addresses",
40 "temporary-valid-lifetime",
41 "temporary-preferred-lifetime")
42 ETH_PARAMS = ("mtu", )
43 ROUTING_PARAMS = ("vrf-id", )
44 VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
45 L2_PARAMS = ("bridge-domain", "split-horizon-group",
46 "bridged-virtual-interface")
52 def _configure_interface(node, interface, data,
53 data_representation=DataRepresentation.JSON):
54 """Send interface configuration data and check the response.
56 :param node: Honeycomb node.
57 :param interface: The name of interface.
58 :param data: Configuration data to be sent in PUT request.
59 :param data_representation: How the data is represented.
63 :type data_representation: DataRepresentation
64 :return: Content of response.
66 :raises HoneycombError: If the status code in response on PUT is not
70 status_code, resp = HcUtil.\
71 put_honeycomb_data(node, "config_vpp_interfaces", data,
72 data_representation=data_representation)
73 if status_code != HTTPCodes.OK:
75 "The configuration of interface '{0}' was not successful. "
76 "Status code: {1}.".format(interface, status_code))
80 def get_all_interfaces_cfg_data(node):
81 """Get configuration data about all interfaces from Honeycomb.
83 :param node: Honeycomb node.
85 :return: Configuration data about all interfaces from Honeycomb.
87 :raises HoneycombError: If it is not possible to get configuration data.
90 status_code, resp = HcUtil.\
91 get_honeycomb_data(node, "config_vpp_interfaces")
92 if status_code != HTTPCodes.OK:
94 "Not possible to get configuration information about the "
95 "interfaces. Status code: {0}.".format(status_code))
97 return resp["interfaces"]["interface"]
99 except (KeyError, TypeError):
103 def get_interface_cfg_data(node, interface):
104 """Get configuration data about the given interface from Honeycomb.
106 :param node: Honeycomb node.
107 :param interface: The name of interface.
110 :return: Configuration data about the given interface from Honeycomb.
114 intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
116 if intf["name"] == interface:
121 def get_all_interfaces_oper_data(node):
122 """Get operational data about all interfaces from Honeycomb.
124 :param node: Honeycomb node.
126 :return: Operational data about all interfaces from Honeycomb.
128 :raises HoneycombError: If it is not possible to get operational data.
131 status_code, resp = HcUtil.\
132 get_honeycomb_data(node, "oper_vpp_interfaces")
133 if status_code != HTTPCodes.OK:
134 raise HoneycombError(
135 "Not possible to get operational information about the "
136 "interfaces. Status code: {0}.".format(status_code))
138 return resp["interfaces-state"]["interface"]
140 except (KeyError, TypeError):
144 def get_interface_oper_data(node, interface):
145 """Get operational data about the given interface from Honeycomb.
147 :param node: Honeycomb node.
148 :param interface: The name of interface.
151 :return: Operational data about the given interface from Honeycomb.
155 intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
157 if intf["name"] == interface:
162 def _set_interface_properties(node, interface, path, new_value=None):
163 """Set interface properties.
165 This method reads interface configuration data, creates, changes or
166 removes the requested data and puts it back to Honeycomb.
168 :param node: Honeycomb node.
169 :param interface: The name of interface.
170 :param path: Path to data we want to change / create / remove.
171 :param new_value: The new value to be set. If None, the item will be
176 :type new_value: str, dict or list
177 :return: Content of response.
179 :raises HoneycombError: If it is not possible to get or set the data.
182 status_code, resp = HcUtil.\
183 get_honeycomb_data(node, "config_vpp_interfaces")
184 if status_code != HTTPCodes.OK:
185 raise HoneycombError(
186 "Not possible to get configuration information about the "
187 "interfaces. Status code: {0}.".format(status_code))
190 new_data = HcUtil.set_item_value(resp, path, new_value)
192 new_data = HcUtil.remove_item(resp, path)
193 return InterfaceKeywords._configure_interface(node, interface, new_data)
196 def set_interface_state(node, interface, state="up"):
197 """Set VPP interface state.
199 The keyword changes the administration state of interface to up or down
200 depending on the parameter "state".
202 :param node: Honeycomb node.
203 :param interface: The name of interface.
204 :param state: The requested state, only "up" and "down" are valid
209 :return: Content of response.
211 :raises KeyError: If the argument "state" is nor "up" or "down".
212 :raises HoneycombError: If the interface is not present on the node.
215 intf_state = {"up": "true",
218 path = ("interfaces", ("interface", "name", str(interface)), "enabled")
219 return InterfaceKeywords._set_interface_properties(
220 node, interface, path, intf_state[state.lower()])
223 def set_interface_up(node, interface):
224 """Set the administration state of VPP interface to up.
226 :param node: Honeycomb node.
227 :param interface: The name of interface.
230 :return: Content of response
234 return InterfaceKeywords.set_interface_state(node, interface, "up")
237 def set_interface_down(node, interface):
238 """Set the administration state of VPP interface to down.
240 :param node: Honeycomb node.
241 :param interface: The name of interface.
244 :return: Content of response.
248 return InterfaceKeywords.set_interface_state(node, interface, "down")
251 def add_bridge_domain_to_interface(node, interface, bd_name,
252 split_horizon_group=None, bvi=None):
253 """Add a new bridge domain to an interface and set its parameters.
255 :param node: Honeycomb node.
256 :param interface: The name of interface.
257 :param bd_name: Bridge domain name.
258 :param split_horizon_group: Split-horizon group name.
259 :param bvi: The bridged virtual interface.
263 :type split_horizon_group: str
265 :return: Content of response.
267 :raises HoneycombError: If the interface is not present on the node.
270 v3po_l2 = {"bridge-domain": str(bd_name)}
271 if split_horizon_group:
272 v3po_l2["split-horizon-group"] = str(split_horizon_group)
274 v3po_l2["bridged-virtual-interface"] = str(bvi)
276 path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
278 return InterfaceKeywords._set_interface_properties(
279 node, interface, path, v3po_l2)
282 def configure_interface_base(node, interface, param, value):
283 """Configure the base parameters of interface.
285 :param node: Honeycomb node.
286 :param interface: The name of interface.
287 :param param: Parameter to configure (set, change, remove)
288 :param value: The value of parameter. If None, the parameter will be
294 :return: Content of response.
296 :raises HoneycombError: If the parameter is not valid.
299 if param not in InterfaceKeywords.INTF_PARAMS:
300 raise HoneycombError("The parameter {0} is invalid.".format(param))
302 path = ("interfaces", ("interface", "name", interface), param)
303 return InterfaceKeywords._set_interface_properties(
304 node, interface, path, value)
307 def configure_interface_ipv4(node, interface, param, value):
308 """Configure IPv4 parameters of interface
310 :param node: Honeycomb node.
311 :param interface: The name of interface.
312 :param param: Parameter to configure (set, change, remove)
313 :param value: The value of parameter. If None, the parameter will be
319 :return: Content of response.
321 :raises HoneycombError: If the parameter is not valid.
324 if param not in InterfaceKeywords.IPV4_PARAMS:
325 raise HoneycombError("The parameter {0} is invalid.".format(param))
327 path = ("interfaces", ("interface", "name", interface),
328 "ietf-ip:ipv4", param)
329 return InterfaceKeywords._set_interface_properties(
330 node, interface, path, value)
333 def add_first_ipv4_address(node, interface, ip_addr, netmask):
334 """Add the first IPv4 address.
336 If there are any other addresses configured, they will be removed.
338 :param node: Honeycomb node.
339 :param interface: The name of interface.
340 :param ip_addr: IPv4 address to be set.
341 :param netmask: Netmask.
346 :return: Content of response.
350 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
351 address = {"address": [{"ip": ip_addr, "netmask": netmask}, ]}
352 return InterfaceKeywords._set_interface_properties(
353 node, interface, path, address)
356 def add_ipv4_address(node, interface, ip_addr, netmask):
359 :param node: Honeycomb node.
360 :param interface: The name of interface.
361 :param ip_addr: IPv4 address to be set.
362 :param netmask: Netmask.
367 :return: Content of response.
371 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
373 address = [{"ip": ip_addr, "prefix-length": netmask}, ]
374 return InterfaceKeywords._set_interface_properties(
375 node, interface, path, address)
378 def remove_all_ipv4_addresses(node, interface):
379 """Remove all IPv4 addresses from interface.
381 :param node: Honeycomb node.
382 :param interface: The name of interface.
385 :return: Content of response.
389 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
391 return InterfaceKeywords._set_interface_properties(
392 node, interface, path, None)
395 def add_first_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
396 """Add the first IPv4 neighbour.
398 If there are any other neighbours configured, they will be removed.
400 :param node: Honeycomb node.
401 :param interface: The name of interface.
402 :param ip_addr: IPv4 address of neighbour to be set.
403 :param link_layer_address: Link layer address.
407 :type link_layer_address: str
408 :return: Content of response.
412 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
413 neighbor = {"neighbor": [{"ip": ip_addr,
414 "link-layer-address": link_layer_address}, ]}
415 return InterfaceKeywords._set_interface_properties(
416 node, interface, path, neighbor)
419 def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
420 """Add the IPv4 neighbour.
422 :param node: Honeycomb node.
423 :param interface: The name of interface.
424 :param ip_addr: IPv4 address of neighbour to be set.
425 :param link_layer_address: Link layer address.
429 :type link_layer_address: str
430 :return: Content of response.
434 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
436 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
437 return InterfaceKeywords._set_interface_properties(
438 node, interface, path, neighbor)
441 def remove_all_ipv4_neighbors(node, interface):
442 """Remove all IPv4 neighbours.
444 :param node: Honeycomb node.
445 :param interface: The name of interface.
448 :return: Content of response.
452 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
454 return InterfaceKeywords._set_interface_properties(
455 node, interface, path, None)
458 def configure_interface_ipv6(node, interface, param, value):
459 """Configure IPv6 parameters of interface
461 :param node: Honeycomb node.
462 :param interface: The name of interface.
463 :param param: Parameter to configure (set, change, remove)
464 :param value: The value of parameter. If None, the parameter will be
470 :return: Content of response.
472 :raises HoneycombError: If the parameter is not valid.
475 if param in InterfaceKeywords.IPV6_PARAMS:
476 path = ("interfaces", ("interface", "name", interface),
477 "ietf-ip:ipv6", param)
478 elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
479 path = ("interfaces", ("interface", "name", interface),
480 "ietf-ip:ipv6", "autoconf", param)
482 raise HoneycombError("The parameter {0} is invalid.".format(param))
484 return InterfaceKeywords._set_interface_properties(
485 node, interface, path, value)
488 def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
489 """Add the first IPv6 address.
491 If there are any other addresses configured, they will be removed.
493 :param node: Honeycomb node.
494 :param interface: The name of interface.
495 :param ip_addr: IPv6 address to be set.
496 :param prefix_len: Prefix length.
500 :type prefix_len: str
501 :return: Content of response.
505 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
506 address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
507 return InterfaceKeywords._set_interface_properties(
508 node, interface, path, address)
511 def add_ipv6_address(node, interface, ip_addr, prefix_len):
514 :param node: Honeycomb node.
515 :param interface: The name of interface.
516 :param ip_addr: IPv6 address to be set.
517 :param prefix_len: Prefix length.
521 :type prefix_len: str
522 :return: Content of response.
526 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
528 address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
529 return InterfaceKeywords._set_interface_properties(
530 node, interface, path, address)
533 def remove_all_ipv6_addresses(node, interface):
534 """Remove all IPv6 addresses from interface.
536 :param node: Honeycomb node.
537 :param interface: The name of interface.
540 :return: Content of response.
544 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
546 return InterfaceKeywords._set_interface_properties(
547 node, interface, path, None)
550 def add_first_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
551 """Add the first IPv6 neighbour.
553 If there are any other neighbours configured, they will be removed.
555 :param node: Honeycomb node.
556 :param interface: The name of interface.
557 :param ip_addr: IPv6 address of neighbour to be set.
558 :param link_layer_address: Link layer address.
562 :type link_layer_address: str
563 :return: Content of response.
567 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
568 neighbor = {"neighbor": [{"ip": ip_addr,
569 "link-layer-address": link_layer_address}, ]}
570 return InterfaceKeywords._set_interface_properties(
571 node, interface, path, neighbor)
574 def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
575 """Add the IPv6 neighbour.
577 :param node: Honeycomb node.
578 :param interface: The name of interface.
579 :param ip_addr: IPv6 address of neighbour to be set.
580 :param link_layer_address: Link layer address.
584 :type link_layer_address: str
585 :return: Content of response.
589 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
591 neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
592 return InterfaceKeywords._set_interface_properties(
593 node, interface, path, neighbor)
596 def remove_all_ipv6_neighbors(node, interface):
597 """Remove all IPv6 neighbours.
599 :param node: Honeycomb node.
600 :param interface: The name of interface.
603 :return: Content of response.
607 path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
609 return InterfaceKeywords._set_interface_properties(
610 node, interface, path, None)
613 def configure_interface_ethernet(node, interface, param, value):
614 """Configure the ethernet parameters of interface.
616 :param node: Honeycomb node.
617 :param interface: The name of interface.
618 :param param: Parameter to configure (set, change, remove)
619 :param value: The value of parameter. If None, the parameter will be
625 :return: Content of response.
627 :raises HoneycombError: If the parameter is not valid.
630 if param not in InterfaceKeywords.ETH_PARAMS:
631 raise HoneycombError("The parameter {0} is invalid.".format(param))
632 path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
634 return InterfaceKeywords._set_interface_properties(
635 node, interface, path, value)
638 def configure_interface_routing(node, interface, param, value):
639 """Configure the routing parameters of interface.
641 :param node: Honeycomb node.
642 :param interface: The name of interface.
643 :param param: Parameter to configure (set, change, remove)
644 :param value: The value of parameter. If None, the parameter will be
650 :return: Content of response.
652 :raises HoneycombError: If the parameter is not valid.
655 if param not in InterfaceKeywords.ROUTING_PARAMS:
656 raise HoneycombError("The parameter {0} is invalid.".format(param))
658 path = ("interfaces", ("interface", "name", interface), "v3po:routing",
660 return InterfaceKeywords._set_interface_properties(
661 node, interface, path, value)
664 def configure_interface_vxlan(node, interface, param, value):
665 """Configure the VxLAN parameters of interface.
667 :param node: Honeycomb node.
668 :param interface: The name of interface.
669 :param param: Parameter to configure (set, change, remove)
670 :param value: The value of parameter. If None, the parameter will be
676 :return: Content of response.
678 :raises HoneycombError: If the parameter is not valid.
681 if param not in InterfaceKeywords.VXLAN_PARAMS:
682 raise HoneycombError("The parameter {0} is invalid.".format(param))
684 path = ("interfaces", ("interface", "name", interface), "v3po:vxlan",
686 return InterfaceKeywords._set_interface_properties(
687 node, interface, path, value)
690 def configure_interface_l2(node, interface, param, value):
691 """Configure the L2 parameters of interface.
693 :param node: Honeycomb node.
694 :param interface: The name of interface.
695 :param param: Parameter to configure (set, change, remove)
696 :param value: The value of parameter. If None, the parameter will be
702 :return: Content of response.
704 :raises HoneycombError: If the parameter is not valid.
707 if param not in InterfaceKeywords.L2_PARAMS:
708 raise HoneycombError("The parameter {0} is invalid.".format(param))
709 path = ("interfaces", ("interface", "name", interface), "v3po:l2",
711 return InterfaceKeywords._set_interface_properties(
712 node, interface, path, value)