Add validate_with_client in BaseCustomConstraint

Since we replace not found error with EntityNotFound instead,
we can now consider use a common function for validate_with_client in most
of constraints. For some constraints that have a more complex validation will
overwrite the function(This is what we already used).

Change-Id: I1c554ba7848279cd60db1661fe7ebbd5b72235d8
This commit is contained in:
ricolin 2015-11-27 12:31:45 +08:00
parent b6ca223944
commit c265494a98
12 changed files with 99 additions and 108 deletions

View File

@ -26,6 +26,8 @@ from heat.engine import constraints
LOG = logging.getLogger(__name__)
SERVICE_NAME = 'cinder'
class CinderClientPlugin(client_plugin.ClientPlugin):
@ -179,33 +181,26 @@ class CinderClientPlugin(client_plugin.ClientPlugin):
return True
class VolumeConstraint(constraints.BaseCustomConstraint):
class BaseCinderConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, volume):
client.client_plugin('cinder').get_volume(volume)
resource_client_name = SERVICE_NAME
class VolumeSnapshotConstraint(constraints.BaseCustomConstraint):
class VolumeConstraint(BaseCinderConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, snapshot):
client.client_plugin('cinder').get_volume_snapshot(snapshot)
resource_getter_name = 'get_volume'
class VolumeTypeConstraint(constraints.BaseCustomConstraint):
class VolumeSnapshotConstraint(BaseCinderConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, volume_type):
client.client_plugin('cinder').get_volume_type(volume_type)
resource_getter_name = 'get_volume_snapshot'
class VolumeBackupConstraint(constraints.BaseCustomConstraint):
class VolumeTypeConstraint(BaseCinderConstraint):
expected_exceptions = (exception.EntityNotFound,)
resource_getter_name = 'get_volume_type'
def validate_with_client(self, client, backup):
client.client_plugin('cinder').get_volume_backup(backup)
class VolumeBackupConstraint(BaseCinderConstraint):
resource_getter_name = 'get_volume_backup'

View File

@ -20,6 +20,8 @@ from heat.common import exception as heat_exception
from heat.engine.clients import client_plugin
from heat.engine import constraints
SERVICE_NAME = 'designate'
class DesignateClientPlugin(client_plugin.ClientPlugin):
@ -88,7 +90,5 @@ class DesignateClientPlugin(client_plugin.ClientPlugin):
class DesignateDomainConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (heat_exception.EntityNotFound,)
def validate_with_client(self, client, domain):
client.client_plugin('designate').get_domain_id(domain)
resource_client_name = SERVICE_NAME
resource_getter_name = 'get_domain_id'

View File

@ -20,6 +20,8 @@ from heat.common.i18n import _
from heat.engine.clients import client_plugin
from heat.engine import constraints
SERVICE_NAME = 'glance'
class GlanceClientPlugin(client_plugin.ClientPlugin):
@ -99,8 +101,5 @@ class GlanceClientPlugin(client_plugin.ClientPlugin):
class ImageConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, value):
client.client_plugin('glance').get_image_id(value)
resource_client_name = SERVICE_NAME
resource_getter_name = 'get_image_id'

View File

@ -18,6 +18,8 @@ from heat.common import heat_keystoneclient as hkc
from heat.engine.clients import client_plugin
from heat.engine import constraints
SERVICE_NAME = 'keystone'
class KeystoneClientPlugin(client_plugin.ClientPlugin):
@ -132,58 +134,43 @@ class KeystoneClientPlugin(client_plugin.ClientPlugin):
name=region)
class KeystoneRoleConstraint(constraints.BaseCustomConstraint):
class KeystoneBaseConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, role):
client.client_plugin('keystone').get_role_id(role)
resource_client_name = SERVICE_NAME
class KeystoneDomainConstraint(constraints.BaseCustomConstraint):
class KeystoneRoleConstraint(KeystoneBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, domain):
client.client_plugin('keystone').get_domain_id(domain)
resource_getter_name = 'get_role_id'
class KeystoneProjectConstraint(constraints.BaseCustomConstraint):
class KeystoneDomainConstraint(KeystoneBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, project):
client.client_plugin('keystone').get_project_id(project)
resource_getter_name = 'get_domain_id'
class KeystoneGroupConstraint(constraints.BaseCustomConstraint):
class KeystoneProjectConstraint(KeystoneBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, group):
client.client_plugin('keystone').get_group_id(group)
resource_getter_name = 'get_project_id'
class KeystoneServiceConstraint(constraints.BaseCustomConstraint):
class KeystoneGroupConstraint(KeystoneBaseConstraint):
resource_getter_name = 'get_group_id'
class KeystoneServiceConstraint(KeystoneBaseConstraint):
expected_exceptions = (exception.EntityNotFound,
exception.KeystoneServiceNameConflict,)
def validate_with_client(self, client, service):
client.client_plugin('keystone').get_service_id(service)
resource_getter_name = 'get_service_id'
class KeystoneUserConstraint(constraints.BaseCustomConstraint):
class KeystoneUserConstraint(KeystoneBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, user):
client.client_plugin('keystone').get_user_id(user)
resource_getter_name = 'get_user_id'
class KeystoneRegionConstraint(constraints.BaseCustomConstraint):
class KeystoneRegionConstraint(KeystoneBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, region):
client.client_plugin('keystone').get_region_id(region)
resource_getter_name = 'get_region_id'

View File

@ -18,6 +18,8 @@ from heat.common import exception
from heat.engine.clients import client_plugin
from heat.engine import constraints
SERVICE_NAME = 'magnum'
class MagnumClientPlugin(client_plugin.ClientPlugin):
@ -54,7 +56,5 @@ class MagnumClientPlugin(client_plugin.ClientPlugin):
class BaymodelConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, value):
client.client_plugin('magnum').get_baymodel(value)
resource_client_name = SERVICE_NAME
resource_getter_name = 'get_baymodel'

View File

@ -17,6 +17,7 @@ from manilaclient import client as manila_client
from manilaclient import exceptions
MANILACLIENT_VERSION = "1"
SERVICE_NAME = 'manila'
class ManilaClientPlugin(client_plugin.ClientPlugin):
@ -115,22 +116,23 @@ class ManilaClientPlugin(client_plugin.ClientPlugin):
class ManilaShareBaseConstraint(constraints.BaseCustomConstraint):
# check that exceptions module has been loaded. Without this check
# doc tests on gates will fail
expected_exceptions = (exceptions.NotFound, exceptions.NoUniqueMatch)
def validate_with_client(self, client, resource_id):
getattr(client.client_plugin("manila"), self.resource_getter_name)(
resource_id)
resource_client_name = SERVICE_NAME
class ManilaShareNetworkConstraint(ManilaShareBaseConstraint):
resource_getter_name = 'get_share_network'
class ManilaShareTypeConstraint(ManilaShareBaseConstraint):
resource_getter_name = 'get_share_type'
class ManilaShareSnapshotConstraint(ManilaShareBaseConstraint):
resource_getter_name = 'get_share_snapshot'

View File

@ -68,7 +68,5 @@ class MonascaClientPlugin(client_plugin.ClientPlugin):
class MonascaNotificationConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (heat_exc.EntityNotFound)
def validate_with_client(self, client, notification):
client.client_plugin(SERVICE_NAME).get_notification(notification)
resource_client_name = SERVICE_NAME
resource_getter_name = 'get_notification'

View File

@ -40,6 +40,7 @@ LOG = logging.getLogger(__name__)
NOVACLIENT_VERSION = "2"
SERVICE_NAME = 'nova'
class NovaClientPlugin(client_plugin.ClientPlugin):
@ -680,46 +681,41 @@ echo -e '%s\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
return alias in self._list_extensions()
class ServerConstraint(constraints.BaseCustomConstraint):
class NovaBaseConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, server):
client.client_plugin('nova').get_server(server)
resource_client_name = SERVICE_NAME
class KeypairConstraint(constraints.BaseCustomConstraint):
class ServerConstraint(NovaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
resource_getter_name = 'get_server'
class KeypairConstraint(NovaBaseConstraint):
resource_getter_name = 'get_keypair'
def validate_with_client(self, client, key_name):
if not key_name:
# Don't validate empty key, which can happen when you
# use a KeyPair resource
return True
client.client_plugin('nova').get_keypair(key_name)
super(KeypairConstraint, self).validate_with_client(client, key_name)
class FlavorConstraint(constraints.BaseCustomConstraint):
class FlavorConstraint(NovaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, flavor):
client.client_plugin('nova').get_flavor_id(flavor)
resource_getter_name = 'get_flavor_id'
class NetworkConstraint(constraints.BaseCustomConstraint):
class NetworkConstraint(NovaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,
exception.PhysicalResourceNameAmbiguity)
def validate_with_client(self, client, network):
client.client_plugin('nova').get_nova_network_id(network)
resource_getter_name = 'get_nova_network_id'
class HostConstraint(constraints.BaseCustomConstraint):
class HostConstraint(NovaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, host_name):
client.client_plugin('nova').get_host(host_name)
resource_getter_name = 'get_host'

View File

@ -23,6 +23,8 @@ from heat.common.i18n import _
from heat.engine.clients import client_plugin
from heat.engine import constraints
SERVICE_NAME = 'sahara'
class SaharaClientPlugin(client_plugin.ClientPlugin):
@ -132,18 +134,17 @@ class SaharaClientPlugin(client_plugin.ClientPlugin):
name=plugin_name)
class ImageConstraint(constraints.BaseCustomConstraint):
class SaharaBaseConstraint(constraints.BaseCustomConstraint):
resource_client_name = SERVICE_NAME
class ImageConstraint(SaharaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,
exception.PhysicalResourceNameAmbiguity,)
def validate_with_client(self, client, value):
client.client_plugin('sahara').get_image_id(value)
resource_getter_name = 'get_image_id'
class PluginConstraint(constraints.BaseCustomConstraint):
class PluginConstraint(SaharaBaseConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, value):
client.client_plugin('sahara').get_plugin_id(value)
resource_getter_name = 'get_plugin_id'

View File

@ -19,6 +19,8 @@ from heat.common.i18n import _
from heat.engine.clients import client_plugin
from heat.engine import constraints
SERVICE_NAME = 'trove'
class TroveClientPlugin(client_plugin.ClientPlugin):
@ -117,5 +119,5 @@ class FlavorConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, flavor):
client.client_plugin('trove').get_flavor_id(flavor)
resource_client_name = SERVICE_NAME
resource_getter_name = 'get_flavor_id'

View File

@ -571,7 +571,9 @@ class BaseCustomConstraint(object):
Subclass must provide `expected_exceptions` and implement
`validate_with_client`.
"""
expected_exceptions = ()
expected_exceptions = (exception.EntityNotFound,)
resource_client_name = None
resource_getter_name = None
_error_message = None
@ -619,3 +621,12 @@ class BaseCustomConstraint(object):
check_cache_or_validate_value.invalidate(cache_value_prefix,
value)
return validation_result
def validate_with_client(self, client, resource_id):
if self.resource_client_name and self.resource_getter_name:
getattr(client.client_plugin(self.resource_client_name),
self.resource_getter_name)(resource_id)
else:
raise exception.InvalidSchemaError(
message=_('Client name and resource getter name must be '
'specified.'))

View File

@ -22,7 +22,7 @@ from heat.tests import common
class MonascaNotificationConstraintTest(common.HeatTestCase):
def test_expected_exceptions(self):
self.assertEqual(
(heat_exception.EntityNotFound),
(heat_exception.EntityNotFound,),
client_plugin.MonascaNotificationConstraint.expected_exceptions,
"MonascaNotificationConstraint expected exceptions error")