92b58308471ca35eff7b1c34ff4520b0c085f7dc
[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     IPV4_PARAMS = ("enabled", "forwarding", "mtu")
40     IPV6_PARAMS = ("enabled", "forwarding", "mtu", "dup-addr-detect-transmits")
41     IPV6_AUTOCONF_PARAMS = ("create-global-addresses",
42                             "create-temporary-addresses",
43                             "temporary-valid-lifetime",
44                             "temporary-preferred-lifetime")
45     ETH_PARAMS = ("mtu", )
46     ROUTING_PARAMS = ("vrf-id", )
47     VXLAN_PARAMS = ("src", "dst", "vni", "encap-vrf-id")
48     L2_PARAMS = ("bridge-domain", "split-horizon-group",
49                  "bridged-virtual-interface")
50     L2_REWRITE_TAG_PARAMS = ("rewrite-operation",
51                              "first-pushed",
52                              "tag1",
53                              "tag2")
54     TAP_PARAMS = ("tap-name", "mac", "device-instance")
55     VHOST_USER_PARAMS = ("socket", "role")
56     SUB_INTF_PARAMS = ("super-interface",
57                        "identifier",
58                        "vlan-type",
59                        "number-of-tags",
60                        "outer-id",
61                        "inner-id",
62                        "match-any-outer-id",
63                        "match-any-inner-id",
64                        "exact-match",
65                        "default-subif")
66     VXLAN_GPE_PARAMS = ("local",
67                         "remote",
68                         "vni",
69                         "next-protocol",
70                         "encap-vrf-id",
71                         "decap-vrf-id")
72
73     def __init__(self):
74         pass
75
76     @staticmethod
77     def _configure_interface(node, interface, data,
78                              data_representation=DataRepresentation.JSON):
79         """Send interface configuration data and check the response.
80
81         :param node: Honeycomb node.
82         :param interface: The name of interface.
83         :param data: Configuration data to be sent in PUT request.
84         :param data_representation: How the data is represented.
85         :type node: dict
86         :type interface: str
87         :type data: dict
88         :type data_representation: DataRepresentation
89         :return: Content of response.
90         :rtype: bytearray
91         :raises HoneycombError: If the status code in response on PUT is not
92         200 = OK.
93         """
94
95         status_code, resp = HcUtil.\
96             put_honeycomb_data(node, "config_vpp_interfaces", data,
97                                data_representation=data_representation)
98         if status_code != HTTPCodes.OK:
99             raise HoneycombError(
100                 "The configuration of interface '{0}' was not successful. "
101                 "Status code: {1}.".format(interface, status_code))
102         return resp
103
104     @staticmethod
105     def get_all_interfaces_cfg_data(node):
106         """Get configuration data about all interfaces from Honeycomb.
107
108         :param node: Honeycomb node.
109         :type node: dict
110         :return: Configuration data about all interfaces from Honeycomb.
111         :rtype: list
112         :raises HoneycombError: If it is not possible to get configuration data.
113         """
114
115         status_code, resp = HcUtil.\
116             get_honeycomb_data(node, "config_vpp_interfaces")
117         if status_code != HTTPCodes.OK:
118             raise HoneycombError(
119                 "Not possible to get configuration information about the "
120                 "interfaces. Status code: {0}.".format(status_code))
121         try:
122             return resp["interfaces"]["interface"]
123
124         except (KeyError, TypeError):
125             return []
126
127     @staticmethod
128     def get_interface_cfg_data(node, interface):
129         """Get configuration data about the given interface from Honeycomb.
130
131         :param node: Honeycomb node.
132         :param interface: The name of interface.
133         :type node: dict
134         :type interface: str
135         :return: Configuration data about the given interface from Honeycomb.
136         :rtype: dict
137         """
138
139         intfs = InterfaceKeywords.get_all_interfaces_cfg_data(node)
140         for intf in intfs:
141             if intf["name"] == interface:
142                 return intf
143         return {}
144
145     @staticmethod
146     def get_all_interfaces_oper_data(node):
147         """Get operational data about all interfaces from Honeycomb.
148
149         :param node: Honeycomb node.
150         :type node: dict
151         :return: Operational data about all interfaces from Honeycomb.
152         :rtype: list
153         :raises HoneycombError: If it is not possible to get operational data.
154         """
155
156         status_code, resp = HcUtil.\
157             get_honeycomb_data(node, "oper_vpp_interfaces")
158         if status_code != HTTPCodes.OK:
159             raise HoneycombError(
160                 "Not possible to get operational information about the "
161                 "interfaces. Status code: {0}.".format(status_code))
162         try:
163             return resp["interfaces-state"]["interface"]
164
165         except (KeyError, TypeError):
166             return []
167
168     @staticmethod
169     def get_interface_oper_data(node, interface):
170         """Get operational data about the given interface from Honeycomb.
171
172         :param node: Honeycomb node.
173         :param interface: The name of interface.
174         :type node: dict
175         :type interface: str
176         :return: Operational data about the given interface from Honeycomb.
177         :rtype: dict
178         """
179
180         intfs = InterfaceKeywords.get_all_interfaces_oper_data(node)
181         for intf in intfs:
182             if intf["name"] == interface:
183                 return intf
184         return {}
185
186     @staticmethod
187     def _set_interface_properties(node, interface, path, new_value=None):
188         """Set interface properties.
189
190         This method reads interface configuration data, creates, changes or
191         removes the requested data and puts it back to Honeycomb.
192
193         :param node: Honeycomb node.
194         :param interface: The name of interface.
195         :param path:  Path to data we want to change / create / remove.
196         :param new_value: The new value to be set. If None, the item will be
197         removed.
198         :type node: dict
199         :type interface: str
200         :type path: tuple
201         :type new_value: str, dict or list
202         :return: Content of response.
203         :rtype: bytearray
204         :raises HoneycombError: If it is not possible to get or set the data.
205         """
206
207         status_code, resp = HcUtil.\
208             get_honeycomb_data(node, "config_vpp_interfaces")
209         if status_code != HTTPCodes.OK:
210             raise HoneycombError(
211                 "Not possible to get configuration information about the "
212                 "interfaces. Status code: {0}.".format(status_code))
213
214         if new_value:
215             new_data = HcUtil.set_item_value(resp, path, new_value)
216         else:
217             new_data = HcUtil.remove_item(resp, path)
218         return InterfaceKeywords._configure_interface(node, interface, new_data)
219
220     @staticmethod
221     def set_interface_state(node, interface, state="up"):
222         """Set VPP interface state.
223
224         The keyword changes the administration state of interface to up or down
225         depending on the parameter "state".
226
227         :param node: Honeycomb node.
228         :param interface: The name of interface.
229         :param state: The requested state, only "up" and "down" are valid
230         values.
231         :type node: dict
232         :type interface: str
233         :type state: str
234         :return: Content of response.
235         :rtype: bytearray
236         :raises KeyError: If the argument "state" is nor "up" or "down".
237         :raises HoneycombError: If the interface is not present on the node.
238         """
239
240         intf_state = {"up": "true",
241                       "down": "false"}
242
243         path = ("interfaces", ("interface", "name", str(interface)), "enabled")
244         return InterfaceKeywords._set_interface_properties(
245             node, interface, path, intf_state[state.lower()])
246
247     @staticmethod
248     def set_interface_up(node, interface):
249         """Set the administration state of VPP interface to up.
250
251         :param node: Honeycomb node.
252         :param interface: The name of interface.
253         :type node: dict
254         :type interface: str
255         :return: Content of response
256         :rtype: bytearray
257         """
258
259         return InterfaceKeywords.set_interface_state(node, interface, "up")
260
261     @staticmethod
262     def set_interface_down(node, interface):
263         """Set the administration state of VPP interface to down.
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, "down")
274
275     @staticmethod
276     def add_bridge_domain_to_interface(node, interface, bd_name,
277                                        split_horizon_group=None, bvi=None):
278         """Add a new bridge domain to an interface and set its parameters.
279
280         :param node: Honeycomb node.
281         :param interface: The name of interface.
282         :param bd_name: Bridge domain name.
283         :param split_horizon_group: Split-horizon group name.
284         :param bvi: The bridged virtual interface.
285         :type node: dict
286         :type interface: str
287         :type bd_name: str
288         :type split_horizon_group: str
289         :type bvi: str
290         :return: Content of response.
291         :rtype: bytearray
292         :raises HoneycombError: If the interface is not present on the node.
293         """
294
295         v3po_l2 = {"bridge-domain": str(bd_name)}
296         if split_horizon_group:
297             v3po_l2["split-horizon-group"] = str(split_horizon_group)
298         if bvi:
299             v3po_l2["bridged-virtual-interface"] = str(bvi)
300
301         path = ("interfaces", ("interface", "name", str(interface)), "v3po:l2")
302
303         return InterfaceKeywords._set_interface_properties(
304             node, interface, path, v3po_l2)
305
306     @staticmethod
307     def configure_interface_base(node, interface, param, value):
308         """Configure the base parameters of interface.
309
310         :param node: Honeycomb node.
311         :param interface: The name of interface.
312         :param param: Parameter to configure (set, change, remove)
313         :param value: The value of parameter. If None, the parameter will be
314         removed.
315         :type node: dict
316         :type interface: str
317         :type param: str
318         :type value: str
319         :return: Content of response.
320         :rtype: bytearray
321         :raises HoneycombError: If the parameter is not valid.
322         """
323
324         if param not in InterfaceKeywords.INTF_PARAMS:
325             raise HoneycombError("The parameter {0} is invalid.".format(param))
326
327         path = ("interfaces", ("interface", "name", interface), param)
328         return InterfaceKeywords._set_interface_properties(
329             node, interface, path, value)
330
331     @staticmethod
332     def configure_interface_ipv4(node, interface, param, value):
333         """Configure IPv4 parameters of interface
334
335         :param node: Honeycomb node.
336         :param interface: The name of interface.
337         :param param: Parameter to configure (set, change, remove)
338         :param value: The value of parameter. If None, the parameter will be
339         removed.
340         :type node: dict
341         :type interface: str
342         :type param: str
343         :type value: str
344         :return: Content of response.
345         :rtype: bytearray
346         :raises HoneycombError: If the parameter is not valid.
347         """
348
349         if param not in InterfaceKeywords.IPV4_PARAMS:
350             raise HoneycombError("The parameter {0} is invalid.".format(param))
351
352         path = ("interfaces", ("interface", "name", interface),
353                 "ietf-ip:ipv4", param)
354         return InterfaceKeywords._set_interface_properties(
355             node, interface, path, value)
356
357     @staticmethod
358     def add_first_ipv4_address(node, interface, ip_addr, network):
359         """Add the first IPv4 address.
360
361         If there are any other addresses configured, they will be removed.
362
363         :param node: Honeycomb node.
364         :param interface: The name of interface.
365         :param ip_addr: IPv4 address to be set.
366         :param network: Netmask or length of network prefix.
367         :type node: dict
368         :type interface: str
369         :type ip_addr: str
370         :type network: str or int
371         :return: Content of response.
372         :rtype: bytearray
373         """
374
375         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
376         if isinstance(network, basestring):
377             address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
378         elif isinstance(network, int) and (0 < network < 33):
379             address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
380         else:
381             raise HoneycombError("Value {0} is not a valid netmask or network "
382                                  "prefix length.".format(network))
383         return InterfaceKeywords._set_interface_properties(
384             node, interface, path, address)
385
386     @staticmethod
387     def add_ipv4_address(node, interface, ip_addr, network):
388         """Add IPv4 address.
389
390         :param node: Honeycomb node.
391         :param interface: The name of interface.
392         :param ip_addr: IPv4 address to be set.
393         :param network: Netmask or length of network prefix.
394         :type node: dict
395         :type interface: str
396         :type ip_addr: str
397         :type network: str or int
398         :return: Content of response.
399         :rtype: bytearray
400         """
401
402         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
403                 "address")
404         if isinstance(network, basestring):
405             address = {"address": [{"ip": ip_addr, "netmask": network}, ]}
406         elif isinstance(network, int) and (0 < network < 33):
407             address = {"address": [{"ip": ip_addr, "prefix-length": network}, ]}
408         else:
409             raise HoneycombError("Value {0} is not a valid netmask or network "
410                                  "prefix length.".format(network))
411         return InterfaceKeywords._set_interface_properties(
412             node, interface, path, address)
413
414     @staticmethod
415     def remove_all_ipv4_addresses(node, interface):
416         """Remove all IPv4 addresses from interface.
417
418         :param node: Honeycomb node.
419         :param interface: The name of interface.
420         :type node: dict
421         :type interface: str
422         :return: Content of response.
423         :rtype: bytearray
424         """
425
426         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
427                 "address")
428         return InterfaceKeywords._set_interface_properties(
429             node, interface, path, None)
430
431     @staticmethod
432     def add_first_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
433         """Add the first IPv4 neighbour.
434
435         If there are any other neighbours configured, they will be removed.
436
437         :param node: Honeycomb node.
438         :param interface: The name of interface.
439         :param ip_addr: IPv4 address of neighbour to be set.
440         :param link_layer_address: Link layer address.
441         :type node: dict
442         :type interface: str
443         :type ip_addr: str
444         :type link_layer_address: str
445         :return: Content of response.
446         :rtype: bytearray
447         """
448
449         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4")
450         neighbor = {"neighbor": [{"ip": ip_addr,
451                                   "link-layer-address": link_layer_address}, ]}
452         return InterfaceKeywords._set_interface_properties(
453             node, interface, path, neighbor)
454
455     @staticmethod
456     def add_ipv4_neighbor(node, interface, ip_addr, link_layer_address):
457         """Add the IPv4 neighbour.
458
459         :param node: Honeycomb node.
460         :param interface: The name of interface.
461         :param ip_addr: IPv4 address of neighbour to be set.
462         :param link_layer_address: Link layer address.
463         :type node: dict
464         :type interface: str
465         :type ip_addr: str
466         :type link_layer_address: str
467         :return: Content of response.
468         :rtype: bytearray
469         """
470
471         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
472                 "neighbor")
473         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
474         return InterfaceKeywords._set_interface_properties(
475             node, interface, path, neighbor)
476
477     @staticmethod
478     def remove_all_ipv4_neighbors(node, interface):
479         """Remove all IPv4 neighbours.
480
481         :param node: Honeycomb node.
482         :param interface: The name of interface.
483         :type node: dict
484         :type interface: str
485         :return: Content of response.
486         :rtype: bytearray
487         """
488
489         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv4",
490                 "neighbor")
491         return InterfaceKeywords._set_interface_properties(
492             node, interface, path, None)
493
494     @staticmethod
495     def configure_interface_ipv6(node, interface, param, value):
496         """Configure IPv6 parameters of interface
497
498         :param node: Honeycomb node.
499         :param interface: The name of interface.
500         :param param: Parameter to configure (set, change, remove)
501         :param value: The value of parameter. If None, the parameter will be
502         removed.
503         :type node: dict
504         :type interface: str
505         :type param: str
506         :type value: str
507         :return: Content of response.
508         :rtype: bytearray
509         :raises HoneycombError: If the parameter is not valid.
510         """
511
512         if param in InterfaceKeywords.IPV6_PARAMS:
513             path = ("interfaces", ("interface", "name", interface),
514                     "ietf-ip:ipv6", param)
515         elif param in InterfaceKeywords.IPV6_AUTOCONF_PARAMS:
516             path = ("interfaces", ("interface", "name", interface),
517                     "ietf-ip:ipv6", "autoconf", param)
518         else:
519             raise HoneycombError("The parameter {0} is invalid.".format(param))
520
521         return InterfaceKeywords._set_interface_properties(
522             node, interface, path, value)
523
524     @staticmethod
525     def add_first_ipv6_address(node, interface, ip_addr, prefix_len):
526         """Add the first IPv6 address.
527
528         If there are any other addresses configured, they will be removed.
529
530         :param node: Honeycomb node.
531         :param interface: The name of interface.
532         :param ip_addr: IPv6 address to be set.
533         :param prefix_len: Prefix length.
534         :type node: dict
535         :type interface: str
536         :type ip_addr: str
537         :type prefix_len: str
538         :return: Content of response.
539         :rtype: bytearray
540         """
541
542         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
543         address = {"address": [{"ip": ip_addr, "prefix-length": prefix_len}, ]}
544         return InterfaceKeywords._set_interface_properties(
545             node, interface, path, address)
546
547     @staticmethod
548     def add_ipv6_address(node, interface, ip_addr, prefix_len):
549         """Add IPv6 address.
550
551         :param node: Honeycomb node.
552         :param interface: The name of interface.
553         :param ip_addr: IPv6 address to be set.
554         :param prefix_len: Prefix length.
555         :type node: dict
556         :type interface: str
557         :type ip_addr: str
558         :type prefix_len: str
559         :return: Content of response.
560         :rtype: bytearray
561         """
562
563         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
564                 "address")
565         address = [{"ip": ip_addr, "prefix-length": prefix_len}, ]
566         return InterfaceKeywords._set_interface_properties(
567             node, interface, path, address)
568
569     @staticmethod
570     def remove_all_ipv6_addresses(node, interface):
571         """Remove all IPv6 addresses from interface.
572
573         :param node: Honeycomb node.
574         :param interface: The name of interface.
575         :type node: dict
576         :type interface: str
577         :return: Content of response.
578         :rtype: bytearray
579         """
580
581         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
582                 "address")
583         return InterfaceKeywords._set_interface_properties(
584             node, interface, path, None)
585
586     @staticmethod
587     def add_first_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
588         """Add the first IPv6 neighbour.
589
590         If there are any other neighbours configured, they will be removed.
591
592         :param node: Honeycomb node.
593         :param interface: The name of interface.
594         :param ip_addr: IPv6 address of neighbour to be set.
595         :param link_layer_address: Link layer address.
596         :type node: dict
597         :type interface: str
598         :type ip_addr: str
599         :type link_layer_address: str
600         :return: Content of response.
601         :rtype: bytearray
602         """
603
604         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6")
605         neighbor = {"neighbor": [{"ip": ip_addr,
606                                   "link-layer-address": link_layer_address}, ]}
607         return InterfaceKeywords._set_interface_properties(
608             node, interface, path, neighbor)
609
610     @staticmethod
611     def add_ipv6_neighbor(node, interface, ip_addr, link_layer_address):
612         """Add the IPv6 neighbour.
613
614         :param node: Honeycomb node.
615         :param interface: The name of interface.
616         :param ip_addr: IPv6 address of neighbour to be set.
617         :param link_layer_address: Link layer address.
618         :type node: dict
619         :type interface: str
620         :type ip_addr: str
621         :type link_layer_address: str
622         :return: Content of response.
623         :rtype: bytearray
624         """
625
626         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
627                 "neighbor")
628         neighbor = [{"ip": ip_addr, "link-layer-address": link_layer_address}, ]
629         return InterfaceKeywords._set_interface_properties(
630             node, interface, path, neighbor)
631
632     @staticmethod
633     def remove_all_ipv6_neighbors(node, interface):
634         """Remove all IPv6 neighbours.
635
636         :param node: Honeycomb node.
637         :param interface: The name of interface.
638         :type node: dict
639         :type interface: str
640         :return: Content of response.
641         :rtype: bytearray
642         """
643
644         path = ("interfaces", ("interface", "name", interface), "ietf-ip:ipv6",
645                 "neighbor")
646         return InterfaceKeywords._set_interface_properties(
647             node, interface, path, None)
648
649     @staticmethod
650     def configure_interface_ethernet(node, interface, param, value):
651         """Configure the ethernet parameters of interface.
652
653         :param node: Honeycomb node.
654         :param interface: The name of interface.
655         :param param: Parameter to configure (set, change, remove)
656         :param value: The value of parameter. If None, the parameter will be
657         removed.
658         :type node: dict
659         :type interface: str
660         :type param: str
661         :type value: str
662         :return: Content of response.
663         :rtype: bytearray
664         :raises HoneycombError: If the parameter is not valid.
665         """
666
667         if param not in InterfaceKeywords.ETH_PARAMS:
668             raise HoneycombError("The parameter {0} is invalid.".format(param))
669         path = ("interfaces", ("interface", "name", interface), "v3po:ethernet",
670                 param)
671         return InterfaceKeywords._set_interface_properties(
672             node, interface, path, value)
673
674     @staticmethod
675     def configure_interface_routing(node, interface, param, value):
676         """Configure the routing parameters of interface.
677
678         :param node: Honeycomb node.
679         :param interface: The name of interface.
680         :param param: Parameter to configure (set, change, remove)
681         :param value: The value of parameter. If None, the parameter will be
682         removed.
683         :type node: dict
684         :type interface: str
685         :type param: str
686         :type value: str
687         :return: Content of response.
688         :rtype: bytearray
689         :raises HoneycombError: If the parameter is not valid.
690         """
691
692         if param not in InterfaceKeywords.ROUTING_PARAMS:
693             raise HoneycombError("The parameter {0} is invalid.".format(param))
694
695         path = ("interfaces", ("interface", "name", interface), "v3po:routing",
696                 param)
697         return InterfaceKeywords._set_interface_properties(
698             node, interface, path, value)
699
700     @staticmethod
701     def create_vxlan_interface(node, interface, **kwargs):
702         """Create a new VxLAN interface.
703
704         :param node: Honeycomb node.
705         :param interface: The name of interface.
706         :param kwargs: Parameters and their values. The accepted parameters are
707         defined in InterfaceKeywords.VXLAN_PARAMS.
708         :type node: dict
709         :type interface: str
710         :type kwargs: dict
711         :return: Content of response.
712         :rtype: bytearray
713         :raises HoneycombError: If the parameter is not valid.
714         """
715
716         new_vx_lan = {
717             "name": interface,
718             "type": "v3po:vxlan-tunnel",
719             "v3po:vxlan": {}
720         }
721         for param, value in kwargs.items():
722             if param not in InterfaceKeywords.VXLAN_PARAMS:
723                 raise HoneycombError("The parameter {0} is invalid.".
724                                      format(param))
725             new_vx_lan["v3po:vxlan"][param] = value
726
727         path = ("interfaces", "interface")
728         vx_lan_structure = [new_vx_lan, ]
729         return InterfaceKeywords._set_interface_properties(
730             node, interface, path, vx_lan_structure)
731
732     @staticmethod
733     def delete_interface(node, interface):
734         """Delete an interface.
735
736         :param node: Honeycomb node.
737         :param interface: The name of interface.
738         :type node: dict
739         :type interface: str
740         :return: Content of response.
741         :rtype: bytearray
742         :raises HoneycombError: If it is not possible to get information about
743         interfaces or it is not possible to delete the interface.
744         """
745
746         path = ("interfaces", ("interface", "name", interface))
747
748         status_code, resp = HcUtil.\
749             get_honeycomb_data(node, "config_vpp_interfaces")
750         if status_code != HTTPCodes.OK:
751             raise HoneycombError(
752                 "Not possible to get configuration information about the "
753                 "interfaces. Status code: {0}.".format(status_code))
754
755         new_data = HcUtil.remove_item(resp, path)
756         status_code, resp = HcUtil.\
757             put_honeycomb_data(node, "config_vpp_interfaces", new_data)
758         if status_code != HTTPCodes.OK:
759             raise HoneycombError("Not possible to remove interface {0}. "
760                                  "Status code: {1}.".
761                                  format(interface, status_code))
762         return resp
763
764     @staticmethod
765     def configure_interface_vxlan(node, interface, **kwargs):
766         """Configure VxLAN on the interface.
767
768         The keyword configures VxLAN parameters on the given interface. The type
769         of interface must be set to "v3po:vxlan-tunnel".
770         The new VxLAN parameters overwrite the current configuration. If a
771         parameter in new configuration is missing, it is removed from VxLAN
772         configuration.
773         If the dictionary kwargs is empty, VxLAN configuration is removed.
774
775         :param node: Honeycomb node.
776         :param interface: The name of interface.
777         :param kwargs: Parameters and their values. The accepted parameters are
778         defined in InterfaceKeywords.VXLAN_PARAMS.
779         :type node: dict
780         :type interface: str
781         :type kwargs: dict
782         :return: Content of response.
783         :rtype: bytearray
784         :raises HoneycombError: If the parameter is not valid.
785         """
786
787         vx_lan_structure = dict()
788         for param, value in kwargs.items():
789             if param not in InterfaceKeywords.VXLAN_PARAMS:
790                 raise HoneycombError("The parameter {0} is invalid.".
791                                      format(param))
792             vx_lan_structure[param] = value
793
794         path = ("interfaces", ("interface", "name", interface), "v3po:vxlan")
795         return InterfaceKeywords._set_interface_properties(
796             node, interface, path, vx_lan_structure)
797
798     @staticmethod
799     def configure_interface_l2(node, interface, param, value):
800         """Configure the L2 parameters of interface.
801
802         :param node: Honeycomb node.
803         :param interface: The name of interface.
804         :param param: Parameter to configure (set, change, remove)
805         :param value: The value of parameter. If None, the parameter will be
806         removed.
807         :type node: dict
808         :type interface: str
809         :type param: str
810         :type value: str
811         :return: Content of response.
812         :rtype: bytearray
813         :raises HoneycombError: If the parameter is not valid.
814         """
815
816         if param not in InterfaceKeywords.L2_PARAMS:
817             raise HoneycombError("The parameter {0} is invalid.".format(param))
818         path = ("interfaces", ("interface", "name", interface), "v3po:l2",
819                 param)
820         return InterfaceKeywords._set_interface_properties(
821             node, interface, path, value)
822
823     @staticmethod
824     def create_tap_interface(node, interface, **kwargs):
825         """Create a new TAP interface.
826
827         :param node: Honeycomb node.
828         :param interface: The name of interface.
829         :param kwargs: Parameters and their values. The accepted parameters are
830         defined in InterfaceKeywords.TAP_PARAMS.
831         :type node: dict
832         :type interface: str
833         :type kwargs: dict
834         :return: Content of response.
835         :rtype: bytearray
836         :raises HoneycombError: If the parameter is not valid.
837         """
838
839         new_tap = {
840             "name": interface,
841             "type": "v3po:tap",
842             "v3po:tap": {}
843         }
844         for param, value in kwargs.items():
845             if param not in InterfaceKeywords.TAP_PARAMS:
846                 raise HoneycombError("The parameter {0} is invalid.".
847                                      format(param))
848             new_tap["v3po:tap"][param] = value
849
850         path = ("interfaces", "interface")
851         new_tap_structure = [new_tap, ]
852         return InterfaceKeywords._set_interface_properties(
853             node, interface, path, new_tap_structure)
854
855     @staticmethod
856     def configure_interface_tap(node, interface, **kwargs):
857         """Configure TAP on the interface.
858
859         The keyword configures TAP parameters on the given interface. The type
860         of interface must be set to "v3po:tap".
861         The new TAP parameters overwrite the current configuration. If a
862         parameter in new configuration is missing, it is removed from TAP
863         configuration.
864         If the dictionary kwargs is empty, TAP configuration is removed.
865
866         :param node: Honeycomb node.
867         :param interface: The name of interface.
868         :param kwargs: Parameters and their values. The accepted parameters are
869         defined in InterfaceKeywords.TAP_PARAMS.
870         :type node: dict
871         :type interface: str
872         :type kwargs: dict
873         :return: Content of response.
874         :rtype: bytearray
875         :raises HoneycombError: If the parameter is not valid.
876         """
877
878         tap_structure = dict()
879         for param, value in kwargs.items():
880             if param not in InterfaceKeywords.TAP_PARAMS:
881                 raise HoneycombError("The parameter {0} is invalid.".
882                                      format(param))
883             tap_structure[param] = value
884
885         path = ("interfaces", ("interface", "name", interface), "v3po:tap")
886         return InterfaceKeywords._set_interface_properties(
887             node, interface, path, tap_structure)
888
889     @staticmethod
890     def configure_interface_vhost_user(node, interface, **kwargs):
891         """Configure vhost-user on the interface.
892
893         The keyword configures vhost-user parameters on the given interface.
894         The type of interface must be set to "v3po:vhost-user".
895         The new vhost-user parameters overwrite the current configuration. If a
896         parameter in new configuration is missing, it is removed from vhost-user
897         configuration.
898         If the dictionary kwargs is empty, vhost-user configuration is removed.
899
900         :param node: Honeycomb node.
901         :param interface: The name of interface.
902         :param kwargs: Parameters and their values. The accepted parameters are
903         defined in InterfaceKeywords.VHOST_USER_PARAMS.
904         :type node: dict
905         :type interface: str
906         :type kwargs: dict
907         :return: Content of response.
908         :rtype: bytearray
909         :raises HoneycombError: If the parameter is not valid.
910         """
911
912         vhost_structure = dict()
913         for param, value in kwargs.items():
914             if param not in InterfaceKeywords.VHOST_USER_PARAMS:
915                 raise HoneycombError("The parameter {0} is invalid.".
916                                      format(param))
917             vhost_structure[param] = value
918
919         path = ("interfaces", ("interface", "name", interface),
920                 "v3po:vhost-user")
921         return InterfaceKeywords._set_interface_properties(
922             node, interface, path, vhost_structure)
923
924     @staticmethod
925     def create_vhost_user_interface(node, interface, **kwargs):
926         """Create a new vhost-user interface.
927
928         :param node: Honeycomb node.
929         :param interface: The name of interface.
930         :param kwargs: Parameters and their values. The accepted parameters are
931         defined in InterfaceKeywords.VHOST_USER_PARAMS.
932         :type node: dict
933         :type interface: str
934         :type kwargs: dict
935         :return: Content of response.
936         :rtype: bytearray
937         :raises HoneycombError: If the parameter is not valid.
938         """
939
940         new_vhost = {
941             "name": interface,
942             "type": "v3po:vhost-user",
943             "v3po:vhost-user": {}
944         }
945         for param, value in kwargs.items():
946             if param not in InterfaceKeywords.VHOST_USER_PARAMS:
947                 raise HoneycombError("The parameter {0} is invalid.".
948                                      format(param))
949             new_vhost["v3po:vhost-user"][param] = value
950
951         path = ("interfaces", "interface")
952         new_vhost_structure = [new_vhost, ]
953         return InterfaceKeywords._set_interface_properties(
954             node, interface, path, new_vhost_structure)
955
956     @staticmethod
957     def create_sub_interface(node, super_interface, identifier, **kwargs):
958         """Create a new sub-interface.
959
960         :param node: Honeycomb node.
961         :param super_interface: The name of super interface.
962         :param identifier: sub-interface identifier.
963         :param kwargs: Parameters and their values. The accepted parameters are
964         defined in InterfaceKeywords.SUB_INTF_PARAMS.
965         :type node: dict
966         :type super_interface: str
967         :type identifier: int
968         :type kwargs: dict
969         :return: Content of response.
970         :rtype: bytearray
971         :raises HoneycombError: If the parameter is not valid.
972         """
973
974         # These parameters are empty types (in JSON represented as empty
975         # dictionary) but ODL internally represents them as Booleans. If the
976         # value is an empty dictionary, it is True, if the parameter is
977         # missing, it is False.
978         empty_types = ("match-any-outer-id",
979                        "match-any-inner-id",
980                        "exact-match",
981                        "default-subif")
982
983         sub_interface_name = "{0}.{1}".format(super_interface, str(identifier))
984         new_sub_interface = {
985             "name": sub_interface_name,
986             "type": "v3po:sub-interface",
987             "enabled": "false",
988             "sub-interface": {
989                 "super-interface": super_interface,
990                 "identifier": identifier
991             }
992         }
993         for param, value in kwargs.items():
994             if param in InterfaceKeywords.INTF_PARAMS:
995                 new_sub_interface[param] = value
996             elif param in InterfaceKeywords.SUB_INTF_PARAMS:
997                 if param in empty_types:
998                     if value:
999                         new_sub_interface["sub-interface"][param] = dict()
1000                 else:
1001                     new_sub_interface["sub-interface"][param] = value
1002             else:
1003                 raise HoneycombError("The parameter {0} is invalid.".
1004                                      format(param))
1005
1006         path = ("interfaces", "interface")
1007         new_sub_interface_structure = [new_sub_interface, ]
1008         return InterfaceKeywords._set_interface_properties(
1009             node, sub_interface_name, path, new_sub_interface_structure)
1010
1011     @staticmethod
1012     def add_vlan_tag_rewrite_to_sub_interface(node, sub_interface, **kwargs):
1013         """Add vlan tag rewrite to a sub-interface.
1014
1015         :param node: Honeycomb node.
1016         :param sub_interface: The name of sub-interface.
1017         :param kwargs: Parameters and their values. The accepted parameters are
1018         defined in InterfaceKeywords.L2_REWRITE_TAG_PARAMS.
1019         :type node: dict
1020         :type sub_interface: str
1021         :type kwargs: dict
1022         :return: Content of response.
1023         :rtype: bytearray
1024         :raises HoneycombError: If the parameter is not valid.
1025         """
1026
1027         new_rewrite = dict()
1028         for param, value in kwargs.items():
1029             if param in InterfaceKeywords.L2_REWRITE_TAG_PARAMS:
1030                 new_rewrite[param] = value
1031             else:
1032                 raise HoneycombError("The parameter {0} is invalid.".
1033                                      format(param))
1034
1035         path = ("interfaces", ("interface", "name", sub_interface), "v3po:l2",
1036                 "vlan-tag-rewrite")
1037         return InterfaceKeywords._set_interface_properties(
1038             node, sub_interface, path, new_rewrite)
1039
1040     @staticmethod
1041     def remove_vlan_tag_rewrite_from_sub_interface(node, sub_interface):
1042         """Remove vlan tag rewrite from a sub-interface.
1043
1044         :param node: Honeycomb node.
1045         :param sub_interface: The name of sub-interface.
1046         :type node: dict
1047         :type sub_interface: str
1048         :rtype: bytearray
1049         :raises HoneycombError: If the parameter is not valid.
1050         """
1051
1052         path = ("interfaces", ("interface", "name", sub_interface), "v3po:l2",
1053                 "vlan-tag-rewrite")
1054         return InterfaceKeywords._set_interface_properties(
1055             node, sub_interface, path, None)
1056
1057     @staticmethod
1058     def compare_interface_lists(list1, list2):
1059         """Compare provided lists of interfaces by name.
1060
1061         :param list1: List of interfaces.
1062         :param list2: List of interfaces.
1063         :type list1: list
1064         :type list2: list
1065         :raises HoneycombError: If an interface exists in only one of the lists.
1066         """
1067
1068         ignore = ["vx_tunnel0", "vxlan_gpe_tunnel0"]
1069         # these have no equivalent in config data and no effect on VPP
1070
1071         names1 = [x['name'] for x in list1]
1072         names2 = [x['name'] for x in list2]
1073
1074         for name in names1:
1075             if name not in names2 and name not in ignore:
1076                 raise HoneycombError("Interface {0} not present in list {1}"
1077                                      .format(name, list2))
1078         for name in names2:
1079             if name not in names1 and name not in ignore:
1080                 raise HoneycombError("Interface {0} not present in list {1}"
1081                                      .format(name, list1))
1082
1083     @staticmethod
1084     def create_vxlan_gpe_interface(node, interface, **kwargs):
1085         """Create a new VxLAN GPE interface.
1086
1087         :param node: Honeycomb node.
1088         :param interface: The name of interface to be created.
1089         :param kwargs: Parameters and their values. The accepted parameters are
1090         defined in InterfaceKeywords.VXLAN_GPE_PARAMS.
1091         :type node: dict
1092         :type interface: str
1093         :type kwargs: dict
1094         :return: Content of response.
1095         :rtype: bytearray
1096         :raises HoneycombError: If a parameter in kwargs is not valid.
1097         """
1098
1099         new_vxlan_gpe = {
1100             "name": interface,
1101             "type": "v3po:vxlan-gpe-tunnel",
1102             "v3po:vxlan-gpe": {}
1103         }
1104         for param, value in kwargs.items():
1105             if param in InterfaceKeywords.INTF_PARAMS:
1106                 new_vxlan_gpe[param] = value
1107             elif param in InterfaceKeywords.VXLAN_GPE_PARAMS:
1108                 new_vxlan_gpe["v3po:vxlan-gpe"][param] = value
1109             else:
1110                 raise HoneycombError("The parameter {0} is invalid.".
1111                                      format(param))
1112         path = ("interfaces", "interface")
1113         vxlan_gpe_structure = [new_vxlan_gpe, ]
1114         return InterfaceKeywords._set_interface_properties(
1115             node, interface, path, vxlan_gpe_structure)