Add api-version to get server versions
Mitaka Cinder added an API to return Versions from the base endpoint URL: http://<url>:8776/ This patch exposes that API for /v3 endpoint microversions 3.0 and above with the command: cinder api-version Implements: blueprint add-get-server-versions Change-Id: Ieb1a56b28188ec17946fe5564b28c165833ffc24
This commit is contained in:
parent
72304df07a
commit
09b51a294e
cinderclient
@ -335,6 +335,14 @@ class Manager(common_base.HookableMixin):
|
||||
body = body or {}
|
||||
return common_base.DictWithMeta(body, resp)
|
||||
|
||||
def _get_with_base_url(self, url, response_key=None):
|
||||
resp, body = self.api.client.get_with_base_url(url)
|
||||
if response_key:
|
||||
return [self.resource_class(self, res, loaded=True)
|
||||
for res in body[response_key] if res]
|
||||
else:
|
||||
return self.resource_class(self, body, loaded=True)
|
||||
|
||||
|
||||
class ManagerWithFind(six.with_metaclass(abc.ABCMeta, Manager)):
|
||||
"""
|
||||
|
@ -151,6 +151,11 @@ class SessionClient(adapter.LegacyJsonAdapter):
|
||||
def delete(self, url, **kwargs):
|
||||
return self._cs_request(url, 'DELETE', **kwargs)
|
||||
|
||||
def _get_base_url(self):
|
||||
endpoint = self.get_endpoint()
|
||||
base_url = '/'.join(endpoint.split('/')[:3]) + '/'
|
||||
return base_url
|
||||
|
||||
def get_volume_api_version_from_endpoint(self):
|
||||
try:
|
||||
version = get_volume_api_from_url(self.get_endpoint())
|
||||
@ -176,6 +181,16 @@ class SessionClient(adapter.LegacyJsonAdapter):
|
||||
raise AttributeError('There is no service catalog for this type of '
|
||||
'auth plugin.')
|
||||
|
||||
def _cs_request_base_url(self, url, method, **kwargs):
|
||||
base_url = self._get_base_url(**kwargs)
|
||||
return self._cs_request(
|
||||
base_url + url,
|
||||
method,
|
||||
**kwargs)
|
||||
|
||||
def get_with_base_url(self, url, **kwargs):
|
||||
return self._cs_request_base_url(url, 'GET', **kwargs)
|
||||
|
||||
|
||||
class HTTPClient(object):
|
||||
|
||||
|
@ -79,6 +79,13 @@ class ClientTest(utils.TestCase):
|
||||
cinderclient.client.get_volume_api_from_url,
|
||||
unknown_url)
|
||||
|
||||
@mock.patch('cinderclient.client.SessionClient.get_endpoint')
|
||||
def test_get_base_url(self, mock_get_endpoint):
|
||||
url = 'http://192.168.122.104:8776/v3/de50d1f33a38415fadfd3e1dea28f4d3'
|
||||
mock_get_endpoint.return_value = url
|
||||
cs = cinderclient.client.SessionClient(self, api_version='3.0')
|
||||
self.assertEqual('http://192.168.122.104:8776/', cs._get_base_url())
|
||||
|
||||
@mock.patch.object(cinderclient.client, '_log_request_id')
|
||||
@mock.patch.object(adapter.Adapter, 'request')
|
||||
@mock.patch.object(exceptions, 'from_response')
|
||||
|
@ -249,6 +249,65 @@ def _stub_extend(id, new_size):
|
||||
return {'volume_id': '712f4980-5ac1-41e5-9383-390aa7c9f58b'}
|
||||
|
||||
|
||||
def _stub_server_versions():
|
||||
return [
|
||||
{
|
||||
"status": "SUPPORTED",
|
||||
"updated": "2015-07-30T11:33:21Z",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://docs.openstack.org/",
|
||||
"type": "text/html",
|
||||
"rel": "describedby",
|
||||
},
|
||||
{
|
||||
"href": "http://localhost:8776/v1/",
|
||||
"rel": "self",
|
||||
}
|
||||
],
|
||||
"min_version": "",
|
||||
"version": "",
|
||||
"id": "v1.0",
|
||||
},
|
||||
{
|
||||
"status": "SUPPORTED",
|
||||
"updated": "2015-09-30T11:33:21Z",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://docs.openstack.org/",
|
||||
"type": "text/html",
|
||||
"rel": "describedby",
|
||||
},
|
||||
{
|
||||
"href": "http://localhost:8776/v2/",
|
||||
"rel": "self",
|
||||
}
|
||||
],
|
||||
"min_version": "",
|
||||
"version": "",
|
||||
"id": "v2.0",
|
||||
},
|
||||
{
|
||||
"status": "CURRENT",
|
||||
"updated": "2016-04-01T11:33:21Z",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://docs.openstack.org/",
|
||||
"type": "text/html",
|
||||
"rel": "describedby",
|
||||
},
|
||||
{
|
||||
"href": "http://localhost:8776/v3/",
|
||||
"rel": "self",
|
||||
}
|
||||
],
|
||||
"min_version": "3.0",
|
||||
"version": "3.1",
|
||||
"id": "v3.0",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class FakeClient(fakes.FakeClient, client.Client):
|
||||
|
||||
def __init__(self, api_version=None, *args, **kwargs):
|
||||
@ -264,7 +323,7 @@ class FakeClient(fakes.FakeClient, client.Client):
|
||||
|
||||
class FakeHTTPClient(base_client.HTTPClient):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, version_header=None, **kwargs):
|
||||
self.username = 'username'
|
||||
self.password = 'password'
|
||||
self.auth_url = 'auth_url'
|
||||
@ -272,6 +331,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
self.management_url = 'http://10.0.2.15:8776/v2/fake'
|
||||
self.osapi_max_limit = 1000
|
||||
self.marker = None
|
||||
self.version_header = version_header
|
||||
|
||||
def _cs_request(self, url, method, **kwargs):
|
||||
# Check that certain things are called correctly
|
||||
@ -308,6 +368,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
status, headers, body = getattr(self, callback)(**kwargs)
|
||||
# add fake request-id header
|
||||
headers['x-openstack-request-id'] = REQUEST_ID
|
||||
if self.version_header:
|
||||
headers['OpenStack-API-version'] = version_header
|
||||
r = utils.TestResponse({
|
||||
"status_code": status,
|
||||
"text": body,
|
||||
@ -969,6 +1031,10 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
return (200, {},
|
||||
{'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
|
||||
|
||||
def get_with_base_url(self, url, **kw):
|
||||
server_versions = _stub_server_versions()
|
||||
return (200, {'versions': server_versions})
|
||||
|
||||
#
|
||||
# Services
|
||||
#
|
||||
|
@ -80,3 +80,8 @@ class ServicesTest(utils.TestCase):
|
||||
self.assertIsInstance(s, services.Service)
|
||||
self.assertEqual('disabled', s.status)
|
||||
self._assert_request_id(s)
|
||||
|
||||
def test_api_version(self):
|
||||
client = fakes.FakeClient(version_header='3.0')
|
||||
svs = client.services.server_api_version()
|
||||
[self.assertIsInstance(s, services.Service) for s in svs]
|
||||
|
@ -16,6 +16,7 @@
|
||||
"""
|
||||
service interface
|
||||
"""
|
||||
from cinderclient import api_versions
|
||||
from cinderclient import base
|
||||
|
||||
|
||||
@ -77,3 +78,16 @@ class ServiceManager(base.ManagerWithFind):
|
||||
"""Failover a replicated backend by hostname."""
|
||||
body = {"host": host, "backend_id": backend_id}
|
||||
return self._update("/os-services/failover_host", body)
|
||||
|
||||
@api_versions.wraps("3.0")
|
||||
def server_api_version(self, url_append=""):
|
||||
"""Returns the API Version supported by the server.
|
||||
|
||||
:param url_append: String to append to url to obtain specific version
|
||||
:return: Returns response obj for a server that supports microversions.
|
||||
Returns an empty list for Liberty and prior Cinder servers.
|
||||
"""
|
||||
try:
|
||||
return self._get_with_base_url(url_append, response_key='versions')
|
||||
except LookupError:
|
||||
return []
|
||||
|
@ -24,6 +24,7 @@ import time
|
||||
|
||||
import six
|
||||
|
||||
from cinderclient import api_versions
|
||||
from cinderclient import base
|
||||
from cinderclient import exceptions
|
||||
from cinderclient import utils
|
||||
@ -2680,3 +2681,12 @@ def do_thaw_host(cs, args):
|
||||
def do_failover_host(cs, args):
|
||||
"""Failover a replicating cinder-volume host."""
|
||||
cs.services.failover_host(args.host, args.backend_id)
|
||||
|
||||
|
||||
@utils.service_type('volumev3')
|
||||
@api_versions.wraps("3.0")
|
||||
def do_api_version(cs, args):
|
||||
"""Display the API version information."""
|
||||
columns = ['ID', 'Status', 'Version', 'Min_version']
|
||||
response = cs.services.server_api_version()
|
||||
utils.print_list(response, columns)
|
||||
|
Loading…
x
Reference in New Issue
Block a user