Added constraint for mistral workflow

Change-Id: Ia1663f653370f4f4e4688b8f93db60a7ebbec240
This commit is contained in:
Dmitriy Uvarenkov 2016-03-15 13:52:38 +02:00
parent 1642f5a7c1
commit c4c33c2348
6 changed files with 56 additions and 1 deletions

View File

@ -14,7 +14,9 @@
from mistralclient.api import base as mistral_base
from mistralclient.api import client as mistral_client
from heat.common import exception
from heat.engine.clients import client_plugin
from heat.engine import constraints
CLIENT_NAME = 'mistral'
@ -47,3 +49,20 @@ class MistralClientPlugin(client_plugin.ClientPlugin):
def is_conflict(self, ex):
return (isinstance(ex, mistral_base.APIException) and
ex.error_code == 409)
def get_workflow_by_identifier(self, workflow_identifier):
try:
return self.client().workflows.get(
workflow_identifier)
except Exception as ex:
if self.is_not_found(ex):
raise exception.EntityNotFound(
entity="Workflow",
name=workflow_identifier)
raise ex
class WorkflowConstraint(constraints.BaseCustomConstraint):
resource_client_name = CLIENT_NAME
resource_getter_name = 'get_workflow_by_identifier'
expected_exceptions = (exception.EntityNotFound,)

View File

@ -74,6 +74,9 @@ class CronTrigger(resource.Resource):
properties.Schema.STRING,
_('Name of the workflow.'),
required=True,
constraints=[
constraints.CustomConstraint('mistral.workflow')
]
),
WORKFLOW_INPUT: properties.Schema(
properties.Schema.MAP,

View File

@ -221,7 +221,10 @@ class Workflow(signal_responder.SignalResponder,
'or by name of the referenced workflow, i.e. '
'{ workflow: wf_name } or '
'{ workflow: { get_resource: wf_name }}. Either '
'action or workflow may be defined in the task.')
'action or workflow may be defined in the task.'),
constraints=[
constraints.CustomConstraint('mistral.workflow')
]
),
PUBLISH: properties.Schema(
properties.Schema.MAP,

View File

@ -11,6 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from heat.common import exception
from heat.engine.clients.os import mistral
from heat.tests import common
from heat.tests import utils
@ -24,3 +28,26 @@ class MistralClientPluginTest(common.HeatTestCase):
self.assertIsNotNone(client.workflows)
self.assertEqual('http://server.test:5000/v3',
client.http_client.base_url)
class WorkflowConstraintTest(common.HeatTestCase):
def setUp(self):
super(WorkflowConstraintTest, self).setUp()
self.ctx = utils.dummy_context()
self.mock_get_workflow_by_identifier = mock.Mock()
self.ctx.clients.client_plugin(
'mistral'
).get_workflow_by_identifier = self.mock_get_workflow_by_identifier
self.constraint = mistral.WorkflowConstraint()
def test_validation(self):
self.mock_get_workflow_by_identifier.return_value = {}
self.assertTrue(self.constraint.validate("foo", self.ctx))
self.mock_get_workflow_by_identifier.assert_called_once_with("foo")
def test_validation_error(self):
exc = exception.EntityNotFound(entity='Workflow', name='bar')
self.mock_get_workflow_by_identifier.side_effect = exc
self.assertFalse(self.constraint.validate("bar", self.ctx))
self.mock_get_workflow_by_identifier.assert_called_once_with("bar")

View File

@ -63,6 +63,8 @@ class MistralCronTriggerTest(common.HeatTestCase):
def _create_resource(self, name, snippet, stack):
ct = cron_trigger.CronTrigger(name, snippet, stack)
mock_get_workflow = mock.Mock(return_value='get_first_glance_image')
ct.client_plugin().get_workflow_by_identifier = mock_get_workflow
self.client.cron_triggers.create.return_value = FakeCronTrigger(
'my_cron_trigger')
self.client.cron_triggers.get.return_value = FakeCronTrigger(

View File

@ -105,6 +105,7 @@ heat.constraints =
manila.share_network = heat.engine.clients.os.manila:ManilaShareNetworkConstraint
manila.share_snapshot = heat.engine.clients.os.manila:ManilaShareSnapshotConstraint
manila.share_type = heat.engine.clients.os.manila:ManilaShareTypeConstraint
mistral.workflow = heat.engine.clients.os.mistral:WorkflowConstraint
monasca.notification = heat.engine.clients.os.monasca:MonascaNotificationConstraint
neutron.address_scope = heat.engine.clients.os.neutron.neutron_constraints:AddressScopeConstraint
neutron.lbaas.listener = heat.engine.clients.os.neutron.lbaas_constraints:ListenerConstraint