diff options
-rw-r--r-- | resources/libraries/python/honeycomb/BGP.py | 301 | ||||
-rw-r--r-- | resources/libraries/python/honeycomb/HoneycombSetup.py | 38 | ||||
-rw-r--r-- | resources/libraries/python/honeycomb/Routing.py | 2 | ||||
-rw-r--r-- | resources/libraries/robot/honeycomb/bgp.robot | 173 | ||||
-rw-r--r-- | resources/templates/honeycomb/config_bgp_peer.url | 1 | ||||
-rw-r--r-- | resources/templates/honeycomb/config_bgp_route.url | 1 | ||||
-rw-r--r-- | resources/templates/honeycomb/oper_bgp.url | 1 | ||||
-rw-r--r-- | resources/test_data/honeycomb/bgp.py | 192 | ||||
-rw-r--r-- | tests/vpp/func/honeycomb/mgmt-cfg-bgp-apihc-apivat-func.robot | 163 |
9 files changed, 855 insertions, 17 deletions
diff --git a/resources/libraries/python/honeycomb/BGP.py b/resources/libraries/python/honeycomb/BGP.py new file mode 100644 index 0000000000..ca50cc3120 --- /dev/null +++ b/resources/libraries/python/honeycomb/BGP.py @@ -0,0 +1,301 @@ +# Copyright (c) 2017 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.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): + 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 on 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 on 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 + """ + + 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): + """Get BGP configuration of the specified peer from the node. + + :param node: Honeycomb node. + :param address: IP address of the peer. + :type node: dict + :type address: str + :returns: BGP peer configuration data. + :rtype: dict + """ + + path = "bgp-openconfig-extensions:neighbors/" \ + "neighbor/{0}".format(address) + status_code, resp = HcUtil. \ + get_honeycomb_data(node, "config_bgp_peer", 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 operation fails. + """ + + 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 operation fails. + """ + + 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) diff --git a/resources/libraries/python/honeycomb/HoneycombSetup.py b/resources/libraries/python/honeycomb/HoneycombSetup.py index d10a5ccb4e..fba2bd4225 100644 --- a/resources/libraries/python/honeycomb/HoneycombSetup.py +++ b/resources/libraries/python/honeycomb/HoneycombSetup.py @@ -293,7 +293,8 @@ class HoneycombSetup(object): "which java", "java -version", "dpkg --list | grep openjdk", - "ls -la /opt/honeycomb") + "ls -la /opt/honeycomb", + "cat /opt/honeycomb/modules/*module-config") for node in nodes: if node['type'] == NodeType.DUT: @@ -365,27 +366,32 @@ class HoneycombSetup(object): """ disabled_features = { - "NSH": "io.fd.hc2vpp.vppnsh.impl.VppNshModule" + "NSH": ["io.fd.hc2vpp.vppnsh.impl.VppNshModule"], + "BGP": ["io.fd.hc2vpp.bgp.inet.BgpInetModule", + "io.fd.honeycomb.infra.bgp.BgpModule", + "io.fd.honeycomb.infra.bgp.BgpReadersModule", + "io.fd.honeycomb.infra.bgp.BgpWritersModule"] } ssh = SSH() ssh.connect(node) if feature in disabled_features.keys(): - # uncomment by replacing the entire line - find = replace = "{0}".format(disabled_features[feature]) - if disable: - replace = "// {0}".format(find) - - argument = '"/{0}/c\\ {1}"'.format(find, replace) - path = "{0}/modules/*module-config"\ - .format(Const.REMOTE_HC_DIR) - command = "sed -i {0} {1}".format(argument, path) - - (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)) + # for every module, uncomment by replacing the entire line + for item in disabled_features[feature]: + find = replace = "{0}".format(item) + if disable: + replace = "// {0}".format(find) + + argument = '"/{0}/c\\ {1}"'.format(find, replace) + path = "{0}/modules/*module-config"\ + .format(Const.REMOTE_HC_DIR) + command = "sed -i {0} {1}".format(argument, path) + + (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)) else: raise HoneycombError( "Unrecognized feature {0}.".format(feature)) diff --git a/resources/libraries/python/honeycomb/Routing.py b/resources/libraries/python/honeycomb/Routing.py index 495e96e0fd..4c6a3f205b 100644 --- a/resources/libraries/python/honeycomb/Routing.py +++ b/resources/libraries/python/honeycomb/Routing.py @@ -157,7 +157,7 @@ class RoutingKeywords(object): if status_code != HTTPCodes.OK: raise HoneycombError( "Not possible to get operational information about the " - "classify tables. Status code: {0}.".format(status_code)) + "routing tables. Status code: {0}.".format(status_code)) data = RoutingKeywords.clean_routing_oper_data( resp['routing-protocol'][0]['static-routes'] diff --git a/resources/libraries/robot/honeycomb/bgp.robot b/resources/libraries/robot/honeycomb/bgp.robot new file mode 100644 index 0000000000..d4c2d6b0a2 --- /dev/null +++ b/resources/libraries/robot/honeycomb/bgp.robot @@ -0,0 +1,173 @@ +# Copyright (c) 2017 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. + +*** Settings *** +| Library | resources.libraries.python.honeycomb.BGP.BGPKeywords +| Library | resources.libraries.python.honeycomb.HcAPIKwInterfaces.InterfaceKeywords + +*** Keywords *** +| No BGP peers should be configured +| | [Documentation] | Uses Honeycomb API to read BGP configuration and checks +| | ... | if there ary BGP peers conffigured. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| No BGP peers should be configured \| ${nodes['DUT1']} \| +| | ... +| | [Arguments] | ${node} +| | ... +| | ${oper_data}= | Get Full BGP Configuration | ${node} +| | Should be Empty | ${oper_data['bgp-openconfig-extensions:bgp']['neighbors']} + +| Honeycomb adds BGP peer +| | [Documentation] | Uses Honeycomb API to add a BGP peer. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - address - IP address of the peer. Type: string +| | ... | - data - Peer configuration data. Type: dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb adds BGP peer \| ${nodes['DUT1']} \| 192.168.0.1 \ +| | ... | \| ${data} \| +| | ... +| | [Arguments] | ${node} | ${address} | ${data} +| | ... +| | Add BGP Peer | ${node} | ${address} | ${data} + +| BGP Peer From Honeycomb Should be +| | [Documentation] | Uses Honeycomb API to verify BGP peer operational data. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - address - IP address of the peer. Type: string +| | ... | - data - Peer configuration data. Type: dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| BGP Peer From Honeycomb Should be \ +| | ... | \| ${nodes['DUT1']} \| 192.168.0.1 \| ${data} \| +| | ... +| | [Arguments] | ${node} | ${address} | ${data} +| | ... +| | ${oper_data}= | Get BGP Peer | ${node} | ${address} +| | Compare Data Structures | ${oper_data} | ${data} + +| Honeycomb removes BGP peer +| | [Documentation] | Uses Honeycomb API to add a BGP peer. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - address - IP address of the peer. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb adds BGP peer \| ${nodes['DUT1']} \| 192.168.0.1 \| +| | ... +| | [Arguments] | ${node} | ${address} +| | ... +| | Remove BGP Peer | ${node} | ${address} + +| Honeycomb configures BGP route +| | [Documentation] | Uses Honeycomb API to add a BGP route\ +| | ... | to the specified peer. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - peer_address - IP address of the peer. Type: string +| | ... | - data - Peer configuration data. Type: dictionary +| | ... | - route_address - IP address of the route. Type: string +| | ... | - route_index - Numeric index of the route under the peer.\ +| | ... | Type: integer +| | ... | - ip_version - IP protocol version, ipv4 or ipv6. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb adds BGP peer \| ${nodes['DUT1']} \| 192.168.0.1 \ +| | ... | \| ${data} \| 192.168.0.2 \| ${0} \| ipv4 \| +| | ... +| | [Arguments] | ${node} | ${peer_address} | ${data} +| | ... | ${route_address} | ${route_index} | ${ip_version} +| | ... +| | Configure BGP Route | ${node} | ${peer_address} | ${data} +| | ... | ${route_address} | ${route_index} | ${ip_version} + +| BGP Route From Honeycomb Should be +| | [Documentation] | Uses Honeycomb API to verify BGP route operational data. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - peer_address - IP address of the peer. Type: string +| | ... | - data - Peer configuration data. Type: dictionary +| | ... | - route_address - IP address of the route. Type: string +| | ... | - route_index - Numeric index of the route under the peer.\ +| | ... | Type: integer +| | ... | - ip_version - IP protocol version, ipv4 or ipv6. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| BGP Peers From Honeycomb Should Include \ +| | ... | \| ${nodes['DUT1']} \| ${data} \| +| | ... +| | [Arguments] | ${node} | ${peer_address} | ${data} +| | ... | ${route_address} | ${route_index} | ${ip_version} +| | ... +| | ${oper_data}= | Get BGP Route | ${node} | ${peer_address} +| | ... | ${route_address} | ${route_index} | ${ip_version} +| | Compare Data Structures | ${oper_data} | ${data} + +| Honeycomb removes BGP route +| | [Documentation] | Uses Honeycomb API to remove a BGP route. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - peer_address - IP address of the peer. Type: string +| | ... | - route_address - IP address of the route. Type: string +| | ... | - route_index - Numeric index of the route under the peer.\ +| | ... | Type: integer +| | ... | - ip_version - IP protocol version, ipv4 or ipv6. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb removes BGP route \| ${nodes['DUT1']} \| 192.168.0.1 \ +| | ... | \| 192.168.0.2 \| ${0} \| ipv4 \| +| | ... +| | [Arguments] | ${node} | ${peer_address} | ${route_address} +| | ... | ${route_index} | ${ip_version} +| | ... +| | Remove BGP Route | ${node} | ${peer_address} | ${route_address} +| | ... | ${route_index} | ${ip_version} + +| No BGP routes should be configured +| | [Documentation] | Uses Honeycomb API to verify that no BGP routes\ +| | ... | are configured under the specified peer. +| | ... +| | ... | *Arguments:* +| | ... | - node - Information about a DUT node. Type: dictionary +| | ... | - peer_address - IP address of the peer. Type: string +| | ... | - ip_version - IP protocol version, ipv4 or ipv6. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| No BGP routes should be configured \| ${nodes['DUT1']} \ +| | ... | \| 192.168.0.1 \| ipv4 \| +| | ... +| | [Arguments] | ${node} | ${peer_address} | ${ip_version} +| | ... +| | ${oper_data}= | Get All Peer Routes +| | ... | ${node} | ${peer_address} | ${ip_version} +| | Should be Empty | ${oper_data['bgp-inet:${ip_version}-routes']} diff --git a/resources/templates/honeycomb/config_bgp_peer.url b/resources/templates/honeycomb/config_bgp_peer.url new file mode 100644 index 0000000000..b5f0666f07 --- /dev/null +++ b/resources/templates/honeycomb/config_bgp_peer.url @@ -0,0 +1 @@ +/restconf/config{odl_url_part}/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/protocol/openconfig-policy-types:BGP/hc-bgp-instance/bgp/
\ No newline at end of file diff --git a/resources/templates/honeycomb/config_bgp_route.url b/resources/templates/honeycomb/config_bgp_route.url new file mode 100644 index 0000000000..71d7f0a250 --- /dev/null +++ b/resources/templates/honeycomb/config_bgp_route.url @@ -0,0 +1 @@ +/restconf/config{odl_url_part}/bgp-rib:application-rib/
\ No newline at end of file diff --git a/resources/templates/honeycomb/oper_bgp.url b/resources/templates/honeycomb/oper_bgp.url new file mode 100644 index 0000000000..c2f90863c4 --- /dev/null +++ b/resources/templates/honeycomb/oper_bgp.url @@ -0,0 +1 @@ +/restconf/operational{odl_url_part}/bgp-rib:bgp-rib/rib/hc-bgp-instance/
\ No newline at end of file diff --git a/resources/test_data/honeycomb/bgp.py b/resources/test_data/honeycomb/bgp.py new file mode 100644 index 0000000000..f9dc4ab233 --- /dev/null +++ b/resources/test_data/honeycomb/bgp.py @@ -0,0 +1,192 @@ +# Copyright (c) 2017 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. + +from copy import deepcopy + +"""Test variables for BGP test suite.""" + +# Internal BGP peers for CRUD tests +address_internal = "192.168.0.2" +address_internal2 = "192.168.0.3" +peer_internal = { + "bgp-openconfig-extensions:neighbor": [{ + "neighbor-address": address_internal, + "config": { + "peer-type": "INTERNAL" + }, + "timers": { + "config": { + "connect-retry": 10, + "hold-time": 60 + } + }, + "transport": { + "config": { + "remote-port": 17900, + "passive-mode": False + } + }, + "afi-safis": { + "afi-safi": [{ + "afi-safi-name": "openconfig-bgp-types:IPV4-UNICAST", + "receive": True, + "send-max": 0 + }] + } + }] + } + +peer_internal_update = { + "bgp-openconfig-extensions:neighbor": [{ + "neighbor-address": address_internal, + "config": { + "peer-type": "INTERNAL" + }, + "timers": { + "config": { + "connect-retry": 5, + "hold-time": 120 + } + }, + "transport": { + "config": { + "remote-port": 17901, + "passive-mode": True + } + }, + "afi-safis": { + "afi-safi": [{ + "afi-safi-name": "openconfig-bgp-types:IPV6-UNICAST", + "receive": False, + "send-max": 1 + }] + } + }] + } + +peer_internal2 = deepcopy(peer_internal) +peer_internal2["bgp-openconfig-extensions:neighbor"][0]["neighbor-address"] = \ + address_internal2 + +# Application BGP peer for CRUD tests +address_application = "192.168.0.4" +peer_application = { + "bgp-openconfig-extensions:neighbor": [{ + "neighbor-address": address_application, + "config": { + "peer-group": "application-peers" + }, + "afi-safis": { + "afi-safi": [ + { + "afi-safi-name": "openconfig-bgp-types:IPV4-UNICAST", + "receive": True, + "send-max": 0 + }, + { + "afi-safi-name": + "openconfig-bgp-types:IPV4-LABELLED-UNICAST", + "receive": True, + "send-max": 0 + }] + } + }] + } + +route_address_ipv4 = "192.168.0.5/32" +route_id_ipv4 = 0 +route_data_ipv4 = { + "bgp-inet:ipv4-route": [{ + "path-id": route_id_ipv4, + "prefix": route_address_ipv4, + "attributes": { + "as-path": {}, + "origin": { + "value": "igp" + }, + "local-pref": { + "pref": 100 + }, + "ipv4-next-hop": { + "global": "192.168.1.1" + } + } + }] +} + +route_data_ipv4_update = { + "bgp-inet:ipv4-route": [{ + "path-id": route_id_ipv4, + "prefix": route_address_ipv4, + "attributes": { + "as-path": {}, + "origin": { + "value": "egp" + }, + "local-pref": { + "pref": 200 + }, + "ipv4-next-hop": { + "global": "192.168.1.2" + } + } + }] +} + +route_address_ipv4_2 = "192.168.0.6/32" +route_id_ipv4_2 = 1 +route_data_ipv4_2 = { + "bgp-inet:ipv4-route": [{ + "path-id": route_id_ipv4_2, + "prefix": route_address_ipv4_2, + "attributes": { + "as-path": {}, + "origin": { + "value": "igp" + }, + "local-pref": { + "pref": 100 + }, + "ipv4-next-hop": { + "global": "192.168.1.2" + } + } + }] +} + +route_address_ipv6 = "3ffe:62::1/64" +route_id_ipv6 = 0 +route_data_ipv6 = { + "bgp-inet:ipv6-route": [{ + "path-id": route_id_ipv6, + "prefix": route_address_ipv6, + "attributes": { + "as-path": {}, + "origin": { + "value": "igp" + }, + "local-pref": { + "pref": 100 + }, + "ipv6-next-hop": { + "global": "3ffe:63::1" + } + } + }] +} + +table1_oper = { + "destination-prefix": route_address_ipv4, + "next-hop": "192.168.1.1", + "vpp-ipv4-route-state": {} +}
\ No newline at end of file diff --git a/tests/vpp/func/honeycomb/mgmt-cfg-bgp-apihc-apivat-func.robot b/tests/vpp/func/honeycomb/mgmt-cfg-bgp-apihc-apivat-func.robot new file mode 100644 index 0000000000..da662dbc69 --- /dev/null +++ b/tests/vpp/func/honeycomb/mgmt-cfg-bgp-apihc-apivat-func.robot @@ -0,0 +1,163 @@ +# Copyright (c) 2017 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. + +*** Variables *** +# Interface to run tests on. +| ${interface}= | ${node['interfaces']['port1']['name']} + +*** Settings *** +| Resource | resources/libraries/robot/shared/default.robot +| Resource | resources/libraries/robot/honeycomb/honeycomb.robot +| Resource | resources/libraries/robot/honeycomb/interfaces.robot +| Resource | resources/libraries/robot/honeycomb/bgp.robot +| Resource | resources/libraries/robot/honeycomb/routing.robot +| Variables | resources/test_data/honeycomb/bgp.py +| ... +| Suite Setup | Run Keywords +| ... | Enable Honeycomb Feature | ${node} | BGP | AND +| ... | Set Up Honeycomb Functional Test Suite | ${node} +| ... +| Suite Teardown | Run Keywords +| ... | Tear Down Honeycomb Functional Test Suite | ${node} | AND +| ... | Disable Honeycomb Feature | ${node} | BGP +| ... +| Force Tags | HC_FUNC +| ... +| Documentation | *Honeycomb BGP management test suite.* + +*** Test Cases *** +| TC01: Honeycomb configures BGP peer - Internal +| | [Documentation] | Check if Honeycomb can configure an internal BGP peer. +| | ... +| | When Honeycomb adds BGP peer +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | Then BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal} + +| TC03: Honeycomb removes peer configuration +| | [Documentation] | Check if Honeycomb can remove a configured BGP peer. +| | ... +| | Given BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | When Honeycomb removes BGP peer | ${node} | ${address_internal} +| | Then No BGP peers should be configured | ${node} + +| TC02: Honeycomb updates existing BGP peer - Internal +| | [Documentation] | Check if Honeycomb can update an existing BGP peer. +| | ... +| | [Teardown] | Honeycomb removes BGP peer | ${node} | ${address_internal} +| | ... +| | Given No BGP peers should be configured | ${node} +| | When Honeycomb adds BGP peer +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | And Honeycomb adds BGP peer +| | ... | ${node} | ${address_internal} | ${peer_internal_update} +| | Then BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal_update} + +| TC04: Honeycomb configures BGP peer - Application +| | [Documentation] | Check if Honeycomb can configure an application BGP peer. +| | ... +| | [Teardown] | Honeycomb removes BGP peer | ${node} | ${address_application} +| | ... +| | Given No BGP peers should be configured | ${node} +| | When Honeycomb adds BGP peer +| | ... | ${node} | ${address_application} | ${peer_application} +| | Then BGP peer from Honeycomb should be +| | ... | ${node} | ${address_application} | ${peer_application} + +| TC05: Honeycomb configures a second BGP peer +| | [Documentation] | Check if Honeycomb can configure more than one BGP peer. +| | ... +| | [Teardown] | Run Keywords +| | ... | Honeycomb removes BGP peer | ${node} | ${address_internal} | AND +| | ... | Honeycomb removes BGP peer | ${node} | ${address_internal2} +| | ... +| | Given No BGP peers should be configured | ${node} +| | When Honeycomb adds BGP peer +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | And Honeycomb adds BGP peer +| | ... | ${node} | ${address_internal2} | ${peer_internal2} +| | Then BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | And BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal2} | ${peer_internal2} + +| TC06: Honeycomb configures IPv4 route using BGP +| | [Documentation] | Check if Honeycomb can configure a BGP route under a peer. +| | ... +| | Given Honeycomb adds BGP peer +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | When Honeycomb configures BGP route +| | ... | ${node} | ${address_internal} | ${route_data_ipv4} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | Then BGP Route from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${route_data_ipv4} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 + +| TC08: Honeycomb removes IPv4 route configuration +| | [Documentation] | Check if Honeycomb can remove a configured BGP route. +| | ... +| | Given BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | And BGP Route from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${route_data_ipv4} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | When Honeycomb removes BGP route | ${node} | ${address_internal} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | Then No BGP Routes Should be Configured +| | ... | ${node} | ${address_internal} | ipv4 + +| TC07: Honeycomb updates existing IPv4 route using BGP +| | [Documentation] | Check if Honeycomb can update an existing BGP route. +| | ... +| | [Teardown] | Honeycomb removes BGP route | ${node} | ${address_internal} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | ... +| | Given BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | And No BGP Routes Should be Configured +| | ... | ${node} | ${address_internal} | ipv4 +| | When Honeycomb configures BGP route +| | ... | ${node} | ${address_internal} | ${route_data_ipv4} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | And Honeycomb configures BGP route +| | ... | ${node} | ${address_internal} | ${route_data_ipv4_update} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | Then BGP Route from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${route_data_ipv4_update} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 + +| TC09: Honeycomb configures a second IPv4 route +| | [Documentation] | Check if Honeycomb can configure more than one BGP route. +| | ... +| | [Teardown] | Run Keywords +| | ... | Honeycomb removes BGP route | ${node} | ${address_internal} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 | AND +| | ... | Honeycomb removes BGP route | ${node} | ${address_internal} +| | ... | ${route_address_ipv4_2} | ${route_id_ipv4_2} | ipv4 +| | ... +| | Given BGP peer from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${peer_internal} +| | When Honeycomb configures BGP route +| | ... | ${node} | ${address_internal} | ${route_data_ipv4} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | And Honeycomb configures BGP route +| | ... | ${node} | ${address_internal} | ${route_data_ipv4_2} +| | ... | ${route_address_ipv4_2} | ${route_id_ipv4_2} | ipv4 +| | Then BGP Route from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${route_data_ipv4} +| | ... | ${route_address_ipv4} | ${route_id_ipv4} | ipv4 +| | And BGP Route from Honeycomb should be +| | ... | ${node} | ${address_internal} | ${route_data_ipv4_2} +| | ... | ${route_address_ipv4_2} | ${route_id_ipv4_2} | ipv4 |