cinder: Add mechanism to compare api microversion
Introduce the capability to detect and compare available api microversion to implement features which require specific microversion. Story: 2011229 Task: 51085 Change-Id: Ic9fa21015dd8a49414b78cbe13a6047f1c80a21f
This commit is contained in:
parent
0135d50659
commit
0b84e5be0d
@ -197,6 +197,12 @@ engine_opts = [
|
|||||||
'this limitation, any nova feature supported with '
|
'this limitation, any nova feature supported with '
|
||||||
'microversion number above max_nova_api_microversion '
|
'microversion number above max_nova_api_microversion '
|
||||||
'will not be available.')),
|
'will not be available.')),
|
||||||
|
cfg.StrOpt('max_cinder_api_microversion',
|
||||||
|
regex=r'^3\.\d+$',
|
||||||
|
help=_('Maximum cinder API version for client plugin. With '
|
||||||
|
'this limitation, any cinder feature supported with '
|
||||||
|
'microversion number above max_cinder_api_microversion '
|
||||||
|
'will not be available.')),
|
||||||
cfg.StrOpt('max_ironic_api_microversion',
|
cfg.StrOpt('max_ironic_api_microversion',
|
||||||
regex=r'^\d+\.\d+$',
|
regex=r'^\d+\.\d+$',
|
||||||
help=_('Maximum ironic API version for client plugin. With '
|
help=_('Maximum ironic API version for client plugin. With '
|
||||||
|
@ -11,6 +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 cinderclient import api_versions
|
||||||
from cinderclient import client as cc
|
from cinderclient import client as cc
|
||||||
from cinderclient import exceptions
|
from cinderclient import exceptions
|
||||||
from keystoneauth1 import exceptions as ks_exceptions
|
from keystoneauth1 import exceptions as ks_exceptions
|
||||||
@ -20,6 +21,7 @@ from oslo_log import log as logging
|
|||||||
from heat.common import exception
|
from heat.common import exception
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
from heat.engine.clients import client_plugin
|
from heat.engine.clients import client_plugin
|
||||||
|
from heat.engine.clients import microversion_mixin
|
||||||
from heat.engine.clients import os as os_client
|
from heat.engine.clients import os as os_client
|
||||||
from heat.engine import constraints
|
from heat.engine import constraints
|
||||||
|
|
||||||
@ -29,13 +31,18 @@ LOG = logging.getLogger(__name__)
|
|||||||
CLIENT_NAME = 'cinder'
|
CLIENT_NAME = 'cinder'
|
||||||
|
|
||||||
|
|
||||||
class CinderClientPlugin(os_client.ExtensionMixin,
|
class CinderClientPlugin(microversion_mixin.MicroversionMixin,
|
||||||
|
os_client.ExtensionMixin,
|
||||||
client_plugin.ClientPlugin):
|
client_plugin.ClientPlugin):
|
||||||
|
|
||||||
exceptions_module = exceptions
|
exceptions_module = exceptions
|
||||||
|
|
||||||
service_types = [VOLUME_V3] = ['volumev3']
|
service_types = [VOLUME_V3] = ['volumev3']
|
||||||
|
|
||||||
|
CINDER_API_VERSION = '3'
|
||||||
|
|
||||||
|
max_microversion = cfg.CONF.max_cinder_api_microversion
|
||||||
|
|
||||||
def get_volume_api_version(self):
|
def get_volume_api_version(self):
|
||||||
'''Returns the most recent API version.'''
|
'''Returns the most recent API version.'''
|
||||||
self.interface = self._get_client_option(CLIENT_NAME, 'endpoint_type')
|
self.interface = self._get_client_option(CLIENT_NAME, 'endpoint_type')
|
||||||
@ -43,28 +50,38 @@ class CinderClientPlugin(os_client.ExtensionMixin,
|
|||||||
self.context.keystone_session.get_endpoint(
|
self.context.keystone_session.get_endpoint(
|
||||||
service_type=self.VOLUME_V3,
|
service_type=self.VOLUME_V3,
|
||||||
interface=self.interface)
|
interface=self.interface)
|
||||||
self.service_type = self.VOLUME_V3
|
|
||||||
self.client_version = '3'
|
|
||||||
except ks_exceptions.EndpointNotFound:
|
except ks_exceptions.EndpointNotFound:
|
||||||
raise exception.Error(_('No volume service available.'))
|
raise exception.Error(_('No volume service available.'))
|
||||||
|
|
||||||
def _create(self):
|
def _create(self, version=None):
|
||||||
|
if version is None:
|
||||||
|
version = self.CINDER_API_VERSION
|
||||||
self.get_volume_api_version()
|
self.get_volume_api_version()
|
||||||
extensions = cc.discover_extensions(self.client_version)
|
extensions = cc.discover_extensions(self.CINDER_API_VERSION)
|
||||||
args = {
|
args = {
|
||||||
'session': self.context.keystone_session,
|
'session': self.context.keystone_session,
|
||||||
'extensions': extensions,
|
'extensions': extensions,
|
||||||
'interface': self.interface,
|
'interface': self.interface,
|
||||||
'service_type': self.service_type,
|
'service_type': self.VOLUME_V3,
|
||||||
'region_name': self._get_region_name(),
|
'region_name': self._get_region_name(),
|
||||||
'connect_retries': cfg.CONF.client_retry_limit,
|
'connect_retries': cfg.CONF.client_retry_limit,
|
||||||
'http_log_debug': self._get_client_option(CLIENT_NAME,
|
'http_log_debug': self._get_client_option(CLIENT_NAME,
|
||||||
'http_log_debug')
|
'http_log_debug')
|
||||||
}
|
}
|
||||||
|
client = cc.Client(version, **args)
|
||||||
client = cc.Client(self.client_version, **args)
|
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
def get_max_microversion(self):
|
||||||
|
if not self.max_microversion:
|
||||||
|
self.max_microversion = api_versions.get_highest_version(
|
||||||
|
self._create()).get_string()
|
||||||
|
return self.max_microversion
|
||||||
|
|
||||||
|
def is_version_supported(self, version):
|
||||||
|
api_ver = api_versions.APIVersion(version)
|
||||||
|
max_api_ver = api_versions.APIVersion(self.get_max_microversion())
|
||||||
|
return max_api_ver >= api_ver
|
||||||
|
|
||||||
@os_client.MEMOIZE_EXTENSIONS
|
@os_client.MEMOIZE_EXTENSIONS
|
||||||
def _list_extensions(self):
|
def _list_extensions(self):
|
||||||
extensions = self.client().list_extensions.show_all()
|
extensions = self.client().list_extensions.show_all()
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import copy
|
import copy
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from cinderclient import api_versions
|
||||||
from cinderclient import exceptions as cinder_exp
|
from cinderclient import exceptions as cinder_exp
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
@ -623,7 +624,8 @@ class VolumeTest(vt_base.VolumeTestCase):
|
|||||||
|
|
||||||
self.create_volume(self.t, stack, 'DataVolume', no_create=True)
|
self.create_volume(self.t, stack, 'DataVolume', no_create=True)
|
||||||
|
|
||||||
cinder.CinderClientPlugin._create.assert_called_once_with()
|
cinder.CinderClientPlugin._create.assert_called_once_with(
|
||||||
|
version=api_versions.MAX_VERSION)
|
||||||
self.m_restore.assert_called_once_with('backup-123')
|
self.m_restore.assert_called_once_with('backup-123')
|
||||||
self.cinder_fc.volumes.get.assert_called_with('vol-123')
|
self.cinder_fc.volumes.get.assert_called_with('vol-123')
|
||||||
self.cinder_fc.volumes.update.assert_called_once_with(
|
self.cinder_fc.volumes.update.assert_called_once_with(
|
||||||
@ -651,7 +653,8 @@ class VolumeTest(vt_base.VolumeTestCase):
|
|||||||
self.assertIn('Went to status error due to "Unknown"',
|
self.assertIn('Went to status error due to "Unknown"',
|
||||||
str(ex))
|
str(ex))
|
||||||
|
|
||||||
cinder.CinderClientPlugin._create.assert_called_once_with()
|
cinder.CinderClientPlugin._create.assert_called_once_with(
|
||||||
|
version=api_versions.MAX_VERSION)
|
||||||
self.m_restore.assert_called_once_with('backup-123')
|
self.m_restore.assert_called_once_with('backup-123')
|
||||||
self.cinder_fc.volumes.update.assert_called_once_with(
|
self.cinder_fc.volumes.update.assert_called_once_with(
|
||||||
fv.id, description=vol_name, name=vol_name)
|
fv.id, description=vol_name, name=vol_name)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
from unittest import mock
|
from unittest import mock
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from cinderclient import api_versions as cinder_api_versions
|
||||||
from cinderclient import exceptions as cinder_exc
|
from cinderclient import exceptions as cinder_exc
|
||||||
from keystoneauth1 import exceptions as ks_exceptions
|
from keystoneauth1 import exceptions as ks_exceptions
|
||||||
|
|
||||||
@ -160,6 +161,8 @@ class CinderClientAPIVersionTest(common.HeatTestCase):
|
|||||||
def test_cinder_api_v3(self):
|
def test_cinder_api_v3(self):
|
||||||
ctx = utils.dummy_context()
|
ctx = utils.dummy_context()
|
||||||
self.patchobject(ctx.keystone_session, 'get_endpoint')
|
self.patchobject(ctx.keystone_session, 'get_endpoint')
|
||||||
|
ctx.clients.client_plugin(
|
||||||
|
'cinder').max_microversion = cinder_api_versions.MAX_VERSION
|
||||||
client = ctx.clients.client('cinder')
|
client = ctx.clients.client('cinder')
|
||||||
self.assertEqual('3.0', client.version)
|
self.assertEqual('3.0', client.version)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from cinderclient import api_versions
|
||||||
from cinderclient.v3 import client as cinderclient
|
from cinderclient.v3 import client as cinderclient
|
||||||
|
|
||||||
from heat.engine.clients.os import cinder
|
from heat.engine.clients.os import cinder
|
||||||
@ -32,6 +33,8 @@ class VolumeTestCase(common.HeatTestCase):
|
|||||||
self.fc = fakes_nova.FakeClient()
|
self.fc = fakes_nova.FakeClient()
|
||||||
self.cinder_fc = cinderclient.Client('username', 'password')
|
self.cinder_fc = cinderclient.Client('username', 'password')
|
||||||
self.cinder_fc.volume_api_version = 3
|
self.cinder_fc.volume_api_version = 3
|
||||||
|
self.patchobject(cinder.CinderClientPlugin, 'get_max_microversion',
|
||||||
|
return_value=api_versions.MAX_VERSION)
|
||||||
self.patchobject(cinder.CinderClientPlugin, '_create',
|
self.patchobject(cinder.CinderClientPlugin, '_create',
|
||||||
return_value=self.cinder_fc)
|
return_value=self.cinder_fc)
|
||||||
self.patchobject(nova.NovaClientPlugin, 'client',
|
self.patchobject(nova.NovaClientPlugin, 'client',
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The new ``[DEFAULT] max_cinder_api_microversion`` option has been added.
|
||||||
|
This option overrides the maximum API microversion supported by Cinder,
|
||||||
|
which is detected automatically by default.
|
Loading…
Reference in New Issue
Block a user