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