def test_heal_vnf_with_infra_post_heal_vnf_fail(self, mock_log, mock_save): heal_vnf_req = objects.HealVnfRequest( vnfc_instance_id=[uuidsentinel.vnfc_instance_id_1]) vnf_instance = fakes.return_vnf_instance( fields.VnfInstanceState.INSTANTIATED, task_state=fields.VnfInstanceTaskState.HEALING) vnf_instance.instantiated_vnf_info.instance_id =\ uuidsentinel.instance_id self._mock_vnf_manager(fail_method_name='post_heal_vnf') driver = vnflcm_driver.VnfLcmDriver() self.assertRaises(exceptions.VnfHealFailed, driver.heal_vnf, self.context, vnf_instance, heal_vnf_req) self.assertEqual(1, mock_save.call_count) self.assertEqual(3, self._vnf_manager.invoke.call_count) self.assertEqual(fields.VnfInstanceTaskState.ERROR, vnf_instance.task_state) expected_msg = ('Failed to store updated resources information for ' 'instance %(instance)s for vnf %(id)s. ' 'Error: %(error)s') mock_log.error.assert_called_with( expected_msg, { 'instance': vnf_instance.instantiated_vnf_info.instance_id, 'id': vnf_instance.id, 'error': 'post_heal_vnf failed' })
def test_heal_vnf_with_infra_heal_vnf_wait_fail(self, mock_log, mock_save): heal_vnf_req = objects.HealVnfRequest( vnfc_instance_id=[uuidsentinel.vnfc_instance_id_1]) vnf_instance = fakes.return_vnf_instance( fields.VnfInstanceState.INSTANTIATED, task_state=fields.VnfInstanceTaskState.HEALING) vnf_instance.instantiated_vnf_info.instance_id =\ uuidsentinel.instance_id self._mock_vnf_manager(fail_method_name='heal_vnf_wait') driver = vnflcm_driver.VnfLcmDriver() # It won't raise any exception if infra driver raises # heal_vnf_wait because there is a possibility the vnfc # resources could go into inconsistent state so it would # proceed further and call post_heal_vnf with a hope # it will work and vnflcm can update the vnfc resources # properly and hence the _vnf_manager.invoke.call_count # should be 3 instead of 2. driver.heal_vnf(self.context, vnf_instance, heal_vnf_req) self.assertEqual(1, mock_save.call_count) self.assertEqual(3, self._vnf_manager.invoke.call_count) self.assertEqual(None, vnf_instance.task_state) expected_msg = ('Failed to update vnf %(id)s resources for ' 'instance%(instance)s. Error: %(error)s') mock_log.error.assert_called_with( expected_msg, { 'id': vnf_instance.id, 'instance': vnf_instance.instantiated_vnf_info.instance_id, 'error': 'heal_vnf_wait failed' })
def test_heal_vnf_without_vnfc_instance(self, mock_log, mock_save, mock_vnf_resource_list, mock_resource_destroy, mock_resource_create, mock_vim, mock_vnf_package_vnfd): vnf_package_vnfd = fakes.return_vnf_package_vnfd() vnf_package_id = vnf_package_vnfd.package_uuid mock_vnf_package_vnfd.return_value = vnf_package_vnfd fake_csar = os.path.join(self.temp_dir, vnf_package_id) cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir, group='vnf_package') self._copy_csar_files(fake_csar, "vnflcm4") mock_vnf_resource_list.return_value = [fakes.return_vnf_resource()] # Heal as per SOL003 i.e. without vnfcInstanceId heal_vnf_req = objects.HealVnfRequest() vim_obj = { 'vim_id': uuidsentinel.vim_id, 'vim_name': 'fake_vim', 'vim_type': 'openstack', 'vim_auth': { 'auth_url': 'http://localhost/identity', 'password': '******', 'username': '******', 'project_name': 'test_project' } } mock_vim.return_value = vim_obj vnf_instance = fakes.return_vnf_instance( fields.VnfInstanceState.INSTANTIATED) vnf_instance.instantiated_vnf_info.instance_id =\ uuidsentinel.instance_id self._mock_vnf_manager() driver = vnflcm_driver.VnfLcmDriver() driver.heal_vnf(self.context, vnf_instance, heal_vnf_req) self.assertEqual(1, mock_save.call_count) # vnf resource software images will be deleted during # deleting vnf instance. self.assertEqual(1, mock_resource_destroy.call_count) # Vnf resource software images will be created during # instantiation. self.assertEqual(1, mock_resource_create.call_count) # Invoke will be called 7 times, 3 for deleting the vnf # resources and 4 during instantiation. self.assertEqual(7, self._vnf_manager.invoke.call_count) expected_msg = ("Request received for healing vnf '%s' " "is completed successfully") mock_log.info.assert_called_with(expected_msg, vnf_instance.id) shutil.rmtree(fake_csar)
def test_heal_vnf_instance(self, mock_get_lock): 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() vnf_instance.instantiation_state = \ fields.VnfInstanceState.INSTANTIATED vnf_instance.save() heal_vnf_req = objects.HealVnfRequest(cause="healing request") self.conductor.heal(self.context, vnf_instance, heal_vnf_req) self.vnflcm_driver.heal_vnf.assert_called_once_with( self.context, mock.ANY, heal_vnf_req)
def test_heal_vnf_without_vnfc_instance_infra_instantiate_vnf_fail( self, mock_log, mock_save, mock_vnf_resource_list, mock_resource_destroy, mock_resource_create, mock_vim, mock_vnf_package_vnfd): vnf_package_vnfd = fakes.return_vnf_package_vnfd() vnf_package_id = vnf_package_vnfd.package_uuid mock_vnf_package_vnfd.return_value = vnf_package_vnfd fake_csar = os.path.join(self.temp_dir, vnf_package_id) cfg.CONF.set_override('vnf_package_csar_path', self.temp_dir, group='vnf_package') base_path = os.path.dirname(os.path.abspath(__file__)) sample_vnf_package_zip = os.path.join( base_path, "../../etc/samples/sample_vnf_package_csar.zip") extracted_zip_path = fake_csar zipfile.ZipFile(sample_vnf_package_zip, 'r').extractall(extracted_zip_path) mock_vnf_resource_list.return_value = [fakes.return_vnf_resource()] # Heal as per SOL003 i.e. without vnfcInstanceId heal_vnf_req = objects.HealVnfRequest() vnf_instance = fakes.return_vnf_instance( fields.VnfInstanceState.INSTANTIATED) vnf_instance.instantiated_vnf_info.instance_id =\ uuidsentinel.instance_id self._mock_vnf_manager(fail_method_name='instantiate_vnf') driver = vnflcm_driver.VnfLcmDriver() self.assertRaises(exceptions.VnfHealFailed, driver.heal_vnf, self.context, vnf_instance, heal_vnf_req) self.assertEqual(1, mock_save.call_count) # vnf resource software images will be deleted during # deleting vnf instance. self.assertEqual(1, mock_resource_destroy.call_count) # Vnf resource software images will be created during # instantiation. self.assertEqual(1, mock_resource_create.call_count) self.assertEqual(5, self._vnf_manager.invoke.call_count) self.assertEqual(fields.VnfInstanceTaskState.ERROR, vnf_instance.task_state) expected_msg = ('Failed to instantiate vnf instance %s ' 'after termination. The vnf is in inconsistent ' 'state. Error: Vnf instantiation failed for vnf %s, ' 'error: instantiate_vnf failed') mock_log.error.assert_called_with(expected_msg % (vnf_instance.id, vnf_instance.id))
def test_heal_vnf_with_vnfc_instance(self, mock_log, mock_save): heal_vnf_req = objects.HealVnfRequest( vnfc_instance_id=[uuidsentinel.vnfc_instance_id_1]) vnf_instance = fakes.return_vnf_instance( fields.VnfInstanceState.INSTANTIATED, task_state=fields.VnfInstanceTaskState.HEALING) self._mock_vnf_manager() driver = vnflcm_driver.VnfLcmDriver() driver.heal_vnf(self.context, vnf_instance, heal_vnf_req) self.assertEqual(1, mock_save.call_count) self.assertEqual(3, self._vnf_manager.invoke.call_count) self.assertEqual(None, vnf_instance.task_state) expected_msg = ("Request received for healing vnf '%s' " "is completed successfully") mock_log.info.assert_called_with(expected_msg, vnf_instance.id)
def execute_action(self, plugin, context, vnf_dict, args): vdu_name = args.get('vdu_name') stack_id = args.get('stack_id', vnf_dict['instance_id']) heat_tpl = args.get('heat_tpl', 'heat_template') cause = args.get('cause', []) if vdu_name is None: LOG.error("VDU resource of vnf '%s' is not present for " "autoheal." % vnf_dict['id']) return def _get_vdu_resources(): """Get all the resources linked to the VDU. Returns: resource list for eg. ['VDU1', CP1] """ resource_list = [vdu_name] heat_template = yaml.safe_load( vnf_dict['attributes'].get(heat_tpl)) vdu_resources = heat_template['resources'].get(vdu_name) cp_resources = vdu_resources['properties'].get('networks') for resource in cp_resources: resource_list.append(resource['port'].get('get_resource')) return resource_list if not cause or type(cause) is not list: cause = [ "Unable to reach while monitoring resource: '%s'", "Failed to monitor VDU resource '%s'" ] resource_list = _get_vdu_resources() additional_params = [] for resource in resource_list: additional_params_obj = objects.HealVnfAdditionalParams( parameter=resource, cause=[cause[0] % resource]) additional_params.append(additional_params_obj) heal_request_data_obj = objects.HealVnfRequest( stack_id=stack_id, cause=(cause[-1] % vdu_name), additional_params=additional_params) plugin.heal_vnf(context, vnf_dict['id'], heal_request_data_obj)
def test_heal_vnf_instance_already_not_instantiated(self, mock_log, mock_get_lock): 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_data['instantiation_state'] =\ fields.VnfInstanceState.NOT_INSTANTIATED vnf_instance = objects.VnfInstance(context=self.context, **vnf_instance_data) vnf_instance.create() heal_vnf_req = objects.HealVnfRequest(cause="healing request") self.conductor.heal(self.context, vnf_instance, heal_vnf_req) self.vnflcm_driver.heal_vnf.assert_not_called() expected_log = ('Heal action cannot be performed on vnf %(id)s ' 'which is in %(state)s state.') mock_log.error.assert_called_once_with(expected_log, {'id': vnf_instance.id, 'state': fields.VnfInstanceState.NOT_INSTANTIATED})
def test_heal_vnf_without_vnfc_instance_infra_delete_fail( self, mock_log, mock_save): # Heal as per SOL003 i.e. without vnfcInstanceId heal_vnf_req = objects.HealVnfRequest() vnf_instance = fakes.return_vnf_instance( fields.VnfInstanceState.INSTANTIATED) vnf_instance.instantiated_vnf_info.instance_id =\ uuidsentinel.instance_id self._mock_vnf_manager(fail_method_name='delete') driver = vnflcm_driver.VnfLcmDriver() self.assertRaises(exceptions.VnfHealFailed, driver.heal_vnf, self.context, vnf_instance, heal_vnf_req) self.assertEqual(1, mock_save.call_count) self.assertEqual(1, self._vnf_manager.invoke.call_count) self.assertEqual(fields.VnfInstanceTaskState.ERROR, vnf_instance.task_state) expected_msg = ('Failed to delete vnf resources for vnf instance %s ' 'before respawning. The vnf is in inconsistent ' 'state. Error: delete failed') mock_log.error.assert_called_with(expected_msg % vnf_instance.id)
def _heal(self, context, vnf_instance, request_body): req_body = utils.convert_camelcase_to_snakecase(request_body) heal_vnf_request = objects.HealVnfRequest(context=context, **req_body) inst_vnf_info = vnf_instance.instantiated_vnf_info vnfc_resource_info_ids = [ vnfc_resource_info.id for vnfc_resource_info in inst_vnf_info.vnfc_resource_info ] for vnfc_id in heal_vnf_request.vnfc_instance_id: # check if vnfc_id exists in vnfc_resource_info if vnfc_id not in vnfc_resource_info_ids: msg = _("Vnfc id %(vnfc_id)s not present in vnf instance " "%(id)s") raise webob.exc.HTTPBadRequest(explanation=msg % { "vnfc_id": vnfc_id, "id": vnf_instance.id }) vnf_instance.task_state = fields.VnfInstanceTaskState.HEALING vnf_instance.save() self.rpc_api.heal(context, vnf_instance, heal_vnf_request)