83267b5e55166234881e1c02d0b302c33d34eb0a
[csit.git] / resources / libraries / python / honeycomb / HcAPIKwInterfaces.py
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:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
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.
13
14 """Keywords to manipulate interface configuration using Honeycomb REST API.
15
16 The keywords make possible to put and get configuration data and to get
17 operational data.
18 """
19 from resources.libraries.python.topology import Topology
20 from resources.libraries.python.HTTPRequest import HTTPCodes
21 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
22 from resources.libraries.python.honeycomb.HoneycombUtil \
23     import DataRepresentation
24 from resources.libraries.python.honeycomb.HoneycombUtil \
25     import HoneycombUtil as HcUtil
26
27
28 # pylint: disable=too-many-public-methods
29 # pylint: disable=too-many-lines
30 class InterfaceKeywords(object):
31     """Keywords for Interface manipulation.
32
33     Implements keywords which get configuration and operational data about
34     vpp interfaces and set the interface's parameters using Honeycomb REST API.
35     """
36
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",
54                      "vlan-type",
55                      "enabled")
56     SUB_IF_MATCH = ("default",
57                     "untagged",
58                     "vlan-tagged",
59                     "vlan-tagged-exact-match")
60     BD_PARAMS = ("bridge-domain",
61                  "split-horizon-group",
62                  "bridged-virtual-interface")
63     VXLAN_GPE_PARAMS = ("local",
64                         "remote",
65                         "vni",
66                         "next-protocol",
67                         "encap-vrf-id",
68                         "decap-vrf-id")
69
70     def __init__(self):
71         pass
72
73     @staticmethod
74     def _configure_interface(node, interface, data,
75                              data_representation=DataRepresentation.JSON):
76         """Send interface configuration data and check the response.
77
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.
82         :type node: dict
83         :type interface: str
84         :type data: dict
85         :type data_representation: DataRepresentation
86         :return: Content of response.
87         :rtype: bytearray
88         :raises HoneycombError: If the status code in response on PUT is not
89         200 = OK.
90         """
91
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:
96             raise HoneycombError(
97                 "The configuration of interface '{0}' was not successful. "
98                 "Status code: {1}.".format(interface, status_code))
99         return resp
100
101     @staticmethod
102     def get_all_interfaces_cfg_data(node):
103         """Get configuration data about all interfaces from Honeycomb.
104
105         :param node: Honeycomb node.
106         :type node: dict
107         :return: Configuration data about all interfaces from Honeycomb.
108         :rtype: list
109         :raises HoneycombError: If it is not possible to get configuration data.
110         """
111
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))
118         try:
119             return resp["interfaces"]["interface"]
120
121         except (KeyError, TypeError):
122             return []
123
124     @staticmethod
125     def get_interface_cfg_data(node, interface):
126         """Get configuration data about the given interface from Honeycomb.
127
128         :param node: Honeycomb node.
129         :param interface: The name of interface.
130         :type node: dict
131         :type interface: str
132         :return: Configuration data about the given interface from Honeycomb.
133         :rtype: dict
134         """
135
136         intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
137         for intf in intfs:
138             if intf["name"] == interface:
139                 return intf
140         return {}
141
142     @staticmethod
143     def get_all_interfaces_oper_data(node):
144         """Get operational data about all interfaces from Honeycomb.
145
146         :param node: Honeycomb node.
147         :type node: dict
148         :return: Operational data about all interfaces from Honeycomb.
149         :rtype: list
150         :raises HoneycombError: If it is not possible to get operational data.
151         """
152
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))
159         try:
160             return resp["interfaces-state"]["interface"]
161
162         except (KeyError, TypeError):
163             return []
164
165     @staticmethod
166     def get_interface_oper_data(node, interface):
167         """Get operational data about the given interface from Honeycomb.
168
169         :param node: Honeycomb node.
170         :param interface: The name of interface.
171         :type node: dict
172         :type interface: str
173         :return: Operational data about the given interface from Honeycomb.
174         :rtype: dict
175         """
176
177         intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
178         for intf in intfs:
179             if intf["name"] == interface:
180                 return intf
181         return {}
182
183     @staticmethod
184     def _set_interface_properties(node, interface, path, new_value=None):
185         """Set interface properties.
186
187         This method reads interface configuration data, creates, changes or
188         removes the requested data and puts it back to Honeycomb.
189
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
194         removed.
195         :type node: dict
196         :type interface: str
197         :type path: tuple
198         :type new_value: str, dict or list
199         :return: Content of response.
200         :rtype: bytearray
201         :raises HoneycombError: If it is not possible to get or set the data.
202         """
203
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))
210
211         if new_value:
212             new_data = HcUtil.set_item_value(resp, path, new_value)
213         else:
214             new_data = HcUtil.remove_item(resp, path)
215         return InterfaceKeywords._configure_interface(node, interface, new_data)
216
217     @staticmethod
218     def set_interface_state(node, interface, state="up"):
219         """Set VPP interface state.
220
221         The keyword changes the administration state of interface to up or down
222         depending on the parameter "state".
223
224         :param node: Honeycomb node.
225         :param interface: Interface name, key, link name or sw_if_index.
226         :param state: The requested state, only "up" and "down" are valid
227         values.
228         :type node: dict
229         :type interface: str
230         :type state: str
231         :return: Content of response.
232         :rtype: bytearray
233         :raises KeyError: If the argument "state" is nor "up" or "down".
234         :raises HoneycombError: If the interface is not present on the node.
235         """
236
237         intf_state = {"up": "true",
238                       "down": "false"}
239
240         interface = Topology.convert_interface_reference(
241             node, interface, "name")
242
243         intf = interface.replace("/", "%2F")
244         path = "/interface/{0}".format(intf)
245
246         status_code, resp = HcUtil.\
247             get_honeycomb_data(node, "config_vpp_interfaces", path)
248         if status_code != HTTPCodes.OK:
249             raise HoneycombError(
250                 "Not possible to get configuration information about the "
251                 "interfaces. Status code: {0}.".format(status_code))
252
253         resp["interface"][0]["enabled"] = intf_state[state.lower()]
254
255         status_code, resp = HcUtil. \
256             put_honeycomb_data(node, "config_vpp_interfaces", resp, path,
257                                data_representation=DataRepresentation.JSON)
258         if status_code != HTTPCodes.OK:
259             raise HoneycombError(
260                 "The configuration of interface '{0}' was not successful. "
261                 "Status code: {1}.".format(interface, status_code))
262         return resp
263
264     @staticmethod
265     def set_interface_up(node, interface):
266         """Set the administration state of VPP interface to up.
267
268         :param node: Honeycomb node.
269         :param interface: The name of interface.
270         :type node: dict
271         :type interface: str
272         :return: Content of response
273         :rtype: bytearray
274         """
275
276         return InterfaceKeywords.set_interface_state(node, interface, "up")
277
278     @staticmethod
279     def set_interface_down(node, interface):
280         """Set the administration state of VPP interface to down.
281
282         :param node: Honeycomb node.
283         :param interface: The name of interface.
284         :type node: dict
285         :type interface: str
286         :return: Content of response.
287         :rtype: bytearray
288         """
289
290         return InterfaceKeywords.set_interface_state(node, interface, "down")
291
292     @staticmethod
293     def add_bridge_domain_to_interface(node, interface, bd_name,
294                                        split_horizon_group=None, bvi=None):
295         """Add a new bridge domain to an interface and set its parameters.
296
297         :param node: Honeycomb node.
298         :param interface: Interface name, key, link name or sw_if_index.
299         :param bd_name: Bridge domain name.
300         :param split_horizon_group: Split-horizon group name.
301         :param bvi: The bridged virtual interface.
302         :type node: dict
303         :type interface: str
304         :type bd_name: str
305         :type split_horizon_group: str
306         :type bvi: str
307         :return: Content of response.
308         :rtype: bytearray
309         :raises HoneycombError: If the interface is not present on the node.
310         """
311
312         interface = Topology.convert_interface_reference(
313             node, interface, "name")
314
315         v3po_l2 = {"bridge-domain": str(bd_name)}
316         if split_horizon_group:
317             v3po_l2["split-horizon-group"] = str(split_horizon_group)
318         if bvi:
319             v3po_l2["bridged-virtual-interface"] = str(bvi)
320
321         path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
322
323         return InterfaceKeywords._set_interface_properties(
324             node, interface, path, v3po_l2)
325
326     @staticmethod
327     def remove_bridge_domain_from_interface(node, interface):
328         """Remove bridge domain assignment from interface.
329
330         :param node: Honeycomb node.
331         :param interface: Interface name, key, link name or sw_if_index.
332         :type node: dict
333         :type interface: str or int
334
335         :raises HoneycombError: If the operation fails.
336         """
337
338         interface = Topology.convert_interface_reference(
339             node, interface, "name")
340
341         intf = interface.replace("/", "%2F")
342
343         path = "/interface/{0}/v3po:l2".format(intf)
344
345         status_code, _ = HcUtil.delete_honeycomb_data(
346             node, "config_vpp_interfaces", path)
347
348         if status_code != HTTPCodes.OK:
349             raise HoneycombError(
350                 "Could not remove bridge domain assignment from interface "
351                 "'{0}'. Status code: {1}.".format(interface, status_code))
352
353     @staticmethod
354     def get_bd_oper_data_from_interface(node, interface):
355         """Returns operational data about bridge domain settings in the
356         interface.
357
358         :param node: Honeycomb node.
359         :param interface: The name of interface.
360         :type node: dict
361         :type interface: str
362         :return: Operational data about bridge domain settings in the
363         interface.
364         :rtype: dict
365         """
366
367         if_data = InterfaceKeywords.get_interface_oper_data(node, interface)
368
369         if if_data:
370             try:
371                 return if_data["v3po:l2"]
372             except KeyError:
373                 return {}
374         return {}
375
376     @staticmethod
377     def configure_interface_base(node, interface, param, value):
378         """Configure the base parameters of interface.
379
380         :param node: Honeycomb node.
381         :param interface: The name of interface.
382         :param param: Parameter to configure (set, change, remove)
383         :param value: The value of parameter. If None, the parameter will be
384         removed.
385         :type node: dict
386         :type interface: str
387         :type param: str
388         :type value: str
389         :return: Content of response.
390         :rtype: bytearray
391         :raises HoneycombError: If the parameter is not valid.
392         """
393
394         if param not in InterfaceKeywords.INTF_PARAMS:
395             raise HoneycombError("The parameter {0} is invalid.".format(param))
396
397         path = ("interfaces", ("interface", "name", interface), param)
398         return InterfaceKeywords._set_interface_properties(
399             node, interface, path, value)
400
401     @staticmethod
402     def configure_interface_ipv4(node, interface, param, value):
403         """Configure IPv4 parameters of interface.
404
405         :param node: Honeycomb node.
406         :param interface: The name of interface.
407         :param param: Parameter to configure (set, change, remove)
408         :param value: The value of parameter. If None, the parameter will be
409         removed.
410         :type node: dict
411         :type interface: str
412         :type param: str
413         :type value: str
414         :return: Content of response.
415         :rtype: bytearray
416         :raises HoneycombError: If the parameter is not valid.
417         """
418
419         interface = Topology.convert_interface_reference(
420             node, interface, "name")
421
422         if param not in InterfaceKeywords.IPV4_PARAMS:
423             raise HoneycombError("The parameter {0} is invalid.".format(param))
424
425         path = ("interfaces", ("interface", "name", interface),
426                 "ietf-ip:ipv4", param)
427         return InterfaceKeywords._set_interface_properties(
428             node, interface, path, value)
429
430     @staticmethod
431     def add_first_ipv4_address(node, interface, ip_addr, network):
432         """Add the first IPv4 address.
433
434         If there are any other addresses configured, they will be removed.
435
436         :param node: Honeycomb node.
437         :param interface: The name of interface.
438         :param ip_addr: IPv4 address to be set.
439         :param network: Netmask or length of network prefix.
440         :type node: dict
441         :type interface: str
442         :type ip_addr: str
443         :type network: str or int
444         :return: Content of response.
445         :rtype: bytearray
446         :raises HoneycombError: If the provided netmask or prefix is not valid.
447         """
448
449         interface = Topology.convert_interface_reference(
450             node, interface, "name")
451
452         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
453         if isinstance(network, basestring):
454             address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
455         elif isinstance(network, int) and (0 < network < 33):
456             address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
457         else:
458             raise HoneycombError("Value {0} is not a valid netmask or network "
459                                  "prefix length.".format(network))
460         return InterfaceKeywords._set_interface_properties(
461             node, interface, path, address)
462
463     @staticmethod
464     def add_ipv4_address(node, interface, ip_addr, network):
465         """Add IPv4 address.
466
467         :param node: Honeycomb node.
468         :param interface: The name of interface.
469         :param ip_addr: IPv4 address to be set.
470         :param network: Netmask or length of network prefix.
471         :type node: dict
472         :type interface: str
473         :type ip_addr: str
474         :type network: str or int
475         :return: Content of response.
476         :rtype: bytearray
477         :raises HoneycombError: If the provided netmask or prefix is not valid.
478         """
479
480         interface = Topology.convert_interface_reference(
481             node, interface, "name")
482
483         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
484                 "address")
485         if isinstance(network, basestring):
486             address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
487         elif isinstance(network, int) and (0 < network < 33):
488             address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
489         else:
490             raise HoneycombError("Value {0} is not a valid netmask or network "
491                                  "prefix length.".format(network))
492         return InterfaceKeywords._set_interface_properties(
493             node, interface, path, address)
494
495     @staticmethod
496     def remove_all_ipv4_addresses(node, interface):
497         """Remove all IPv4 addresses from interface.
498
499         :param node: Honeycomb node.
500         :param interface: The name of interface.
501         :type node: dict
502         :type interface: str
503         :return: Content of response.
504         :rtype: bytearray
505         """
506
507         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
508                 "address")
509         return InterfaceKeywords._set_interface_properties(
510             node, interface, path, None)
511
512     @staticmethod
513     def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
514         """Add the IPv4 neighbour.
515
516         :param node: Honeycomb node.
517         :param interface: The name of interface.
518         :param ip_addr: IPv4 address of neighbour to be set.
519         :param link_layer_address: Link layer address.
520         :type node: dict
521         :type interface: str
522         :type ip_addr: str
523         :type link_layer_address: str
524         :return: Content of response.
525         :rtype: bytearray
526         """
527
528         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
529                 "neighbor")
530         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
531         return InterfaceKeywords._set_interface_properties(
532             node, interface, path, neighbor)
533
534     @staticmethod
535     def remove_all_ipv4_neighbors(node, interface):
536         """Remove all IPv4 neighbours.
537
538         :param node: Honeycomb node.
539         :param interface: The name of interface.
540         :type node: dict
541         :type interface: str
542         :return: Content of response.
543         :rtype: bytearray
544         """
545
546         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
547                 "neighbor")
548         return InterfaceKeywords._set_interface_properties(
549             node, interface, path, None)
550
551     @staticmethod
552     def configure_interface_ipv6(node, interface, param, value):
553         """Configure IPv6 parameters of interface
554
555         :param node: Honeycomb node.
556         :param interface: The name of interface.
557         :param param: Parameter to configure (set, change, remove)
558         :param value: The value of parameter. If None, the parameter will be
559         removed.
560         :type node: dict
561         :type interface: str
562         :type param: str
563         :type value: str
564         :return: Content of response.
565         :rtype: bytearray
566         :raises HoneycombError: If the parameter is not valid.
567         """
568
569         if param in InterfaceKeywords.IPV6_PARAMS:
570             path = ("interfaces", ("interface", "name", interface),
571                     "ietf-ip:ipv6", param)
572         elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
573             path = ("interfaces", ("interface", "name", interface),
574                     "ietf-ip:ipv6", "autoconf", param)
575         else:
576             raise HoneycombError("The parameter {0} is invalid.".format(param))
577
578         return InterfaceKeywords._set_interface_properties(
579             node, interface, path, value)
580
581     @staticmethod
582     def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
583         """Add the first IPv6 address.
584
585         If there are any other addresses configured, they will be removed.
586
587         :param node: Honeycomb node.
588         :param interface: The name of interface.
589         :param ip_addr: IPv6 address to be set.
590         :param prefix_len: Prefix length.
591         :type node: dict
592         :type interface: str
593         :type ip_addr: str
594         :type prefix_len: str
595         :return: Content of response.
596         :rtype: bytearray
597         """
598
599         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
600         address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
601         return InterfaceKeywords._set_interface_properties(
602             node, interface, path, address)
603
604     @staticmethod
605     def add_ipv6_address(node, interface, ip_addr, prefix_len):
606         """Add IPv6 address.
607
608         :param node: Honeycomb node.
609         :param interface: The name of interface.
610         :param ip_addr: IPv6 address to be set.
611         :param prefix_len: Prefix length.
612         :type node: dict
613         :type interface: str
614         :type ip_addr: str
615         :type prefix_len: str
616         :return: Content of response.
617         :rtype: bytearray
618         """
619
620         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
621                 "address")
622         address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
623         return InterfaceKeywords._set_interface_properties(
624             node, interface, path, address)
625
626     @staticmethod
627     def remove_all_ipv6_addresses(node, interface):
628         """Remove all IPv6 addresses from interface.
629
630         :param node: Honeycomb node.
631         :param interface: The name of interface.
632         :type node: dict
633         :type interface: str
634         :return: Content of response.
635         :rtype: bytearray
636         """
637
638         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
639                 "address")
640         return InterfaceKeywords._set_interface_properties(
641             node, interface, path, None)
642
643     @staticmethod
644     def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
645         """Add the IPv6 neighbour.
646
647         :param node: Honeycomb node.
648         :param interface: The name of interface.
649         :param ip_addr: IPv6 address of neighbour to be set.
650         :param link_layer_address: Link layer address.
651         :type node: dict
652         :type interface: str
653         :type ip_addr: str
654         :type link_layer_address: str
655         :return: Content of response.
656         :rtype: bytearray
657         """
658
659         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
660                 "neighbor")
661         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
662         return InterfaceKeywords._set_interface_properties(
663             node, interface, path, neighbor)
664
665     @staticmethod
666     def remove_all_ipv6_neighbors(node, interface):
667         """Remove all IPv6 neighbours.
668
669         :param node: Honeycomb node.
670         :param interface: The name of interface.
671         :type node: dict
672         :type interface: str
673         :return: Content of response.
674         :rtype: bytearray
675         """
676
677         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
678                 "neighbor")
679         return InterfaceKeywords._set_interface_properties(
680             node, interface, path, None)
681
682     @staticmethod
683     def configure_interface_ethernet(node, interface, param, value):
684         """Configure the ethernet parameters of interface.
685
686         :param node: Honeycomb node.
687         :param interface: The name of interface.
688         :param param: Parameter to configure (set, change, remove)
689         :param value: The value of parameter. If None, the parameter will be
690         removed.
691         :type node: dict
692         :type interface: str
693         :type param: str
694         :type value: str
695         :return: Content of response.
696         :rtype: bytearray
697         :raises HoneycombError: If the parameter is not valid.
698         """
699
700         if param not in InterfaceKeywords.ETH_PARAMS:
701             raise HoneycombError("The parameter {0} is invalid.".format(param))
702         path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
703                 param)
704         return InterfaceKeywords._set_interface_properties(
705             node, interface, path, value)
706
707     @staticmethod
708     def configure_interface_routing(node, interface, param, value):
709         """Configure the routing parameters of interface.
710
711         :param node: Honeycomb node.
712         :param interface: The name of interface.
713         :param param: Parameter to configure (set, change, remove)
714         :param value: The value of parameter. If None, the parameter will be
715         removed.
716         :type node: dict
717         :type interface: str
718         :type param: str
719         :type value: str
720         :return: Content of response.
721         :rtype: bytearray
722         :raises HoneycombError: If the parameter is not valid.
723         """
724
725         if param not in InterfaceKeywords.ROUTING_PARAMS:
726             raise HoneycombError("The parameter {0} is invalid.".format(param))
727
728         path = ("interfaces", ("interface", "name", interface), "v3po:routing",
729                 param)
730         return InterfaceKeywords._set_interface_properties(
731             node, interface, path, value)
732
733     @staticmethod
734     def create_vxlan_interface(node, interface, **kwargs):
735         """Create a new VxLAN interface.
736
737         :param node: Honeycomb node.
738         :param interface: The name of interface.
739         :param kwargs: Parameters and their values. The accepted parameters are
740         defined in InterfaceKeywords.VXLAN_PARAMS.
741         :type node: dict
742         :type interface: str
743         :type kwargs: dict
744         :return: Content of response.
745         :rtype: bytearray
746         :raises HoneycombError: If the parameter is not valid.
747         """
748
749         new_vx_lan = {
750             "name": interface,
751             "type": "v3po:vxlan-tunnel",
752             "v3po:vxlan": {}
753         }
754         for param, value in kwargs.items():
755             if param not in InterfaceKeywords.VXLAN_PARAMS:
756                 raise HoneycombError("The parameter {0} is invalid.".
757                                      format(param))
758             new_vx_lan["v3po:vxlan"][param] = value
759
760         path = ("interfaces", "interface")
761         vx_lan_structure = [new_vx_lan, ]
762         return InterfaceKeywords._set_interface_properties(
763             node, interface, path, vx_lan_structure)
764
765     @staticmethod
766     def delete_interface(node, interface):
767         """Delete an interface.
768
769         :param node: Honeycomb node.
770         :param interface: The name of interface.
771         :type node: dict
772         :type interface: str
773         :return: Content of response.
774         :rtype: bytearray
775         :raises HoneycombError: If it is not possible to get information about
776         interfaces or it is not possible to delete the interface.
777         """
778
779         path = ("interfaces", ("interface", "name", interface))
780
781         status_code, resp = HcUtil.\
782             get_honeycomb_data(node, "config_vpp_interfaces")
783         if status_code != HTTPCodes.OK:
784             raise HoneycombError(
785                 "Not possible to get configuration information about the "
786                 "interfaces. Status code: {0}.".format(status_code))
787
788         new_data = HcUtil.remove_item(resp, path)
789         status_code, resp = HcUtil.\
790             put_honeycomb_data(node, "config_vpp_interfaces", new_data)
791         if status_code != HTTPCodes.OK:
792             raise HoneycombError("Not possible to remove interface {0}. "
793                                  "Status code: {1}.".
794                                  format(interface, status_code))
795         return resp
796
797     @staticmethod
798     def configure_interface_vxlan(node, interface, **kwargs):
799         """Configure VxLAN on the interface.
800
801         The keyword configures VxLAN parameters on the given interface. The type
802         of interface must be set to "v3po:vxlan-tunnel".
803         The new VxLAN parameters overwrite the current configuration. If a
804         parameter in new configuration is missing, it is removed from VxLAN
805         configuration.
806         If the dictionary kwargs is empty, VxLAN configuration is removed.
807
808         :param node: Honeycomb node.
809         :param interface: The name of interface.
810         :param kwargs: Parameters and their values. The accepted parameters are
811         defined in InterfaceKeywords.VXLAN_PARAMS.
812         :type node: dict
813         :type interface: str
814         :type kwargs: dict
815         :return: Content of response.
816         :rtype: bytearray
817         :raises HoneycombError: If the parameter is not valid.
818         """
819
820         vx_lan_structure = dict()
821         for param, value in kwargs.items():
822             if param not in InterfaceKeywords.VXLAN_PARAMS:
823                 raise HoneycombError("The parameter {0} is invalid.".
824                                      format(param))
825             vx_lan_structure[param] = value
826
827         path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
828         return InterfaceKeywords._set_interface_properties(
829             node, interface, path, vx_lan_structure)
830
831     @staticmethod
832     def configure_interface_l2(node, interface, param, value):
833         """Configure the L2 parameters of interface.
834
835         :param node: Honeycomb node.
836         :param interface: The name of interface.
837         :param param: Parameter to configure (set, change, remove)
838         :param value: The value of parameter. If None, the parameter will be
839         removed.
840         :type node: dict
841         :type interface: str
842         :type param: str
843         :type value: str
844         :return: Content of response.
845         :rtype: bytearray
846         :raises HoneycombError: If the parameter is not valid.
847         """
848
849         if param not in InterfaceKeywords.L2_PARAMS:
850             raise HoneycombError("The parameter {0} is invalid.".format(param))
851         path = ("interfaces", ("interface", "name", interface), "v3po:l2",
852                 param)
853         return InterfaceKeywords._set_interface_properties(
854             node, interface, path, value)
855
856     @staticmethod
857     def create_tap_interface(node, interface, **kwargs):
858         """Create a new TAP interface.
859
860         :param node: Honeycomb node.
861         :param interface: The name of interface.
862         :param kwargs: Parameters and their values. The accepted parameters are
863         defined in InterfaceKeywords.TAP_PARAMS.
864         :type node: dict
865         :type interface: str
866         :type kwargs: dict
867         :return: Content of response.
868         :rtype: bytearray
869         :raises HoneycombError: If the parameter is not valid.
870         """
871
872         new_tap = {
873             "name": interface,
874             "type": "v3po:tap",
875             "v3po:tap": {}
876         }
877         for param, value in kwargs.items():
878             if param not in InterfaceKeywords.TAP_PARAMS:
879                 raise HoneycombError("The parameter {0} is invalid.".
880                                      format(param))
881             new_tap["v3po:tap"][param] = value
882
883         path = ("interfaces", "interface")
884         new_tap_structure = [new_tap, ]
885         return InterfaceKeywords._set_interface_properties(
886             node, interface, path, new_tap_structure)
887
888     @staticmethod
889     def configure_interface_tap(node, interface, **kwargs):
890         """Configure TAP on the interface.
891
892         The keyword configures TAP parameters on the given interface. The type
893         of interface must be set to "v3po:tap".
894         The new TAP parameters overwrite the current configuration. If a
895         parameter in new configuration is missing, it is removed from TAP
896         configuration.
897         If the dictionary kwargs is empty, TAP configuration is removed.
898
899         :param node: Honeycomb node.
900         :param interface: The name of interface.
901         :param kwargs: Parameters and their values. The accepted parameters are
902         defined in InterfaceKeywords.TAP_PARAMS.
903         :type node: dict
904         :type interface: str
905         :type kwargs: dict
906         :return: Content of response.
907         :rtype: bytearray
908         :raises HoneycombError: If the parameter is not valid.
909         """
910
911         tap_structure = dict()
912         for param, value in kwargs.items():
913             if param not in InterfaceKeywords.TAP_PARAMS:
914                 raise HoneycombError("The parameter {0} is invalid.".
915                                      format(param))
916             tap_structure[param] = value
917
918         path = ("interfaces", ("interface", "name", interface), "v3po:tap")
919         return InterfaceKeywords._set_interface_properties(
920             node, interface, path, tap_structure)
921
922     @staticmethod
923     def configure_interface_vhost_user(node, interface, **kwargs):
924         """Configure vhost-user on the interface.
925
926         The keyword configures vhost-user parameters on the given interface.
927         The type of interface must be set to "v3po:vhost-user".
928         The new vhost-user parameters overwrite the current configuration. If a
929         parameter in new configuration is missing, it is removed from vhost-user
930         configuration.
931         If the dictionary kwargs is empty, vhost-user configuration is removed.
932
933         :param node: Honeycomb node.
934         :param interface: The name of interface.
935         :param kwargs: Parameters and their values. The accepted parameters are
936         defined in InterfaceKeywords.VHOST_USER_PARAMS.
937         :type node: dict
938         :type interface: str
939         :type kwargs: dict
940         :return: Content of response.
941         :rtype: bytearray
942         :raises HoneycombError: If the parameter is not valid.
943         """
944
945         vhost_structure = dict()
946         for param, value in kwargs.items():
947             if param not in InterfaceKeywords.VHOST_USER_PARAMS:
948                 raise HoneycombError("The parameter {0} is invalid.".
949                                      format(param))
950             vhost_structure[param] = value
951
952         path = ("interfaces", ("interface", "name", interface),
953                 "v3po:vhost-user")
954         return InterfaceKeywords._set_interface_properties(
955             node, interface, path, vhost_structure)
956
957     @staticmethod
958     def create_vhost_user_interface(node, interface, **kwargs):
959         """Create a new vhost-user interface.
960
961         :param node: Honeycomb node.
962         :param interface: The name of interface.
963         :param kwargs: Parameters and their values. The accepted parameters are
964         defined in InterfaceKeywords.VHOST_USER_PARAMS.
965         :type node: dict
966         :type interface: str
967         :type kwargs: dict
968         :return: Content of response.
969         :rtype: bytearray
970         :raises HoneycombError: If the parameter is not valid.
971         """
972
973         new_vhost = {
974             "name": interface,
975             "type": "v3po:vhost-user",
976             "v3po:vhost-user": {}
977         }
978         for param, value in kwargs.items():
979             if param not in InterfaceKeywords.VHOST_USER_PARAMS:
980                 raise HoneycombError("The parameter {0} is invalid.".
981                                      format(param))
982             new_vhost["v3po:vhost-user"][param] = value
983
984         path = ("interfaces", "interface")
985         new_vhost_structure = [new_vhost, ]
986         return InterfaceKeywords._set_interface_properties(
987             node, interface, path, new_vhost_structure)
988
989     @staticmethod
990     def create_sub_interface(node, super_interface, match, tags=None, **kwargs):
991         """Create a new sub-interface.
992
993         :param node: Honeycomb node.
994         :param super_interface: Super interface.
995         :param match: Match type. The valid values are defined in
996         InterfaceKeywords.SUB_IF_MATCH.
997         :param tags: List of tags.
998         :param kwargs: Parameters and their values. The accepted parameters are
999         defined in InterfaceKeywords.SUB_IF_PARAMS.
1000         :type node: dict
1001         :type super_interface: str
1002         :type match: str
1003         :type tags: list
1004         :type kwargs: dict
1005         :return: Content of response.
1006         :rtype: bytearray
1007         :raises HoneycombError: If the parameter is not valid.
1008         :raises KeyError: If the parameter 'match' is invalid.
1009         """
1010
1011         match_type = {
1012             "default":
1013                 {"default": {}},
1014             "untagged":
1015                 {"untagged": {}},
1016             "vlan-tagged":
1017                 {"vlan-tagged": {"match-exact-tags": "false"}},
1018             "vlan-tagged-exact-match":
1019                 {"vlan-tagged": {"match-exact-tags": "true"}}
1020         }
1021
1022         new_sub_interface = {
1023             "tags": {
1024                 "tag": []
1025             },
1026         }
1027
1028         for param, value in kwargs.items():
1029             if param in InterfaceKeywords.SUB_IF_PARAMS:
1030                 new_sub_interface[param] = value
1031             else:
1032                 raise HoneycombError("The parameter {0} is invalid.".
1033                                      format(param))
1034         try:
1035             new_sub_interface["match"] = match_type[match]
1036         except KeyError:
1037             raise HoneycombError("The value '{0}' of parameter 'match' is "
1038                                  "invalid.".format(match))
1039
1040         if tags:
1041             new_sub_interface["tags"]["tag"].extend(tags)
1042
1043         path = ("interfaces",
1044                 ("interface", "name", super_interface),
1045                 "vpp-vlan:sub-interfaces",
1046                 "sub-interface")
1047         new_sub_interface_structure = [new_sub_interface, ]
1048         return InterfaceKeywords._set_interface_properties(
1049             node, super_interface, path, new_sub_interface_structure)
1050
1051     @staticmethod
1052     def get_sub_interface_oper_data(node, super_interface, identifier):
1053         """Retrieves sub-interface operational data using Honeycomb API.
1054
1055         :param node: Honeycomb node.
1056         :param super_interface: Super interface.
1057         :param identifier: The ID of sub-interface.
1058         :type node: dict
1059         :type super_interface: str
1060         :type identifier: int
1061         :return: Sub-interface operational data.
1062         :rtype: dict
1063         :raises HoneycombError: If there is no sub-interface with the given ID.
1064         """
1065
1066         if_data = InterfaceKeywords.get_interface_oper_data(node,
1067                                                             super_interface)
1068         for sub_if in if_data["vpp-vlan:sub-interfaces"]["sub-interface"]:
1069             if str(sub_if["identifier"]) == str(identifier):
1070                 return sub_if
1071
1072         raise HoneycombError("The interface {0} does not have sub-interface "
1073                              "with ID {1}".format(super_interface, identifier))
1074
1075     @staticmethod
1076     def remove_all_sub_interfaces(node, super_interface):
1077         """Remove all sub-interfaces from the given interface.
1078
1079         :param node: Honeycomb node.
1080         :param super_interface: Super interface.
1081         :type node: dict
1082         :type super_interface: str
1083         :return: Content of response.
1084         :rtype: bytearray
1085         """
1086
1087         path = ("interfaces",
1088                 ("interface", "name", super_interface),
1089                 "vpp-vlan:sub-interfaces")
1090
1091         return InterfaceKeywords._set_interface_properties(
1092             node, super_interface, path, {})
1093
1094     @staticmethod
1095     def set_sub_interface_state(node, super_interface, identifier, state):
1096         """Set the administrative state of sub-interface.
1097
1098         :param node: Honeycomb node.
1099         :param super_interface: Super interface.
1100         :param identifier: The ID of sub-interface.
1101         :param state: Required sub-interface state - up or down.
1102         :type node: dict
1103         :type super_interface: str
1104         :type identifier: int
1105         :type state: str
1106         :return: Content of response.
1107         :rtype: bytearray
1108         """
1109
1110         intf_state = {"up": "true",
1111                       "down": "false"}
1112
1113         path = ("interfaces",
1114                 ("interface", "name", super_interface),
1115                 "vpp-vlan:sub-interfaces",
1116                 ("sub-interface", "identifier", identifier),
1117                 "enabled")
1118
1119         return InterfaceKeywords._set_interface_properties(
1120             node, super_interface, path, intf_state[state])
1121
1122     @staticmethod
1123     def add_bridge_domain_to_sub_interface(node, super_interface, identifier,
1124                                            config):
1125         """Add a sub-interface to a bridge domain and set its parameters.
1126
1127         :param node: Honeycomb node.
1128         :param super_interface: Super interface.
1129         :param identifier: The ID of sub-interface.
1130         :param config: Bridge domain configuration.
1131         :type node: dict
1132         :type super_interface: str
1133         :type identifier: int
1134         :type config: dict
1135         :return: Content of response.
1136         :rtype: bytearray
1137         """
1138
1139         path = ("interfaces",
1140                 ("interface", "name", super_interface),
1141                 "vpp-vlan:sub-interfaces",
1142                 ("sub-interface", "identifier", int(identifier)),
1143                 "l2")
1144
1145         return InterfaceKeywords._set_interface_properties(
1146             node, super_interface, path, config)
1147
1148     @staticmethod
1149     def get_bd_data_from_sub_interface(node, super_interface, identifier):
1150         """Get the operational data about the bridge domain from sub-interface.
1151
1152         :param node: Honeycomb node.
1153         :param super_interface: Super interface.
1154         :param identifier: The ID of sub-interface.
1155         :type node: dict
1156         :type super_interface: str
1157         :type identifier: int
1158         :return: Operational data about the bridge domain.
1159         :rtype: dict
1160         :raises HoneycombError: If there is no sub-interface with the given ID.
1161         """
1162
1163         try:
1164             bd_data = InterfaceKeywords.get_sub_interface_oper_data(
1165                 node, super_interface, identifier)["l2"]
1166             return bd_data
1167         except KeyError:
1168             raise HoneycombError("The operational data does not contain "
1169                                  "information about a bridge domain.")
1170
1171     @staticmethod
1172     def configure_tag_rewrite(node, super_interface, identifier, config):
1173         """Add / change / disable vlan tag rewrite on a sub-interface.
1174
1175         :param node: Honeycomb node.
1176         :param super_interface: Super interface.
1177         :param identifier: The ID of sub-interface.
1178         :param config: Rewrite tag configuration.
1179         :type node: dict
1180         :type super_interface: str
1181         :type identifier: int
1182         :type config: dict
1183         :return: Content of response.
1184         :rtype: bytearray
1185         """
1186
1187         path = ("interfaces",
1188                 ("interface", "name", super_interface),
1189                 "vpp-vlan:sub-interfaces",
1190                 ("sub-interface", "identifier", int(identifier)),
1191                 "l2",
1192                 "rewrite")
1193
1194         return InterfaceKeywords._set_interface_properties(
1195             node, super_interface, path, config)
1196
1197     @staticmethod
1198     def get_tag_rewrite_oper_data(node, super_interface, identifier):
1199         """Get the operational data about tag rewrite.
1200
1201         :param node: Honeycomb node.
1202         :param super_interface: Super interface.
1203         :param identifier: The ID of sub-interface.
1204         :type node: dict
1205         :type super_interface: str
1206         :type identifier: int
1207         :return: Operational data about tag rewrite.
1208         :rtype: dict
1209         :raises HoneycombError: If there is no sub-interface with the given ID.
1210         """
1211
1212         try:
1213             tag_rewrite = InterfaceKeywords.get_sub_interface_oper_data(
1214                 node, super_interface, identifier)["l2"]["rewrite"]
1215             return tag_rewrite
1216         except KeyError:
1217             raise HoneycombError("The operational data does not contain "
1218                                  "information about the tag-rewrite.")
1219
1220     @staticmethod
1221     def add_ipv4_address_to_sub_interface(node, super_interface, identifier,
1222                                           ip_addr, network):
1223         """Add an ipv4 address to the specified sub-interface, with the provided
1224         netmask or network prefix length. Any existing ipv4 addresses on the
1225         sub-interface will be replaced.
1226
1227         :param node: Honeycomb node.
1228         :param super_interface: Super interface.
1229         :param identifier: The ID of sub-interface.
1230         :param ip_addr: IPv4 address to be set.
1231         :param network: Network mask or network prefix length.
1232         :type node: dict
1233         :type super_interface: str
1234         :type identifier: int
1235         :type ip_addr: str
1236         :type network: str or int
1237         :return: Content of response.
1238         :rtype: bytearray
1239         :raises HoneycombError: If the provided netmask or prefix is not valid.
1240         """
1241
1242         path = ("interfaces",
1243                 ("interface", "name", super_interface),
1244                 "vpp-vlan:sub-interfaces",
1245                 ("sub-interface", "identifier", int(identifier)),
1246                 "ipv4")
1247
1248         if isinstance(network, basestring):
1249             address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
1250
1251         elif isinstance(network, int) and 0 < network < 33:
1252             address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
1253
1254         else:
1255             raise HoneycombError("{0} is not a valid netmask or prefix length."
1256                                  .format(network))
1257
1258         return InterfaceKeywords._set_interface_properties(
1259             node, super_interface, path, address)
1260
1261     @staticmethod
1262     def remove_all_ipv4_addresses_from_sub_interface(node, super_interface, # pylint: disable=invalid-name
1263                                                      identifier):
1264         """Remove all ipv4 addresses from the specified sub-interface.
1265
1266         :param node: Honeycomb node.
1267         :param super_interface: Super interface.
1268         :param identifier: The ID of sub-interface.
1269         :type node: dict
1270         :type super_interface: str
1271         :type identifier: int
1272         :return: Content of response.
1273         :rtype: bytearray
1274         """
1275
1276         path = ("interfaces",
1277                 ("interface", "name", super_interface),
1278                 "vpp-vlan:sub-interfaces",
1279                 ("sub-interface", "identifier", int(identifier)),
1280                 "ipv4", "address")
1281
1282         return InterfaceKeywords._set_interface_properties(
1283             node, super_interface, path, None)
1284
1285     @staticmethod
1286     def compare_data_structures(data, ref, ignore=()):
1287         """Checks if data obtained from UUT is as expected.
1288
1289         :param data: Data to be checked.
1290         :param ref: Referential data used for comparison.
1291         :param ignore: Dictionary keys to be ignored.
1292         :type data: dict
1293         :type ref: dict
1294         :type ignore: iterable
1295         :raises HoneycombError: If a parameter from referential data is not
1296         present in operational data or if it has different value.
1297         """
1298
1299         errors = ""
1300
1301         for key, item in ref.items():
1302             if key in ignore:
1303                 continue
1304             try:
1305                 if data[key] != item:
1306                     errors += ("\nThe value of parameter '{0}' is "
1307                                "incorrect. It should be "
1308                                "'{1}' but it is '{2}'".
1309                                format(key, item, data[key]))
1310             except KeyError:
1311                 errors += ("\nThe parameter '{0}' is not present in "
1312                            "operational data".format(key))
1313
1314         if errors:
1315             raise HoneycombError(errors)
1316
1317     @staticmethod
1318     def compare_interface_lists(list1, list2):
1319         """Compare provided lists of interfaces by name.
1320
1321         :param list1: List of interfaces.
1322         :param list2: List of interfaces.
1323         :type list1: list
1324         :type list2: list
1325         :raises HoneycombError: If an interface exists in only one of the lists.
1326         """
1327
1328         ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1329         # these have no equivalent in config data and no effect on VPP
1330
1331         names1 = [x['name'] for x in list1]
1332         names2 = [x['name'] for x in list2]
1333
1334         for name in names1:
1335             if name not in names2 and name not in ignore:
1336                 raise HoneycombError("Interface {0} not present in list {1}"
1337                                      .format(name, list2))
1338         for name in names2:
1339             if name not in names1 and name not in ignore:
1340                 raise HoneycombError("Interface {0} not present in list {1}"
1341                                      .format(name, list1))
1342
1343     @staticmethod
1344     def create_vxlan_gpe_interface(node, interface, **kwargs):
1345         """Create a new VxLAN GPE interface.
1346
1347         :param node: Honeycomb node.
1348         :param interface: The name of interface to be created.
1349         :param kwargs: Parameters and their values. The accepted parameters are
1350         defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1351         :type node: dict
1352         :type interface: str
1353         :type kwargs: dict
1354         :return: Content of response.
1355         :rtype: bytearray
1356         :raises HoneycombError: If a parameter in kwargs is not valid.
1357         """
1358
1359         new_vxlan_gpe = {
1360             "name": interface,
1361             "type": "v3po:vxlan-gpe-tunnel",
1362             "v3po:vxlan-gpe": {}
1363         }
1364         for param, value in kwargs.items():
1365             if param in InterfaceKeywords.INTF_PARAMS:
1366                 new_vxlan_gpe[param] = value
1367             elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1368                 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1369             else:
1370                 raise HoneycombError("The parameter {0} is invalid.".
1371                                      format(param))
1372         path = ("interfaces", "interface")
1373         vxlan_gpe_structure = [new_vxlan_gpe, ]
1374         return InterfaceKeywords._set_interface_properties(
1375             node, interface, path, vxlan_gpe_structure)
1376
1377     @staticmethod
1378     def enable_acl_on_interface(node, interface, table_name):
1379         """Enable ACL on the given interface.
1380
1381         :param node: Honeycomb node.
1382         :param interface: The interface where the ACL will be enabled.
1383         :param table_name: Name of the classify table.
1384         :type node: dict
1385         :type interface: str
1386         :type table_name: str
1387         :return: Content of response.
1388         :rtype: bytearray
1389         :raises HoneycombError: If the configuration of interface is not
1390         successful.
1391         """
1392
1393         interface = interface.replace("/", "%2F")
1394
1395         data = {
1396             "v3po:acl": {
1397                 "l2-acl": {
1398                     "classify-table": table_name
1399                 },
1400                 "ip4-acl": {
1401                     "classify-table": table_name
1402                 }
1403             }
1404         }
1405
1406         path = "/interface/" + interface + "/v3po:acl"
1407         status_code, resp = HcUtil.\
1408             put_honeycomb_data(node, "config_vpp_interfaces", data, path,
1409                                data_representation=DataRepresentation.JSON)
1410         if status_code != HTTPCodes.OK:
1411             raise HoneycombError(
1412                 "The configuration of interface '{0}' was not successful. "
1413                 "Status code: {1}.".format(interface, status_code))
1414         return resp
1415
1416     @staticmethod
1417     def disable_acl_on_interface(node, interface):
1418         """Disable ACL on the given interface.
1419
1420         :param node: Honeycomb node.
1421         :param interface: The interface where the ACL will be disabled.
1422         :type node: dict
1423         :type interface: str
1424         :return: Content of response.
1425         :rtype: bytearray
1426         :raises HoneycombError: If the configuration of interface is not
1427         successful.
1428         """
1429
1430         interface = interface.replace("/", "%2F")
1431
1432         path = "/interface/" + interface + "/v3po:acl"
1433
1434         status_code, resp = HcUtil.\
1435             delete_honeycomb_data(node, "config_vpp_interfaces", path)
1436
1437         if status_code != HTTPCodes.OK:
1438             raise HoneycombError(
1439                 "The configuration of interface '{0}' was not successful. "
1440                 "Status code: {1}.".format(interface, status_code))
1441         return resp
1442
1443     @staticmethod
1444     def create_pbb_sub_interface(node, intf, sub_if_id, params):
1445         """Creates a PBB sub-interface on the given interface and sets its
1446         parameters.
1447
1448         :param node: Honeycomb node.
1449         :param intf: The interface where PBB sub-interface will be configured.
1450         :param sub_if_id: Sub-interface ID.
1451         :param params: Configuration parameters of the sub-interface to be
1452         created.
1453         :type node: dict
1454         :type intf: str
1455         :type sub_if_id: str or int
1456         :type params: dict
1457         :return: Content of response.
1458         :rtype: bytearray
1459         :raises HoneycombError: If the configuration of sub-interface is not
1460         successful.
1461         """
1462
1463         interface = intf.replace("/", "%2F")
1464         path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1465                "{1}".format(interface, sub_if_id)
1466         status_code, resp = HcUtil. \
1467             put_honeycomb_data(node, "config_vpp_interfaces", params, path,
1468                                data_representation=DataRepresentation.JSON)
1469         if status_code != HTTPCodes.OK:
1470             raise HoneycombError(
1471                 "The configuration of PBB sub-interface '{0}' was not "
1472                 "successful. Status code: {1}.".format(intf, status_code))
1473         return resp
1474
1475     @staticmethod
1476     def delete_pbb_sub_interface(node, intf, sub_if_id):
1477         """Deletes the given PBB sub-interface.
1478
1479         :param node: Honeycomb node.
1480         :param intf: The interface where PBB sub-interface will be deleted.
1481         :param sub_if_id: ID of the PBB sub-interface to be deleted.
1482         :type node: dict
1483         :type intf: str
1484         :type sub_if_id: str or int
1485         :return: Content of response.
1486         :rtype: bytearray
1487         :raises HoneycombError: If the removal of sub-interface is not
1488         successful.
1489         """
1490
1491         interface = intf.replace("/", "%2F")
1492         path = "/interface/{0}/sub-interfaces:sub-interfaces/sub-interface/" \
1493                "{1}".format(interface, sub_if_id)
1494
1495         status_code, resp = HcUtil. \
1496             delete_honeycomb_data(node, "config_vpp_interfaces", path)
1497         if status_code != HTTPCodes.OK:
1498             raise HoneycombError(
1499                 "The removal of pbb sub-interface '{0}' was not successful. "
1500                 "Status code: {1}.".format(intf, status_code))
1501         return resp
1502
1503     @staticmethod
1504     def get_pbb_sub_interface_oper_data(node, intf, sub_if_id):
1505         """Retrieves PBB sub-interface operational data from Honeycomb.
1506
1507         :param node: Honeycomb node.
1508         :param intf: The interface where PBB sub-interface is located.
1509         :param sub_if_id: ID of the PBB sub-interface.
1510         :type node: dict
1511         :type intf: str
1512         :type sub_if_id: str or int
1513         :return: PBB sub-interface operational data.
1514         :rtype: dict
1515         :raises HoneycombError: If the removal of sub-interface is not
1516         successful.
1517         """
1518
1519         interface = "{0}.{1}".format(intf, sub_if_id)
1520         return InterfaceKeywords.get_interface_oper_data(node, interface)