Move Honeycomb libraries to honeycomb subdirectory.
[csit.git] / resources / libraries / python / honeycomb / HcAPIKwBridgeDomain.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 bridge domain 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 class BridgeDomainKeywords(object):
29     """Keywords to manipulate bridge domain configuration.
30
31     Implements keywords which get configuration and operational data about
32     bridge domains and put the bridge domains' parameters using Honeycomb REST
33     API.
34     """
35
36     PARAMS = ("flood", "forward", "learn", "unknown-unicast-flood",
37               "arp-termination")
38
39     def __init__(self):
40         pass
41
42     @staticmethod
43     def _configure_bd(node, bd_name, data,
44                       data_representation=DataRepresentation.JSON):
45         """Send bridge domain configuration data and check the response.
46
47         :param node: Honeycomb node.
48         :param bd_name: The name of bridge domain.
49         :param data: Configuration data to be sent in PUT request.
50         :param data_representation: How the data is represented.
51         :type node: dict
52         :type bd_name: str
53         :type data: dict
54         :type data_representation: DataRepresentation
55         :return: Content of response.
56         :rtype: bytearray
57         :raises HoneycombError: If the status code in response on PUT is not
58         200 = OK.
59         """
60
61         status_code, resp = HcUtil.\
62             put_honeycomb_data(node, "config_bridge_domain", data,
63                                data_representation=data_representation)
64         if status_code != HTTPCodes.OK:
65             raise HoneycombError(
66                 "The configuration of bridge domain '{0}' was not successful. "
67                 "Status code: {1}.".format(bd_name, status_code))
68         return resp
69
70     @staticmethod
71     def _set_bd_properties(node, bd_name, path, new_value=None):
72         """Set bridge domain properties.
73
74         This method reads bridge domain configuration data, creates, changes or
75         removes the requested data and puts it back to Honeycomb.
76
77         :param node: Honeycomb node.
78         :param bd_name: The name of bridge domain.
79         :param path:  Path to data we want to change, create or remove.
80         :param new_value: The new value to be set. If None, the item will be
81         removed.
82         :type node: dict
83         :type bd_name: str
84         :type path: tuple
85         :type new_value: str, dict or list
86         :return: Content of response.
87         :rtype: bytearray
88         :raises HoneycombError: If it is not possible to get or set the data.
89         """
90
91         status_code, resp = HcUtil.\
92             get_honeycomb_data(node, "config_bridge_domain")
93         if status_code != HTTPCodes.OK:
94             raise HoneycombError(
95                 "Not possible to get configuration information about the "
96                 "bridge domains. Status code: {0}.".format(status_code))
97
98         if new_value:
99             new_data = HcUtil.set_item_value(resp, path, new_value)
100         else:
101             new_data = HcUtil.remove_item(resp, path)
102         return BridgeDomainKeywords._configure_bd(node, bd_name, new_data)
103
104     @staticmethod
105     def _create_bd_structure(bd_name, **kwargs):
106         """Create the bridge domain data structure as it is expected by
107         Honeycomb REST API.
108
109         :param bd_name: Bridge domain name.
110         :param kwargs: Parameters and their values. The accepted parameters are
111         defined in BridgeDomainKeywords.PARAMS.
112         :type bd_name: str
113         :type kwargs: dict
114         :return: Bridge domain data structure.
115         :rtype: dict
116         """
117
118         bd_structure = {"name": bd_name}
119
120         for param, value in kwargs.items():
121             if param not in BridgeDomainKeywords.PARAMS:
122                 raise HoneycombError("The parameter {0} is invalid.".
123                                      format(param))
124             bd_structure[param] = str(value)
125
126         return bd_structure
127
128     @staticmethod
129     def get_all_bds_cfg_data(node):
130         """Get configuration data about all bridge domains from Honeycomb.
131
132         :param node: Honeycomb node.
133         :type node: dict
134         :return: Configuration data about all bridge domains from Honeycomb.
135         :rtype: list
136         :raises HoneycombError: If it is not possible to get configuration data.
137         """
138
139         status_code, resp = HcUtil.\
140             get_honeycomb_data(node, "config_bridge_domain")
141         if status_code != HTTPCodes.OK:
142             raise HoneycombError(
143                 "Not possible to get configuration information about the "
144                 "bridge domains. Status code: {0}.".format(status_code))
145         try:
146             return resp["bridge-domains"]["bridge-domain"]
147
148         except (KeyError, TypeError):
149             return []
150
151     @staticmethod
152     def get_bd_cfg_data(node, bd_name):
153         """Get configuration data about the given bridge domain from Honeycomb.
154
155         :param node: Honeycomb node.
156         :param bd_name: The name of bridge domain.
157         :type node: dict
158         :type bd_name: str
159         :return: Configuration data about the given bridge domain from
160         Honeycomb.
161         :rtype: dict
162         """
163
164         intfs = BridgeDomainKeywords.get_all_bds_cfg_data(node)
165         for intf in intfs:
166             if intf["name"] == bd_name:
167                 return intf
168         return {}
169
170     @staticmethod
171     def get_all_bds_oper_data(node):
172         """Get operational data about all bridge domains from Honeycomb.
173
174         :param node: Honeycomb node.
175         :type node: dict
176         :return: Operational data about all bridge domains from Honeycomb.
177         :rtype: list
178         :raises HoneycombError: If it is not possible to get operational data.
179         """
180
181         status_code, resp = HcUtil.\
182             get_honeycomb_data(node, "oper_bridge_domains")
183         if status_code != HTTPCodes.OK:
184             raise HoneycombError(
185                 "Not possible to get operational information about the "
186                 "bridge domains. Status code: {0}.".format(status_code))
187         try:
188             return resp["bridge-domains"]["bridge-domain"]
189
190         except (KeyError, TypeError):
191             return []
192
193     @staticmethod
194     def get_bd_oper_data(node, bd_name):
195         """Get operational data about the given bridge domain from Honeycomb.
196
197         :param node: Honeycomb node.
198         :param bd_name: The name of bridge domain.
199         :type node: dict
200         :type bd_name: str
201         :return: Operational data about the given bridge domain from Honeycomb.
202         :rtype: dict
203         """
204
205         intfs = BridgeDomainKeywords.get_all_bds_oper_data(node)
206         for intf in intfs:
207             if intf["name"] == bd_name:
208                 return intf
209         return {}
210
211     @staticmethod
212     def add_first_bd(node, bd_name, **kwargs):
213         """Add the first bridge domain.
214
215         If there are any other bridge domains configured, they will be removed.
216
217         :param node: Honeycomb node.
218         :param bd_name: Bridge domain name.
219         :param kwargs: Parameters and their values. The accepted parameters are
220         defined in BridgeDomainKeywords.PARAMS
221         :type node: dict
222         :type bd_name: str
223         :type kwargs: dict
224         :return: Bridge domain data structure.
225         :rtype: dict
226         """
227
228         path = ("bridge-domains", )
229         new_bd = BridgeDomainKeywords._create_bd_structure(bd_name, **kwargs)
230         bridge_domain = {"bridge-domain": [new_bd, ]}
231         return BridgeDomainKeywords._set_bd_properties(node, bd_name, path,
232                                                        bridge_domain)
233
234     @staticmethod
235     def add_bd(node, bd_name, **kwargs):
236         """Add a bridge domain.
237
238         :param node: Honeycomb node.
239         :param bd_name: Bridge domain name.
240         :param kwargs: Parameters and their values. The accepted parameters are
241         defined in BridgeDomainKeywords.PARAMS
242         :type node: dict
243         :type bd_name: str
244         :type kwargs: dict
245         :return: Bridge domain data structure.
246         :rtype: dict
247         """
248
249         path = ("bridge-domains", "bridge-domain")
250         new_bd = BridgeDomainKeywords._create_bd_structure(bd_name, **kwargs)
251         bridge_domain = [new_bd, ]
252         return BridgeDomainKeywords._set_bd_properties(node, bd_name, path,
253                                                        bridge_domain)
254
255     @staticmethod
256     def remove_all_bds(node):
257         """Remove all bridge domains.
258
259         :param node: Honeycomb node.
260         :type node: dict
261         :return: Content of response.
262         :rtype: bytearray
263         :raises HoneycombError: If it is not possible to remove all bridge
264         domains.
265         """
266
267         data = {"bridge-domains": {"bridge-domain": []}}
268         status_code, resp = HcUtil.\
269             put_honeycomb_data(node, "config_bridge_domain", data)
270         if status_code != HTTPCodes.OK:
271             raise HoneycombError("Not possible to remove all bridge domains. "
272                                  "Status code: {0}.".format(status_code))
273         return resp
274
275     @staticmethod
276     def remove_bridge_domain(node, bd_name):
277         """Remove a bridge domain.
278
279         :param node:  Honeycomb node.
280         :param bd_name: The name of bridge domain to be removed.
281         :type node: dict
282         :type bd_name: str
283         :return: Content of response.
284         :rtype: bytearray
285         :raises HoneycombError:If it is not possible to remove the bridge
286         domain.
287         """
288
289         path = ("bridge-domains", ("bridge-domain", "name", bd_name))
290
291         status_code, resp = HcUtil.\
292             get_honeycomb_data(node, "config_bridge_domain")
293         if status_code != HTTPCodes.OK:
294             raise HoneycombError(
295                 "Not possible to get configuration information about the "
296                 "bridge domains. Status code: {0}.".format(status_code))
297
298         new_data = HcUtil.remove_item(resp, path)
299         status_code, resp = HcUtil.\
300             put_honeycomb_data(node, "config_bridge_domain", new_data)
301         if status_code != HTTPCodes.OK:
302             raise HoneycombError("Not possible to remove bridge domain {0}. "
303                                  "Status code: {1}.".
304                                  format(bd_name, status_code))
305         return resp
306
307     @staticmethod
308     def configure_bridge_domain(node, bd_name, param, value):
309         """Configure a bridge domain.
310
311         :param node: Honeycomb node.
312         :param bd_name: Bridge domain name.
313         :param param: Parameter to set, change or remove. The accepted
314         parameters are defined in BridgeDomainKeywords.PARAMS
315         :param value: The new value to be set, change or remove. If None, the
316         item will be removed.
317         :type node: dict
318         :type bd_name: str
319         :type param: str
320         :type value: str
321         :return: Content of response.
322         :rtype: bytearray
323         """
324
325         if param not in BridgeDomainKeywords.PARAMS:
326             raise HoneycombError("The parameter {0} is invalid.".format(param))
327
328         path = ("bridge-domains", ("bridge-domain", "name", bd_name), param)
329         return BridgeDomainKeywords.\
330             _set_bd_properties(node, bd_name, path, value)