diff --git a/tacker/conductor/conductor_server.py b/tacker/conductor/conductor_server.py index 6a30a3d35..317b49ad6 100644 --- a/tacker/conductor/conductor_server.py +++ b/tacker/conductor/conductor_server.py @@ -2071,7 +2071,10 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook): self._build_instantiated_vnf_info(context, vnf_instance, instantiate_vnf_req=instantiate_vnf) - vim_id = instantiate_vnf.vim_connection_info[0].vim_id + if instantiate_vnf.vim_connection_info: + vim_id = instantiate_vnf.vim_connection_info[0].vim_id + else: + vim_id = vnflcm_utils._get_vim(context, None)['vim_id'] self._update_vnf_attributes(context, vnf_instance, vnf_dict, constants.PENDING_STATUSES, constants.ACTIVE, vim_id=vim_id) @@ -2162,8 +2165,15 @@ class Conductor(manager.Manager, v2_hook.ConductorV2Hook): vnf_dict['current_error_point'] = EP.NOTIFY_COMPLETED + # Register the default VIM in the same as when create + default_vim = vnflcm_utils._get_vim(context, None) + vim_conn = objects.VimConnectionInfo( + id=uuidutils.generate_uuid(), vim_id=default_vim.get('vim_id'), + vim_type=default_vim.get('vim_type'), access_info={}, + interface_info={}, extra=default_vim.get('extra', {})) + self.vnflcm_driver._vnf_instance_update(context, vnf_instance, - vim_connection_info=[], task_state=None, + vim_connection_info=[vim_conn], task_state=None, instantiation_state=fields.VnfInstanceState.NOT_INSTANTIATED) vnf_instance.instantiated_vnf_info.reinitialize() diff --git a/tacker/tests/functional/sol/vnflcm/test_vnf_instance.py b/tacker/tests/functional/sol/vnflcm/test_vnf_instance.py index b5cda9425..e4cc532c8 100644 --- a/tacker/tests/functional/sol/vnflcm/test_vnf_instance.py +++ b/tacker/tests/functional/sol/vnflcm/test_vnf_instance.py @@ -730,6 +730,41 @@ class VnfLcmTest(base.BaseTackerTest): self._delete_vnf_instance(vnf_instance['id']) + def test_instantiate_vnf_without_vim_connection_info(self): + """Test instantiation API without vimConnectionInfo""" + + # Create vnf instance + vnf_instance_name = ( + f'vnf_without_vimConnectionInfo-{uuidutils.generate_uuid()}') + vnf_instance_description = 'vnf without vimConnectionInfo' + resp, vnf_instance = self._create_vnf_instance(self.vnfd_id_1, + vnf_instance_name=vnf_instance_name, + vnf_instance_description=vnf_instance_description) + + self.assertIsNotNone(vnf_instance['id']) + self.assertEqual(201, resp.status_code) + + request_body = self._instantiate_vnf_request('simple', vim_id=None) + + self._instantiate_vnf_instance(vnf_instance['id'], request_body) + + vnf_instance = self._show_vnf_instance(vnf_instance['id']) + vdu_count = len(vnf_instance['instantiatedVnfInfo'] + ['vnfcResourceInfo']) + self.assertEqual(1, vdu_count) + self.assertEqual(self.vim_id, vnf_instance['instantiatedVnfInfo'] + ['vnfcResourceInfo'][0]['computeResource']['vimConnectionId']) + + # Terminate vnf gracefully with graceful timeout set to 60 + terminate_req_body = { + 'terminationType': fields.VnfInstanceTerminationType.GRACEFUL, + 'gracefulTerminationTimeout': 60 + } + + self._terminate_vnf_instance(vnf_instance['id'], terminate_req_body) + + self._delete_vnf_instance(vnf_instance['id']) + def test_instantiate_vnf_with_instantiation_level(self): """Test instantiation and heal API with instantiation level diff --git a/tacker/tests/unit/conductor/test_conductor_server.py b/tacker/tests/unit/conductor/test_conductor_server.py index 3f6ed3934..a960617cd 100644 --- a/tacker/tests/unit/conductor/test_conductor_server.py +++ b/tacker/tests/unit/conductor/test_conductor_server.py @@ -578,6 +578,45 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): mock.ANY, mock.ANY, mock.ANY, constants.ACTIVE, vim_id=vim_id) + @mock.patch('tacker.vnflcm.utils._get_vim') + @mock.patch('tacker.conductor.conductor_server.Conductor' + '._update_vnf_attributes') + @mock.patch('tacker.conductor.conductor_server.Conductor' + '._change_vnf_status') + @mock.patch('tacker.conductor.conductor_server.Conductor' + '._build_instantiated_vnf_info') + @mock.patch.object(objects.VnfLcmOpOcc, 'save') + @mock.patch.object(coordination.Coordinator, 'get_lock') + @mock.patch('tacker.vnflcm.utils._get_vnfd_dict') + @mock.patch('tacker.vnflcm.utils._convert_desired_capacity') + @mock.patch.object(objects.VnfLcmOpOcc, 'get_by_id') + def test_instantiate_vnf_instance_without_vim_connection_info( + self, mock_vnf_by_id, mock_des, mock_vnfd_dict, mock_get_lock, + mock_save, mock_build_info, mock_change_vnf_status, + mock_update_vnf_attributes, mock_get_vim): + lcm_op_occs_data = fakes.get_lcm_op_occs_data() + mock_vnf_by_id.return_value = ( + objects.VnfLcmOpOcc(context=self.context, **lcm_op_occs_data)) + vnf_package_vnfd = self._create_and_upload_vnf_package() + vnf_instance_data = fake_obj.get_vnf_instance_data( + vnf_package_vnfd.vnfd_id) + vnf_instance = objects.VnfInstance(context=self.context, + **vnf_instance_data) + vnf_instance.create() + instantiate_vnf_req = vnflcm_fakes.get_instantiate_vnf_request_obj() + instantiate_vnf_req.vim_connection_info = [] + vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id + vnf_dict = db_utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid, + flavour=instantiate_vnf_req.flavour_id) + vnf_dict['before_error_point'] = fields.ErrorPoint.INITIAL + default_vim_id = uuidsentinel.vim_id + mock_get_vim.return_value = {'vim_id': default_vim_id} + self.conductor.instantiate(self.context, vnf_instance, vnf_dict, + instantiate_vnf_req, vnf_lcm_op_occs_id) + mock_update_vnf_attributes.assert_called_with(self.context, + mock.ANY, mock.ANY, mock.ANY, constants.ACTIVE, + vim_id=default_vim_id) + @mock.patch('tacker.conductor.conductor_server.Conductor' '._change_vnf_status') @mock.patch('tacker.conductor.conductor_server.Conductor' @@ -1134,27 +1173,29 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): instantiate_vnf_req, vnf_lcm_op_occs_id) self.vnflcm_driver._vnf_instance_update.assert_called_once() + @mock.patch('tacker.vnflcm.utils._get_vim') @mock.patch('tacker.conductor.conductor_server.Conductor' '._change_vnf_status') @mock.patch('tacker.conductor.conductor_server.Conductor' '._send_lcm_op_occ_notification') @mock.patch.object(coordination.Coordinator, 'get_lock') def test_terminate_vnf_instance(self, mock_get_lock, - mock_send_notification, - mock_change_vnf_status): + mock_send_notification, mock_change_vnf_status, mock_get_vim): inst_vnf_info = fd_utils.get_vnf_instantiated_info() - vnf_instance = fd_utils. \ - get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info) + vnf_instance = (fd_utils. + get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info)) terminate_vnf_req = objects.TerminateVnfRequest( termination_type=fields.VnfInstanceTerminationType.GRACEFUL, - additional_params={"key": "value"}) + additional_params={'key': 'value'}) vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id vnf_dict = { **db_utils.get_dummy_vnf(instance_id=self.instance_uuid), 'before_error_point': fields.ErrorPoint.INITIAL, 'status': '' } + mock_get_vim.return_value = {'vim_id': uuidsentinel.vim_id, + 'vim_type': 'openstack'} self.conductor.terminate(self.context, vnf_lcm_op_occs_id, vnf_instance, terminate_vnf_req, vnf_dict) @@ -1164,6 +1205,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): self.assertEqual(mock_send_notification.call_count, 2) self.assertEqual(mock_change_vnf_status.call_count, 2) + @mock.patch('tacker.vnflcm.utils._get_vim') @mock.patch('tacker.conductor.conductor_server.Conductor' '._change_vnf_status') @mock.patch('tacker.conductor.conductor_server.Conductor' @@ -1171,17 +1213,19 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): @mock.patch.object(coordination.Coordinator, 'get_lock') def test_terminate_vnf_instance_error_point_notify_processing( self, mock_get_lock, mock_send_notification, - mock_change_vnf_status): + mock_change_vnf_status, mock_get_vim): inst_vnf_info = fd_utils.get_vnf_instantiated_info() - vnf_instance = fd_utils. \ - get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info) + vnf_instance = (fd_utils. + get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info)) terminate_vnf_req = objects.TerminateVnfRequest( termination_type=fields.VnfInstanceTerminationType.GRACEFUL, - additional_params={"key": "value"}) + additional_params={'key': 'value'}) vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id vnf_dict = db_utils.get_dummy_vnf(instance_id=self.instance_uuid) vnf_dict['before_error_point'] = fields.ErrorPoint.NOTIFY_PROCESSING + mock_get_vim.return_value = {'vim_id': uuidsentinel.vim_id, + 'vim_type': 'openstack'} self.conductor.terminate(self.context, vnf_lcm_op_occs_id, vnf_instance, terminate_vnf_req, vnf_dict) @@ -1191,6 +1235,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): self.assertEqual(mock_send_notification.call_count, 2) self.assertEqual(mock_change_vnf_status.call_count, 2) + @mock.patch('tacker.vnflcm.utils._get_vim') @mock.patch('tacker.conductor.conductor_server.Conductor' '._change_vnf_status') @mock.patch('tacker.conductor.conductor_server.Conductor' @@ -1198,17 +1243,19 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): @mock.patch.object(coordination.Coordinator, 'get_lock') def test_terminate_vnf_instance_error_point_internal_processing( self, mock_get_lock, mock_send_notification, - mock_change_vnf_status): + mock_change_vnf_status, mock_get_vim): inst_vnf_info = fd_utils.get_vnf_instantiated_info() - vnf_instance = fd_utils. \ - get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info) + vnf_instance = (fd_utils. + get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info)) terminate_vnf_req = objects.TerminateVnfRequest( termination_type=fields.VnfInstanceTerminationType.GRACEFUL, - additional_params={"key": "value"}) + additional_params={'key': 'value'}) vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id vnf_dict = db_utils.get_dummy_vnf(instance_id=self.instance_uuid) vnf_dict['before_error_point'] = fields.ErrorPoint.INTERNAL_PROCESSING + mock_get_vim.return_value = {'vim_id': uuidsentinel.vim_id, + 'vim_type': 'openstack'} self.conductor.terminate(self.context, vnf_lcm_op_occs_id, vnf_instance, terminate_vnf_req, vnf_dict) @@ -1218,6 +1265,7 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): self.assertEqual(mock_send_notification.call_count, 2) self.assertEqual(mock_change_vnf_status.call_count, 1) + @mock.patch('tacker.vnflcm.utils._get_vim') @mock.patch('tacker.vnflcm.vnflcm_driver.VnfLcmDriver' '.terminate_vnf') @mock.patch('tacker.conductor.conductor_server.Conductor' @@ -1225,19 +1273,21 @@ class TestConductor(SqlTestCase, unit_base.FixturedTestCase): @mock.patch('tacker.conductor.conductor_server.Conductor' '._send_lcm_op_occ_notification') @mock.patch.object(coordination.Coordinator, 'get_lock') - def test_terminate_vnf_instance_error_point_notify_completed( - self, mock_get_lock, mock_send_notification, - mock_change_vnf_status, mock_vnflcm_driver_terminate_vnf): + def test_terminate_vnf_instance_error_point_notify_completed(self, + mock_get_lock, mock_send_notification, mock_change_vnf_status, + mock_vnflcm_driver_terminate_vnf, mock_get_vim): inst_vnf_info = fd_utils.get_vnf_instantiated_info() - vnf_instance = fd_utils. \ - get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info) + vnf_instance = (fd_utils. + get_vnf_instance_object(instantiated_vnf_info=inst_vnf_info)) terminate_vnf_req = objects.TerminateVnfRequest( termination_type=fields.VnfInstanceTerminationType.GRACEFUL, - additional_params={"key": "value"}) + additional_params={'key': 'value'}) vnf_lcm_op_occs_id = uuidsentinel.vnf_lcm_op_occs_id vnf_dict = db_utils.get_dummy_vnf(instance_id=self.instance_uuid) vnf_dict['before_error_point'] = fields.ErrorPoint.NOTIFY_COMPLETED + mock_get_vim.return_value = {'vim_id': uuidsentinel.vim_id, + 'vim_type': 'openstack'} self.conductor.terminate(self.context, vnf_lcm_op_occs_id, vnf_instance, terminate_vnf_req, vnf_dict)