X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2Fhoneycomb%2FBGP.py;fp=resources%2Flibraries%2Fpython%2Fhoneycomb%2FBGP.py;h=0000000000000000000000000000000000000000;hp=976e41d37993bea9f3cbd2777c71b025c7e50929;hb=e7ad66f3147662973039caaac33015de7e0c6f8c;hpb=20cc67d5f23a7f4e05b08012bf3d3a63be4bcf63 diff --git a/resources/libraries/python/honeycomb/BGP.py b/resources/libraries/python/honeycomb/BGP.py deleted file mode 100644 index 976e41d379..0000000000 --- a/resources/libraries/python/honeycomb/BGP.py +++ /dev/null @@ -1,396 +0,0 @@ -# Copyright (c) 2018 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Keywords to manipulate BGP configuration using Honeycomb REST API.""" - -from resources.libraries.python.Constants import Constants as Const -from resources.libraries.python.HTTPRequest import HTTPCodes -from resources.libraries.python.honeycomb.HoneycombSetup import HoneycombError -from resources.libraries.python.honeycomb.HoneycombUtil \ - import HoneycombUtil as HcUtil - - -class BGPKeywords(object): - """Keywords to manipulate BGP configuration. - - Implements keywords which read configuration and operational data for - the BGP feature, and configure BGP parameters using Honeycomb REST API. - """ - - def __init__(self): - """Initializer.""" - pass - - @staticmethod - def _configure_bgp_peer(node, path, data=None): - """Send BGP peer configuration data and check the response. - - :param node: Honeycomb node. - :param path: Additional path to append to the base BGP config path. - :param data: Configuration data to be sent in PUT request. - :type node: dict - :type path: str - :type data: dict - :returns: Content of response. - :rtype: bytearray - :raises HoneycombError: If the status code in response to PUT is not - 200 = OK or 201 = ACCEPTED. - """ - - if data is None: - status_code, resp = HcUtil. \ - delete_honeycomb_data(node, "config_bgp_peer", path) - else: - status_code, resp = HcUtil.\ - put_honeycomb_data(node, "config_bgp_peer", data, path) - if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED): - raise HoneycombError( - "The configuration of BGP peer was not successful. " - "Status code: {0}.".format(status_code)) - return resp - - @staticmethod - def _configure_bgp_route(node, path, data=None): - """Send BGP route configuration data and check the response. - - :param node: Honeycomb node. - :param path: Additional path to append to the base BGP config path. - :param data: Configuration data to be sent in PUT request. - :type node: dict - :type path: str - :type data: dict - :returns: Content of response. - :rtype: bytearray - :raises HoneycombError: If the status code in response to PUT is not - 200 = OK or 201 = ACCEPTED. - """ - - if data is None: - status_code, resp = HcUtil. \ - delete_honeycomb_data(node, "config_bgp_route", path) - else: - status_code, resp = HcUtil. \ - put_honeycomb_data(node, "config_bgp_route", data, path) - if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED): - raise HoneycombError( - "The configuration of BGP route was not successful. " - "Status code: {0}.".format(status_code)) - return resp - - @staticmethod - def get_full_bgp_configuration(node): - """Get BGP configuration from the node. - - :param node: Honeycomb node. - :type node: dict - :returns: BGP configuration data. - :rtype: dict - :raises HoneycombError: If the status code in response is not 200 = OK. - """ - - status_code, resp = HcUtil. \ - get_honeycomb_data(node, "config_bgp_peer") - if status_code != HTTPCodes.OK: - raise HoneycombError( - "Not possible to get configuration information about BGP." - " Status code: {0}.".format(status_code)) - return resp - - @staticmethod - def get_bgp_peer(node, address, datastore='config'): - """Get BGP configuration of the specified peer from the node. - - :param node: Honeycomb node. - :param address: IP address of the peer. - :param datastore: Get data from config or operational datastore. - :type node: dict - :type address: str - :type datastore: str - :returns: BGP peer configuration data. - :rtype: dict - :raises HoneycombError: If the status code in response is not 200 = OK. - """ - - path = "bgp-openconfig-extensions:neighbors/" \ - "neighbor/{0}".format(address) - if datastore != "operational": - url = "config_bgp_peer" - else: - url = "oper_bgp" - path = "peer/bgp:%2F%2F{0}".format(address) - status_code, resp = HcUtil. \ - get_honeycomb_data(node, url, path) - if status_code != HTTPCodes.OK: - raise HoneycombError( - "Not possible to get configuration information about the BGP" - " peer. Status code: {0}.".format(status_code)) - return resp - - @staticmethod - def add_bgp_peer(node, address, data): - """Configure a BGP peer on the node. - - :param node: Honeycomb node. - :param address: IP address of the peer. - :param data: Peer configuration data. - :type node: dict - :type address: str - :type data: dict - :returns: Content of response. - :rtype: bytearray - """ - - path = "bgp-openconfig-extensions:neighbors/neighbor/{address}".format( - address=address) - return BGPKeywords._configure_bgp_peer(node, path, data) - - @staticmethod - def remove_bgp_peer(node, address): - """Remove a BGP peer from the configuration. - - :param node: Honeycomb node. - :param address: IP address of the peer. - :type node: dict - :type address: str - :returns: Content of response. - :rtype: bytearray - """ - - path = "bgp-openconfig-extensions:neighbors/neighbor/{address}".format( - address=address) - return BGPKeywords._configure_bgp_peer(node, path) - - @staticmethod - def configure_bgp_route(node, peer_address, data, route_address, - index, ip_version): - """Configure a route for the BGP peer specified by peer IP address. - - :param node: Honeycomb node. - :param peer_address: IP address of the BGP peer. - :param data: Route configuration data. - :param route_address: IP address of the route. - :param index: Index number of the route within specified peer. - :param ip_version: IP protocol version. ipv4 or ipv6 - :type node: dict - :type peer_address: str - :type data: dict - :type route_address: str - :type index: int - :type ip_version: str - :returns: Content of response. - :rtype: bytearray - """ - - route_address = route_address.replace("/", "%2F") - - if ip_version.lower() == "ipv4": - path = "{0}/tables/bgp-types:ipv4-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv4-routes/ipv4-route/{1}/{2}" \ - .format(peer_address, route_address, index) - else: - path = "{0}/tables/bgp-types:ipv6-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv6-routes/ipv6-route/{1}/{2}" \ - .format(peer_address, route_address, index) - - return BGPKeywords._configure_bgp_route(node, path, data) - - @staticmethod - def get_bgp_route(node, peer_address, route_address, index, ip_version): - """Get all BGP peers from operational data. - - :param node: Honeycomb node. - :param peer_address: IP address of the BGP peer. - :param route_address: IP address of the route. - :param index: Index number of the route within specified peer. - :param ip_version: IP protocol version. ipv4 or ipv6 - :type node: dict - :type peer_address: str - :type route_address: str - :type index: int - :type ip_version: str - :returns: Content of response. - :rtype: bytearray - :raises HoneycombError: If the status code in response is not 200 = OK. - """ - - route_address = route_address.replace("/", "%2F") - - if ip_version.lower() == "ipv4": - path = "{0}/tables/bgp-types:ipv4-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv4-routes/ipv4-route/{1}/{2}" \ - .format(peer_address, route_address, index) - else: - path = "{0}/tables/bgp-types:ipv6-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv6-routes/ipv6-route/{1}/{2}" \ - .format(peer_address, route_address, index) - status_code, resp = HcUtil. \ - get_honeycomb_data(node, "config_bgp_route", path) - if status_code != HTTPCodes.OK: - raise HoneycombError( - "Not possible to get configuration information about the BGP" - " route. Status code: {0}.".format(status_code)) - - return resp - - @staticmethod - def get_all_peer_routes(node, peer_address, ip_version): - """Get all configured routes for the given BGP peer. - - :param node: Honeycomb node. - :param peer_address: IP address of the peer. - :param ip_version: IP protocol version. ipv4 or ipv6 - :type node: dict - :type peer_address: str - :type ip_version: str - :returns: Content of response. - :rtype: bytearray - :raises HoneycombError: If the status code in response is not 200 = OK. - """ - - if ip_version.lower() == "ipv4": - path = "{0}/tables/bgp-types:ipv4-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv4-routes".format(peer_address) - else: - path = "{0}/tables/bgp-types:ipv6-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv6-routes".format(peer_address) - status_code, resp = HcUtil. \ - get_honeycomb_data(node, "config_bgp_route", path) - if status_code != HTTPCodes.OK: - raise HoneycombError( - "Not possible to get configuration information about BGP" - " routes. Status code: {0}.".format(status_code)) - - return resp - - @staticmethod - def remove_bgp_route(node, peer_address, route_address, index, ip_version): - """Remove the specified BGP route from configuration. - - :param node: Honeycomb node. - :param peer_address: IP address of the BGP peer. - :param route_address: IP address of the route. - :param index: Index number of the route within specified peer. - :param ip_version: IP protocol version. ipv4 or ipv6 - :type node: dict - :type peer_address: str - :type route_address: str - :type index: int - :type ip_version: str - :returns: Content of response. - :rtype: bytearray - """ - - route_address = route_address.replace("/", "%2F") - - if ip_version.lower() == "ipv4": - path = "{0}/tables/bgp-types:ipv4-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv4-routes/ipv4-route/{1}/{2}" \ - .format(peer_address, route_address, index) - else: - path = "{0}/tables/bgp-types:ipv6-address-family/" \ - "bgp-types:unicast-subsequent-address-family/" \ - "bgp-inet:ipv6-routes/ipv6-route/{1}/{2}" \ - .format(peer_address, route_address, index) - - return BGPKeywords._configure_bgp_route(node, path) - - @staticmethod - def get_bgp_local_rib(node): - """Get local RIB table from the Honeycomb node. - - :param node: Honeycomb node. - :type node: dict - :returns: RIB operational data. - :rtype: dict - :raises HoneycombError: If the status code in response is not 200 = OK. - """ - - path = "loc-rib" - - status_code, resp = HcUtil. \ - get_honeycomb_data(node, "oper_bgp", path) - - if status_code != HTTPCodes.OK: - raise HoneycombError( - "Not possible to get operational data from BGP local RIB." - " Status code: {0}.".format(status_code)) - - return resp - - @staticmethod - def configure_bgp_base(node, ip_address, port, as_number): - """Modify BGP config file. Requires a restart of Honeycomb to take - effect. - - :param node: Honeycomb node. - :param ip_address: BGP peer identifier/binding address. - :param port: BGP binding port. - :param as_number: Autonomous System ID number. - :type node: dict - :type ip_address: str - :type port: int - :type as_number: int - :raises HoneycombError: If modifying the configuration fails. - """ - - from resources.libraries.python.ssh import SSH - - config = { - '\\"bgp-binding-address\\"': '\\"{0}\\"'.format(ip_address), - '\\"bgp-port\\"': port, - '\\"bgp-as-number\\"': as_number} - - path = "{0}/config/bgp.json".format(Const.REMOTE_HC_DIR) - - for key, value in config.items(): - find = key - replace = '"{0}": "{1}",'.format(key, value) - - argument = '"/{0}/c\\ {1}"'.format(find, replace) - command = "sed -i {0} {1}".format(argument, path) - - ssh = SSH() - ssh.connect(node) - (ret_code, _, stderr) = ssh.exec_command_sudo(command) - if ret_code != 0: - raise HoneycombError("Failed to modify configuration on " - "node {0}, {1}".format(node, stderr)) - - @staticmethod - def compare_rib_tables(data, ref): - """Compare provided RIB table with reference. All reference entries must - be present in data. Data entries not present in reference are ignored. - - :param data: Data from Honeycomb node. - :param ref: Reference data to compare against. - :type data: dict - :type ref: dict - :raises HoneycombError: If the tables do not match. - """ - - # Remove runtime attributes from data - for item in data: - item.pop("attributes", "") - - for item in ref: - if item not in data: - raise HoneycombError( - "RIB entry {0} not found in operational data {1}." - .format(item, data))