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 utils
from tripleoclient.tests import base
from tripleoclient.tests import fakes
from six.moves.configparser import ConfigParser
@ -1651,3 +1652,24 @@ class TestParseExtraVars(TestCase):
input_parameter = ['key1 val1']
self.assertRaises(
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()
self.cmd = overcloud_deploy.GetDeploymentStatus(self.app, None)
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(
'tripleoclient.workflows.deployment.get_deployment_status',
autospec=True)
'tripleo_common.actions.deployment.DeploymentStatusAction.run',
autospec=True
)
def test_get_deployment_status(self, mock_get_deployment_status):
parsed_args = self.check_parser(self.cmd, [], [])
self.cmd.app.stdout = six.StringIO()
status = {
'workflow_status': {
'payload': {
'plan_name': 'testplan',
'deployment_status': 'SUCCESS'
}
}
}
status = dict(
cd_status='SUCCESS',
stack_status='SUCCESS',
deployment_status='SUCCESS',
ansible_status='SUCCESS',
status_update='SUCCESS'
)
mock_get_deployment_status.return_value = status
self.cmd.take_action(parsed_args)
@ -1696,7 +1700,7 @@ class TestGetDeploymentStatus(utils.TestCommand):
'+-----------+-------------------+\n'
'| Plan Name | Deployment Status |\n'
'+-----------+-------------------+\n'
'| testplan | SUCCESS |\n'
'| overcloud | SUCCESS |\n'
'+-----------+-------------------+\n')
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}
LOG.error(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)
plan = parsed_args.plan
status = deployment.get_deployment_status(
status, plan = deployment.get_deployment_status(
self.app.client_manager,
plan=plan
)
@ -1041,11 +1041,9 @@ class GetDeploymentStatus(command.Command):
print('No deployment was found for %s' % plan)
return
payload = status['workflow_status']['payload']
table = PrettyTable(
['Plan Name', 'Deployment Status'])
table.add_row([payload['plan_name'],
payload['deployment_status']])
table.add_row([plan, status])
print(table, file=self.app.stdout)

View File

@ -19,6 +19,7 @@ import yaml
from heatclient.common import event_utils
from openstackclient import shell
from tripleo_common.actions import deployment
from tripleoclient.constants import ANSIBLE_TRIPLEO_PLAYBOOKS
from tripleoclient import exceptions
@ -360,29 +361,32 @@ def get_horizon_url(stack):
return f.read().strip()
def get_deployment_status(clients, **workflow_input):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
def get_deployment_status(clients, plan):
"""Return current deployment status.
with tripleoclients.messaging_websocket() as ws:
execution = base.start_workflow(
workflow_client,
'tripleo.deployment.v1.get_deployment_status',
workflow_input=workflow_input
:param clients: application client object.
:type clients: Object
:param plan: Plan name.
: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
)
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']
return status_update, plan
else:
raise exceptions.WorkflowServiceError(
'Exception getting deployment status: {}'.format(
payload.get('message', '')))
return deployment_status, plan
def set_deployment_status(clients, status='success', **workflow_input):