Fix cropping the endpoint url
`nova version-list` crops the endpoint url to exclude API version and project-id(for microversions < 2.18). It is ok, but the code was designed before Nova-API moved under uwsgi, which changed the endpoint url format. The latest endpoint url contains the hostname and port which can be one for several services and it is a wrong case to cut the whole path from the endpoint. Closes-Bug: #1702194 Change-Id: Icba858b496855e2ffd71b35168e8057b28236119
This commit is contained in:
@@ -100,7 +100,7 @@ class SimpleReadOnlyNovaClientTest(base.ClientTestBase):
|
|||||||
self.nova('migration-list', flags='--debug')
|
self.nova('migration-list', flags='--debug')
|
||||||
|
|
||||||
def test_version_list(self):
|
def test_version_list(self):
|
||||||
self.nova('version-list')
|
self.nova('version-list', flags='--debug')
|
||||||
|
|
||||||
def test_quota_defaults(self):
|
def test_quota_defaults(self):
|
||||||
self.nova('quota-defaults')
|
self.nova('quota-defaults')
|
||||||
|
@@ -30,7 +30,7 @@ class VersionsTest(utils.TestCase):
|
|||||||
def test_list_services(self):
|
def test_list_services(self):
|
||||||
vl = self.cs.versions.list()
|
vl = self.cs.versions.list()
|
||||||
self.assert_request_id(vl, fakes.FAKE_REQUEST_ID_LIST)
|
self.assert_request_id(vl, fakes.FAKE_REQUEST_ID_LIST)
|
||||||
self.cs.assert_called('GET', 'http://nova-api:8774/')
|
self.cs.assert_called('GET', 'http://nova-api:8774')
|
||||||
|
|
||||||
def test_get_current(self):
|
def test_get_current(self):
|
||||||
self.cs.callback = []
|
self.cs.callback = []
|
||||||
@@ -75,3 +75,28 @@ class VersionsTest(utils.TestCase):
|
|||||||
|
|
||||||
# check that the full request works as expected
|
# check that the full request works as expected
|
||||||
cs_2.assert_called('GET', expected_endpoint)
|
cs_2.assert_called('GET', expected_endpoint)
|
||||||
|
|
||||||
|
def test_list_versions(self):
|
||||||
|
fapi = mock.Mock()
|
||||||
|
version_mgr = versions.VersionManager(fapi)
|
||||||
|
version_mgr._list = mock.Mock()
|
||||||
|
data = [
|
||||||
|
("https://example.com:777/v2", "https://example.com:777"),
|
||||||
|
("https://example.com/v2", "https://example.com"),
|
||||||
|
("http://example.com/compute/v2", "http://example.com/compute"),
|
||||||
|
("https://example.com/v2/prrrooojeect-uuid",
|
||||||
|
"https://example.com"),
|
||||||
|
("https://example.com:777/v2.1", "https://example.com:777"),
|
||||||
|
("https://example.com/v2.1", "https://example.com"),
|
||||||
|
("http://example.com/compute/v2.1", "http://example.com/compute"),
|
||||||
|
("https://example.com/v2.1/prrrooojeect-uuid",
|
||||||
|
"https://example.com"),
|
||||||
|
("http://example.com/compute", "http://example.com/compute"),
|
||||||
|
("http://compute.example.com", "http://compute.example.com"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for endpoint, expected in data:
|
||||||
|
version_mgr._list.reset_mock()
|
||||||
|
fapi.client.get_endpoint.return_value = endpoint
|
||||||
|
version_mgr.list()
|
||||||
|
version_mgr._list.assert_called_once_with(expected, "versions")
|
||||||
|
@@ -78,11 +78,25 @@ class VersionManager(base.ManagerWithFind):
|
|||||||
def list(self):
|
def list(self):
|
||||||
"""List all versions."""
|
"""List all versions."""
|
||||||
|
|
||||||
# NOTE: "list versions" API needs to be accessed without base
|
|
||||||
# URI (like "v2/{project-id}"), so here should be a scheme("http",
|
|
||||||
# etc.) and a hostname.
|
|
||||||
endpoint = self.api.client.get_endpoint()
|
endpoint = self.api.client.get_endpoint()
|
||||||
url = urllib.parse.urlparse(endpoint)
|
url = urllib.parse.urlparse(endpoint)
|
||||||
version_url = '%s://%s/' % (url.scheme, url.netloc)
|
# NOTE(andreykurilin): endpoint URL has at least 3 formats:
|
||||||
|
# 1. the classic (legacy) endpoint:
|
||||||
|
# http://{host}:{optional_port}/v{2 or 2.1}/{project-id}
|
||||||
|
# 2. starting from microversion 2.18 project-id is not included:
|
||||||
|
# http://{host}:{optional_port}/v{2 or 2.1}
|
||||||
|
# 3. under wsgi:
|
||||||
|
# http://{host}:{optional_port}/compute/v{2 or 2.1}
|
||||||
|
if (url.path.endswith("v2") or "/v2/" in url.path or
|
||||||
|
url.path.endswith("v2.1") or "/v2.1/" in url.path):
|
||||||
|
# this way should handle all 3 possible formats
|
||||||
|
path = url.path[:url.path.rfind("/v2")]
|
||||||
|
version_url = '%s://%s%s' % (url.scheme, url.netloc, path)
|
||||||
|
else:
|
||||||
|
# NOTE(andreykurilin): probably, it is one of the next cases:
|
||||||
|
# * https://compute.example.com/
|
||||||
|
# * https://example.com/compute
|
||||||
|
# leave as is without cropping.
|
||||||
|
version_url = endpoint
|
||||||
|
|
||||||
return self._list(version_url, "versions")
|
return self._list(version_url, "versions")
|
||||||
|
Reference in New Issue
Block a user