Allow plugins to be specified as a cloud_backend

Currently, the cloud_backend configuration option can only use modules
imported in-tree before clients.py is imported. This does not work for
plugins because they are dynamically imported in
heat/engine/resources/__init__.py after clients.py is imported. Change
the cloud_backend module to be specified when the client class needs
to be initialized rather than when clients.py is imported. This change
requires a class to be specified for the cloud_backend rather than a
module name.

Change-Id: I8f2b93bfb6a9585d1e7dc52d70092105b6e1bfaa
Closes-Bug: 1242870
This commit is contained in:
Andrew Plunk 2013-10-21 16:12:54 -07:00
parent 4382fbe868
commit 8ce5e0f88e
3 changed files with 42 additions and 11 deletions

View File

@ -107,9 +107,9 @@
# Options defined in heat.engine.clients
#
# Cloud module to use as a backend. Defaults to OpenStack.
# Fully qualified class name to use as a client backend.
# (string value)
#cloud_backend=<None>
#cloud_backend=heat.engine.clients.OpenStackClients
#

View File

@ -46,11 +46,12 @@ except ImportError:
ceilometerclient = None
logger.info('ceilometerclient not available')
_default_backend = "heat.engine.clients.OpenStackClients"
cloud_opts = [
cfg.StrOpt('cloud_backend',
default=None,
help="Cloud module to use as a backend. Defaults to OpenStack.")
default=_default_backend,
help="Fully qualified class name to use as a client backend.")
]
cfg.CONF.register_opts(cloud_opts)
@ -59,7 +60,6 @@ class OpenStackClients(object):
'''
Convenience class to create and cache client instances.
'''
def __init__(self, context):
self.context = context
self._nova = {}
@ -210,10 +210,18 @@ class OpenStackClients(object):
return self._ceilometer
if cfg.CONF.cloud_backend:
cloud_backend_module = importutils.import_module(cfg.CONF.cloud_backend)
Clients = cloud_backend_module.Clients
else:
Clients = OpenStackClients
class ClientBackend(object):
'''Delay choosing the backend client module until the client's class needs
to be initialized.
'''
def __new__(cls, context):
if cfg.CONF.cloud_backend == _default_backend:
return OpenStackClients(context)
else:
return importutils.import_object(
cfg.CONF.cloud_backend,
context
)
logger.debug('Using backend %s' % Clients)
Clients = ClientBackend

View File

@ -0,0 +1,23 @@
# 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.
from heat.engine import clients
from heat.tests.common import HeatTestCase
class ClientsTest(HeatTestCase):
def test_clients_chosen_at_module_initilization(self):
self.assertFalse(hasattr(clients.Clients, 'nova'))
self.assertTrue(hasattr(clients.Clients('fakecontext'), 'nova'))