ca50cc31201d950d9497d8b504e19e02c7b1626f
[csit.git] / resources / libraries / python / honeycomb / BGP.py
1 # Copyright (c) 2017 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 BGP configuration using Honeycomb REST API."""
15
16 from resources.libraries.python.HTTPRequest import HTTPCodes
17 from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError
18 from resources.libraries.python.honeycomb.HoneycombUtil \
19     import HoneycombUtil as HcUtil
20
21
22 class BGPKeywords(object):
23     """Keywords to manipulate BGP configuration.
24
25     Implements keywords which read configuration and operational data for
26     the BGP feature, and configure BGP parameters using Honeycomb REST API.
27     """
28
29     def __init__(self):
30         pass
31
32     @staticmethod
33     def _configure_bgp_peer(node, path, data=None):
34         """Send BGP peer configuration data and check the response.
35
36         :param node: Honeycomb node.
37         :param path: Additional path to append to the base BGP config path.
38         :param data: Configuration data to be sent in PUT request.
39         :type node: dict
40         :type path: str
41         :type data: dict
42         :returns: Content of response.
43         :rtype: bytearray
44         :raises HoneycombError: If the status code in response on PUT is not
45         200 = OK or 201 = ACCEPTED.
46         """
47
48         if data is None:
49             status_code, resp = HcUtil. \
50                 delete_honeycomb_data(node, "config_bgp_peer", path)
51         else:
52             status_code, resp = HcUtil.\
53                 put_honeycomb_data(node, "config_bgp_peer", data, path)
54         if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
55             raise HoneycombError(
56                 "The configuration of BGP peer was not successful. "
57                 "Status code: {0}.".format(status_code))
58         return resp
59
60     @staticmethod
61     def _configure_bgp_route(node, path, data=None):
62         """Send BGP route configuration data and check the response.
63
64         :param node: Honeycomb node.
65         :param path: Additional path to append to the base BGP config path.
66         :param data: Configuration data to be sent in PUT request.
67         :type node: dict
68         :type path: str
69         :type data: dict
70         :returns: Content of response.
71         :rtype: bytearray
72         :raises HoneycombError: If the status code in response on PUT is not
73         200 = OK or 201 = ACCEPTED.
74         """
75
76         if data is None:
77             status_code, resp = HcUtil. \
78                 delete_honeycomb_data(node, "config_bgp_route", path)
79         else:
80             status_code, resp = HcUtil. \
81                 put_honeycomb_data(node, "config_bgp_route", data, path)
82         if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED):
83             raise HoneycombError(
84                 "The configuration of BGP route was not successful. "
85                 "Status code: {0}.".format(status_code))
86         return resp
87
88     @staticmethod
89     def get_full_bgp_configuration(node):
90         """Get BGP configuration from the node.
91
92         :param node: Honeycomb node.
93         :type node: dict
94         :returns: BGP configuration data.
95         :rtype: dict
96         """
97
98         status_code, resp = HcUtil. \
99             get_honeycomb_data(node, "config_bgp_peer")
100         if status_code != HTTPCodes.OK:
101             raise HoneycombError(
102                 "Not possible to get configuration information about BGP."
103                 " Status code: {0}.".format(status_code))
104         return resp
105
106     @staticmethod
107     def get_bgp_peer(node, address):
108         """Get BGP configuration of the specified peer from the node.
109
110         :param node: Honeycomb node.
111         :param address: IP address of the peer.
112         :type node: dict
113         :type address: str
114         :returns: BGP peer configuration data.
115         :rtype: dict
116         """
117
118         path = "bgp-openconfig-extensions:neighbors/" \
119                "neighbor/{0}".format(address)
120         status_code, resp = HcUtil. \
121             get_honeycomb_data(node, "config_bgp_peer", path)
122         if status_code != HTTPCodes.OK:
123             raise HoneycombError(
124                 "Not possible to get configuration information about the BGP"
125                 " peer. Status code: {0}.".format(status_code))
126         return resp
127
128     @staticmethod
129     def add_bgp_peer(node, address, data):
130         """Configure a BGP peer on the node.
131
132         :param node: Honeycomb node.
133         :param address: IP address of the peer.
134         :param data: Peer configuration data.
135         :type node: dict
136         :type address: str
137         :type data: dict
138         :returns: Content of response.
139         :rtype: bytearray
140         """
141
142         path = "bgp-openconfig-extensions:neighbors/neighbor/{address}".format(
143             address=address)
144         return BGPKeywords._configure_bgp_peer(node, path, data)
145
146     @staticmethod
147     def remove_bgp_peer(node, address):
148         """Remove a BGP peer from the configuration.
149
150         :param node: Honeycomb node.
151         :param address: IP address of the peer.
152         :type node: dict
153         :type address: str
154         :returns: Content of response.
155         :rtype: bytearray
156         """
157
158         path = "bgp-openconfig-extensions:neighbors/neighbor/{address}".format(
159             address=address)
160         return BGPKeywords._configure_bgp_peer(node, path)
161
162     @staticmethod
163     def configure_bgp_route(node, peer_address, data, route_address,
164                             index, ip_version):
165         """Configure a route for the BGP peer specified by peer IP address.
166
167         :param node: Honeycomb node.
168         :param peer_address: IP address of the BGP peer.
169         :param data: Route configuration data.
170         :param route_address: IP address of the route.
171         :param index: Index number of the route within specified peer.
172         :param ip_version: IP protocol version. ipv4 or ipv6
173         :type node: dict
174         :type peer_address: str
175         :type data: dict
176         :type route_address: str
177         :type index: int
178         :type ip_version: str
179         :returns: Content of response.
180         :rtype: bytearray
181         """
182
183         route_address = route_address.replace("/", "%2F")
184
185         if ip_version.lower() == "ipv4":
186             path = "{0}/tables/bgp-types:ipv4-address-family/" \
187                    "bgp-types:unicast-subsequent-address-family/" \
188                    "bgp-inet:ipv4-routes/ipv4-route/{1}/{2}" \
189                 .format(peer_address, route_address, index)
190         else:
191             path = "{0}/tables/bgp-types:ipv6-address-family/" \
192                    "bgp-types:unicast-subsequent-address-family/" \
193                    "bgp-inet:ipv6-routes/ipv6-route/{1}/{2}" \
194                 .format(peer_address, route_address, index)
195
196         return BGPKeywords._configure_bgp_route(node, path, data)
197
198     @staticmethod
199     def get_bgp_route(node, peer_address, route_address, index, ip_version):
200         """Get all BGP peers from operational data.
201
202         :param node: Honeycomb node.
203         :param peer_address: IP address of the BGP peer.
204         :param route_address: IP address of the route.
205         :param index: Index number of the route within specified peer.
206         :param ip_version: IP protocol version. ipv4 or ipv6
207         :type node: dict
208         :type peer_address: str
209         :type route_address: str
210         :type index: int
211         :type ip_version: str
212         :returns: Content of response.
213         :rtype: bytearray
214         :raises HoneycombError: If the operation fails.
215         """
216
217         route_address = route_address.replace("/", "%2F")
218
219         if ip_version.lower() == "ipv4":
220             path = "{0}/tables/bgp-types:ipv4-address-family/" \
221                    "bgp-types:unicast-subsequent-address-family/" \
222                    "bgp-inet:ipv4-routes/ipv4-route/{1}/{2}" \
223                 .format(peer_address, route_address, index)
224         else:
225             path = "{0}/tables/bgp-types:ipv6-address-family/" \
226                    "bgp-types:unicast-subsequent-address-family/" \
227                    "bgp-inet:ipv6-routes/ipv6-route/{1}/{2}" \
228                 .format(peer_address, route_address, index)
229         status_code, resp = HcUtil. \
230             get_honeycomb_data(node, "config_bgp_route", path)
231         if status_code != HTTPCodes.OK:
232             raise HoneycombError(
233                 "Not possible to get configuration information about the BGP"
234                 " route. Status code: {0}.".format(status_code))
235
236         return resp
237
238     @staticmethod
239     def get_all_peer_routes(node, peer_address, ip_version):
240         """Get all configured routes for the given BGP peer.
241
242         :param node: HOneycomb node.
243         :param peer_address: IP address of the peer.
244         :param ip_version: IP protocol version. ipv4 or ipv6
245         :type node: dict
246         :type peer_address: str
247         :type ip_version: str
248         :returns: Content of response.
249         :rtype: bytearray
250         :raises HoneycombError: If the operation fails.
251         """
252
253         if ip_version.lower() == "ipv4":
254             path = "{0}/tables/bgp-types:ipv4-address-family/" \
255                    "bgp-types:unicast-subsequent-address-family/" \
256                    "bgp-inet:ipv4-routes".format(peer_address)
257         else:
258             path = "{0}/tables/bgp-types:ipv6-address-family/" \
259                    "bgp-types:unicast-subsequent-address-family/" \
260                    "bgp-inet:ipv6-routes".format(peer_address)
261         status_code, resp = HcUtil. \
262             get_honeycomb_data(node, "config_bgp_route", path)
263         if status_code != HTTPCodes.OK:
264             raise HoneycombError(
265                 "Not possible to get configuration information about BGP"
266                 " routes. Status code: {0}.".format(status_code))
267
268         return resp
269
270     @staticmethod
271     def remove_bgp_route(node, peer_address, route_address, index, ip_version):
272         """Remove the specified BGP route from configuration.
273
274         :param node: Honeycomb node.
275         :param peer_address: IP address of the BGP peer.
276         :param route_address: IP address of the route.
277         :param index: Index number of the route within specified peer.
278         :param ip_version: IP protocol version. ipv4 or ipv6
279         :type node: dict
280         :type peer_address: str
281         :type route_address: str
282         :type index: int
283         :type ip_version: str
284         :returns: Content of response.
285         :rtype: bytearray
286         """
287
288         route_address = route_address.replace("/", "%2F")
289
290         if ip_version.lower() == "ipv4":
291             path = "{0}/tables/bgp-types:ipv4-address-family/" \
292                    "bgp-types:unicast-subsequent-address-family/" \
293                    "bgp-inet:ipv4-routes/ipv4-route/{1}/{2}" \
294                 .format(peer_address, route_address, index)
295         else:
296             path = "{0}/tables/bgp-types:ipv6-address-family/" \
297                    "bgp-types:unicast-subsequent-address-family/" \
298                    "bgp-inet:ipv6-routes/ipv6-route/{1}/{2}" \
299                 .format(peer_address, route_address, index)
300
301         return BGPKeywords._configure_bgp_route(node, path)