Adding mistral_lib actions to mistral

This deprecates the mistral.actions.base:Action in favor of
mistral_lib.actions:Action

Change-Id: I3dedb6474922c341088a12696f3f5c418594847b
This commit is contained in:
Adriano Petrich 2017-05-12 13:34:13 +01:00
parent 1f9db4cd52
commit a4fa5ba0f9
10 changed files with 253 additions and 233 deletions

View File

@ -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):

View File

@ -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

View File

@ -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))
)

View File

@ -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 {}

View File

@ -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")

View File

@ -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))

View File

@ -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))

View File

@ -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:

View File

@ -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)

View File

@ -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'])