diff options
Diffstat (limited to 'resources')
-rw-r--r-- | resources/libraries/python/honeycomb/HcAPIKwNSH.py | 173 | ||||
-rw-r--r-- | resources/libraries/python/honeycomb/HoneycombSetup.py | 33 | ||||
-rw-r--r-- | resources/libraries/robot/honeycomb/nsh.robot | 161 | ||||
-rw-r--r-- | resources/templates/honeycomb/config_nsh.url | 1 | ||||
-rw-r--r-- | resources/templates/honeycomb/oper_nsh.url | 1 | ||||
-rw-r--r-- | resources/test_data/honeycomb/nsh.py | 190 | ||||
-rwxr-xr-x | resources/tools/download_hc_pkgs.sh | 8 |
7 files changed, 567 insertions, 0 deletions
diff --git a/resources/libraries/python/honeycomb/HcAPIKwNSH.py b/resources/libraries/python/honeycomb/HcAPIKwNSH.py new file mode 100644 index 0000000000..ce60628d83 --- /dev/null +++ b/resources/libraries/python/honeycomb/HcAPIKwNSH.py @@ -0,0 +1,173 @@ +# Copyright (c) 2016 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. + +"""This module implements keywords to manipulate NSH-SFC data structures 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 +from resources.libraries.python.honeycomb.HoneycombUtil \ + import DataRepresentation + + +class NSHKeywords(object): + """Implementation of keywords which make it possible to: + - add and remove NSH entries, + - get operational data about NSH entries, + - add and remove NSH maps, + - get operational data about NSH maps. + """ + + def __init__(self): + pass + + @staticmethod + def _set_nsh_properties(node, path, data=None): + """Set NSH properties and check the return code. + + :param node: Honeycomb node. + :param path: Path which is added to the base path to identify the data. + :param data: The new data to be set. If None, the item will be removed. + :type node: dict + :type path: str + :type data: dict + :return: Content of response. + :rtype: bytearray + :raises HoneycombError: If the status code in response to PUT is not + OK or ACCEPTED. + """ + + if data: + status_code, resp = HcUtil. \ + put_honeycomb_data(node, "config_nsh", data, path, + data_representation=DataRepresentation.JSON) + else: + status_code, resp = HcUtil. \ + delete_honeycomb_data(node, "config_nsh", path) + + if status_code not in (HTTPCodes.OK, HTTPCodes.ACCEPTED): + raise HoneycombError( + "The configuration of NSH-SFC was not successful. " + "Status code: {0}.".format(status_code)) + return resp + + @staticmethod + def add_nsh_entry(node, name, data): + """Add an NSH entry to the list of entries. The keyword does + not validate given data. + + :param node: Honeycomb node. + :param name: Name for the NSH entry. + :param data: Settings for the new entry. + :type node: dict + :type name: str + :type data: dict + :return: Content of response. + :rtype: bytearray + """ + + path = "/nsh-entries/nsh-entry/{0}".format(name) + + return NSHKeywords._set_nsh_properties(node, path, data) + + @staticmethod + def add_nsh_map(node, name, data): + """Add an NSH map to the list of maps. The keyword does + not validate given data. + + :param node: Honeycomb node. + :param name: Name for the NSH map. + :param data: Settings for the new map. + :type node: dict + :type name: str + :type data: dict + :return: Content of response. + :rtype: bytearray + """ + path = "/nsh-maps/nsh-map/{0}".format(name) + + return NSHKeywords._set_nsh_properties(node, path, data) + + @staticmethod + def remove_nsh_entry(node, name): + """Remove an NSH entry from the list of entries. + :param node: Honeycomb node. + :param name: Name of the NSH entry. + :type node: dict + :type name: str + :return: Content of response. + :rtype: bytearray + """ + + path = "/nsh-entries/nsh-entry/{0}".format(name) + return NSHKeywords._set_nsh_properties(node, path) + + @staticmethod + def remove_nsh_map(node, name): + """Remove an NSH map from the list of maps. + :param node: Honeycomb node. + :param name: Name of the NSH map. + :type node: dict + :type name: str + :return: Content of response. + :rtype: bytearray + """ + + path = "/nsh-maps/nsh-map/{0}".format(name) + return NSHKeywords._set_nsh_properties(node, path) + + @staticmethod + def get_nsh_oper_data(node, entry_name=None, map_name=None): + """Get all NSH operational data present on the node. Optionally + filter out data for a specific entry or map. + + :param node: Honeycomb node. + :param entry_name: Name of a specific NSH entry. Optional. + :param map_name: Name of a specific NSH map. Optional. Do not use + together with entry_name. + :type node: dict + :type entry_name: str + :type map_name: str + :return: List of classify tables. + :rtype: list + """ + if entry_name: + path = "/nsh-entries/nsh-entry/{0}".format(entry_name) + elif map_name: + path = "/nsh-maps/nsh-map/{0}".format(map_name) + else: + path = '' + + status_code, resp = HcUtil. \ + get_honeycomb_data(node, "oper_nsh", path) + + if status_code != HTTPCodes.OK: + raise HoneycombError( + "Not possible to get operational information about the " + "classify tables. Status code: {0}.".format(status_code)) + + return resp + + @staticmethod + def clear_nsh_settings(node): + """Remove the entire NSH container with all of its entries and maps. + + :param node: Honeycomb node. + :type node: dict + :return: Content of response. + :rtype: bytearray + """ + + return NSHKeywords._set_nsh_properties(node, '') diff --git a/resources/libraries/python/honeycomb/HoneycombSetup.py b/resources/libraries/python/honeycomb/HoneycombSetup.py index 06b35db8a1..99f334e3b4 100644 --- a/resources/libraries/python/honeycomb/HoneycombSetup.py +++ b/resources/libraries/python/honeycomb/HoneycombSetup.py @@ -296,3 +296,36 @@ class HoneycombSetup(object): if ret_code != 0: raise HoneycombError("Failed to modify configuration on " "node {0}, {1}".format(node, stderr)) + + @staticmethod + def enable_module_features(node): + """Configure Honeycomb to use VPP modules that are disabled by default. + + Note: If the module is not enabled in VPP, Honeycomb will + be unable to establish VPP connection. + + :param node: Honeycomb node. + :type node: dict + :raises HoneycombError: If the configuration could not be changed. + """ + + disabled_features = { + "NSH": "io.fd.honeycomb.vppnsh.impl.VppNshModule" + } + + ssh = SSH() + ssh.connect(node) + + for feature in disabled_features.keys(): + # uncomment by replacing the entire line + find = replace = "{0}".format(disabled_features[feature]) + + argument = '"/{0}/c\\ {1}"'.format(find, replace) + path = "{0}/modules/io-fd-honeycomb-vpp-integration*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)) diff --git a/resources/libraries/robot/honeycomb/nsh.robot b/resources/libraries/robot/honeycomb/nsh.robot new file mode 100644 index 0000000000..f2a8ffdf8d --- /dev/null +++ b/resources/libraries/robot/honeycomb/nsh.robot @@ -0,0 +1,161 @@ +# Copyright (c) 2016 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.InterfaceUtil +| Library | resources.libraries.python.honeycomb.HcAPIKwNSH.NSHKeywords +| Library | resources.libraries.python.honeycomb.HcAPIKwInterfaces.InterfaceKeywords +| ... | WITH NAME | InterfaceAPI +| Documentation | Keywords used to test Honeycomb NSH node. + +*** Keywords *** +| NSH configuration from Honeycomb should be empty +| | [Documentation] | Uses Honeycomb API to retrieve NSH configuration\ +| | ... | and expects to fail. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... +| | ... | *Example:* +| | ... +| | ... | \| NSH configuration from Honeycomb should be empty \ +| | ... | \| ${nodes['DUT1']} \| +| | [Arguments] | ${node} +| | Run keyword and expect error | *Status code: 404* +| | ... | Get NSH oper data | ${node} + +| Honeycomb adds NSH entry +| | [Documentation] | Uses Honeycomb API to configure an NSH entry. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name for the NSH entry. Type: string +| | ... | - data - settings for the NSH entry. Type: dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb configures NSH entry \| ${nodes['DUT1']} \| nsh_1 \ +| | ... | \| ${data} \| +| | [Arguments] | ${node} | ${name} | ${data} +| | Add NSH entry | ${node} | ${name} | ${data} + +| Honeycomb removes NSH entry +| | [Documentation] | Uses Honeycomb API to delete the specified NSH entry. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name of the NSH entry to be deleted. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb removes NSH entry \| ${nodes['DUT1']} \| nsh_1 \| +| | [Arguments] | ${node} | ${name} +| | Remove NSH entry | ${node} | ${name} + +| Honeycomb adds NSH map +| | [Documentation] | Uses Honeycomb API to configure an NSH map. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name for the NSH map. Type: string +| | ... | - data - settings for the NSH map. Type: dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb configures NSH map \| ${nodes['DUT1']} \| nsh_1 \ +| | ... | \| ${data} \| +| | [Arguments] | ${node} | ${name} | ${data} +| | Add NSH map | ${node} | ${name} | ${data} + +| Honeycomb removes NSH map +| | [Documentation] | Uses Honeycomb API to delete an NSH map. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name of the NSH map to be deleted. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Honeycomb removes NSH map \| ${nodes['DUT1']} \| nsh_1 \| +| | [Arguments] | ${node} | ${name} +| | Remove NSH map | ${node} | ${name} + +| NSH entry from Honeycomb should be +| | [Documentation] | Retrieves oper data for NSH entry and compares\ +| | ... | with provided values. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name of the NSH entry. Type: string +| | ... | - data - expected NSH entry settings. Type dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| NSH entry from Honeycomb should be \| ${nodes['DUT1']} \| nsh_1 \ +| | ... | \| ${data} \| +| | [Arguments] | ${node} | ${name} | ${data} +| | ${oper_data}= | Get NSH oper data | ${node} | entry_name=${name} +| | Compare data structures | ${oper_data} | ${data} + +| NSH map from Honeycomb should be +| | [Documentation] | Retrieves oper data for NSH map and compares\ +| | ... | with provided values. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name of the NSH map. Type: string +| | ... | - data - expected NSH map settings. Type dictionary +| | ... +| | ... | *Example:* +| | ... +| | ... | \| NSH map from Honeycomb should be \| ${nodes['DUT1']} \| nsh_1 \ +| | ... | \| ${data} \| +| | [Arguments] | ${node} | ${name} | ${data} +| | ${oper_data}= | Get NSH oper data | ${node} | map_name=${name} +| | Compare data structures | ${oper_data} | ${data} + +| NSH entry from Honeycomb should not exist +| | [Documentation] | Retrieves oper data for NSH entry and expects to fail. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name of the NSH entry. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| NSH entry from Honeycomb should not exist \| ${nodes['DUT1']} \ +| | ... | \| nsh_1 \| +| | [Arguments] | ${node} | ${name} +| | Run keyword and expect error | *Status code: 404* +| | ... | Get NSH oper data | ${node} | entry_name=${name} + +| NSH map from Honeycomb should not exist +| | [Documentation] | Retrieves oper data for NSH map and expects to fail. +| | ... +| | ... | *Arguments:* +| | ... | - node - information about a DUT node. Type: dict +| | ... | - name - name of the NSH map. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| NSH map from Honeycomb should not exist \| ${nodes['DUT1']} \ +| | ... | \| nsh_1 \| +| | [Arguments] | ${node} | ${name} +| | Run keyword and expect error | *Status code: 404* +| | ... | Get NSH oper data | ${node} | map_name=${name} + +| Honeycomb clears NSH configuration +| | [Documentation] | Uses Honeycomb API to remove all NSH settings. +| | ... +| | [Arguments] | ${node} +| | Clear NSH settings | ${node}
\ No newline at end of file diff --git a/resources/templates/honeycomb/config_nsh.url b/resources/templates/honeycomb/config_nsh.url new file mode 100644 index 0000000000..ad14e953e8 --- /dev/null +++ b/resources/templates/honeycomb/config_nsh.url @@ -0,0 +1 @@ +/restconf/config/vpp-nsh:vpp-nsh
\ No newline at end of file diff --git a/resources/templates/honeycomb/oper_nsh.url b/resources/templates/honeycomb/oper_nsh.url new file mode 100644 index 0000000000..5be706d9df --- /dev/null +++ b/resources/templates/honeycomb/oper_nsh.url @@ -0,0 +1 @@ +/restconf/operational/vpp-nsh:vpp-nsh-state
\ No newline at end of file diff --git a/resources/test_data/honeycomb/nsh.py b/resources/test_data/honeycomb/nsh.py new file mode 100644 index 0000000000..11e9e4ba0c --- /dev/null +++ b/resources/test_data/honeycomb/nsh.py @@ -0,0 +1,190 @@ +# Copyright (c) 2016 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. + +"""Test variables for LISP test suite.""" + +nsh_entry1 = { + "nsh-entry": [{ + "name": "entry1", + "version": 0, + "length": 6, + "md-type": "md-type1", + "next-protocol": "ethernet", + "nsp": 184, + "nsi": 255, + "c1": 1, + "c2": 2, + "c3": 3, + "c4": 4 + }] +} + +nsh_entry1_oper = { + "nsh-entry": [{ + "name": "entry1", + "version": 0, + "length": 6, + "md-type": "vpp-nsh:md-type1", + "next-protocol": "vpp-nsh:ethernet", + "nsp": 184, + "nsi": 255, + "c1": 1, + "c2": 2, + "c3": 3, + "c4": 4 + }] +} + +nsh_entry2 = { + "nsh-entry": [{ + "name": "entry2", + "version": 0, + "length": 5, + "md-type": "md-type1", + "next-protocol": "ethernet", + "nsp": 183, + "nsi": 254, + "c1": 2, + "c2": 3, + "c3": 4, + "c4": 5 + }] +} + +nsh_entry2_oper = { + "nsh-entry": [{ + "name": "entry2", + "version": 0, + "length": 5, + "md-type": "vpp-nsh:md-type1", + "next-protocol": "vpp-nsh:ethernet", + "nsp": 183, + "nsi": 254, + "c1": 2, + "c2": 3, + "c3": 4, + "c4": 5 + }] +} + +# Settings for VxLAN GPE interfaces, needed to configure NSH maps +vxlan_gpe_if1 = 'vxlan_gpe_test1' +vxlan_gpe_base_settings1 = { + 'name': vxlan_gpe_if1, + 'description': 'for testing NSH', + 'enabled': True, + 'link-up-down-trap-enable': 'enabled' +} +vxlan_gpe_settings1 = { + 'local': '192.168.0.1', + 'remote': '192.168.0.2', + 'vni': 5, + 'next-protocol': 'ethernet', + 'encap-vrf-id': 0, + 'decap-vrf-id': 0 +} + +vxlan_gpe_if2 = 'vxlan_gpe_test2' +vxlan_gpe_base_settings2 = { + 'name': vxlan_gpe_if2, + 'description': 'for testing NSH', + 'enabled': True, + 'link-up-down-trap-enable': 'enabled' +} +vxlan_gpe_settings2 = { + 'local': '192.168.1.1', + 'remote': '192.168.1.2', + 'vni': 6, + 'next-protocol': 'ethernet', + 'encap-vrf-id': 0, + 'decap-vrf-id': 0 +} + + +nsh_map1 = { + "nsh-map": [{ + "name": "map1", + "nsp": 184, + "nsi": 255, + "mapped-nsp": 183, + "mapped-nsi": 254, + "nsh-action": "push", + "encap-type": "vxlan-gpe", + "encap-if-name": vxlan_gpe_if1 + }] +} + +nsh_map1_oper = { + "nsh-map": [{ + "name": "map1", + "nsp": 184, + "nsi": 255, + "mapped-nsp": 183, + "mapped-nsi": 254, + "nsh-action": "vpp-nsh:push", + "encap-type": "vpp-nsh:vxlan-gpe", + "encap-if-name": vxlan_gpe_if1 + }] +} + +nsh_map1_edit = { + "nsh-map": [{ + "name": "map1_edit", + "nsp": 184, + "nsi": 255, + "mapped-nsp": 184, + "mapped-nsi": 253, + "nsh-action": "push", + "encap-type": "vxlan-gpe", + "encap-if-name": vxlan_gpe_if1 + }] +} + +nsh_map1_edit_oper = { + "nsh-map": [{ + "name": "map1_edit", + "nsp": 184, + "nsi": 255, + "mapped-nsp": 184, + "mapped-nsi": 253, + "nsh-action": "vpp-nsh:push", + "encap-type": "vpp-nsh:vxlan-gpe", + "encap-if-name": vxlan_gpe_if1 + }] +} + +nsh_map2 = { + "nsh-map": [{ + "name": "map2", + "nsp": 183, + "nsi": 254, + "mapped-nsp": 182, + "mapped-nsi": 253, + "nsh-action": "vpp-nsh:push", + "encap-type": "vpp-nsh:vxlan-gpe", + "encap-if-name": vxlan_gpe_if2 + }] +} + +nsh_map2_oper = { + "nsh-map": [{ + "name": "map2", + "nsp": 183, + "nsi": 254, + "mapped-nsp": 182, + "mapped-nsi": 253, + "nsh-action": "vpp-nsh:push", + "encap-type": "vpp-nsh:vxlan-gpe", + "encap-if-name": vxlan_gpe_if2 + }] +} diff --git a/resources/tools/download_hc_pkgs.sh b/resources/tools/download_hc_pkgs.sh index d9ddff8074..136f6fc63b 100755 --- a/resources/tools/download_hc_pkgs.sh +++ b/resources/tools/download_hc_pkgs.sh @@ -23,8 +23,10 @@ VER="RELEASE" REPO='fd.io.master.ubuntu.trusty.main' GROUP="io.fd.vpp" HC_GROUP="io.fd.honeycomb" +NSH_GROUP="io.fd.nsh_sfc" VPP_ARTIFACTS="vpp vpp-dbg vpp-dev vpp-dpdk-dev vpp-dpdk-dkms vpp-lib vpp-plugins" HC_ARTIFACTS="honeycomb" +NSH_ARTIFACT="vpp-nsh-plugin" PACKAGE="deb deb.md5" CLASS="deb" @@ -40,6 +42,12 @@ for ART in ${HC_ARTIFACTS}; do done done +for ART in ${NSH_ARTIFACTS}; do + for PAC in $PACKAGE; do + curl "${URL}?r=${REPO}&g=${NSH_GROUP}&a=${ART}&p=${PAC}&v=${VER}&c=${CLASS}" -O -J || exit + done +done + for FILE in *.deb; do echo " "${FILE} >> ${FILE}.md5 done |