diff options
-rw-r--r-- | docs/release/userguide/feature.userguide.rst | 11 | ||||
-rw-r--r-- | sfc/lib/config.py | 74 | ||||
-rw-r--r-- | sfc/lib/odl_utils.py | 19 | ||||
-rw-r--r-- | sfc/tests/functest/pod.yaml.sample | 58 | ||||
-rw-r--r-- | sfc/tests/functest/run_sfc_tests.py | 46 | ||||
-rw-r--r-- | sfc/tests/functest/sfc_parent_function.py | 99 |
6 files changed, 230 insertions, 77 deletions
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 |