Remove mistral from the get_deployment_status workflow

This change Converts plan status checks to using a direct call instead of
executing via mistral.

* A new method was added allowing us to update the deployment status object
  when required.
* Tests have been added for the new static method update_deployment_status.

Story: 2007212
Task: 38430

Change-Id: Ie19be2078e2f349bf06e5b99ab93ca843e367463
Signed-off-by: Kevin Carter <kecarter@redhat.com>
This commit is contained in:
Kevin Carter 2020-02-03 16:08:03 -06:00 committed by Alex Schultz
parent bfed90d630
commit 13e1c2fe42
5 changed files with 108 additions and 38 deletions

View File

@ -38,6 +38,7 @@ import yaml
from tripleoclient import exceptions from tripleoclient import exceptions
from tripleoclient import utils from tripleoclient import utils
from tripleoclient.tests import base
from tripleoclient.tests import fakes from tripleoclient.tests import fakes
from six.moves.configparser import ConfigParser from six.moves.configparser import ConfigParser
@ -1651,3 +1652,24 @@ class TestParseExtraVars(TestCase):
input_parameter = ['key1 val1'] input_parameter = ['key1 val1']
self.assertRaises( self.assertRaises(
ValueError, utils.parse_extra_vars, input_parameter) ValueError, utils.parse_extra_vars, input_parameter)
class TestGeneralUtils(base.TestCommand):
def setUp(self):
super(TestGeneralUtils, self).setUp()
self.tc = self.app.client_manager.tripleoclient = mock.Mock()
obj = self.tc.object_store = mock.Mock()
obj.put_object = mock.Mock()
def test_update_deployment_status(self):
mock_status = {
'status_update': 'TESTING',
'deployment_status': 'TESTING'
}
utils.update_deployment_status(
self.app.client_manager,
'overcloud',
mock_status
)
self.tc.object_store.put_object.assert_called()

View File

@ -1670,24 +1670,28 @@ class TestGetDeploymentStatus(utils.TestCommand):
super(TestGetDeploymentStatus, self).setUp() super(TestGetDeploymentStatus, self).setUp()
self.cmd = overcloud_deploy.GetDeploymentStatus(self.app, None) self.cmd = overcloud_deploy.GetDeploymentStatus(self.app, None)
self.app.client_manager = mock.Mock() self.app.client_manager = mock.Mock()
self.clients = self.app.client_manager clients = self.clients = self.app.client_manager
tc = clients.tripleoclient = ooofakes.FakeClientWrapper()
tc.create_mistral_context = plugin.ClientWrapper(
instance=ooofakes.FakeInstanceData
).create_mistral_context
obj = tc.object_store = mock.Mock()
obj.put_object = mock.Mock()
@mock.patch( @mock.patch(
'tripleoclient.workflows.deployment.get_deployment_status', 'tripleo_common.actions.deployment.DeploymentStatusAction.run',
autospec=True) autospec=True
)
def test_get_deployment_status(self, mock_get_deployment_status): def test_get_deployment_status(self, mock_get_deployment_status):
parsed_args = self.check_parser(self.cmd, [], []) parsed_args = self.check_parser(self.cmd, [], [])
self.cmd.app.stdout = six.StringIO() self.cmd.app.stdout = six.StringIO()
status = dict(
status = { cd_status='SUCCESS',
'workflow_status': { stack_status='SUCCESS',
'payload': { deployment_status='SUCCESS',
'plan_name': 'testplan', ansible_status='SUCCESS',
'deployment_status': 'SUCCESS' status_update='SUCCESS'
} )
}
}
mock_get_deployment_status.return_value = status mock_get_deployment_status.return_value = status
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
@ -1696,7 +1700,7 @@ class TestGetDeploymentStatus(utils.TestCommand):
'+-----------+-------------------+\n' '+-----------+-------------------+\n'
'| Plan Name | Deployment Status |\n' '| Plan Name | Deployment Status |\n'
'+-----------+-------------------+\n' '+-----------+-------------------+\n'
'| testplan | SUCCESS |\n' '| overcloud | SUCCESS |\n'
'+-----------+-------------------+\n') '+-----------+-------------------+\n')
self.assertEqual(expected, self.cmd.app.stdout.getvalue()) self.assertEqual(expected, self.cmd.app.stdout.getvalue())

View File

@ -2302,3 +2302,45 @@ def copy_clouds_yaml(user):
' with sudo') % {'user': user, 'dir': clouds_config_dir} ' with sudo') % {'user': user, 'dir': clouds_config_dir}
LOG.error(msg) LOG.error(msg)
raise exceptions.DeploymentError(msg) raise exceptions.DeploymentError(msg)
def update_deployment_status(clients, plan, status, message=None):
"""Update the deployment status object in swift.
:param clients: application client object.
:type clients: Object
:param plan: Plan name.
:type plan: String
:param status: Status information.
:type status: Dictionary
:param message: Status message.
:type message: String
"""
if not message:
message = 'Status updated without mistral.'
clients.tripleoclient.object_store.put_object(
'{}-messages'.format(plan),
'deployment_status.yaml',
yaml.safe_dump(
{
'deployment_status': status['status_update'],
'workflow_status': {
'payload': {
'deployment_status': status['status_update'],
'execution_id': 'UNDEFINED',
'message': message,
'plan_name': plan,
'root_execution_id': 'UNDEFINED',
'status': status['status_update']
},
'type': 'tripleoclient'
}
},
default_flow_style=False
)
)

View File

@ -1032,7 +1032,7 @@ class GetDeploymentStatus(command.Command):
self.log.debug("take_action(%s)" % parsed_args) self.log.debug("take_action(%s)" % parsed_args)
plan = parsed_args.plan plan = parsed_args.plan
status = deployment.get_deployment_status( status, plan = deployment.get_deployment_status(
self.app.client_manager, self.app.client_manager,
plan=plan plan=plan
) )
@ -1041,11 +1041,9 @@ class GetDeploymentStatus(command.Command):
print('No deployment was found for %s' % plan) print('No deployment was found for %s' % plan)
return return
payload = status['workflow_status']['payload']
table = PrettyTable( table = PrettyTable(
['Plan Name', 'Deployment Status']) ['Plan Name', 'Deployment Status'])
table.add_row([payload['plan_name'], table.add_row([plan, status])
payload['deployment_status']])
print(table, file=self.app.stdout) print(table, file=self.app.stdout)

View File

@ -19,6 +19,7 @@ import yaml
from heatclient.common import event_utils from heatclient.common import event_utils
from openstackclient import shell from openstackclient import shell
from tripleo_common.actions import deployment
from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS
from tripleoclient import exceptions from tripleoclient import exceptions
@ -360,29 +361,32 @@ def get_horizon_url(stack):
return f.read().strip() return f.read().strip()
def get_deployment_status(clients, **workflow_input): def get_deployment_status(clients, plan):
workflow_client = clients.workflow_engine """Return current deployment status.
tripleoclients = clients.tripleoclient
with tripleoclients.messaging_websocket() as ws: :param clients: application client object.
execution = base.start_workflow( :type clients: Object
workflow_client,
'tripleo.deployment.v1.get_deployment_status', :param plan: Plan name.
workflow_input=workflow_input :type plan: String
:returns: string
"""
context = clients.tripleoclient.create_mistral_context()
get_deployment_status = deployment.DeploymentStatusAction(plan=plan)
status = get_deployment_status.run(context=context)
status_update = status.get('status_update')
deployment_status = status.get('deployment_status')
if status_update:
utils.update_deployment_status(
clients=clients,
plan=plan,
status=status
) )
return status_update, plan
for payload in base.wait_for_messages(workflow_client, ws, execution,
_WORKFLOW_TIMEOUT):
message = payload.get('message')
if message:
print(message)
if payload['status'] == 'SUCCESS':
return payload['deployment_status']
else: else:
raise exceptions.WorkflowServiceError( return deployment_status, plan
'Exception getting deployment status: {}'.format(
payload.get('message', '')))
def set_deployment_status(clients, status='success', **workflow_input): def set_deployment_status(clients, status='success', **workflow_input):