Add senlin constraints

Add 3 new constraints for senlin:
senlin.cluster
senlin.profile_type
senlin.policy_type

blueprint senlin-resources
Change-Id: Icd7bb3304d81d7711631c93f9fd9610a01ca53fd
This commit is contained in:
Ethan Lynn 2016-02-01 17:23:37 +08:00
parent 02c53735e2
commit f3a0502830
3 changed files with 120 additions and 2 deletions

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from heat.common import exception
from heat.common.i18n import _
from heat.engine.clients import client_plugin
from heat.engine import constraints
@ -41,8 +43,50 @@ class SenlinClientPlugin(client_plugin.ClientPlugin):
class ProfileConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exc.sdkexc.ResourceNotFound,)
# If name is not unique, will raise exc.sdkexc.HttpException
expected_exceptions = (exc.sdkexc.HttpException,)
def validate_with_client(self, client, profile):
client.client(CLIENT_NAME).get_profile(profile)
class ClusterConstraint(constraints.BaseCustomConstraint):
# If name is not unique, will raise exc.sdkexc.HttpException
expected_exceptions = (exc.sdkexc.HttpException,)
def validate_with_client(self, client, value):
client.client(CLIENT_NAME).get_cluster(value)
class ProfileTypeConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.StackValidationFailed,)
def validate_with_client(self, client, value):
senlin_client = client.client(CLIENT_NAME)
type_list = senlin_client.profile_types()
names = [pt['name'] for pt in type_list]
if value not in names:
not_found_message = (
_("Unable to find senlin profile type '%(pt)s', "
"available profile types are %(pts)s.") %
{'pt': value, 'pts': names}
)
raise exception.StackValidationFailed(message=not_found_message)
class PolicyTypeConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.StackValidationFailed,)
def validate_with_client(self, client, value):
senlin_client = client.client(CLIENT_NAME)
type_list = senlin_client.policy_types()
names = [pt['name'] for pt in type_list]
if value not in names:
not_found_message = (
_("Unable to find senlin policy type '%(pt)s', "
"available policy types are %(pts)s.") %
{'pt': value, 'pts': names}
)
raise exception.StackValidationFailed(message=not_found_message)

View File

@ -47,3 +47,74 @@ class ProfileConstraintTest(common.HeatTestCase):
self.mock_get_profile.side_effect = exc.sdkexc.ResourceNotFound(
'PROFILE_ID')
self.assertFalse(self.constraint.validate("PROFILE_ID", self.ctx))
self.mock_get_profile.side_effect = exc.sdkexc.HttpException(
'PROFILE_ID')
self.assertFalse(self.constraint.validate("PROFILE_ID", self.ctx))
class ClusterConstraintTest(common.HeatTestCase):
def setUp(self):
super(ClusterConstraintTest, self).setUp()
self.senlin_client = mock.MagicMock()
self.ctx = utils.dummy_context()
self.mock_get_cluster = mock.Mock()
self.ctx.clients.client(
'senlin').get_cluster = self.mock_get_cluster
self.constraint = senlin_plugin.ClusterConstraint()
def test_validate_true(self):
self.mock_get_cluster.return_value = None
self.assertTrue(self.constraint.validate("CLUSTER_ID", self.ctx))
def test_validate_false(self):
self.mock_get_cluster.side_effect = exc.sdkexc.ResourceNotFound(
'CLUSTER_ID')
self.assertFalse(self.constraint.validate("CLUSTER_ID", self.ctx))
self.mock_get_cluster.side_effect = exc.sdkexc.HttpException(
'CLUSTER_ID')
self.assertFalse(self.constraint.validate("CLUSTER_ID", self.ctx))
class ProfileTypeConstraintTest(common.HeatTestCase):
def setUp(self):
super(ProfileTypeConstraintTest, self).setUp()
self.senlin_client = mock.MagicMock()
self.ctx = utils.dummy_context()
self.mock_profile_types = mock.Mock(
return_value=[{'name': 'os.heat.stack-1.0'},
{'name': 'os.nova.server-1.0'}])
self.ctx.clients.client(
'senlin').profile_types = self.mock_profile_types
self.constraint = senlin_plugin.ProfileTypeConstraint()
def test_validate_true(self):
self.assertTrue(self.constraint.validate("os.heat.stack-1.0",
self.ctx))
def test_validate_false(self):
self.assertFalse(self.constraint.validate("Invalid_type",
self.ctx))
class PolicyTypeConstraintTest(common.HeatTestCase):
def setUp(self):
super(PolicyTypeConstraintTest, self).setUp()
self.senlin_client = mock.MagicMock()
self.ctx = utils.dummy_context()
self.mock_policy_types = mock.Mock(
return_value=[{'name': 'senlin.policy.deletion-1.0'},
{'name': 'senlin.policy.loadbalance-1.0'}])
self.ctx.clients.client(
'senlin').policy_types = self.mock_policy_types
self.constraint = senlin_plugin.PolicyTypeConstraint()
def test_validate_true(self):
self.assertTrue(self.constraint.validate(
"senlin.policy.deletion-1.0", self.ctx))
def test_validate_false(self):
self.assertFalse(self.constraint.validate("Invalid_type",
self.ctx))

View File

@ -119,7 +119,10 @@ heat.constraints =
cron_expression = heat.engine.constraint.common_constraints:CRONExpressionConstraint
monasca.notification = heat.engine.clients.os.monasca:MonascaNotificationConstraint
sahara.plugin = heat.engine.clients.os.sahara:PluginConstraint
senlin.cluster = heat.engine.clients.os.senlin:ClusterConstraint
senlin.policy_type = heat.engine.clients.os.senlin:PolicyTypeConstraint
senlin.profile = heat.engine.clients.os.senlin:ProfileConstraint
senlin.profile_type = heat.engine.clients.os.senlin:ProfileTypeConstraint
heat.stack_lifecycle_plugins =