Merge "Remove Mistral from plan list and call the Mistral action directly"

This commit is contained in:
Zuul 2020-02-07 01:22:28 +00:00 committed by Gerrit Code Review
commit f9aff96fb9
6 changed files with 131 additions and 36 deletions

View File

@ -171,6 +171,46 @@ class WebsocketClient(object):
pass pass
class MistralContext(object):
"""MistralContext, a shim for calling Mistral actions directly
The MistralContext and MistralSecurityContext combined mimic the context
which Mistral passes to actions during a Workflow execution. It does
not include all the data or cover all of the functionality but it does
include everything we use in tripleo-common.
The MistralContext should be created by the create_mistral_context method
on the ClientWrapper class below.
This should be refactored and removed once Mistral server has been removed.
"""
def __init__(self, security_ctx=None):
self.security = security_ctx
class MistralSecurityContext(object):
def __init__(self, auth_uri=None, auth_cacert=None, insecure=None,
service_catalog=None, region_name=None, is_trust_scoped=None,
redelivered=None, expires_at=None, trust_id=None,
is_target=None, project_id=None, project_name=None,
user_name=None, user_id=None, auth_token=None):
self.auth_uri = auth_uri
self.auth_cacert = auth_cacert
self.insecure = insecure
self.service_catalog = service_catalog
self.region_name = region_name
self.is_trust_scoped = is_trust_scoped
self.redelivered = redelivered
self.expires_at = expires_at
self.trust_id = trust_id
self.is_target = is_target
self.project_id = project_id
self.project_name = project_name
self.user_name = user_name
self.user_id = user_id
self.auth_token = auth_token
class ClientWrapper(object): class ClientWrapper(object):
def __init__(self, instance): def __init__(self, instance):
@ -178,6 +218,28 @@ class ClientWrapper(object):
self._object_store = None self._object_store = None
self._local_orchestration = None self._local_orchestration = None
def create_mistral_context(self):
"""Create a Mistral context
Create a class that mimics the Mistral context. This allows us to call
Mistral action classes directly.
See the docstring on MistralContext for more context.
"""
session = self._instance.session
security_ctx = MistralSecurityContext(
auth_token=self._instance.auth.get_token(session),
auth_uri=self._instance.auth.auth_url,
project_id=self._instance.auth.get_project_id(session),
project_name=self._instance.auth._project_name,
service_catalog=session.auth.auth_ref._data['token'],
trust_id=self._instance.auth_ref.trust_id,
user_name=self._instance.auth._username,
auth_cacert=self._instance.cacert,
user_id=self._instance.auth._user_id
)
return MistralContext(security_ctx=security_ctx)
def local_orchestration(self, api_port): def local_orchestration(self, api_port):
"""Returns an local_orchestration service client""" """Returns an local_orchestration service client"""

View File

@ -89,6 +89,38 @@ class FakeRunnerConfig(object):
pass pass
class FakeInstanceData(object):
cacert = '/file/system/path'
_region_name = 'region1'
@staticmethod
def get_endpoint_for_service_type(*args, **kwargs):
return 'http://things'
class auth_ref(object):
trust_id = 'yy'
project_id = 'ww'
class auth(object):
auth_url = 'http://url'
_project_name = 'projectname'
_username = 'username'
_user_id = 'zz'
@staticmethod
def get_token(*args, **kwargs):
return '12345abcde'
@staticmethod
def get_project_id(*args, **kwargs):
return 'xx'
class session(object):
class auth(object):
class auth_ref(object):
_data = {'token': {}}
def fake_ansible_runner_run_return(rc=0): def fake_ansible_runner_run_return(rc=0):
return 'Test Status', rc return 'Test Status', rc

View File

@ -42,10 +42,6 @@ class PlanManagementFixture(fixtures.Fixture):
self.mock_tarball = self.useFixture(fixtures.MockPatch( self.mock_tarball = self.useFixture(fixtures.MockPatch(
'tripleoclient.workflows.plan_management.tarball') 'tripleoclient.workflows.plan_management.tarball')
).mock ).mock
self.mock_list_plans = self.useFixture(fixtures.MockPatch(
'tripleoclient.workflows.plan_management.list_deployment_plans',
return_value=[])
).mock
class UtilsOvercloudFixture(fixtures.Fixture): class UtilsOvercloudFixture(fixtures.Fixture):

View File

@ -28,6 +28,8 @@ from swiftclient.exceptions import ClientException as ObjectClientException
from tripleoclient import constants from tripleoclient import constants
from tripleoclient import exceptions from tripleoclient import exceptions
from tripleoclient import plugin
from tripleoclient.tests import fakes as ooofakes
from tripleoclient.tests.fixture_data import deployment from tripleoclient.tests.fixture_data import deployment
from tripleoclient.tests.v1.overcloud_deploy import fakes from tripleoclient.tests.v1.overcloud_deploy import fakes
from tripleoclient.v1 import overcloud_deploy from tripleoclient.v1 import overcloud_deploy
@ -86,6 +88,26 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
mock_sleep = mock.patch('time.sleep', autospec=True) mock_sleep = mock.patch('time.sleep', autospec=True)
mock_sleep.start() mock_sleep.start()
self.addCleanup(mock_sleep.stop) self.addCleanup(mock_sleep.stop)
plan_list = mock.patch(
"tripleoclient.workflows.plan_management.list_deployment_plans",
autospec=True
)
plan_list.start()
plan_list.return_value = ([
"test-plan-1",
"test-plan-2",
])
self.addCleanup(plan_list.stop)
client = self.app.client_manager.tripleoclient = plugin.ClientWrapper(
instance=ooofakes.FakeInstanceData
)
client.messaging_websocket = \
ooofakes.FakeClientWrapper().messaging_websocket
get_object = client.object_store.get_object = mock.Mock()
get_object.return_value = ('f1', 'content')
client.object_store.put_object = mock.Mock()
get_container = client.object_store.get_container = mock.MagicMock()
get_container.return_value = ('container', [{'name': 'f1'}])
def tearDown(self): def tearDown(self):
super(TestDeployOvercloud, self).tearDown() super(TestDeployOvercloud, self).tearDown()
@ -1056,8 +1078,6 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
verifylist = [ verifylist = [
('templates', '/usr/share/openstack-tripleo-heat-templates/'), ('templates', '/usr/share/openstack-tripleo-heat-templates/'),
] ]
clients = self.app.client_manager
workflow_client = clients.workflow_engine workflow_client = clients.workflow_engine
workflow_client.action_executions.create.return_value = mock.MagicMock( workflow_client.action_executions.create.return_value = mock.MagicMock(
output='{"result":[]}') output='{"result":[]}')

View File

@ -15,6 +15,8 @@ import mock
from osc_lib.tests import utils from osc_lib.tests import utils
from tripleoclient import exceptions from tripleoclient import exceptions
from tripleoclient import plugin
from tripleoclient.tests import fakes
from tripleoclient.v1 import overcloud_plan from tripleoclient.v1 import overcloud_plan
@ -36,30 +38,29 @@ class TestOvercloudPlanList(utils.TestCommand):
def setUp(self): def setUp(self):
super(TestOvercloudPlanList, self).setUp() super(TestOvercloudPlanList, self).setUp()
self.app.client_manager.tripleoclient = plugin.ClientWrapper(
instance=fakes.FakeInstanceData
)
self.cmd = overcloud_plan.ListPlans(self.app, None) self.cmd = overcloud_plan.ListPlans(self.app, None)
self.app.client_manager.workflow_engine = mock.Mock()
@mock.patch( @mock.patch("tripleoclient.workflows.plan_management."
'tripleoclient.workflows.plan_management.list_deployment_plans', "list_deployment_plans",
autospec=True) autospec=True)
def test_list_empty(self, mock_list_plans): def test_list_empty(self, mock_list_plans):
mock_list_plans.return_value = [] mock_list_plans.return_value = []
result = self.cmd.take_action(None) result = self.cmd.take_action(None)
mock_list_plans.assert_called_once_with(self.app.client_manager)
self.assertEqual(0, len(result[1])) self.assertEqual(0, len(result[1]))
@mock.patch( @mock.patch("tripleoclient.workflows.plan_management."
'tripleoclient.workflows.plan_management.list_deployment_plans', "list_deployment_plans",
autospec=True) autospec=True)
def test_list(self, mock_list_plans): def test_list(self, mock_list_plans):
mock_list_plans.return_value = ( mock_list_plans.return_value = (
['test-plan-1', 'test-plan-2']) ['test-plan-1', 'test-plan-2'])
result = self.cmd.take_action(None) result = self.cmd.take_action(None)
mock_list_plans.assert_called_once_with(self.app.client_manager)
self.assertEqual(1, len(result[0])) self.assertEqual(1, len(result[0]))
self.assertEqual([('test-plan-1',), ('test-plan-2',)], result[1]) self.assertEqual([('test-plan-1',), ('test-plan-2',)], result[1])

View File

@ -15,6 +15,7 @@ import tempfile
import yaml import yaml
from swiftclient import exceptions as swift_exc from swiftclient import exceptions as swift_exc
from tripleo_common.actions import plan
from tripleo_common.utils import swift as swiftutils from tripleo_common.utils import swift as swiftutils
from tripleo_common.utils import tarball from tripleo_common.utils import tarball
@ -122,26 +123,9 @@ def update_deployment_plan(clients, **workflow_input):
'Exception updating plan: {}'.format(payload['message'])) 'Exception updating plan: {}'.format(payload['message']))
def list_deployment_plans(clients, **workflow_input): def list_deployment_plans(clients):
workflow_client = clients.workflow_engine mistral_context = clients.tripleoclient.create_mistral_context()
tripleoclients = clients.tripleoclient return plan.ListPlansAction().run(mistral_context)
with tripleoclients.messaging_websocket() as ws:
execution = base.start_workflow(
workflow_client,
'tripleo.plan_management.v1.list_plans',
workflow_input=workflow_input
)
for payload in base.wait_for_messages(workflow_client, ws, execution,
_WORKFLOW_TIMEOUT):
if payload['status'] != 'SUCCESS':
raise exceptions.WorkflowServiceError(
'Exception listing plans: {}'.format(payload['message']))
# return plans if the message contains plans
if 'plans' in payload:
return payload['plans']
def create_container(workflow_client, **input_): def create_container(workflow_client, **input_):