]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Load resources dynamically
authorZane Bitter <zbitter@redhat.com>
Tue, 27 Nov 2012 15:15:56 +0000 (16:15 +0100)
committerZane Bitter <zbitter@redhat.com>
Wed, 28 Nov 2012 15:50:50 +0000 (16:50 +0100)
Automatically load all resources as "plugins" when importing the package
heat.engine.resources, instead of having to list them explicitly.

Change-Id: I9d11ab9a5b1dd21bc5f9c2f0aad95c035a9c9aa0
Signed-off-by: Zane Bitter <zbitter@redhat.com>
heat/engine/resource.py
heat/engine/resources/__init__.py
heat/engine/resources/register.py [deleted file]
heat/engine/service.py

index 8d0cff129cdad6088bb5a8e5159eff557a10726a..6e07f02083f320bf7e09b5a870548efdc2aa2330 100644 (file)
@@ -28,6 +28,22 @@ from heat.openstack.common import log as logging
 logger = logging.getLogger(__name__)
 
 
+_resource_classes = {}
+
+
+def get_class(resource_type):
+    return _resource_classes.get(resource_type)
+
+
+def _register_class(resource_type, resource_class):
+    logger.info(_('Registering resource type %s') % resource_type)
+    if resource_type in _resource_classes:
+        logger.warning(_('Replacing existing resource type %s') %
+                resource_type)
+
+    _resource_classes[resource_type] = resource_class
+
+
 class Metadata(object):
     '''
     A descriptor for accessing the metadata of a resource while ensuring the
@@ -86,8 +102,7 @@ class Resource(object):
             return super(Resource, cls).__new__(cls)
 
         # Select the correct subclass to instantiate
-        from heat.engine.resources import register
-        ResourceClass = register.get_class(json['Type']) or GenericResource
+        ResourceClass = get_class(json['Type']) or GenericResource
         return ResourceClass(name, json, stack)
 
     def __init__(self, name, json_snippet, stack):
index e8e403594152912bed8c5a341795ba08bf925d34..087ac64e2a6ac4114db7f81d8df13f27bf6eaef8 100644 (file)
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
+
+
+def _register_resources(type_pairs):
+    from heat.engine import resource
+
+    for res_name, res_class in type_pairs:
+        resource._register_class(res_name, res_class)
+
+
+def _get_module_resources(module):
+    if callable(getattr(module, 'resource_mapping', None)):
+        try:
+            return module.resource_mapping().iteritems()
+        except Exception as ex:
+            logger.error(_('Failed to load resources from %s') % str(module))
+    else:
+        return []
+
+
+def _register_modules(modules):
+    import itertools
+
+    resource_lists = (_get_module_resources(m) for m in modules)
+    _register_resources(itertools.chain.from_iterable(resource_lists))
+
+
+def _initialise():
+    import sys
+    from heat.common import plugin_loader
+
+    _register_modules(plugin_loader.load_modules(sys.modules[__name__]))
+
+
+_initialise()
diff --git a/heat/engine/resources/register.py b/heat/engine/resources/register.py
deleted file mode 100644 (file)
index a61d657..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-Register of resource types and their mapping to Resource classes.
-"""
-
-from heat.engine.resources import autoscaling
-from heat.engine.resources import cloud_watch
-from heat.engine.resources import dbinstance
-from heat.engine.resources import eip
-from heat.engine.resources import instance
-from heat.engine.resources import loadbalancer
-from heat.engine.resources import s3
-from heat.engine.resources import security_group
-from heat.engine.resources import stack
-from heat.engine.resources import user
-from heat.engine.resources import volume
-from heat.engine.resources import wait_condition
-from heat.engine.resources.quantum import floatingip
-from heat.engine.resources.quantum import net
-from heat.engine.resources.quantum import port
-from heat.engine.resources.quantum import router
-from heat.engine.resources.quantum import subnet
-
-from heat.openstack.common import log as logging
-
-logger = logging.getLogger('heat.engine.resources.register')
-
-
-_modules = [
-    autoscaling, cloud_watch, dbinstance, eip, instance, loadbalancer, s3,
-    security_group, stack, user, volume, wait_condition, floatingip, net, port,
-    router, subnet,
-]
-
-_resource_classes = {}
-
-
-def get_class(resource_type):
-    return _resource_classes.get(resource_type)
-
-
-def _register_class(resource_type, resource_class):
-    logger.info(_('Registering resource type %s') % resource_type)
-    if resource_type in _resource_classes:
-        logger.warning(_('Replacing existing resource type %s') %
-                resource_type)
-
-    _resource_classes[resource_type] = resource_class
-
-
-for m in _modules:
-    for res_type, res_class in m.resource_mapping().items():
-        _register_class(res_type, res_class)
index 8c844af97d0fbcf7ed9ddd377b1a12d9545b3707..d4256b7553975de685676c255220bd512d834667 100644 (file)
@@ -22,6 +22,7 @@ from heat.engine import api
 from heat.engine.event import Event
 from heat.engine import identifier
 from heat.engine import parser
+from heat.engine import resources
 from heat.engine import watchrule
 
 from heat.openstack.common import cfg