Support loading constraints as stevedore extensions

This still maintains support for the existing mechanism
but moves the in tree constraints to using stevedore.

part of blueprint stevedore-plugins
Change-Id: I86907e6518281083a508f840269d79dfa3875e9a
This commit is contained in:
Angus Salkeld 2014-06-27 18:18:06 +10:00
parent b160972b08
commit 248224661a
9 changed files with 30 additions and 23 deletions

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from stevedore import extension
from heat.engine import environment
from heat.engine import plugin_manager
@ -25,6 +27,14 @@ def _register_constraints(env, type_pairs):
env.register_constraint(constraint_name, constraint)
def _get_mapping(namespace):
mgr = extension.ExtensionManager(
namespace=namespace,
invoke_on_load=False,
verify_requirements=True)
return [[name, mgr[name].plugin] for name in mgr.names()]
_environment = None
@ -50,8 +60,9 @@ def _load_global_environment(env):
def _load_global_resources(env):
manager = plugin_manager.PluginManager(__name__)
_register_constraints(env, _get_mapping('heat.constraints'))
manager = plugin_manager.PluginManager(__name__)
# Sometimes resources should not be available for registration in Heat due
# to unsatisfied dependencies. We look first for the function
# 'available_resource_mapping', which should return the filtered resources.
@ -61,4 +72,5 @@ def _load_global_resources(env):
constraint_mapping = plugin_manager.PluginMapping('constraint')
_register_resources(env, resource_mapping.load_all(manager))
_register_constraints(env, constraint_mapping.load_all(manager))

View File

@ -23,7 +23,3 @@ class ImageConstraint(constraints.BaseCustomConstraint):
def validate_with_client(self, client, value):
glance_client = client.glance()
glance_utils.get_image_id(glance_client, value)
def constraint_mapping():
return {'glance.image': ImageConstraint}

View File

@ -23,7 +23,3 @@ class ISO8601Constraint(object):
return False
else:
return True
def constraint_mapping():
return {'iso_8601': ISO8601Constraint}

View File

@ -194,12 +194,6 @@ class NetworkConstraint(constraints.BaseCustomConstraint):
neutron_client, 'network', value)
def constraint_mapping():
if clients.neutronclient is None:
return {}
return {'neutron.network': NetworkConstraint}
def resource_mapping():
if clients.neutronclient is None:
return {}

View File

@ -142,9 +142,5 @@ class KeypairConstraint(constraints.BaseCustomConstraint):
nova_utils.get_keypair(nova_client, value)
def constraint_mapping():
return {'nova.keypair': KeypairConstraint}
def resource_mapping():
return {'OS::Nova::KeyPair': KeyPair}

View File

@ -1053,10 +1053,6 @@ class FlavorConstraint(constraints.BaseCustomConstraint):
nova_utils.get_flavor_id(nova_client, value)
def constraint_mapping():
return {'nova.flavor': FlavorConstraint}
def resource_mapping():
return {
'OS::Nova::Server': Server,

View File

@ -153,6 +153,14 @@ def constraint_mapping():
resources._load_global_environment, env)
self.assertEqual("oops", str(error))
def test_constraints_registry_stevedore(self):
env = environment.Environment({})
resources._load_global_environment(env)
self.assertEqual("FlavorConstraint",
env.get_constraint("nova.flavor").__name__)
self.assertIs(None, env.get_constraint("no_constraint"))
class EnvironmentDuplicateTest(common.HeatTestCase):

View File

@ -29,4 +29,5 @@ Routes>=1.12.3
six>=1.6.0
SQLAlchemy>=0.7.8,<=0.9.99
sqlalchemy-migrate>=0.9.1
stevedore>=0.14
WebOb>=1.2.3

View File

@ -37,6 +37,14 @@ oslo.config.opts =
heat.common.config = heat.common.config:list_opts
heat.common.wsgi = heat.common.wsgi:list_opts
heat.constraints =
nova.flavor = heat.engine.resources.server:FlavorConstraint
neutron.network = heat.engine.resources.neutron.net:NetworkConstraint
glance.image = heat.engine.resources.image:ImageConstraint
iso_8601 = heat.engine.resources.iso_8601:ISO8601Constraint
nova.keypair = heat.engine.resources.nova_keypair:KeypairConstraint
[global]
setup-hooks =
pbr.hooks.setup_hook