Implement glance client plugin

This moves the client creation code out of Clients._glance() into
its own client plugin.

Glance is a core project, and python-glanceclient is a dependency,
so the import is now mandatory.

Change-Id: If61f2510344bf67b7e9aded1dc9d9cedf2426228
This commit is contained in:
Steve Baker 2014-06-04 14:24:30 +12:00
parent 76979a4fd1
commit 9e58745627
17 changed files with 89 additions and 69 deletions

View File

@ -16,7 +16,7 @@ import mox
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
@ -69,8 +69,8 @@ class CloudServersTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\

View File

@ -13,7 +13,6 @@
from ceilometerclient import client as ceilometerclient from ceilometerclient import client as ceilometerclient
from cinderclient import client as cinderclient from cinderclient import client as cinderclient
from glanceclient import client as glanceclient
from heatclient import client as heatclient from heatclient import client as heatclient
from neutronclient.v2_0 import client as neutronclient from neutronclient.v2_0 import client as neutronclient
from oslo.config import cfg from oslo.config import cfg
@ -108,26 +107,6 @@ class OpenStackClients(object):
'Replace with calls to client("glance")') 'Replace with calls to client("glance")')
return self.client('glance') return self.client('glance')
def _glance(self):
con = self.context
endpoint_type = self._get_client_option('glance', 'endpoint_type')
endpoint = self.url_for(service_type='image',
endpoint_type=endpoint_type)
args = {
'auth_url': con.auth_url,
'service_type': 'image',
'project_id': con.tenant,
'token': self.auth_token,
'endpoint_type': endpoint_type,
'ca_file': self._get_client_option('glance', 'ca_file'),
'cert_file': self._get_client_option('glance', 'cert_file'),
'key_file': self._get_client_option('glance', 'key_file'),
'insecure': self._get_client_option('glance', 'insecure')
}
return glanceclient.Client('1', endpoint, **args)
def neutron(self): def neutron(self):
warnings.warn('neutron() is deprecated. ' warnings.warn('neutron() is deprecated. '
'Replace with calls to client("neutron")') 'Replace with calls to client("neutron")')

View File

@ -0,0 +1,39 @@
#
# 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 glanceclient import client as gc
from heat.engine.clients import client_plugin
class GlanceClientPlugin(client_plugin.ClientPlugin):
def _create(self):
con = self.context
endpoint_type = self._get_client_option('glance', 'endpoint_type')
endpoint = self.url_for(service_type='image',
endpoint_type=endpoint_type)
args = {
'auth_url': con.auth_url,
'service_type': 'image',
'project_id': con.tenant,
'token': self.auth_token,
'endpoint_type': endpoint_type,
'ca_file': self._get_client_option('glance', 'ca_file'),
'cert_file': self._get_client_option('glance', 'cert_file'),
'key_file': self._get_client_option('glance', 'key_file'),
'insecure': self._get_client_option('glance', 'insecure')
}
return gc.Client('1', endpoint, **args)

View File

@ -11,7 +11,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from glanceclient.common import exceptions as glance_exceptions from glanceclient import exc as glance_exceptions
from heat.engine import constraints from heat.engine import constraints
from heat.engine import properties from heat.engine import properties

View File

@ -20,7 +20,7 @@ from testtools.matchers import MatchesRegex
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import function from heat.engine import function
from heat.engine.notification import stack as notification from heat.engine.notification import stack as notification
@ -214,8 +214,8 @@ class AutoScalingGroupTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId, def _mock_get_image_id_success(self, imageId_input, imageId,
update_image=None): update_image=None):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')

View File

@ -31,7 +31,7 @@ from heat.common import identifier
from heat.common import template_format from heat.common import template_format
from heat.common import urlfetch from heat.common import urlfetch
from heat.db import api as db_api from heat.db import api as db_api
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import dependencies from heat.engine import dependencies
from heat.engine import environment from heat.engine import environment
@ -204,8 +204,8 @@ def setup_keystone_mocks(mocks, stack):
def setup_mock_for_image_constraint(mocks, imageId_input, def setup_mock_for_image_constraint(mocks, imageId_input,
imageId_output=744): imageId_output=744):
g_cli_mock = mocks.CreateMockAnything() g_cli_mock = mocks.CreateMockAnything()
mocks.StubOutWithMock(clients.OpenStackClients, '_glance') mocks.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
mocks.StubOutWithMock(glance_utils, 'get_image_id') mocks.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).\ glance_utils.get_image_id(g_cli_mock, imageId_input).\

View File

@ -11,7 +11,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from glanceclient.common.exceptions import HTTPNotFound from glanceclient import exc as glance_exceptions
import mock import mock
import six import six
@ -190,5 +190,5 @@ class GlanceImageTest(HeatTestCase):
self.my_image.resource_id = image_id self.my_image.resource_id = image_id
self.images.delete.return_value = None self.images.delete.return_value = None
self.assertIsNone(self.my_image.handle_delete()) self.assertIsNone(self.my_image.handle_delete())
self.images.delete.side_effect = HTTPNotFound(404) self.images.delete.side_effect = glance_exceptions.HTTPNotFound(404)
self.assertIsNone(self.my_image.handle_delete()) self.assertIsNone(self.my_image.handle_delete())

View File

@ -20,7 +20,7 @@ from neutronclient.v2_0 import client as neutronclient
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
@ -81,8 +81,8 @@ class InstancesTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\
@ -90,8 +90,8 @@ class InstancesTest(HeatTestCase):
def _mock_get_image_id_fail(self, image_id, exp): def _mock_get_image_id_fail(self, image_id, exp):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp) glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp)

View File

@ -14,7 +14,7 @@
import uuid import uuid
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
@ -153,8 +153,8 @@ class instancesTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\

View File

@ -20,7 +20,7 @@ from oslo.config import cfg
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import resource from heat.engine import resource
from heat.engine.resources import glance_utils from heat.engine.resources import glance_utils
@ -125,8 +125,8 @@ class LoadBalancerTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).\ glance_utils.get_image_id(g_cli_mock, imageId_input).\

View File

@ -12,7 +12,7 @@
# under the License. # under the License.
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine.resources import glance_utils from heat.engine.resources import glance_utils
from heat.engine.resources import instance as instances from heat.engine.resources import instance as instances
@ -63,8 +63,8 @@ class nokeyTest(HeatTestCase):
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
nova.NovaClientPlugin._create().AndReturn(self.fc) nova.NovaClientPlugin._create().AndReturn(self.fc)
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, 'CentOS 5.2').MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, 'CentOS 5.2').MultipleTimes().\

View File

@ -21,7 +21,7 @@ from novaclient import exceptions as nova_exceptions
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
@ -164,8 +164,8 @@ class ServersTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId, def _mock_get_image_id_success(self, imageId_input, imageId,
server_rebuild=False): server_rebuild=False):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\
@ -177,8 +177,8 @@ class ServersTest(HeatTestCase):
def _mock_get_image_id_fail(self, image_id, exp): def _mock_get_image_id_fail(self, image_id, exp):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp) glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp)

View File

@ -17,7 +17,7 @@ import uuid
import mox import mox
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
@ -133,8 +133,8 @@ class ServerTagsTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\

View File

@ -25,7 +25,7 @@ from heat.common import context
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.db.sqlalchemy import api as db_api from heat.db.sqlalchemy import api as db_api
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine import parser from heat.engine import parser
@ -97,8 +97,8 @@ class SqlAlchemyTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\

View File

@ -11,13 +11,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from glanceclient import exc as g_exc from glanceclient import exc as glance_exceptions
import mock import mock
from testtools import skipIf from testtools import skipIf
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import environment from heat.engine import environment
from heat.engine.hot.template import HOTemplate from heat.engine.hot.template import HOTemplate
@ -820,8 +820,8 @@ class validateTest(HeatTestCase):
def _mock_get_image_id_success(self, imageId_input, imageId): def _mock_get_image_id_success(self, imageId_input, imageId):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, imageId_input).MultipleTimes().\
@ -829,8 +829,8 @@ class validateTest(HeatTestCase):
def _mock_get_image_id_fail(self, image_id, exp): def _mock_get_image_id_fail(self, image_id, exp):
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp) glance_utils.get_image_id(g_cli_mock, image_id).AndRaise(exp)
@ -1301,9 +1301,9 @@ class validateTest(HeatTestCase):
self.m.StubOutWithMock(self.gc.images, 'list') self.m.StubOutWithMock(self.gc.images, 'list')
self.gc.images.list().AndRaise( self.gc.images.list().AndRaise(
g_exc.ClientException(500)) glance_exceptions.ClientException(500))
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn(self.gc) glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(self.gc)
self.m.ReplayAll() self.m.ReplayAll()
self.assertRaises(exception.StackValidationFailed, stack.validate) self.assertRaises(exception.StackValidationFailed, stack.validate)

View File

@ -22,6 +22,7 @@ from testtools import skipIf
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine import clients from heat.engine import clients
from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine.resources import glance_utils from heat.engine.resources import glance_utils
from heat.engine.resources import image from heat.engine.resources import image
@ -893,8 +894,8 @@ class VolumeTest(HeatTestCase):
clients.OpenStackClients._cinder().MultipleTimes().AndReturn( clients.OpenStackClients._cinder().MultipleTimes().AndReturn(
self.cinder_fc) self.cinder_fc)
g_cli_mock = self.m.CreateMockAnything() g_cli_mock = self.m.CreateMockAnything()
self.m.StubOutWithMock(clients.OpenStackClients, '_glance') self.m.StubOutWithMock(glance.GlanceClientPlugin, '_create')
clients.OpenStackClients._glance().MultipleTimes().AndReturn( glance.GlanceClientPlugin._create().MultipleTimes().AndReturn(
g_cli_mock) g_cli_mock)
self.m.StubOutWithMock(glance_utils, 'get_image_id') self.m.StubOutWithMock(glance_utils, 'get_image_id')
glance_utils.get_image_id(g_cli_mock, image_id).MultipleTimes().\ glance_utils.get_image_id(g_cli_mock, image_id).MultipleTimes().\

View File

@ -38,6 +38,7 @@ oslo.config.opts =
heat.common.wsgi = heat.common.wsgi:list_opts heat.common.wsgi = heat.common.wsgi:list_opts
heat.clients = heat.clients =
glance = heat.engine.clients.os.glance:GlanceClientPlugin
nova = heat.engine.clients.os.nova:NovaClientPlugin nova = heat.engine.clients.os.nova:NovaClientPlugin
swift = heat.engine.clients.os.swift:SwiftClientPlugin swift = heat.engine.clients.os.swift:SwiftClientPlugin