Add sahara.plugin custom constraint

Change-Id: I042cfd88b07e393c1d6d2e8622a9135cdd485ee5
This commit is contained in:
Tetiana Lashchova 2015-09-04 15:53:18 +03:00
parent 66725065b6
commit 87e8b11d0b
7 changed files with 82 additions and 3 deletions

View File

@ -118,6 +118,20 @@ class SaharaClientPlugin(client_plugin.ClientPlugin):
else:
return image_list[0].id
def get_plugin_id(self, plugin_name):
"""Get the id for the specified plugin name.
:param plugin_name: the name of the plugin to find
:returns: the id of :plugin:
:raises: exception.EntityNotFound
"""
try:
self.client().plugins.get(plugin_name)
except sahara_base.APIException:
LOG.info(_LI("Plugin %s was not found in sahara"), plugin_name)
raise exception.EntityNotFound(entity='Plugin',
name=plugin_name)
class ImageConstraint(constraints.BaseCustomConstraint):
@ -126,3 +140,11 @@ class ImageConstraint(constraints.BaseCustomConstraint):
def validate_with_client(self, client, value):
client.client_plugin('sahara').get_image_id(value)
class PluginConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, value):
client.client_plugin('sahara').get_plugin_id(value)

View File

@ -57,6 +57,9 @@ class SaharaCluster(resource.Resource):
properties.Schema.STRING,
_('Plugin name.'),
required=True,
constraints=[
constraints.CustomConstraint('sahara.plugin')
]
),
HADOOP_VERSION: properties.Schema(
properties.Schema.STRING,

View File

@ -72,6 +72,9 @@ class SaharaNodeGroupTemplate(resource.Resource):
properties.Schema.STRING,
_('Plugin name.'),
required=True,
constraints=[
constraints.CustomConstraint('sahara.plugin')
]
),
HADOOP_VERSION: properties.Schema(
properties.Schema.STRING,
@ -301,6 +304,9 @@ class SaharaClusterTemplate(resource.Resource):
properties.Schema.STRING,
_('Plugin name.'),
required=True,
constraints=[
constraints.CustomConstraint('sahara.plugin')
]
),
HADOOP_VERSION: properties.Schema(
properties.Schema.STRING,

View File

@ -37,6 +37,7 @@ class SaharaUtilsTests(common.HeatTestCase):
self.sahara_plugin = c.client_plugin('sahara')
self.sahara_plugin._client = self.sahara_client
self.my_image = mock.MagicMock()
self.my_plugin = mock.MagicMock()
def test_get_image_id(self):
"""Tests the get_image_id function."""
@ -114,6 +115,26 @@ class SaharaUtilsTests(common.HeatTestCase):
self.sahara_plugin.get_image_id, img_name)
self.sahara_client.images.find.assert_called_once_with(name=img_name)
def test_get_plugin_id(self):
"""Tests the get_plugin_id function."""
plugin_name = 'myfakeplugin'
self.my_plugin.name = plugin_name
def side_effect(name):
if name == plugin_name:
return self.my_plugin
else:
raise sahara_base.APIException(error_code=404,
error_name='NOT_FOUND')
self.sahara_client.plugins.get.side_effect = side_effect
self.assertEqual(None, self.sahara_plugin.get_plugin_id(plugin_name))
self.assertRaises(exception.EntityNotFound,
self.sahara_plugin.get_plugin_id, 'noplugin')
calls = [mock.call(plugin_name), mock.call('noplugin')]
self.sahara_client.plugins.get.assert_has_calls(calls)
class ImageConstraintTest(common.HeatTestCase):
@ -133,3 +154,23 @@ class ImageConstraintTest(common.HeatTestCase):
self.mock_get_image.side_effect = exception.EntityNotFound(
entity='Image', name='bar')
self.assertFalse(self.constraint.validate("bar", self.ctx))
class PluginConstraintTest(common.HeatTestCase):
def setUp(self):
super(PluginConstraintTest, self).setUp()
self.ctx = utils.dummy_context()
self.mock_get_plugin = mock.Mock()
self.ctx.clients.client_plugin(
'sahara').get_plugin_id = self.mock_get_plugin
self.constraint = sahara.PluginConstraint()
def test_validation(self):
self.mock_get_plugin.return_value = "id1"
self.assertTrue(self.constraint.validate("foo", self.ctx))
def test_validation_error(self):
self.mock_get_plugin.side_effect = exception.EntityNotFound(
entity='Plugin', name='bar')
self.assertFalse(self.constraint.validate("bar", self.ctx))

View File

@ -31,6 +31,7 @@ from heat.engine.clients.os import glance
from heat.engine.clients.os import keystone
from heat.engine.clients.os import neutron
from heat.engine.clients.os import nova
from heat.engine.clients.os import sahara
from heat.engine.clients.os import trove
from heat.engine import environment
from heat.engine import resource
@ -266,3 +267,7 @@ class HeatTestCase(testscenarios.WithScenarios,
validate = self.patchobject(keystone.KeystoneProjectConstraint,
'validate')
validate.return_value = True
def stub_SaharaPluginConstraint(self):
validate = self.patchobject(sahara.PluginConstraint, 'validate')
validate.return_value = True

View File

@ -102,8 +102,9 @@ class FakeClusterTemplate(object):
class SaharaNodeGroupTemplateTest(common.HeatTestCase):
def setUp(self):
super(SaharaNodeGroupTemplateTest, self).setUp()
self.patchobject(st.constraints.CustomConstraint,
'_is_valid').return_value = True
self.stub_FlavorConstraint_validate()
self.stub_SaharaPluginConstraint()
self.stub_VolumeTypeConstraint_validate()
self.patchobject(nova.NovaClientPlugin, 'get_flavor_id'
).return_value = 'someflavorid'
self.patchobject(neutron.NeutronClientPlugin, '_create')
@ -215,7 +216,7 @@ class SaharaNodeGroupTemplateTest(common.HeatTestCase):
self.t['resources']['node-group']['properties'].pop('floating_ip_pool')
self.t['resources']['node-group']['properties'].pop('volume_type')
ngt = self._init_ngt(self.t)
self.patchobject(st.constraints.CustomConstraint, '_is_valid'
self.patchobject(nova.FlavorConstraint, 'validate'
).return_value = False
self.patchobject(ngt, 'is_using_neutron').return_value = False

View File

@ -98,6 +98,7 @@ heat.constraints =
timezone = heat.engine.constraint.common_constraints:TimezoneConstraint
cron_expression = heat.engine.constraint.common_constraints:CRONExpressionConstraint
monasca.notification = heat.engine.clients.os.monasca:MonascaNotificationConstraint
sahara.plugin = heat.engine.clients.os.sahara:PluginConstraint
heat.stack_lifecycle_plugins =