aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/release/release-notes/releasenotes.rst44
-rw-r--r--docs/release/userguide/feature.userguide.rst11
-rw-r--r--sfc/lib/config.py74
-rw-r--r--sfc/lib/odl_utils.py19
-rw-r--r--sfc/tests/functest/pod.yaml.sample58
-rw-r--r--sfc/tests/functest/run_sfc_tests.py46
-rw-r--r--sfc/tests/functest/sfc_parent_function.py99
7 files changed, 241 insertions, 110 deletions
diff --git a/docs/release/release-notes/releasenotes.rst b/docs/release/release-notes/releasenotes.rst
index a02b82bb..22ae740e 100644
--- a/docs/release/release-notes/releasenotes.rst
+++ b/docs/release/release-notes/releasenotes.rst
@@ -5,21 +5,20 @@
Abstract
========
-This document compiles the release notes for the Gambia release of
+This document compiles the release notes for the Hunter release of
OPNFV SFC
Important notes
===============
These notes provide release information for the use of SFC with the
-Apex installer, xci tool and Compass4NFV for the Gambia release of OPNFV.
+Apex installer and xci tool for the Hunter release of OPNFV.
Summary
=======
The goal of the SFC release is to integrate the OpenDaylight SFC project
-into an OPNFV environment, with either the Apex installer, xci tool or
-Compass4NFV.
+into an OPNFV environment, with either the Apex installer or xci tool.
More information about OpenDaylight and SFC can be found here.
@@ -46,18 +45,16 @@ Release Data
| **Project** | sfc |
| | |
+--------------------------------------+--------------------------------------+
-| **Repo/tag** | opnfv-7.2.0 |
+| **Repo/tag** | opnfv-8.0.0 |
| | |
+--------------------------------------+--------------------------------------+
-| **Release designation** | Gambia 7.2 |
+| **Release designation** | Hunter 8.0 |
| | |
+--------------------------------------+--------------------------------------+
-| **Release date** | January 25th, 2019 |
+| **Release date** | May 10th, 2019 |
| | |
+--------------------------------------+--------------------------------------+
-| **Purpose of the delivery** | Move to OpenStack Rocky, ODL FLuorine|
-| | and OVS 2.9.2 (NSH native support) |
-| | Move to odl_v2 driver in n-sfc |
+| **Purpose of the delivery** | Project maintenance |
+--------------------------------------+--------------------------------------+
Version change
@@ -75,7 +72,7 @@ This release of OPNFV sfc is based on following upstream versions:
Document changes
~~~~~~~~~~~~~~~~
-This is the first tracked version of OPNFV SFC Gambia. It comes with
+This is the first tracked version of OPNFV SFC Hunter. It comes with
the following documentation:
- :ref:`Design document <sfc-design>`
@@ -90,11 +87,6 @@ Reason for version
Feature additions
~~~~~~~~~~~~~~~~~
-- `Use odl_v2 driver for n-sfc`
-- `Unit test creation`
-- `Code refactored`
-- `Tests can be run without tacker and with n-sfc directly`
-
Bug corrections
~~~~~~~~~~~~~~~
@@ -104,7 +96,7 @@ Deliverables
Software deliverables
~~~~~~~~~~~~~~~~~~~~~
-No specific deliverables are created, as SFC is included with Apex and Compass4NFV.
+No specific deliverables are created, as SFC is included with Apex
Documentation deliverables
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -120,32 +112,18 @@ Known Limitations, Issues and Workarounds
System Limitations
------------------
-The Gambia 2.0 release has a few limitations:
-
-1 - The testcase sfc_two_chains_SSH_and_HTTP is disabled in this release due to
-a missing feature in ODL. We are unable to currently update a chain config
-
Known issues
------------
-1 - When tacker is deployed without Mistral, there is an ERROR in the logs and
-the VIM is always in 'PENDING' state because tacker cannot monitor its health.
-However, everything works and SFs can be created.
-
-2 - When tacker is deployed without barbican, it cannot be in HA mode because
-barbican is the only way to fetch the fernet keys.
-
Workarounds
-----------
Test results
============
-The Gambia release of SFC has undergone QA test runs with Functest tests on the
-Apex and Compass installers and xci utility
References
==========
-For more information on the OPNFV Gambia release, please see:
+For more information on the OPNFV Hunter release, please see:
OPNFV
-----
@@ -154,7 +132,7 @@ OPNFV
2) `OPNFV documentation- and software downloads <https://www.opnfv.org/software/download>`_
-3) `OPNFV Gambia release <https://docs.opnfv.org/en/stable-gambia/index.html>`_
+3) `OPNFV Hunter release <https://docs.opnfv.org/en/latest/index.html>`_
OpenStack
---------
diff --git a/docs/release/userguide/feature.userguide.rst b/docs/release/userguide/feature.userguide.rst
index 0e9ce2cf..050a0c86 100644
--- a/docs/release/userguide/feature.userguide.rst
+++ b/docs/release/userguide/feature.userguide.rst
@@ -36,6 +36,17 @@ SFC capabilities and usage
The OPNFV SFC feature can be deployed with either the "os-odl-sfc-ha" or the
"os-odl-sfc-noha" scenario. SFC usage for both of these scenarios is the same.
+Once the deployment has been completed, the SFC test cases use information
+(e.g. INSTALLER IP, Controller IP, etc) of the environment which have been
+retrieved first from the installer in order to execute the SFC test cases properly.
+This is the default behavior.
+In case there is not an installer in place and the server for the SFC test execution
+has been prepared manually, installing all necessary components (e.g. OpenStack OpenDayLight etc)
+by hand. The user should update the "pod.yaml" file, including the all necessary details
+for each node which participates in the scenario.
+In case the dovetail project triggers the SFC test scenarios, the "pod.yaml" file will be prepared
+by dovetail project automatically.
+
As previously mentioned, Tacker is used as a VNF Manager and SFC Orchestrator. All
the configuration necessary to create working service chains and classifiers can
be performed using the Tacker command line. Refer to the `Tacker walkthrough <https://github.com/trozet/sfc-random/blob/master/tacker_sfc_apex_walkthrough.txt>`_
diff --git a/sfc/lib/config.py b/sfc/lib/config.py
index 507142c9..bf9864a5 100644
--- a/sfc/lib/config.py
+++ b/sfc/lib/config.py
@@ -46,33 +46,55 @@ class CommonConfig(object):
self.config_file = os.path.join(self.sfc_test_dir, "config.yaml")
self.vim_file = os.path.join(self.sfc_test_dir, "register-vim.json")
- self.installer_type = env.get('INSTALLER_TYPE')
-
- self.installer_fields = test_utils.fill_installer_dict(
- self.installer_type)
-
- self.installer_ip = env.get('INSTALLER_IP')
-
- self.installer_user = ft_utils.get_parameter_from_yaml(
- self.installer_fields['user'], self.config_file)
-
- try:
- self.installer_password = ft_utils.get_parameter_from_yaml(
- self.installer_fields['password'], self.config_file)
- except Exception:
- self.installer_password = None
-
- try:
- self.installer_key_file = ft_utils.get_parameter_from_yaml(
- self.installer_fields['pkey_file'], self.config_file)
- except Exception:
- self.installer_key_file = None
-
- try:
- self.installer_cluster = ft_utils.get_parameter_from_yaml(
- self.installer_fields['cluster'], self.config_file)
- except Exception:
+ pod_yaml_exists = os.path.isfile(self.sfc_test_dir + "/pod.yaml")
+
+ if pod_yaml_exists:
+ self.pod_file = os.path.join(self.sfc_test_dir, "pod.yaml")
+ self.nodes_pod = ft_utils.get_parameter_from_yaml(
+ "nodes", self.pod_file)
+ self.host_ip = self.nodes_pod[0]['ip']
+ self.host_user = self.nodes_pod[0]['user']
+
+ self.installer_type = 'configByUser'
+ self.installer_ip = self.host_ip
+ self.installer_user = self.host_user
self.installer_cluster = None
+ try:
+ self.installer_password = self.host_ip[0]['password']
+ except Exception:
+ self.installer_password = None
+
+ try:
+ self.installer_key_file = self.host_ip[0]['key_filename']
+ except Exception:
+ self.installer_key_file = None
+ else:
+ self.nodes_pod = None
+ self.host_ip = None
+ self.installer_type = env.get('INSTALLER_TYPE')
+ self.installer_fields = test_utils.fill_installer_dict(
+ self.installer_type)
+ self.installer_ip = env.get('INSTALLER_IP')
+ self.installer_user = ft_utils.get_parameter_from_yaml(
+ self.installer_fields['user'], self.config_file)
+
+ try:
+ self.installer_password = ft_utils.get_parameter_from_yaml(
+ self.installer_fields['password'], self.config_file)
+ except Exception:
+ self.installer_password = None
+
+ try:
+ self.installer_key_file = ft_utils.get_parameter_from_yaml(
+ self.installer_fields['pkey_file'], self.config_file)
+ except Exception:
+ self.installer_key_file = None
+
+ try:
+ self.installer_cluster = ft_utils.get_parameter_from_yaml(
+ self.installer_fields['cluster'], self.config_file)
+ except Exception:
+ self.installer_cluster = None
self.flavor = ft_utils.get_parameter_from_yaml(
"defaults.flavor", self.config_file)
diff --git a/sfc/lib/odl_utils.py b/sfc/lib/odl_utils.py
index 459c83ec..2c657a13 100644
--- a/sfc/lib/odl_utils.py
+++ b/sfc/lib/odl_utils.py
@@ -252,6 +252,25 @@ def get_odl_ip_port(nodes):
return ip, port
+def get_odl_ip_port_no_installer(nodes_pod):
+ node_index = 0
+ for n in nodes_pod:
+ if n['role'] == 'Controller':
+ break
+ node_index += 1
+ remote_ml2_conf_etc = '/etc/neutron/plugins/ml2/ml2_conf.ini'
+ os.system('scp {0}@{1}:{2} .'.
+ format(nodes_pod[node_index]['user'],
+ nodes_pod[node_index]['ip'],
+ remote_ml2_conf_etc))
+ file = open('ml2_conf.ini', 'r')
+ string = re.findall(r'[0-9]+(?:\.[0-9]+){3}\:[0-9]+', file.read())
+ file.close()
+ ip = string[0].split(':')[0]
+ port = string[0].split(':')[1]
+ return ip, port
+
+
def get_odl_username_password():
local_ml2_conf_file = os.path.join(os.getcwd(), 'ml2_conf.ini')
con_par = ConfigParser.RawConfigParser()
diff --git a/sfc/tests/functest/pod.yaml.sample b/sfc/tests/functest/pod.yaml.sample
new file mode 100644
index 00000000..aa5fddad
--- /dev/null
+++ b/sfc/tests/functest/pod.yaml.sample
@@ -0,0 +1,58 @@
+# Sample config file about the POD information is located under the dovetail project.
+# https://github.com/opnfv/dovetail/blob/master/etc/userconfig/pod.yaml.sample
+# On the top of the above template the node0 could be used, defining the role Host.
+# After that the proper number of controller nodes should be defined and
+# at the end the respective compute nodes.
+
+nodes:
+-
+ # This can not be changed and must be node0.
+ name: node0
+
+ # This must be Host.
+ role: Host
+
+ # This is the instance IP of a node which has installed.
+ ip: xx.xx.xx.xx
+
+ # User name of the user of this node. This user **must** have sudo privileges.
+ user: root
+
+ # keyfile of the user.
+ key_filename: /root/.ssh/id_rsa
+
+-
+ # This can not be changed and must be node1.
+ name: node1
+
+ # This must be controller.
+ role: Controller
+
+ # This is the instance IP of a controller node
+ ip: xx.xx.xx.xx
+
+ # User name of the user of this node. This user **must** have sudo privileges.
+ user: root
+
+ # keyfile of the user.
+ key_filename: /root/.ssh/id_rsa
+
+-
+ # This can not be changed and must be node1.
+ name: node2
+
+ # This must be compute.
+ role: Compute
+
+ # This is the instance IP of a compute node
+ ip: xx.xx.xx.xx
+
+ # User name of the user of this node. This user **must** have sudo privileges.
+ user: root
+
+ # keyfile of the user.
+ key_filename: /root/.ssh/id_rsa
+
+ # Private ssh key for accessing the controller nodes. If there is not
+ # a keyfile for that use, the password of the user could be used instead.
+ # password: root \ No newline at end of file
diff --git a/sfc/tests/functest/run_sfc_tests.py b/sfc/tests/functest/run_sfc_tests.py
index c3d68811..7f0eaa8a 100644
--- a/sfc/tests/functest/run_sfc_tests.py
+++ b/sfc/tests/functest/run_sfc_tests.py
@@ -104,35 +104,49 @@ class SfcFunctest(testcase.TestCase):
time.sleep(10)
def __disable_heat_resource_finder_cache(self, nodes, installer_type):
- controllers = [node for node in nodes if node.is_controller()]
+
+ if COMMON_CONFIG.installer_type != 'configByUser':
+ controllers = [node for node in nodes if node.is_controller()]
+ else:
+ controllers = []
+ for n in COMMON_CONFIG.nodes_pod:
+ if n['role'] == 'Controller':
+ controllers.append(n)
+ logger.info("CONTROLLER : %s", controllers)
if installer_type == 'apex':
self.__disable_heat_resource_finder_cache_apex(controllers)
elif installer_type == "fuel":
self.__disable_heat_resource_finder_cache_fuel(controllers)
- elif installer_type == "osa" or "compass":
+ elif installer_type == "osa" or "compass" or "configByUser":
pass
else:
raise Exception('Unsupported installer')
def run(self):
- deploymentHandler = DeploymentFactory.get_handler(
- COMMON_CONFIG.installer_type,
- COMMON_CONFIG.installer_ip,
- COMMON_CONFIG.installer_user,
- COMMON_CONFIG.installer_password,
- COMMON_CONFIG.installer_key_file)
-
cluster = COMMON_CONFIG.installer_cluster
- nodes = (deploymentHandler.get_nodes({'cluster': cluster})
- if cluster is not None
- else deploymentHandler.get_nodes())
+ if COMMON_CONFIG.installer_type != 'configByUser':
+ deploymentHandler = DeploymentFactory.get_handler(
+ COMMON_CONFIG.installer_type,
+ COMMON_CONFIG.installer_ip,
+ COMMON_CONFIG.installer_user,
+ COMMON_CONFIG.installer_password,
+ COMMON_CONFIG.installer_key_file)
+
+ nodes = (deploymentHandler.get_nodes({'cluster': cluster})
+ if cluster is not None
+ else deploymentHandler.get_nodes())
+ self.__disable_heat_resource_finder_cache(nodes,
+ COMMON_CONFIG.
+ installer_type)
+ odl_ip, odl_port = odl_utils.get_odl_ip_port(nodes)
- self.__disable_heat_resource_finder_cache(nodes,
- COMMON_CONFIG.installer_type)
-
- odl_ip, odl_port = odl_utils.get_odl_ip_port(nodes)
+ else:
+ nodes = COMMON_CONFIG.nodes_pod
+ self.__disable_heat_resource_finder_cache(nodes, "configByUser")
+ odl_ip, odl_port = odl_utils. \
+ get_odl_ip_port_no_installer(COMMON_CONFIG.nodes_pod)
ovs_logger = ovs_log.OVSLogger(
os.path.join(COMMON_CONFIG.sfc_test_dir, 'ovs-logs'),
diff --git a/sfc/tests/functest/sfc_parent_function.py b/sfc/tests/functest/sfc_parent_function.py
index 40d5d1a1..410c0e71 100644
--- a/sfc/tests/functest/sfc_parent_function.py
+++ b/sfc/tests/functest/sfc_parent_function.py
@@ -70,37 +70,66 @@ class SfcCommonTestCase(object):
:return: Environment preparation
"""
- deployment_handler = DeploymentFactory.get_handler(
- COMMON_CONFIG.installer_type,
- COMMON_CONFIG.installer_ip,
- COMMON_CONFIG.installer_user,
- COMMON_CONFIG.installer_password,
- COMMON_CONFIG.installer_key_file)
+ if COMMON_CONFIG.installer_type != 'configByUser':
+ deployment_handler = DeploymentFactory.get_handler(
+ COMMON_CONFIG.installer_type,
+ COMMON_CONFIG.installer_ip,
+ COMMON_CONFIG.installer_user,
+ COMMON_CONFIG.installer_password,
+ COMMON_CONFIG.installer_key_file)
+
+ installer_type = os.environ.get("INSTALLER_TYPE")
+ installer_ip = os.environ.get("INSTALLER_IP")
+ cluster = COMMON_CONFIG.installer_cluster
+ openstack_nodes = (deployment_handler.
+ get_nodes({'cluster': cluster})
+ if cluster is not None
+ else deployment_handler.get_nodes())
+
+ self.compute_nodes = [node for node in openstack_nodes
+ if node.is_compute()]
+
+ for compute in self.compute_nodes:
+ logger.info("This is a compute: %s" % compute.ip)
+
+ controller_nodes = [node for node in openstack_nodes
+ if node.is_controller()]
+ self.controller_clients = test_utils. \
+ get_ssh_clients(controller_nodes)
+ self.compute_clients = test_utils. \
+ get_ssh_clients(self.compute_nodes)
+
+ self.odl_ip, self.odl_port = odl_utils. \
+ get_odl_ip_port(openstack_nodes)
- installer_type = os.environ.get("INSTALLER_TYPE")
+ else:
+ installer_type = 'configByUser'
+ installer_ip = COMMON_CONFIG.installer_ip
+ openstack_nodes = COMMON_CONFIG.nodes_pod
+ self.compute_nodes = [node for node in
+ COMMON_CONFIG.nodes_pod
+ if node['role'] == 'Compute']
+
+ for compute in self.compute_nodes:
+ logger.info("This is a compute: %s" % compute['ip'])
+
+ controller_nodes = [node for node in openstack_nodes
+ if node['role'] == 'Controller']
+
+ self.odl_ip, self.odl_port = odl_utils. \
+ get_odl_ip_port_no_installer(openstack_nodes)
if installer_type not in supported_installers:
- raise Exception(
- '\033[91mYour installer is not supported yet\033[0m')
+ if installer_type != 'configByUser':
+ raise Exception(
+ '\033[91mYour installer is not supported yet\033[0m')
- installer_ip = os.environ.get("INSTALLER_IP")
if not installer_ip:
logger.error(
'\033[91minstaller ip is not set\033[0m')
raise Exception(
'\033[91mexport INSTALLER_IP=<ip>\033[0m')
- cluster = COMMON_CONFIG.installer_cluster
- openstack_nodes = (deployment_handler.get_nodes({'cluster': cluster})
- if cluster is not None
- else deployment_handler.get_nodes())
-
- self.compute_nodes = [node for node in openstack_nodes
- if node.is_compute()]
-
- for compute in self.compute_nodes:
- logger.info("This is a compute: %s" % compute.ip)
-
results.add_to_summary(0, "=")
results.add_to_summary(2, "STATUS", "SUBTEST")
results.add_to_summary(0, "=")
@@ -113,12 +142,6 @@ class SfcCommonTestCase(object):
if not custom_flv:
raise Exception("Failed to create custom flavor")
- controller_nodes = [node for node in openstack_nodes
- if node.is_controller()]
-
- self.controller_clients = test_utils.get_ssh_clients(controller_nodes)
- self.compute_clients = test_utils.get_ssh_clients(self.compute_nodes)
-
if COMMON_CONFIG.mano_component == 'tacker':
self.tacker_client = os_sfc_utils.get_tacker_client()
os_sfc_utils.register_vim(self.tacker_client,
@@ -153,7 +176,6 @@ class SfcCommonTestCase(object):
self.creators = openstack_sfc.creators
- self.odl_ip, self.odl_port = odl_utils.get_odl_ip_port(openstack_nodes)
odl_utils.get_odl_username_password()
self.default_param_file = os.path.join(
@@ -176,7 +198,6 @@ class SfcCommonTestCase(object):
self.sg,
self.test_topology['server'],
[SERVER + '-port'])
- self.port_server = port_server[0]
self.client_instance, port_client = \
openstack_sfc.create_instance(CLIENT, COMMON_CONFIG.flavor,
@@ -184,18 +205,26 @@ class SfcCommonTestCase(object):
self.sg,
self.test_topology['client'],
[CLIENT + '-port'])
- self.port_client = port_client[0]
logger.info('This test is run with the topology {0}'.format(
self.test_topology['id']))
logger.info('Topology description: {0}'.format(
self.test_topology['description']))
- port_fixed_ips = self.port_server.fixed_ips
- for ip in port_fixed_ips:
- self.server_ip = ip.get('ip_address')
- logger.info("Server instance received private ip [{}]".format(
- self.server_ip))
+ if COMMON_CONFIG.installer_type != 'configByUser':
+ self.port_server = port_server[0]
+ self.port_client = port_client[0]
+ port_fixed_ips = self.port_server
+ for ip in port_fixed_ips:
+ self.server_ip = ip.get('ip_address')
+ logger.info("Server instance received private ip [{}]".format(
+ self.server_ip))
+ else:
+ self.port_server = port_server
+ self.port_client = port_client
+ self.server_ip = self.server_instance.ports[0].ips[0]['ip_address']
+ logger.info("Server instance received private ip [{}]".format(
+ self.server_ip))
def register_vnf_template(self, test_case_name, template_name):
""" Register the template which defines the VNF