CFN signal URLs don't work when trusts is enabled

Bug #1227901 reported by Thomas Herve
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Heat
Fix Released
High
Steven Hardy

Bug Description

We're testing signal URLs using HARestarter with trusts enabled. When hitting the URL, we're getting the following traceback in the engine:

[-] Exception during message handling
Traceback (most recent call last):
  File "/opt/stack/heat/heat/openstack/common/rpc/amqp.py", line 461, in _process_data
    **args)
  File "/opt/stack/heat/heat/openstack/common/rpc/dispatcher.py", line 172, in dispatch
    result = getattr(proxyobj, method)(ctxt, **kwargs)
  File "/opt/stack/heat/heat/engine/service.py", line 56, in wrapped
    return func(self, ctx, *args, **kwargs)
  File "/opt/stack/heat/heat/engine/service.py", line 550, in resource_signal
    stack_context = self._load_user_creds(s.user_creds_id)
  File "/opt/stack/heat/heat/engine/service.py", line 640, in _load_user_creds
    kc = hkc.KeystoneClient(stored_context)
  File "/opt/stack/heat/heat/common/heat_keystoneclient.py", line 53, in __init__
    self.client_v3 = self._v3_client_init()
  File "/opt/stack/heat/heat/common/heat_keystoneclient.py", line 144, in _v3_client_init
    if not client_v3.authenticate():
  File "/opt/stack/python-keystoneclient/keystoneclient/httpclient.py", line 467, in authenticate
    resp, body = self.get_raw_token_from_identity_service(**kwargs)
  File "/opt/stack/python-keystoneclient/keystoneclient/v3/client.py", line 159, in get_raw_token_from_identity_service
    trust_id=trust_id)
  File "/opt/stack/python-keystoneclient/keystoneclient/v3/client.py", line 245, in _do_auth
    resp, body = self.request(url, 'POST', body=body, headers=headers)
  File "/opt/stack/python-keystoneclient/keystoneclient/httpclient.py", line 609, in request
    **request_kwargs)
  File "/opt/stack/python-keystoneclient/keystoneclient/httpclient.py", line 123, in request
    raise exceptions.from_response(resp, method, url)
Unauthorized: Invalid username or password (HTTP 401)

The keystone client is created with:

{'username': 'heat', 'password': '<PASSWORD>', 'project_name': 'service', 'auth_url': 'http://<IP>:5000/v3', 'trust_id': '<TRUST_ID>'}

After investigation, it seems that we're making 2 authenticate calls: the first one retrieves a token with the user/password and the trust, impersonating the user. The second one is requesting a new token, which is forbidden by keystone (token obtained via trusts can't request other tokens).

If we prevent the second authenticate calls, the v2_client created just after fails in a similar fashion.

Revision history for this message
Thomas Herve (therve) wrote :

We've been hacking around this a bit, and it seems that the best solution would be *not* call authenticate unconditionally. We need to call it when we only have a trust, but it shouldn't be necessary otherwise. We can get the catalog and other authentication info from the keystone middleware. The "auth_ref" attribute then provide enough information to do what we need without talking to keystone again.

We may need to change KeystoneClient.create_trust_context to use auth_ref attributes instead of poking into the dictionnary (which is different between v2 and v3).

Changed in heat:
status: New → Triaged
Steven Hardy (shardy)
Changed in heat:
assignee: nobody → Steven Hardy (shardy)
Steven Hardy (shardy)
Changed in heat:
status: Triaged → In Progress
Revision history for this message
Steven Hardy (shardy) wrote :

Ok, so the fix seems to be:

1. Don't call authenticate again for v3 clients
2. Add support for re-scoping a v2 token to a trust (which will require an explicit authenticate

See https://bugs.launchpad.net/python-keystoneclient/+bug/1231483 which will enable (2)

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to heat (master)

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

Revision history for this message
OpenStack Infra (hudson-openstack) wrote :

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

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to heat (master)

Reviewed: https://review.openstack.org/48627
Committed: http://github.com/openstack/heat/commit/01d6ce3858606f5f7896c133681bde4ba9d88bd3
Submitter: Jenkins
Branch: master

commit 01d6ce3858606f5f7896c133681bde4ba9d88bd3
Author: Steven Hardy <email address hidden>
Date: Fri Sep 27 11:11:59 2013 +0100

    Store tenant with trust details in user_creds

    Currently we don't store tenant name/ID to user_creds when a trust_id
    is found in the context. However as mentioned in bug #1231483 keystone
    currently requires the tenant_id when re-scoping a token to a trust via
    the v2 tokens API.

    Change-Id: I5bd9cb914a8c9365ed30ece8e0a61ba1e0a3c4bc
    Partial-Bug: #1227901

Revision history for this message
Faramir (faramir) wrote : AUTO: Hai Liang Wang is on vacation from 09-29 to 10-08 (returning 10/09/2013)

I am out of the office until 10/09/2013.

Conact me by phone for anything urgency.
Phone Number - 15801213126 . thanks !

Note: This is an automated response to your message "[Bug 1227901] Fix
merged to heat (master)" sent on 09/28/2013 17:11:00.

This is the only notification you will receive while this person is away.

Revision history for this message
Steven Hardy (shardy) wrote :

Hmm, OK so it's currently not looking like the keystone folks are open to quickly accepting my keystoneclient patch:

https://review.openstack.org/#/c/48462/

So I'm not sure what we can do for RC1 :(

I have an update coming for https://review.openstack.org/#/c/48628/, which fixes the review comments and the test issues observed by therve, but unless we can get the keystoneclient patch in, I guess we'll have to defer this bug to Icehouse.

I guess we really only have two options:

1. revert bp/heat-trusts patches since the feature is broken
2. Leave things in their current state for Havana, then fix in Icehouse and backport to stable/havana

I think (2) is the best option, we'll have to document that trusts support is broken in the Havana release notes.

Revision history for this message
Thierry Carrez (ttx) wrote :

I think we can get the patch in keystoneclient before RC1 -- my understanding is that Adam would like to see tempest tests that would exercise this functionality, if it is to be exposed through the client... Ideally those tests would be contributed before the patch is accepted into keystoneclient, but if RC1 hinges on that I wouldn't block on it.

Revision history for this message
Steve Baker (steve-stevebaker) wrote :

What is the consequence of committing the heat change without the keystoneclient change?

If trusts currently has issues anyway, then we can still release rc1 and recommend users not enable trusts until the keystoneclient change is out.

Revision history for this message
Steven Hardy (shardy) wrote :

> What is the consequence of committing the heat change without the keystoneclient change?

Any attempt to enable trusts would make the engine crash, as we'd be attempting to use a non-existing argument to the v2 keystonclient authenticate().

>If trusts currently has issues anyway, then we can still release rc1 and recommend users not enable trusts until the keystoneclient change is out.

It looks like we'll have to release rc1 anyway, and recommend users not enable trusts until this bug is fixed (which will include a bump to a keystoneclient release containing the v2 authenticate() change mentioned above, probably)

I'll post an updated patch tomorrow, and we can make a final call then, but IMO we shouldn't block RC1 on this, we'll just have to handle it via a stable-branch backport after the fix is proven and the keystoneclient change is available.

Revision history for this message
Thierry Carrez (ttx) wrote :

I'd suggest you push the patch in RC1, but handle the case where a non-compliant keystoneclient is used a bit more gracefully than by crashing.

That way the RC1 already contains the fix and the only thing we need to push post-RC1 is a new keystoneclient.

Revision history for this message
Steven Hardy (shardy) wrote :

Ok, so looking again at the code, by "engine crash" comment was inaccurate:

https://review.openstack.org/#/c/48628/3/heat/common/heat_keystoneclient.py

What will happen (if trusts are enabled, which they aren't by default), is simply that we'll create the trust OK, but fail with a TypeError when we attempt to consume it (when a periodic event happens).

I agree this is probably no worse than the current behaviour, we'll get an engine traceback in either case, but the engine will remain operational.

I'm hoping this will be temporary, so I won't put a try/catch around the v2 authenticate(), we'll just document that trusts won't work until the keystoneclient patch is merged.

I have had independent test feedback from therve which indicates his previous issues are resolved with the latest version of my patch, so hopefully we can go ahead and push it for RC1.

Changed in heat:
assignee: Steven Hardy (shardy) → Bartosz Górski (bartosz-gorski)
Changed in heat:
assignee: Bartosz Górski (bartosz-gorski) → Steven Hardy (shardy)
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to heat (master)

Reviewed: https://review.openstack.org/48628
Committed: http://github.com/openstack/heat/commit/288ae018ebf511b9fc5e6a2559feb8bed2821be2
Submitter: Jenkins
Branch: master

commit 288ae018ebf511b9fc5e6a2559feb8bed2821be2
Author: Steven Hardy <email address hidden>
Date: Fri Sep 27 08:11:03 2013 +0100

    heat_keystoneclient: Fix consuming trusts via v2 API

    Contrary to my understanding when I first wrote this code, it is
    possible to consume trusts (ie get a trust scoped token) via the
    v2 keystone API. So this patch reworks the heat_keystoneclient
    so we:
    - Consume trusts via the v2 client (so we can access the ec2tokens
      extension which is v2-only)
    - Only create a v3 client when required (when creating or deleting
      a trust), so we minimise the requests to keystone.
    - Similarly it's only necessary to create the v2 client when creating
      the client object if we need to consume a trust
    - When a trust is found in the context, we always consume it
    - Don't modify the request context, as this has undesired side-effects
      if the context is subsequently used to perform actions which require
      obtaining a keystone token, instead create a context containing a
      trust_id and trustor_user_id when the stack is stored.

    Note this change depends on this patch to python-keystoneclient:
    https://review.openstack.org/#/c/48462/, so consuming trusts won't
    work unless a version of keystoneclient including this change is
    used.

    Change-Id: I61b380bc63d606c128ce029f1960c6812a3324e3
    Closes-Bug: #1227901

Changed in heat:
status: In Progress → Fix Committed
Thierry Carrez (ttx)
Changed in heat:
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in heat:
milestone: havana-rc1 → 2013.2
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.