Merge "Add custom SSL CA Cert support for api.cinder.get_microversion" into stable/train
This commit is contained in:
commit
dd8943b536
|
@ -30,6 +30,7 @@ from cinderclient import api_versions
|
|||
from cinderclient import client as cinder_client
|
||||
from cinderclient import exceptions as cinder_exception
|
||||
from cinderclient.v2.contrib import list_extensions as cinder_list_extensions
|
||||
from six.moves import urllib
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon.utils.memoized import memoized
|
||||
|
@ -253,11 +254,60 @@ def get_microversion(request, features):
|
|||
version, cinder_url = _find_cinder_url(request)
|
||||
except exceptions.ServiceCatalogException:
|
||||
return None
|
||||
min_ver, max_ver = cinder_client.get_server_version(cinder_url)
|
||||
min_ver, max_ver = _get_server_version(request, cinder_url)
|
||||
return microversions.get_microversion_for_features(
|
||||
'cinder', features, api_versions.APIVersion, min_ver, max_ver)
|
||||
|
||||
|
||||
# NOTE(amotoki): Borrowed from cinderclient.client.get_server_version()
|
||||
# to support custom SSL CA Cert support with cinderclient<5.
|
||||
def _get_server_version(request, url):
|
||||
min_version = "2.0"
|
||||
current_version = "2.0"
|
||||
try:
|
||||
u = urllib.parse.urlparse(url)
|
||||
version_url = None
|
||||
|
||||
# NOTE(andreykurilin): endpoint URL has at least 2 formats:
|
||||
# 1. The classic (legacy) endpoint:
|
||||
# http://{host}:{optional_port}/v{2 or 3}/{project-id}
|
||||
# http://{host}:{optional_port}/v{2 or 3}
|
||||
# 3. Under wsgi:
|
||||
# http://{host}:{optional_port}/volume/v{2 or 3}
|
||||
for ver in ['v2', 'v3']:
|
||||
if u.path.endswith(ver) or "/{0}/".format(ver) in u.path:
|
||||
path = u.path[:u.path.rfind(ver)]
|
||||
version_url = '%s://%s%s' % (u.scheme, u.netloc, path)
|
||||
break
|
||||
|
||||
if not version_url:
|
||||
# NOTE(andreykurilin): probably, it is one of the next cases:
|
||||
# * https://volume.example.com/
|
||||
# * https://example.com/volume
|
||||
# leave as is without cropping.
|
||||
version_url = url
|
||||
|
||||
c = cinderclient(request)
|
||||
resp, data = c.client.request(version_url, 'GET')
|
||||
|
||||
versions = data['versions']
|
||||
for version in versions:
|
||||
if '3.' in version['version']:
|
||||
min_version = version['min_version']
|
||||
current_version = version['version']
|
||||
break
|
||||
else:
|
||||
# Set the values, but don't break out the loop here in case v3
|
||||
# comes later
|
||||
min_version = '2.0'
|
||||
current_version = '2.0'
|
||||
except cinder_exception.ClientException as e:
|
||||
LOG.warning("Error in server version query:%s\n"
|
||||
"Returning APIVersion 2.0", e)
|
||||
return (api_versions.APIVersion(min_version),
|
||||
api_versions.APIVersion(current_version))
|
||||
|
||||
|
||||
def _cinderclient_with_features(request, features,
|
||||
raise_exc=False, message=False):
|
||||
version = get_microversion(request, features)
|
||||
|
|
|
@ -36,6 +36,7 @@ from openstack_dashboard.usage import quotas as usage_quotas
|
|||
|
||||
|
||||
def data(TEST):
|
||||
TEST.cinder_versions = utils.TestDataContainer()
|
||||
TEST.cinder_services = utils.TestDataContainer()
|
||||
TEST.cinder_volumes = utils.TestDataContainer()
|
||||
TEST.cinder_volume_backups = utils.TestDataContainer()
|
||||
|
@ -59,6 +60,41 @@ def data(TEST):
|
|||
TEST.cinder_group_volumes = utils.TestDataContainer()
|
||||
TEST.cinder_volume_snapshots_with_groups = utils.TestDataContainer()
|
||||
|
||||
ver2 = {
|
||||
'id': 'v2.0',
|
||||
'links': [{'href': 'http://docs.openstack.org/',
|
||||
'rel': 'describedby',
|
||||
'type': 'text/html'},
|
||||
{'href': 'http://192.168.50.25/volume/v2/',
|
||||
'rel': 'self'}],
|
||||
'media-types': [
|
||||
{'base': 'application/json',
|
||||
'type': 'application/vnd.openstack.volume+json;version=2'}
|
||||
],
|
||||
'min_version': '',
|
||||
'status': 'DEPRECATED',
|
||||
'updated': '2014-06-28T12:20:21Z',
|
||||
'version': '',
|
||||
}
|
||||
ver3 = {
|
||||
'id': 'v3.0',
|
||||
'links': [{'href': 'http://docs.openstack.org/',
|
||||
'rel': 'describedby',
|
||||
'type': 'text/html'},
|
||||
{'href': 'http://192.168.50.25/volume/v3/',
|
||||
'rel': 'self'}],
|
||||
'media-types': [
|
||||
{'base': 'application/json',
|
||||
'type': 'application/vnd.openstack.volume+json;version=3'}
|
||||
],
|
||||
'min_version': '3.0',
|
||||
'status': 'CURRENT',
|
||||
'updated': '2016-02-08T12:20:21Z',
|
||||
'version': '3.16',
|
||||
}
|
||||
TEST.cinder_versions.add(ver2)
|
||||
TEST.cinder_versions.add(ver3)
|
||||
|
||||
# Services
|
||||
service_1 = services.Service(services.ServiceManager(None), {
|
||||
"service": "cinder-scheduler",
|
||||
|
|
|
@ -16,6 +16,8 @@ from django.conf import settings
|
|||
from django.test.utils import override_settings
|
||||
|
||||
import cinderclient as cinder_client
|
||||
from cinderclient import api_versions
|
||||
from cinderclient import exceptions as cinder_exception
|
||||
import mock
|
||||
|
||||
from openstack_dashboard import api
|
||||
|
@ -446,6 +448,83 @@ class CinderApiTests(test.APIMockTestCase):
|
|||
self.assertEqual(default_volume_type, volume_type)
|
||||
cinderclient.volume_types.default.assert_called_once()
|
||||
|
||||
@mock.patch.object(api.cinder, 'cinderclient')
|
||||
def _check_get_server_version_v3(self, volume_url, version_url, expected,
|
||||
mock_cinderclient):
|
||||
versions = {'versions': self.cinder_versions.list()}
|
||||
cinder_client = mock_cinderclient.return_value
|
||||
cinder_client.client.request.return_value = (200, versions)
|
||||
|
||||
versions = api.cinder._get_server_version(self.request, volume_url)
|
||||
|
||||
self.assertEqual(expected, versions)
|
||||
cinder_client.client.request.assert_called_once_with(
|
||||
version_url, 'GET')
|
||||
|
||||
def test_get_server_version_v3_dedicated_port_http(self):
|
||||
volume_url = ('http://192.168.122.127:8776/v3/'
|
||||
'e5526285ebd741b1819393f772f11fc3')
|
||||
version_url = 'http://192.168.122.127:8776/'
|
||||
expected = (api_versions.APIVersion('3.0'),
|
||||
api_versions.APIVersion('3.16'))
|
||||
self._check_get_server_version_v3(volume_url, version_url, expected)
|
||||
|
||||
def test_get_server_version_v3_dedicated_port_https(self):
|
||||
volume_url = ('https://192.168.122.127:8776/v3/'
|
||||
'e55285ebd741b1819393f772f11fc3')
|
||||
version_url = 'https://192.168.122.127:8776/'
|
||||
expected = (api_versions.APIVersion('3.0'),
|
||||
api_versions.APIVersion('3.16'))
|
||||
self._check_get_server_version_v3(volume_url, version_url, expected)
|
||||
|
||||
def test_get_server_version_v3_path(self):
|
||||
volume_url = ('http://192.168.122.127/volumes/v3/'
|
||||
'e5526285ebd741b1819393f772f11fc3')
|
||||
version_url = 'http://192.168.122.127/volumes/'
|
||||
expected = (api_versions.APIVersion('3.0'),
|
||||
api_versions.APIVersion('3.16'))
|
||||
self._check_get_server_version_v3(volume_url, version_url, expected)
|
||||
|
||||
def test_get_server_version_v3_without_project_id(self):
|
||||
volume_url = 'http://192.168.122.127/volumes/v3/'
|
||||
version_url = 'http://192.168.122.127/volumes/'
|
||||
expected = (api_versions.APIVersion('3.0'),
|
||||
api_versions.APIVersion('3.16'))
|
||||
self._check_get_server_version_v3(volume_url, version_url, expected)
|
||||
|
||||
@mock.patch.object(api.cinder, 'cinderclient')
|
||||
def test_get_server_version_v2(self, mock_cinderclient):
|
||||
versions = {'versions': [x for x in self.cinder_versions.list()
|
||||
if x['id'] == 'v2.0']}
|
||||
cinder_client = mock_cinderclient.return_value
|
||||
cinder_client.client.request.return_value = (200, versions)
|
||||
|
||||
versions = api.cinder._get_server_version(
|
||||
self.request,
|
||||
'http://192.168.122.127:8776/v2/e5526285ebd741b1819393f772f11fc3')
|
||||
|
||||
self.assertEqual((api_versions.APIVersion('2.0'),
|
||||
api_versions.APIVersion('2.0')),
|
||||
versions)
|
||||
cinder_client.client.request.assert_called_once_with(
|
||||
'http://192.168.122.127:8776/', 'GET')
|
||||
|
||||
@mock.patch.object(api.cinder, 'cinderclient')
|
||||
def test_get_server_version_exception(self, mock_cinderclient):
|
||||
cinder_client = mock_cinderclient.return_value
|
||||
cinder_client.client.request.side_effect = \
|
||||
cinder_exception.ClientException(500)
|
||||
|
||||
versions = api.cinder._get_server_version(
|
||||
self.request,
|
||||
'http://192.168.122.127:8776/v3/')
|
||||
|
||||
self.assertEqual((api_versions.APIVersion('2.0'),
|
||||
api_versions.APIVersion('2.0')),
|
||||
versions)
|
||||
cinder_client.client.request.assert_called_once_with(
|
||||
'http://192.168.122.127:8776/', 'GET')
|
||||
|
||||
|
||||
class CinderApiVersionTests(test.TestCase):
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
[:bug:`1744670`]
|
||||
Previously when a custom SSL CA is used horizon cannot retrieve volume
|
||||
and snapshot information from cinder. It is fixed now and a custom CA
|
||||
is handled properly in horizon when communicating with cinder.
|
Loading…
Reference in New Issue