Add support for ironic single-version responses
The ironic payload looks like: {'id': 'v1', 'links': [{"href": "https://bare-metal.example.com/v1/", "rel": "self"}]} This does not have version info in it, nor min/max ranges for microversion discovery. We can't really get any useful information from this document, but we can at least not fail when trying to deal with it. This should then be upwards-compatible with ironic adding version discovery information to the document that is returned. Change-Id: I47e0f9b295c24ef168f4a033faf573b953025d4c
This commit is contained in:
parent
e0f1f792ce
commit
c40eb2951d
@ -119,6 +119,28 @@ def get_version_data(session, url, authenticated=None):
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Older Ironic does not actually return a discovery document for the
|
||||
# single version discovery endpoint, which confuses the single-version
|
||||
# fallback logic. While there are no known other services returning
|
||||
# min/max ranges using headers instead of body, this is done in a
|
||||
# non-Ironic specific manner just in case.
|
||||
# The existence of this support should not be an indication to any
|
||||
# OpenStack services that they should ADD this.
|
||||
if 'id' in body_resp:
|
||||
body_resp['status'] = Status.CURRENT
|
||||
for header in resp.headers:
|
||||
# We lose the case-insensitive quality here
|
||||
header = header.lower()
|
||||
if not header.startswith('x-openstack'):
|
||||
continue
|
||||
# Once the body starts having these values, stop overriding
|
||||
# with the header values
|
||||
if header.endswith('api-minimum-version'):
|
||||
body_resp.setdefault('min_version', resp.headers[header])
|
||||
if header.endswith('api-maximum-version'):
|
||||
body_resp.setdefault('version', resp.headers[header])
|
||||
return [body_resp]
|
||||
|
||||
# Otherwise if we query an endpoint like /v2.0 then we will get back
|
||||
# just the one available version.
|
||||
try:
|
||||
@ -742,7 +764,7 @@ class Discover(object):
|
||||
# so that they know what version they got. We can return the first
|
||||
# entry from version_data, because the user hasn't requested anything
|
||||
# different.
|
||||
if no_version and url:
|
||||
if no_version and url and len(version_data) > 0:
|
||||
return version_data[0]
|
||||
|
||||
# We couldn't find a match.
|
||||
@ -1121,6 +1143,9 @@ class EndpointData(object):
|
||||
" and {max_version}".format(
|
||||
min_version=version_to_string(min_version),
|
||||
max_version=version_to_string(max_version)))
|
||||
else:
|
||||
raise exceptions.DiscoveryFailure(
|
||||
"No version data found remotely at all")
|
||||
|
||||
self.min_microversion = discovered_data['min_microversion']
|
||||
self.max_microversion = discovered_data['max_microversion']
|
||||
|
@ -560,6 +560,72 @@ class VersionDataTests(utils.TestCase):
|
||||
|
||||
self.assertTrue(mock.called_once)
|
||||
|
||||
def test_version_data_ironic_microversions(self):
|
||||
"""Validate detection of Ironic microversion ranges."""
|
||||
ironic_url = 'https://bare-metal.example.com/v1/'
|
||||
self.requests_mock.get(
|
||||
ironic_url, status_code=200,
|
||||
json={
|
||||
'id': 'v1',
|
||||
'links': [{
|
||||
"href": ironic_url,
|
||||
"rel": "self"}],
|
||||
'version': '1.40',
|
||||
'min_version': '1.10',
|
||||
},
|
||||
# Keep headers so we can verify that body trumps headers
|
||||
headers={
|
||||
'X-OpenStack-Ironic-API-Minimum-Version': '1.3',
|
||||
'X-OpenStack-Ironic-API-Maximum-Version': '1.21',
|
||||
})
|
||||
|
||||
self.assertEqual(
|
||||
[
|
||||
{
|
||||
'collection': None,
|
||||
'version': (1, 0),
|
||||
'url': ironic_url,
|
||||
'status': discover.Status.CURRENT,
|
||||
'raw_status': discover.Status.CURRENT,
|
||||
'min_microversion': (1, 10),
|
||||
'max_microversion': (1, 40),
|
||||
'next_min_version': None,
|
||||
'not_before': None,
|
||||
},
|
||||
],
|
||||
discover.Discover(self.session, ironic_url).version_data())
|
||||
|
||||
def test_version_data_legacy_ironic_microversions(self):
|
||||
"""Validate detection of legacy Ironic microversion ranges."""
|
||||
ironic_url = 'https://bare-metal.example.com/v1/'
|
||||
self.requests_mock.get(
|
||||
ironic_url, status_code=200,
|
||||
json={
|
||||
'id': 'v1',
|
||||
'links': [{
|
||||
"href": ironic_url,
|
||||
"rel": "self"}]},
|
||||
headers={
|
||||
'X-OpenStack-Ironic-API-Minimum-Version': '1.3',
|
||||
'X-OpenStack-Ironic-API-Maximum-Version': '1.21',
|
||||
})
|
||||
|
||||
self.assertEqual(
|
||||
[
|
||||
{
|
||||
'collection': None,
|
||||
'version': (1, 0),
|
||||
'url': ironic_url,
|
||||
'status': discover.Status.CURRENT,
|
||||
'raw_status': discover.Status.CURRENT,
|
||||
'min_microversion': (1, 3),
|
||||
'max_microversion': (1, 21),
|
||||
'next_min_version': None,
|
||||
'not_before': None,
|
||||
},
|
||||
],
|
||||
discover.Discover(self.session, ironic_url).version_data())
|
||||
|
||||
def test_version_data_microversions(self):
|
||||
"""Validate [min_|max_]version conversion to {min|max}_microversion."""
|
||||
def setup_mock(versions_in):
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed support for detecting microversion ranges on older Ironic
|
||||
installations.
|
Loading…
Reference in New Issue
Block a user