From 64e097037a1c0cd1aedcb3d1220f4f48ffb379f4 Mon Sep 17 00:00:00 2001 From: John Kung Date: Thu, 28 Nov 2019 16:15:53 -0500 Subject: [PATCH] Allow host-delete for unprovisioned hosts without mtce notify In the case of host-delete in which hostname or personality has not yet been provisioned, host-delete must not send the notification to mtce. This is because mtce is not notified by sysinv about hosts which have not yet been provisioned with a hostname or personality. Change-Id: Iec310641411520ab2e1b711632c6c64e251ac64b Closes-Bug: 1850683 Signed-off-by: John Kung --- .../sysinv/sysinv/api/controllers/v1/host.py | 60 +++++++++++-------- .../sysinv/sysinv/tests/api/test_host.py | 31 ++++++++++ 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py index 2fdab07db5..fb589c4bc4 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py @@ -2406,32 +2406,8 @@ class HostController(rest.RestController): openstack_worker = True break - idict = {'operation': constants.DELETE_ACTION, - 'uuid': ihost.uuid, - 'invprovision': ihost.invprovision} - - mtc_response_dict = mtce_api.host_delete( - self._api_token, self._mtc_address, self._mtc_port, - idict, constants.MTC_DELETE_TIMEOUT_IN_SECS) - - LOG.info("Mtce Delete Response: %s", mtc_response_dict) - - if mtc_response_dict is None: - mtc_response_dict = {'status': 'fail', - 'reason': 'no response', - 'action': 'retry'} - - # Check mtce response prior to attempting delete - if mtc_response_dict.get('status') != 'pass': - self._vim_host_add(ihost) - if mtc_response_dict.get('reason') != 'no response': - raise wsme.exc.ClientSideError(_("Mtce rejected delete request." - "Please retry and if problem persists then contact your " - "system administrator.")) - else: - raise wsme.exc.ClientSideError(_("Timeout waiting for system response. Please wait for a " - "few moments. If the host is not deleted,please retry. If " - "problem persists then contact your system administrator.")) + if ihost.hostname and ihost.personality: + self._notify_mtce_host_delete(ihost) pecan.request.rpcapi.unconfigure_ihost(pecan.request.context, ihost) @@ -2537,6 +2513,38 @@ class HostController(rest.RestController): pecan.request.rpcapi.evaluate_app_reapply( pecan.request.context, constants.HELM_APP_OPENSTACK) + def _notify_mtce_host_delete(self, ihost): + + mtce_request_dict = {'operation': constants.DELETE_ACTION, + 'uuid': ihost.uuid, + 'invprovision': ihost.invprovision} + + mtc_response_dict = mtce_api.host_delete( + self._api_token, self._mtc_address, self._mtc_port, + mtce_request_dict, constants.MTC_DELETE_TIMEOUT_IN_SECS) + + LOG.info("Mtce Delete Response: %s", mtc_response_dict) + + if mtc_response_dict is None: + mtc_response_dict = {'status': 'fail', + 'reason': 'no response', + 'action': 'retry'} + + # Check mtce response prior to attempting delete + if mtc_response_dict.get('status') != 'pass': + self._vim_host_add(ihost) + if mtc_response_dict.get('reason') != 'no response': + raise wsme.exc.ClientSideError( + _("Mtce rejected host-delete request." + "Please retry and if problem persists then contact " + "your system administrator.")) + else: + raise wsme.exc.ClientSideError( + _("Timeout waiting for system response. Please wait " + "for a few moments. If the host is not deleted, " + "please retry. If problem persists then contact " + "your system administrator.")) + def _check_upgrade_provision_order(self, personality, hostname): LOG.info("_check_upgrade_provision_order personality=%s, hostname=%s" % (personality, hostname)) diff --git a/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py b/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py index fc2b3c7d47..c904d540a5 100644 --- a/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py +++ b/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py @@ -311,6 +311,37 @@ class TestDelete(TestHost): self.assertEqual(response.content_type, 'application/json') self.assertTrue(response.json['error_message']) + def test_delete_unprovisioned_host(self): + # Create controller-0 + self._create_controller_0() + # Create an unprovisioned host (i.e. without hostname or personality) + ndict = dbutils.post_get_test_ihost(uuid=uuidutils.generate_uuid, + personality=None, + hostname=None, + mgmt_ip='192.168.204.111') + self.dbapi.ihost_create(ndict) + # Delete the worker host + self.delete('/ihosts/%s' % ndict['uuid'], + headers={'User-Agent': 'sysinv-test'}) + + # Verify that the host was deleted from the VIM + self.mock_vim_api_host_delete.assert_called_once() + # Verify that the delete was not sent to maintenance + self.mock_mtce_api_host_delete.assert_not_called() + # Verify that the host was unconfigured + self.fake_conductor_api.unconfigure_ihost.assert_called_once() + # Verify that the host was deleted from barbican + self.fake_conductor_api.delete_barbican_secret.assert_called_once() + # Verify that the patch drop host was not invoked + self.mock_patch_api_drop_host.assert_not_called() + + # Verify the host no longer exists + response = self.get_json('/ihosts/%s' % ndict['uuid'], + expect_errors=True) + self.assertEqual(response.status_int, 404) + self.assertEqual(response.content_type, 'application/json') + self.assertTrue(response.json['error_message']) + class TestListHosts(TestHost):