diff --git a/mistral/actions/base.py b/mistral/actions/base.py index a0d804376..139f47ac6 100644 --- a/mistral/actions/base.py +++ b/mistral/actions/base.py @@ -13,6 +13,12 @@ # limitations under the License. import abc +import warnings + +warnings.warn( + "mistral.actions.Action is deprecated as of the 5.0.0 release in favor of" + "mistral_lib. It will be removed in a future release.", DeprecationWarning +) class Action(object): diff --git a/mistral/actions/openstack/actions.py b/mistral/actions/openstack/actions.py index ab77811c8..e494b312e 100644 --- a/mistral/actions/openstack/actions.py +++ b/mistral/actions/openstack/actions.py @@ -22,7 +22,6 @@ from keystoneclient.auth import identity from keystoneclient import httpclient from mistral.actions.openstack import base -from mistral import context from mistral.utils import inspect_utils from mistral.utils.openstack import keystone as keystone_utils @@ -76,10 +75,9 @@ class NovaAction(base.OpenStackAction): _service_name = 'nova' _service_type = 'compute' - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Nova action security context: %s" % ctx) + LOG.debug("Nova action security context: %s" % context) keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() nova_endpoint = self.get_service_endpoint() @@ -90,16 +88,16 @@ class NovaAction(base.OpenStackAction): api_key=None, endpoint_type=CONF.openstack_actions.os_actions_endpoint_type, service_type='compute', - auth_token=ctx.auth_token, - tenant_id=ctx.project_id, + auth_token=context.auth_token, + tenant_id=context.project_id, region_name=nova_endpoint.region, auth_url=keystone_endpoint.url, - insecure=ctx.insecure + insecure=context.insecure ) client.client.management_url = keystone_utils.format_url( nova_endpoint.url, - {'tenant_id': ctx.project_id} + {'tenant_id': context.project_id} ) return client @@ -116,18 +114,17 @@ class GlanceAction(base.OpenStackAction): def _get_client_class(cls): return glanceclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Glance action security context: %s" % ctx) + LOG.debug("Glance action security context: %s" % context) glance_endpoint = self.get_service_endpoint() return self._get_client_class()( glance_endpoint.url, region_name=glance_endpoint.region, - token=ctx.auth_token, - insecure=ctx.insecure + token=context.auth_token, + insecure=context.insecure ) @classmethod @@ -141,30 +138,29 @@ class KeystoneAction(base.OpenStackAction): def _get_client_class(cls): return keystoneclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Keystone action security context: %s" % ctx) + LOG.debug("Keystone action security context: %s" % context) # TODO(akovi) cacert is deprecated in favor of session # TODO(akovi) this piece of code should be refactored # TODO(akovi) to follow the new guide lines kwargs = { - 'token': ctx.auth_token, - 'auth_url': ctx.auth_uri, - 'project_id': ctx.project_id, - 'cacert': ctx.auth_cacert, - 'insecure': ctx.insecure + 'token': context.auth_token, + 'auth_url': context.auth_uri, + 'project_id': context.project_id, + 'cacert': context.auth_cacert, + 'insecure': context.insecure } # In case of trust-scoped token explicitly pass endpoint parameter. - if (ctx.is_trust_scoped - or keystone_utils.is_token_trust_scoped(ctx.auth_token)): - kwargs['endpoint'] = ctx.auth_uri + if (context.is_trust_scoped + or keystone_utils.is_token_trust_scoped(context.auth_token)): + kwargs['endpoint'] = context.auth_uri client = self._get_client_class()(**kwargs) - client.management_url = ctx.auth_uri + client.management_url = context.auth_uri return client @@ -189,24 +185,23 @@ class CeilometerAction(base.OpenStackAction): def _get_client_class(cls): return ceilometerclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Ceilometer action security context: %s" % ctx) + LOG.debug("Ceilometer action security context: %s" % context) ceilometer_endpoint = self.get_service_endpoint() endpoint_url = keystone_utils.format_url( ceilometer_endpoint.url, - {'tenant_id': ctx.project_id} + {'tenant_id': context.project_id} ) return self._get_client_class()( endpoint_url, region_name=ceilometer_endpoint.region, - token=ctx.auth_token, - username=ctx.user_name, - insecure=ctx.insecure + token=context.auth_token, + username=context.user_name, + insecure=context.insecure ) @classmethod @@ -221,27 +216,26 @@ class HeatAction(base.OpenStackAction): def _get_client_class(cls): return heatclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Heat action security context: %s" % ctx) + LOG.debug("Heat action security context: %s" % context) heat_endpoint = self.get_service_endpoint() endpoint_url = keystone_utils.format_url( heat_endpoint.url, { - 'tenant_id': ctx.project_id, - 'project_id': ctx.project_id + 'tenant_id': context.project_id, + 'project_id': context.project_id } ) return self._get_client_class()( endpoint_url, region_name=heat_endpoint.region, - token=ctx.auth_token, - username=ctx.user_name, - insecure=ctx.insecure + token=context.auth_token, + username=context.user_name, + insecure=context.insecure ) @classmethod @@ -256,19 +250,18 @@ class NeutronAction(base.OpenStackAction): def _get_client_class(cls): return neutronclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Neutron action security context: %s" % ctx) + LOG.debug("Neutron action security context: %s" % context) neutron_endpoint = self.get_service_endpoint() return self._get_client_class()( endpoint_url=neutron_endpoint.url, region_name=neutron_endpoint.region, - token=ctx.auth_token, - auth_url=ctx.auth_uri, - insecure=ctx.insecure + token=context.auth_token, + auth_url=context.auth_uri, + insecure=context.insecure ) @@ -279,31 +272,30 @@ class CinderAction(base.OpenStackAction): def _get_client_class(cls): return cinderclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Cinder action security context: %s" % ctx) + LOG.debug("Cinder action security context: %s" % context) cinder_endpoint = self.get_service_endpoint() cinder_url = keystone_utils.format_url( cinder_endpoint.url, { - 'tenant_id': ctx.project_id, - 'project_id': ctx.project_id + 'tenant_id': context.project_id, + 'project_id': context.project_id } ) client = self._get_client_class()( - ctx.user_name, - ctx.auth_token, - project_id=ctx.project_id, + context.user_name, + context.auth_token, + project_id=context.project_id, auth_url=cinder_url, region_name=cinder_endpoint.region, - insecure=ctx.insecure + insecure=context.insecure ) - client.client.auth_token = ctx.auth_token + client.client.auth_token = context.auth_token client.client.management_url = cinder_url return client @@ -319,14 +311,13 @@ class MistralAction(base.OpenStackAction): def _get_client_class(cls): return mistralclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Mistral action security context: %s" % ctx) + LOG.debug("Mistral action security context: %s" % context) # Check for trust scope token. This may occur if the action is # called from a workflow triggered by a Mistral cron trigger. - if ctx.is_trust_scoped: + if context.is_trust_scoped: auth_url = None mistral_endpoint = keystone_utils.get_endpoint_for_project( 'mistral' @@ -339,11 +330,11 @@ class MistralAction(base.OpenStackAction): return self._get_client_class()( mistral_url=mistral_url, - auth_token=ctx.auth_token, - project_id=ctx.project_id, - user_id=ctx.user_id, + auth_token=context.auth_token, + project_id=context.project_id, + user_id=context.user_id, auth_url=auth_url, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -358,28 +349,27 @@ class TroveAction(base.OpenStackAction): def _get_client_class(cls): return troveclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Trove action security context: %s" % ctx) + LOG.debug("Trove action security context: %s" % context) trove_endpoint = self.get_service_endpoint() trove_url = keystone_utils.format_url( trove_endpoint.url, - {'tenant_id': ctx.project_id} + {'tenant_id': context.project_id} ) client = self._get_client_class()( - ctx.user_name, - ctx.auth_token, - project_id=ctx.project_id, + context.user_name, + context.auth_token, + project_id=context.project_id, auth_url=trove_url, region_name=trove_endpoint.region, - insecure=ctx.insecure + insecure=context.insecure ) - client.client.auth_token = ctx.auth_token + client.client.auth_token = context.auth_token client.client.management_url = trove_url return client @@ -396,19 +386,18 @@ class IronicAction(base.OpenStackAction): def _get_client_class(cls): return ironicclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Ironic action security context: %s" % ctx) + LOG.debug("Ironic action security context: %s" % context) ironic_endpoint = self.get_service_endpoint() return self._get_client_class()( ironic_endpoint.url, - token=ctx.auth_token, + token=context.auth_token, region_name=ironic_endpoint.region, os_ironic_api_version=IRONIC_API_VERSION, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -444,10 +433,10 @@ class BaremetalIntrospectionAction(base.OpenStackAction): return cls._get_client_class()() - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Baremetal introspection action security context: %s" % ctx) + LOG.debug( + "Baremetal introspection action security context: %s" % context) inspector_endpoint = keystone_utils.get_endpoint_for_project( service_type='baremetal-introspection' @@ -456,7 +445,7 @@ class BaremetalIntrospectionAction(base.OpenStackAction): return self._get_client_class()( api_version=1, inspector_url=inspector_endpoint.url, - auth_token=ctx.auth_token, + auth_token=context.auth_token, ) @@ -466,17 +455,18 @@ class SwiftAction(base.OpenStackAction): def _get_client_class(cls): return swift_client.Connection - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Swift action security context: %s" % ctx) + LOG.debug("Swift action security context: %s" % context) swift_endpoint = keystone_utils.get_endpoint_for_project('swift') kwargs = { - 'preauthurl': swift_endpoint.url % {'tenant_id': ctx.project_id}, - 'preauthtoken': ctx.auth_token, - 'insecure': ctx.insecure + 'preauthurl': swift_endpoint.url % { + 'tenant_id': context.project_id + }, + 'preauthtoken': context.auth_token, + 'insecure': context.insecure } return self._get_client_class()(**kwargs) @@ -488,20 +478,19 @@ class ZaqarAction(base.OpenStackAction): def _get_client_class(cls): return zaqarclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Zaqar action security context: %s" % ctx) + LOG.debug("Zaqar action security context: %s" % context) zaqar_endpoint = keystone_utils.get_endpoint_for_project( service_type='messaging') keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() opts = { - 'os_auth_token': ctx.auth_token, + 'os_auth_token': context.auth_token, 'os_auth_url': keystone_endpoint.url, - 'os_project_id': ctx.project_id, - 'insecure': ctx.insecure, + 'os_project_id': context.project_id, + 'insecure': context.insecure, } auth_opts = {'backend': 'keystone', 'options': opts} conf = {'auth_opts': auth_opts} @@ -585,26 +574,25 @@ class BarbicanAction(base.OpenStackAction): def _get_client_class(cls): return barbicanclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Barbican action security context: %s" % ctx) + LOG.debug("Barbican action security context: %s" % context) barbican_endpoint = keystone_utils.get_endpoint_for_project('barbican') keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() auth = identity.v2.Token( auth_url=keystone_endpoint.url, - tenant_name=ctx.user_name, - token=ctx.auth_token, - tenant_id=ctx.project_id + tenant_name=context.user_name, + token=context.auth_token, + tenant_id=context.project_id ) return self._get_client_class()( - project_id=ctx.project_id, + project_id=context.project_id, endpoint=barbican_endpoint.url, auth=auth, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -689,28 +677,27 @@ class DesignateAction(base.OpenStackAction): def _get_client_class(cls): return designateclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Designate action security context: %s" % ctx) + LOG.debug("Designate action security context: %s" % context) designate_endpoint = self.get_service_endpoint() designate_url = keystone_utils.format_url( designate_endpoint.url, - {'tenant_id': ctx.project_id} + {'tenant_id': context.project_id} ) client = self._get_client_class()( endpoint=designate_url, - tenant_id=ctx.project_id, - auth_url=ctx.auth_uri, + tenant_id=context.project_id, + auth_url=context.auth_uri, region_name=designate_endpoint.region, service_type='dns', - insecure=ctx.insecure + insecure=context.insecure ) - client.client.auth_token = ctx.auth_token + client.client.auth_token = context.auth_token client.client.management_url = designate_url return client @@ -726,10 +713,9 @@ class MagnumAction(base.OpenStackAction): def _get_client_class(cls): return magnumclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Magnum action security context: %s" % ctx) + LOG.debug("Magnum action security context: %s" % context) keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() auth_url = keystone_endpoint.url @@ -737,11 +723,11 @@ class MagnumAction(base.OpenStackAction): return self._get_client_class()( magnum_url=magnum_url, - auth_token=ctx.auth_token, - project_id=ctx.project_id, - user_id=ctx.user_id, + auth_token=context.auth_token, + project_id=context.project_id, + user_id=context.user_id, auth_url=auth_url, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -756,21 +742,20 @@ class MuranoAction(base.OpenStackAction): def _get_client_class(cls): return muranoclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Murano action security context: %s" % ctx) + LOG.debug("Murano action security context: %s" % context) keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() murano_endpoint = self.get_service_endpoint() return self._get_client_class()( endpoint=murano_endpoint.url, - token=ctx.auth_token, - tenant=ctx.project_id, + token=context.auth_token, + tenant=context.project_id, region_name=murano_endpoint.region, auth_url=keystone_endpoint.url, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -785,21 +770,20 @@ class TackerAction(base.OpenStackAction): def _get_client_class(cls): return tackerclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Tacker action security context: %s" % ctx) + LOG.debug("Tacker action security context: %s" % context) keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() tacker_endpoint = self.get_service_endpoint() return self._get_client_class()( endpoint_url=tacker_endpoint.url, - token=ctx.auth_token, - tenant_id=ctx.project_id, + token=context.auth_token, + tenant_id=context.project_id, region_name=tacker_endpoint.region, auth_url=keystone_endpoint.url, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -814,21 +798,20 @@ class SenlinAction(base.OpenStackAction): def _get_client_class(cls): return senlinclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Senlin action security context: %s" % ctx) + LOG.debug("Senlin action security context: %s" % context) keystone_endpoint = keystone_utils.get_keystone_endpoint_v2() senlin_endpoint = self.get_service_endpoint() return self._get_client_class()( endpoint_url=senlin_endpoint.url, - token=ctx.auth_token, - tenant_id=ctx.project_id, + token=context.auth_token, + tenant_id=context.project_id, region_name=senlin_endpoint.region, auth_url=keystone_endpoint.url, - insecure=ctx.insecure + insecure=context.insecure ) @classmethod @@ -843,24 +826,23 @@ class AodhAction(base.OpenStackAction): def _get_client_class(cls): return aodhclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Aodh action security context: %s" % ctx) + LOG.debug("Aodh action security context: %s" % context) aodh_endpoint = self.get_service_endpoint() endpoint_url = keystone_utils.format_url( aodh_endpoint.url, - {'tenant_id': ctx.project_id} + {'tenant_id': context.project_id} ) return self._get_client_class()( endpoint_url, region_name=aodh_endpoint.region, - token=ctx.auth_token, - username=ctx.user_name, - insecure=ctx.insecure + token=context.auth_token, + username=context.user_name, + insecure=context.insecure ) @classmethod @@ -875,23 +857,22 @@ class GnocchiAction(base.OpenStackAction): def _get_client_class(cls): return gnocchiclient.Client - def _create_client(self): - ctx = context.ctx() + def _create_client(self, context): - LOG.debug("Gnocchi action security context: %s" % ctx) + LOG.debug("Gnocchi action security context: %s" % context) gnocchi_endpoint = self.get_service_endpoint() endpoint_url = keystone_utils.format_url( gnocchi_endpoint.url, - {'tenant_id': ctx.project_id} + {'tenant_id': context.project_id} ) return self._get_client_class()( endpoint_url, region_name=gnocchi_endpoint.region, - token=ctx.auth_token, - username=ctx.user_name + token=context.auth_token, + username=context.user_name ) @classmethod diff --git a/mistral/actions/openstack/base.py b/mistral/actions/openstack/base.py index 7f1ddd572..d9fde82ce 100644 --- a/mistral/actions/openstack/base.py +++ b/mistral/actions/openstack/base.py @@ -20,17 +20,16 @@ from cachetools import LRUCache from oslo_log import log -from mistral.actions import base -from mistral import context from mistral import exceptions as exc from mistral.utils.openstack import keystone as keystone_utils +from mistral_lib import actions from threading import Lock LOG = log.getLogger(__name__) -class OpenStackAction(base.Action): +class OpenStackAction(actions.Action): """OpenStack Action. OpenStack Action is the basis of all OpenStack-specific actions, @@ -80,7 +79,7 @@ class OpenStackAction(base.Action): def get_fake_client_method(cls): return cls._get_client_method(cls._get_fake_client()) - def _get_client(self): + def _get_client(self, context): """Returns python-client instance via cache or creation Gets client instance according to specific OpenStack Service @@ -92,16 +91,15 @@ class OpenStackAction(base.Action): # regressions in Mistral. It is disabled for now and # will be revisited in Ocata. See: # https://bugs.launchpad.net/mistral/+bug/1627689 - return self._create_client() + return self._create_client(context) - ctx = context.ctx() client_class = self.__class__.__name__ # Colon character is reserved (rfc3986) which avoids key collisions. - key = client_class + ':' + ctx.project_id + key = client_class + ':' + context.project_id def create_cached_client(): - new_client = self._create_client() - new_client._mistral_ctx_expires_at = ctx.expires_at + new_client = self._create_client(context) + new_client._mistral_ctx_expires_at = context.expires_at with self._lock: self._clients[key] = new_client @@ -137,9 +135,9 @@ class OpenStackAction(base.Action): return endpoint - def run(self): + def run(self, context): try: - method = self._get_client_method(self._get_client()) + method = self._get_client_method(self._get_client(context)) result = method(**self._kwargs_for_run) @@ -159,7 +157,7 @@ class OpenStackAction(base.Action): (self.__class__.__name__, self.client_method_name, e_str) ) - def test(self): + def test(self, context): return dict( zip(self._kwargs_for_run, ['test'] * len(self._kwargs_for_run)) ) diff --git a/mistral/actions/std_actions.py b/mistral/actions/std_actions.py index 3bd564907..a89b48449 100644 --- a/mistral/actions/std_actions.py +++ b/mistral/actions/std_actions.py @@ -22,17 +22,17 @@ import six import smtplib import time -from mistral.actions import base from mistral import exceptions as exc from mistral.utils import javascript from mistral.utils import ssh_utils from mistral.workflow import utils as wf_utils +from mistral_lib import actions from oslo_log import log as logging LOG = logging.getLogger(__name__) -class EchoAction(base.Action): +class EchoAction(actions.Action): """Echo action. This action just returns a configured value as a result without doing @@ -45,16 +45,16 @@ class EchoAction(base.Action): def __init__(self, output): self.output = output - def run(self): + def run(self, context): LOG.info('Running echo action [output=%s]' % self.output) return self.output - def test(self): + def test(self, context): return 'Echo' -class NoOpAction(base.Action): +class NoOpAction(actions.Action): """No-operation action. This action does nothing. It can be mostly useful for testing and @@ -63,12 +63,12 @@ class NoOpAction(base.Action): def __init__(self): pass - def run(self): + def run(self, context): LOG.info('Running no-op action') return None - def test(self): + def test(self, context): return None @@ -78,7 +78,7 @@ class AsyncNoOpAction(NoOpAction): return False -class FailAction(base.Action): +class FailAction(actions.Action): """'Always fail' action. This action just always throws an instance of ActionException. @@ -89,16 +89,16 @@ class FailAction(base.Action): def __init__(self): pass - def run(self): + def run(self, context): LOG.info('Running fail action.') raise exc.ActionException('Fail action expected exception.') - def test(self): + def test(self, context): raise exc.ActionException('Fail action expected exception.') -class HTTPAction(base.Action): +class HTTPAction(actions.Action): """Constructs an HTTP action. :param url: URL for the new HTTP request. @@ -158,7 +158,7 @@ class HTTPAction(base.Action): self.proxies = proxies self.verify = verify - def run(self): + def run(self, context): LOG.info("Running HTTP action " "[url=%s, method=%s, params=%s, body=%s, headers=%s," " cookies=%s, auth=%s, timeout=%s, allow_redirects=%s," @@ -227,12 +227,13 @@ class HTTPAction(base.Action): return _result - def test(self): + def test(self, context): # TODO(rakhmerov): Implement. return None class MistralHTTPAction(HTTPAction): + def __init__(self, action_context, url, @@ -275,11 +276,11 @@ class MistralHTTPAction(HTTPAction): def is_sync(self): return False - def test(self): + def test(self, context): return None -class SendEmailAction(base.Action): +class SendEmailAction(actions.Action): def __init__(self, from_addr, to_addrs, smtp_server, smtp_password=None, subject=None, body=None): # TODO(dzimine): validate parameters @@ -294,7 +295,7 @@ class SendEmailAction(base.Action): self.sender = from_addr self.password = smtp_password - def run(self): + def run(self, context): LOG.info("Sending email message " "[from=%s, to=%s, subject=%s, using smtp=%s, body=%s...]" % (self.sender, self.to, self.subject, @@ -322,7 +323,7 @@ class SendEmailAction(base.Action): raise exc.ActionException("Failed to send an email message: %s" % e) - def test(self): + def test(self, context): # Just logging the operation since this action is not supposed # to return a result. LOG.info("Sending email message " @@ -331,7 +332,7 @@ class SendEmailAction(base.Action): self.smtp_server, self.body[:128])) -class SSHAction(base.Action): +class SSHAction(actions.Action): """Runs Secure Shell (SSH) command on provided single or multiple hosts. It is allowed to provide either a single host or a list of hosts in @@ -359,7 +360,7 @@ class SSHAction(base.Action): 'private_key_filename': self.private_key_filename } - def run(self): + def run(self, context): def raise_exc(parent_exc=None): message = ("Failed to execute ssh cmd " "'%s' on %s" % (self.cmd, self.host)) @@ -390,7 +391,7 @@ class SSHAction(base.Action): except Exception as e: return raise_exc(parent_exc=e) - def test(self): + def test(self, context): # TODO(rakhmerov): Implement. return None @@ -423,30 +424,36 @@ class SSHProxiedAction(SSHAction): ) -class JavaScriptAction(base.Action): +class JavaScriptAction(actions.Action): """Evaluates given JavaScript. """ - def __init__(self, script, context=None): - self.script = script - self.context = context - def run(self): + def __init__(self, script, context=None): + """Context here refers to a javasctript context + + Not the usual mistral context. That is passed during the run method + """ + + self.script = script + self.js_context = context + + def run(self, context): try: script = """function f() { %s } f() """ % self.script - return javascript.evaluate(script, self.context) + return javascript.evaluate(script, self.js_context) except Exception as e: raise exc.ActionException("JavaScriptAction failed: %s" % str(e)) - def test(self): + def test(self, context): return self.script -class SleepAction(base.Action): +class SleepAction(actions.Action): """Sleep action. This action sleeps for given amount of seconds. It can be mostly useful @@ -459,20 +466,20 @@ class SleepAction(base.Action): except ValueError: self._seconds = 0 - def run(self): + def run(self, context): LOG.info('Running sleep action [seconds=%s]' % self._seconds) time.sleep(self._seconds) return None - def test(self): + def test(self, context): time.sleep(1) return None -class TestDictAction(base.Action): +class TestDictAction(actions.Action): """Generates test dict.""" def __init__(self, size=0, key_prefix='', val=''): @@ -480,7 +487,7 @@ class TestDictAction(base.Action): self.key_prefix = key_prefix self.val = val - def run(self): + def run(self, context): LOG.info( 'Running test_dict action [size=%s, key_prefix=%s, val=%s]' % (self.size, self.key_prefix, self.val) @@ -493,5 +500,5 @@ class TestDictAction(base.Action): return res - def test(self): + def test(self, context): return {} diff --git a/mistral/tests/unit/actions/openstack/test_openstack_actions.py b/mistral/tests/unit/actions/openstack/test_openstack_actions.py index d0c701a4c..ab27b7cec 100644 --- a/mistral/tests/unit/actions/openstack/test_openstack_actions.py +++ b/mistral/tests/unit/actions/openstack/test_openstack_actions.py @@ -27,12 +27,13 @@ class FakeEndpoint(object): class OpenStackActionTest(base.BaseTestCase): @mock.patch.object(actions.NovaAction, '_get_client') def test_nova_action(self, mocked): + mock_ctx = mock.Mock() method_name = "servers.get" action_class = actions.NovaAction action_class.client_method_name = method_name params = {'server': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().servers.get.called) mocked().servers.get.assert_called_once_with(server="1234-abcd") @@ -56,7 +57,6 @@ class OpenStackActionTest(base.BaseTestCase): expires_at='3016-07-13T18:34:22.000000Z', insecure=False ) - ctx.set_ctx(test_ctx) # attributes mirror keystone Endpoint object exactly # (with endpoint type public) @@ -98,7 +98,7 @@ class OpenStackActionTest(base.BaseTestCase): action_class.client_method_name = method_name params = {'server': '1234-abcd'} action = action_class(**params) - action.run() + action.run(test_ctx) mock_novaclient.Client.assert_called_once_with( 2, @@ -119,7 +119,7 @@ class OpenStackActionTest(base.BaseTestCase): # Repeat test in order to validate cache. mock_novaclient.reset_mock() - action.run() + action.run(test_ctx) # TODO(d0ugal): Uncomment the following line when caching is fixed. # mock_novaclient.Client.assert_not_called() @@ -129,10 +129,9 @@ class OpenStackActionTest(base.BaseTestCase): # Repeat again with different context for cache testing. test_ctx.project_name = 'service' test_ctx.project_id = '1235' - ctx.set_ctx(test_ctx) mock_novaclient.reset_mock() - action.run() + action.run(test_ctx) mock_novaclient.Client.assert_called_once_with( 2, username=None, @@ -152,132 +151,143 @@ class OpenStackActionTest(base.BaseTestCase): @mock.patch.object(actions.GlanceAction, '_get_client') def test_glance_action(self, mocked): + mock_ctx = mock.Mock() method_name = "images.delete" action_class = actions.GlanceAction action_class.client_method_name = method_name params = {'image': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().images.delete.called) mocked().images.delete.assert_called_once_with(image="1234-abcd") @mock.patch.object(actions.KeystoneAction, '_get_client') def test_keystone_action(self, mocked): + mock_ctx = mock.Mock() method_name = "users.get" action_class = actions.KeystoneAction action_class.client_method_name = method_name params = {'user': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().users.get.called) mocked().users.get.assert_called_once_with(user="1234-abcd") @mock.patch.object(actions.HeatAction, '_get_client') def test_heat_action(self, mocked): + mock_ctx = mock.Mock() method_name = "stacks.get" action_class = actions.HeatAction action_class.client_method_name = method_name params = {'id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().stacks.get.called) mocked().stacks.get.assert_called_once_with(id="1234-abcd") @mock.patch.object(actions.NeutronAction, '_get_client') def test_neutron_action(self, mocked): + mock_ctx = mock.Mock() method_name = "show_network" action_class = actions.NeutronAction action_class.client_method_name = method_name params = {'id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().show_network.called) mocked().show_network.assert_called_once_with(id="1234-abcd") @mock.patch.object(actions.CinderAction, '_get_client') def test_cinder_action(self, mocked): + mock_ctx = mock.Mock() method_name = "volumes.get" action_class = actions.CinderAction action_class.client_method_name = method_name params = {'volume': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().volumes.get.called) mocked().volumes.get.assert_called_once_with(volume="1234-abcd") @mock.patch.object(actions.CeilometerAction, '_get_client') def test_ceilometer_action(self, mocked): + mock_ctx = mock.Mock() method_name = "alarms.get" action_class = actions.CeilometerAction action_class.client_method_name = method_name params = {'alarm_id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().alarms.get.called) mocked().alarms.get.assert_called_once_with(alarm_id="1234-abcd") @mock.patch.object(actions.TroveAction, '_get_client') def test_trove_action(self, mocked): + mock_ctx = mock.Mock() method_name = "instances.get" action_class = actions.TroveAction action_class.client_method_name = method_name params = {'instance': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().instances.get.called) mocked().instances.get.assert_called_once_with(instance="1234-abcd") @mock.patch.object(actions.IronicAction, '_get_client') def test_ironic_action(self, mocked): + mock_ctx = mock.Mock() method_name = "node.get" action_class = actions.IronicAction action_class.client_method_name = method_name params = {'node': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().node.get.called) mocked().node.get.assert_called_once_with(node="1234-abcd") @mock.patch.object(actions.BaremetalIntrospectionAction, '_get_client') def test_baremetal_introspector_action(self, mocked): + mock_ctx = mock.Mock() method_name = "get_status" action_class = actions.BaremetalIntrospectionAction action_class.client_method_name = method_name params = {'uuid': '1234'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().get_status.called) mocked().get_status.assert_called_once_with(uuid="1234") @mock.patch.object(actions.MistralAction, '_get_client') def test_mistral_action(self, mocked): + mock_ctx = mock.Mock() method_name = "workflows.get" action_class = actions.MistralAction action_class.client_method_name = method_name params = {'name': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().workflows.get.called) mocked().workflows.get.assert_called_once_with(name="1234-abcd") @mock.patch.object(actions.SwiftAction, '_get_client') def test_swift_action(self, mocked): + mock_ctx = mock.Mock() method_name = "get_object" action_class = actions.SwiftAction action_class.client_method_name = method_name params = {'container': 'foo', 'object': 'bar'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().get_object.called) mocked().get_object.assert_called_once_with(container='foo', @@ -285,60 +295,65 @@ class OpenStackActionTest(base.BaseTestCase): @mock.patch.object(actions.ZaqarAction, '_get_client') def test_zaqar_action(self, mocked): + mock_ctx = mock.Mock() method_name = "queue_messages" action_class = actions.ZaqarAction action_class.client_method_name = method_name params = {'queue_name': 'foo'} action = action_class(**params) - action.run() + action.run(mock_ctx) mocked().queue.assert_called_once_with('foo') mocked().queue().messages.assert_called_once_with() @mock.patch.object(actions.BarbicanAction, '_get_client') def test_barbican_action(self, mocked): + mock_ctx = mock.Mock() method_name = "orders_list" action_class = actions.BarbicanAction action_class.client_method_name = method_name params = {'limit': 5} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().orders_list.called) mocked().orders_list.assert_called_once_with(limit=5) @mock.patch.object(actions.DesignateAction, '_get_client') def test_designate_action(self, mocked): + mock_ctx = mock.Mock() method_name = "domain.get" action_class = actions.DesignateAction action_class.client_method_name = method_name params = {'domain': 'example.com'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().domain.get.called) mocked().domain.get.assert_called_once_with(domain="example.com") @mock.patch.object(actions.MagnumAction, '_get_client') def test_magnum_action(self, mocked): + mock_ctx = mock.Mock() method_name = "baymodels.get" action_class = actions.MagnumAction action_class.client_method_name = method_name params = {'id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().baymodels.get.called) mocked().baymodels.get.assert_called_once_with(id="1234-abcd") @mock.patch.object(actions.MuranoAction, '_get_client') def test_murano_action(self, mocked): + mock_ctx = mock.Mock() method_name = "categories.get" action_class = actions.MuranoAction action_class.client_method_name = method_name params = {'category_id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().categories.get.called) mocked().categories.get.assert_called_once_with( @@ -347,12 +362,13 @@ class OpenStackActionTest(base.BaseTestCase): @mock.patch.object(actions.TackerAction, '_get_client') def test_tacker_action(self, mocked): + mock_ctx = mock.Mock() method_name = "show_vim" action_class = actions.TackerAction action_class.client_method_name = method_name params = {'vim_id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().show_vim.called) mocked().show_vim.assert_called_once_with( @@ -361,11 +377,12 @@ class OpenStackActionTest(base.BaseTestCase): @mock.patch.object(actions.SenlinAction, '_get_client') def test_senlin_action(self, mocked): + mock_ctx = mock.Mock() action_class = actions.SenlinAction action_class.client_method_name = "get_cluster" action = action_class(cluster_id='1234-abcd') - action.run() + action.run(mock_ctx) self.assertTrue(mocked().get_cluster.called) @@ -375,24 +392,26 @@ class OpenStackActionTest(base.BaseTestCase): @mock.patch.object(actions.AodhAction, '_get_client') def test_aodh_action(self, mocked): + mock_ctx = mock.Mock() method_name = "alarm.get" action_class = actions.AodhAction action_class.client_method_name = method_name params = {'alarm_id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().alarm.get.called) mocked().alarm.get.assert_called_once_with(alarm_id="1234-abcd") @mock.patch.object(actions.GnocchiAction, '_get_client') def test_gnocchi_action(self, mocked): + mock_ctx = mock.Mock() method_name = "metric.get" action_class = actions.GnocchiAction action_class.client_method_name = method_name params = {'metric_id': '1234-abcd'} action = action_class(**params) - action.run() + action.run(mock_ctx) self.assertTrue(mocked().metric.get.called) mocked().metric.get.assert_called_once_with(metric_id="1234-abcd") diff --git a/mistral/tests/unit/actions/test_javascript_action.py b/mistral/tests/unit/actions/test_javascript_action.py index bf8153517..c1e794998 100644 --- a/mistral/tests/unit/actions/test_javascript_action.py +++ b/mistral/tests/unit/actions/test_javascript_action.py @@ -24,7 +24,8 @@ class JavascriptActionTest(base.BaseTest): javascript, 'evaluate', mock.Mock(return_value="3") ) def test_js_action(self): + mock_ctx = mock.Mock() script = "return 1 + 2" action = std.JavaScriptAction(script) - self.assertEqual("3", action.run()) + self.assertEqual("3", action.run(mock_ctx)) diff --git a/mistral/tests/unit/actions/test_std_echo_action.py b/mistral/tests/unit/actions/test_std_echo_action.py index 3a9a4bb41..5ae2d4b1e 100644 --- a/mistral/tests/unit/actions/test_std_echo_action.py +++ b/mistral/tests/unit/actions/test_std_echo_action.py @@ -14,11 +14,13 @@ from mistral.actions import std_actions as std from mistral.tests.unit import base +import mock class EchoActionTest(base.BaseTest): def test_fake_action(self): expected = "my output" + mock_ctx = mock.Mock() action = std.EchoAction(expected) - self.assertEqual(expected, action.run()) + self.assertEqual(expected, action.run(mock_ctx)) diff --git a/mistral/tests/unit/actions/test_std_email_action.py b/mistral/tests/unit/actions/test_std_email_action.py index d7547ebb8..6eee21a95 100644 --- a/mistral/tests/unit/actions/test_std_email_action.py +++ b/mistral/tests/unit/actions/test_std_email_action.py @@ -61,6 +61,7 @@ class SendEmailActionTest(base.BaseTest): self.from_addr = "bot@example.com" self.to_addrs_str = ", ".join(self.to_addrs) + self.ctx = mock.Mock() @testtools.skipIf(not LOCAL_SMTPD, "Setup local smtpd to run it") def test_send_email_real(self): @@ -68,7 +69,7 @@ class SendEmailActionTest(base.BaseTest): self.from_addr, self.to_addrs, self.smtp_server, None, self.subject, self.body ) - action.run() + action.run(self.ctx) @testtools.skipIf(not REMOTE_SMTP, "Configure Remote SMTP to run it") def test_with_password_real(self): @@ -82,7 +83,7 @@ class SendEmailActionTest(base.BaseTest): self.smtp_server, self.smtp_password, self.subject, self.body ) - action.run() + action.run(self.ctx) @mock.patch('smtplib.SMTP') def test_with_mutli_to_addrs(self, smtp): @@ -91,7 +92,7 @@ class SendEmailActionTest(base.BaseTest): self.from_addr, self.to_addrs, self.smtp_server, smtp_password, self.subject, self.body ) - action.run() + action.run(self.ctx) @mock.patch('smtplib.SMTP') def test_with_one_to_addr(self, smtp): @@ -102,7 +103,7 @@ class SendEmailActionTest(base.BaseTest): self.from_addr, to_addr, self.smtp_server, smtp_password, self.subject, self.body ) - action.run() + action.run(self.ctx) @mock.patch('smtplib.SMTP') def test_send_email(self, smtp): @@ -111,7 +112,7 @@ class SendEmailActionTest(base.BaseTest): self.smtp_server, None, self.subject, self.body ) - action.run() + action.run(self.ctx) smtp.assert_called_once_with(self.smtp_server) @@ -157,7 +158,7 @@ class SendEmailActionTest(base.BaseTest): self.smtp_server, self.smtp_password, self.subject, self.body ) - action.run() + action.run(self.ctx) smtpmock = smtp.return_value calls = [mock.call.ehlo(), mock.call.starttls(), mock.call.ehlo(), @@ -177,7 +178,7 @@ class SendEmailActionTest(base.BaseTest): ) try: - action.run() + action.run(self.ctx) except exc.ActionException: pass else: diff --git a/mistral/tests/unit/actions/test_std_fail_action.py b/mistral/tests/unit/actions/test_std_fail_action.py index cebb9e752..47f8689d0 100644 --- a/mistral/tests/unit/actions/test_std_fail_action.py +++ b/mistral/tests/unit/actions/test_std_fail_action.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import mock from mistral.actions import std_actions as std from mistral import exceptions as exc @@ -21,4 +22,4 @@ class FailActionTest(base.BaseTest): def test_fail_action(self): action = std.FailAction() - self.assertRaises(exc.ActionException, action.run) + self.assertRaises(exc.ActionException, action.run, mock.Mock) diff --git a/mistral/tests/unit/actions/test_std_http_action.py b/mistral/tests/unit/actions/test_std_http_action.py index 695569e12..4bb159529 100644 --- a/mistral/tests/unit/actions/test_std_http_action.py +++ b/mistral/tests/unit/actions/test_std_http_action.py @@ -53,6 +53,7 @@ class HTTPActionTest(base.BaseTest): @mock.patch.object(requests, 'request') def test_http_action(self, mocked_method): mocked_method.return_value = get_success_fake_response() + mock_ctx = mock.Mock() action = std.HTTPAction( url=URL, @@ -67,7 +68,7 @@ class HTTPActionTest(base.BaseTest): self.assertEqual(DATA_STR, action.body) self.assertEqual(URL, action.url) - result = action.run() + result = action.run(mock_ctx) self.assertIsInstance(result, dict) self.assertEqual(DATA, result['content']) @@ -91,6 +92,7 @@ class HTTPActionTest(base.BaseTest): @mock.patch.object(requests, 'request') def test_http_action_error_result(self, mocked_method): mocked_method.return_value = get_error_fake_response() + mock_ctx = mock.Mock() action = std.HTTPAction( url=URL, @@ -105,7 +107,7 @@ class HTTPActionTest(base.BaseTest): self.assertEqual(DATA_STR, action.body) self.assertEqual(URL, action.url) - result = action.run() + result = action.run(mock_ctx) self.assertIsInstance(result, wf_utils.Result) self.assertEqual(401, result.error['status']) @@ -127,6 +129,7 @@ class HTTPActionTest(base.BaseTest): @mock.patch.object(requests, 'request') def test_http_action_with_auth(self, mocked_method): mocked_method.return_value = get_success_fake_response() + mock_ctx = mock.Mock() action = std.HTTPAction( url=URL, @@ -140,7 +143,7 @@ class HTTPActionTest(base.BaseTest): self.assertEqual(data_str, action.body) self.assertEqual(URL, action.url) - result = action.run() + result = action.run(mock_ctx) self.assertIsInstance(result, dict) self.assertEqual(DATA, result['content']) @@ -164,6 +167,7 @@ class HTTPActionTest(base.BaseTest): @mock.patch.object(requests, 'request') def test_http_action_with_headers(self, mocked_method): mocked_method.return_value = get_success_fake_response() + mock_ctx = mock.Mock() headers = {'int_header': 33, 'bool_header': True, 'float_header': 3.0, 'regular_header': 'teststring'} @@ -183,7 +187,7 @@ class HTTPActionTest(base.BaseTest): self.assertEqual(data_str, action.body) self.assertEqual(URL, action.url) - result = action.run() + result = action.run(mock_ctx) self.assertIsInstance(result, dict) self.assertEqual(DATA, result['content'])