diff options
author | Pavlo Shchelokovskyy <shchelokovskyy@gmail.com> | 2017-10-05 16:48:45 +0000 |
---|---|---|
committer | Pavlo Shchelokovskyy <shchelokovskyy@gmail.com> | 2017-10-06 07:59:02 +0000 |
commit | 61c5eba5f2a0e6fc642fee47351b92e17e03cbd6 (patch) | |
tree | 1c4ba210a3c4c6e976294dd15d30ecfeece7ce19 | |
parent | 60e0ea26fb6dc97724240b0e87e7bf06fc10c33c (diff) | |
download | python-ironicclient-61c5eba5f2a0e6fc642fee47351b92e17e03cbd6.tar.gz |
Do not use urljoin in base http client
this fails when ironic API endpoint is not in the form
"host:port", but "host/vhost" instead
(as when ironic-api is deployed behind Apache),
since the 'vhost' gets swallowed by 'urljoin'.
This leads to a failure when using ironicclient with token and
endpoint passed in, otherwise a SessionClient is used that does
not have this problem.
Simply concat those url parts together (ensuring there is at least a
single '/' between them).
Change-Id: I583e0f9bdc81a655861c6ff508782173021428f0
Closes-Bug: #1721599
-rw-r--r-- | ironicclient/common/http.py | 9 | ||||
-rw-r--r-- | ironicclient/tests/unit/common/test_http.py | 5 | ||||
-rw-r--r-- | releasenotes/notes/fix-token-with-vhosts-5d0a6d53e807fa5e.yaml | 7 |
3 files changed, 16 insertions, 5 deletions
diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py index d4b60bb..3a425f8 100644 --- a/ironicclient/common/http.py +++ b/ironicclient/common/http.py @@ -64,7 +64,7 @@ SUPPORTED_ENDPOINT_SCHEME = ('http', 'https') def _trim_endpoint_api_version(url): """Trim API version and trailing slash from endpoint.""" - return url.rstrip('/').rstrip(API_VERSION) + return url.rstrip('/').rstrip(API_VERSION).rstrip('/') def _extract_error_json(body): @@ -274,7 +274,7 @@ class HTTPClient(VersionNegotiationMixin): body = strutils.mask_password(kwargs['body']) curl.append('-d \'%s\'' % body) - curl.append(urlparse.urljoin(self.endpoint_trimmed, url)) + curl.append(self._make_connection_url(url)) LOG.debug(' '.join(curl)) @staticmethod @@ -292,7 +292,10 @@ class HTTPClient(VersionNegotiationMixin): LOG.debug('\n'.join(dump)) def _make_connection_url(self, url): - return urlparse.urljoin(self.endpoint_trimmed, url) + # NOTE(pas-ha) we already stripped trailing / from endpoint_trimmed + if not url.startswith('/'): + url = '/' + url + return self.endpoint_trimmed + url def _parse_version_headers(self, resp): return self._generic_parse_version_headers(resp.headers.get) diff --git a/ironicclient/tests/unit/common/test_http.py b/ironicclient/tests/unit/common/test_http.py index 1a11a74..7d45759 100644 --- a/ironicclient/tests/unit/common/test_http.py +++ b/ironicclient/tests/unit/common/test_http.py @@ -382,9 +382,10 @@ class HttpClientTest(utils.BaseTestCase): client = http.HTTPClient('http://localhost/') kwargs = {'headers': {'foo-header': 'bar-header'}, 'body': '{"password": "foo"}'} - client.log_curl_request('foo', 'http://127.0.0.1', kwargs) + client.log_curl_request('foo', '/v1/nodes', kwargs) expected_log = ("curl -i -X foo -H 'foo-header: bar-header' " - "-d '{\"password\": \"***\"}' http://127.0.0.1") + "-d '{\"password\": \"***\"}' " + "http://localhost/v1/nodes") mock_log.assert_called_once_with(expected_log) @mock.patch.object(http.LOG, 'debug', autospec=True) diff --git a/releasenotes/notes/fix-token-with-vhosts-5d0a6d53e807fa5e.yaml b/releasenotes/notes/fix-token-with-vhosts-5d0a6d53e807fa5e.yaml new file mode 100644 index 0000000..9c0e2bd --- /dev/null +++ b/releasenotes/notes/fix-token-with-vhosts-5d0a6d53e807fa5e.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixed a bug where ironicclient instantiated with keystone token and + ironic API endpoint could not access ironic API that has a virtual host + in its endpoint (like "http://hostname/baremetal"). + For more details see `bug 1721599 <https://launchpad.net/bugs/1721599>`_. |