ironicclient fails with token auth when ironic-api endpoint is using virtual hosts

Bug #1721599 reported by Pavlo Shchelokovskyy on 2017-10-05
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
python-ironicclient
Fix Released
High
Pavlo Shchelokovskyy

Bug Description

using fresh devstack master, ironicclient from master, with ironic-api deployed under apache.

when passing --ironic-url and --os-auth-token to 'ironic' command, it fails to access ironic API:

$ # show ironic endpoint
$ openstack --os-cloud devstack-admin catalog show baremetal -f value -c endpoints
RegionOne
  public: https://192.168.100.11/baremetal

$ # get a token
$ openstack --os-cloud devstack admin token issue -f value -c id
<TOKEN_REDACTED>

$ # issue ironicclient command
$ ironic --debug --insecure --os-auth-token "<TOKEN_REDACTED>" --ironic-url "https://192.168.100.11/baremetal" node-list
You are using the default API version of the 'ironic' command. This is currently API version 1.9. In the future, the default will be the latest API version understood by both A
PI and CLI. You can preserve the current behavior by passing the --ironic-api-version argument with the desired version or using the IRONIC_API_VERSION environment variable.
DEBUG (http:278) curl -i -X GET -H 'X-OpenStack-Ironic-API-Version: 1.9' -H 'X-Auth-Token: {SHA1}08db9386e257c279fbac247c4f72e0bf4937ce48' -H 'Content-Type: application/json' -
H 'Accept: application/json' -H 'User-Agent: python-ironicclient' -k --cert None --key None https://192.168.100.11/v1/nodes
DEBUG (connectionpool:824) Starting new HTTPS connection (1): 192.168.100.11
/usr/local/lib/python2.7/dist-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongl
y advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
DEBUG (connectionpool:396) https://192.168.100.11:443 "GET /v1/nodes HTTP/1.1" 404 286
DEBUG (http:292)
HTTP/1.1 404 Not Found
Date: Thu, 05 Oct 2017 16:55:28 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Length: 286
Content-Type: text/html; charset=iso-8859-1
Connection: close

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /v1/nodes was not found on this server.</p>
<hr>
<address>Apache/2.4.18 (Ubuntu) Server at 192.168.100.11 Port 80</address>
</body></html>

Not Found (HTTP 404)

Notice how ironicclient tries to access "https://<IP>/v1/nodes" instead of "https://<IP>/baremetal/v1/nodes"

This is happening due to the fact that when given token and endpoint, ironicclient is not using the SessionClient based on keystoneauth Adapter, but instead is using a legacy HTTPClient [0], where the endpoint and API path get joined thru urlparse.urljoin [1], which swallows the vhost in the endpoint.

In particular, this breaks ironic-inspector when ironic API is deployed under web server + WSGI (e.g. Apache) since inspector might use an incoming token to create ironicclient [2] exactly in the same manner as described above.

[0] http://git.openstack.org/cgit/openstack/python-ironicclient/tree/ironicclient/common/http.py#n629
[1] http://git.openstack.org/cgit/openstack/python-ironicclient/tree/ironicclient/common/http.py#n295
[2] http://git.openstack.org/cgit/openstack/ironic-inspector/tree/ironic_inspector/common/ironic.py#n137

tags: added: backport-potential
Changed in python-ironicclient:
assignee: nobody → Pavlo Shchelokovskyy (pshchelo)

Fix proposed to branch: master
Review: https://review.openstack.org/509851

Changed in python-ironicclient:
status: New → In Progress
Ruby Loo (rloo) on 2017-10-05
Changed in python-ironicclient:
importance: Undecided → High

Reviewed: https://review.openstack.org/509851
Committed: https://git.openstack.org/cgit/openstack/python-ironicclient/commit/?id=61c5eba5f2a0e6fc642fee47351b92e17e03cbd6
Submitter: Jenkins
Branch: master

commit 61c5eba5f2a0e6fc642fee47351b92e17e03cbd6
Author: Pavlo Shchelokovskyy <email address hidden>
Date: Thu Oct 5 16:48:45 2017 +0000

    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

Changed in python-ironicclient:
status: In Progress → Fix Released

This issue was fixed in the openstack/python-ironicclient 2.0.0 release.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers