diff --git a/tacker/extensions/vnfm.py b/tacker/extensions/vnfm.py index f337f3a26..fc122ead3 100644 --- a/tacker/extensions/vnfm.py +++ b/tacker/extensions/vnfm.py @@ -68,11 +68,11 @@ class VNFCreateFailed(exceptions.TackerException): class VNFUpdateWaitFailed(exceptions.TackerException): - message = _('%(reason)s') + message = _('VNF Update %(reason)s') class VNFCreateWaitFailed(exceptions.TackerException): - message = _('%(reason)s') + message = _('VNF Create %(reason)s') class VNFScaleWaitFailed(exceptions.TackerException): @@ -80,7 +80,7 @@ class VNFScaleWaitFailed(exceptions.TackerException): class VNFDeleteWaitFailed(exceptions.TackerException): - message = _('%(reason)s') + message = _('VNF Delete %(reason)s') class VNFDeleteFailed(exceptions.TackerException): diff --git a/tacker/tests/unit/vnfm/test_plugin.py b/tacker/tests/unit/vnfm/test_plugin.py index 86751689b..3500f7b3a 100644 --- a/tacker/tests/unit/vnfm/test_plugin.py +++ b/tacker/tests/unit/vnfm/test_plugin.py @@ -504,7 +504,7 @@ class TestVNFMPlugin(db_base.SqlTestCase): self._insert_dummy_vnf_template() vnf_obj = utils.get_dummy_vnf_obj() self.create_wait.side_effect = vnfm.VNFCreateWaitFailed( - reason="TEST") + reason="failed") vnf_dict = self.vnfm_plugin.create_vnf(self.context, vnf_obj) self.assertEqual(constants.ERROR, vnf_dict['status']) @@ -602,7 +602,8 @@ class TestVNFMPlugin(db_base.SqlTestCase): mock_set_vnf_error_status_reason): self._insert_dummy_vnf_template() dummy_vnf_obj = self._insert_dummy_vnf() - self.delete_wait.side_effect = vnfm.VNFDeleteWaitFailed(reason='test') + self.delete_wait.side_effect = vnfm.VNFDeleteWaitFailed( + reason='failed') self.vnfm_plugin.delete_vnf(self.context, dummy_vnf_obj['id']) mock_set_vnf_error_status_reason.assert_called_once_with(self.context, mock.ANY, @@ -742,8 +743,8 @@ class TestVNFMPlugin(db_base.SqlTestCase): self._insert_dummy_vnf_template() dummy_vnf_obj = self._insert_dummy_vnf() vnf_config_obj = utils.get_dummy_vnf_config_obj() - self.update_wait.side_effect = vnfm.VNFUpdateWaitFailed(reason='VNF' - ' Updation failed') + self.update_wait.side_effect = vnfm.VNFUpdateWaitFailed( + reason='failed') self.assertRaises(vnfm.VNFUpdateWaitFailed, self.vnfm_plugin.update_vnf, self.context, dummy_vnf_obj['id'], vnf_config_obj) @@ -751,7 +752,7 @@ class TestVNFMPlugin(db_base.SqlTestCase): delete_hosting_vnf.assert_called_once_with(dummy_vnf_obj['id']) mock_set_vnf_error_status_reason.assert_called_once_with(self.context, dummy_vnf_obj['id'], - 'VNF Updation failed') + 'VNF Update failed') def _get_dummy_scaling_policy(self, type): vnf_scale = {} diff --git a/tacker/vnfm/infra_drivers/openstack/openstack.py b/tacker/vnfm/infra_drivers/openstack/openstack.py index 9aae433e1..2935cd4b2 100644 --- a/tacker/vnfm/infra_drivers/openstack/openstack.py +++ b/tacker/vnfm/infra_drivers/openstack/openstack.py @@ -129,24 +129,10 @@ class OpenStack(abstract_driver.VnfAbstractDriver, 'region_name', None) heatclient = hc.HeatClient(auth_attr, region_name) - stack, status, stack_retries = self._wait_until_stack_ready( + stack = self._wait_until_stack_ready( vnf_id, auth_attr, infra_cnst.STACK_CREATE_IN_PROGRESS, - region_name=region_name) - - if stack_retries == 0 and status != infra_cnst.STACK_CREATE_COMPLETE: - error_reason = _("Resource creation is not completed within" - " {wait} seconds as creation of stack {stack}" - " is not completed").format( - wait=(self.STACK_RETRIES * - self.STACK_RETRY_WAIT), - stack=vnf_id) - LOG.warning("VNF Creation failed: %(reason)s", - {'reason': error_reason}) - raise vnfm.VNFCreateWaitFailed(reason=error_reason) - - elif stack_retries != 0 and status != infra_cnst.STACK_CREATE_COMPLETE: - error_reason = stack.stack_status_reason - raise vnfm.VNFCreateWaitFailed(reason=error_reason) + infra_cnst.STACK_CREATE_COMPLETE, + vnfm.VNFCreateWaitFailed, region_name=region_name) # scaling enabled if vnf_dict['attributes'].get('scaling_group_names'): @@ -162,15 +148,23 @@ class OpenStack(abstract_driver.VnfAbstractDriver, vnf_dict['mgmt_ip_address'] = jsonutils.dump_as_bytes(mgmt_ips) def _wait_until_stack_ready(self, vnf_id, auth_attr, wait_status, + expected_status, exception_class, region_name=None): heatclient = hc.HeatClient(auth_attr, region_name) - stack = heatclient.get(vnf_id) - status = stack.stack_status stack_retries = self.STACK_RETRIES - while status == wait_status and stack_retries > 0: - time.sleep(self.STACK_RETRY_WAIT) + status = wait_status + stack = None + while stack_retries > 0: try: + stack_retries = stack_retries - 1 stack = heatclient.get(vnf_id) + status = stack.stack_status + if status == expected_status: + LOG.debug('stack status: %(stack)s %(status)s', + {'stack': str(stack), 'status': status}) + return stack + time.sleep(self.STACK_RETRY_WAIT) + LOG.debug('status: %s', status) except Exception: LOG.warning("VNF Instance setup may not have " "happened because Heat API request failed " @@ -178,13 +172,23 @@ class OpenStack(abstract_driver.VnfAbstractDriver, "created", {'stack': vnf_id}) # continue to avoid temporary connection error to target # VIM - status = stack.stack_status - LOG.debug('status: %s', status) - stack_retries = stack_retries - 1 - LOG.debug('stack status: %(stack)s %(status)s', - {'stack': str(stack), 'status': status}) - - return stack, status, stack_retries + if stack_retries == 0 and status != expected_status: + error_reason = _("action is not completed within {wait} " + "seconds on stack {stack}").format( + wait=(self.STACK_RETRIES * + self.STACK_RETRY_WAIT), + stack=vnf_id) + raise exception_class(reason=error_reason) + elif stack_retries != 0 and status != wait_status: + if stack: + error_reason = stack.stack_status_reason + else: + error_reason = _("action on VNF %(vnf_id) is not " + "completed. Current status of stack is " + "%(stack_status)") % {'vnf_id': vnf_id, + 'stack_status': status} + LOG.warning(error_reason) + raise exception_class(reason=error_reason) def _find_mgmt_ips(self, outputs): LOG.debug('outputs %s', outputs) @@ -230,25 +234,10 @@ class OpenStack(abstract_driver.VnfAbstractDriver, @log.log def update_wait(self, plugin, context, vnf_dict, auth_attr, region_name=None): - stack, status, stack_retries = self._wait_until_stack_ready( - vnf_dict['instance_id'], auth_attr, - infra_cnst.STACK_UPDATE_IN_PROGRESS, - region_name=region_name) - - if stack_retries == 0 and status != infra_cnst.STACK_UPDATE_COMPLETE: - error_reason = _("Resource updation is not completed within" - " {wait} seconds as updation of stack {stack}" - " is not completed").format( - wait=(self.STACK_RETRIES * self.STACK_RETRY_WAIT), - stack=vnf_dict['instance_id']) - LOG.error("VNF Updation failed: %(reason)s", - {'reason': error_reason}) - raise vnfm.VNFUpdateWaitFailed(reason=error_reason) - - elif stack_retries != 0 and (status != - infra_cnst.STACK_UPDATE_COMPLETE): - error_reason = stack.stack_status_reason - raise vnfm.VNFUpdateWaitFailed(reason=error_reason) + stack = self._wait_until_stack_ready(vnf_dict['instance_id'], + auth_attr, infra_cnst.STACK_UPDATE_IN_PROGRESS, + infra_cnst.STACK_UPDATE_COMPLETE, + vnfm.VNFUpdateWaitFailed, region_name=region_name) mgmt_ips = self._find_mgmt_ips(stack.outputs) @@ -263,25 +252,10 @@ class OpenStack(abstract_driver.VnfAbstractDriver, @log.log def delete_wait(self, plugin, context, vnf_id, auth_attr, region_name=None): - stack, status, stack_retries = self._wait_until_stack_ready( - vnf_id, auth_attr, infra_cnst.STACK_DELETE_IN_PROGRESS, - region_name=region_name) - - if stack_retries == 0 and status != infra_cnst.STACK_DELETE_COMPLETE: - error_reason = _("Resource cleanup for vnf is" - " not completed within {wait} seconds as " - "deletion of Stack {stack} is " - "not completed").format(stack=vnf_id, - wait=(self.STACK_RETRIES * self.STACK_RETRY_WAIT)) - LOG.warning(error_reason) - raise vnfm.VNFDeleteWaitFailed(reason=error_reason) - - if stack_retries != 0 and status != infra_cnst.STACK_DELETE_COMPLETE: - error_reason = _("VNF {vnf_id} deletion is not completed. " - "{stack_status}").format(vnf_id=vnf_id, - stack_status=status) - LOG.warning(error_reason) - raise vnfm.VNFDeleteWaitFailed(reason=error_reason) + self._wait_until_stack_ready(vnf_id, auth_attr, + infra_cnst.STACK_DELETE_IN_PROGRESS, + infra_cnst.STACK_DELETE_COMPLETE, vnfm.VNFDeleteWaitFailed, + region_name=region_name) @classmethod def _find_mgmt_ips_from_groups(cls, heat_client, instance_id, group_names):