Ask Your Question
0

EndpointNotFound errors with Keystone v3 Python API [closed]

asked 2015-03-17 10:42:04 -0600

jproulx gravatar image

updated 2015-03-18 13:49:35 -0600

Using Juno...

I'm an operator trying to replace the crufty Essex era bash scripts we use for account registration with something saner. Using keystone v3 python api seems the right thing.

Keystone is serving v2 and v3. My 'identity' endoint points to v2 but Horizion uses v3 and I can access v3 vi the 'openstack' cli by specifying the right OS_AUTH_URL and OS_IDENTITY_API_VERSION=3

But...I cannot get my python script to do the right thing, it keeps failing with:

keystoneclient.openstack.common.apiclient.exceptions.EndpointNotFound

If I switch my identity enpoint to be explicity /v3 then everything works but my understanding is that leaving it a /v2.0 for the majority version 2 clients should work with newer clients being able to do discovery.

I'm following the example at http://docs.openstack.org/developer/p...

My specific case uses

from keystoneclient.auth.identity import v3
from keystoneclient import session
from keystoneclient.v3 import client

from os import environ
from subprocess import Popen, PIPE, call, check_output, check_call

#interactive-fu
import rlcompleter, readline
readline.parse_and_bind('tab: complete')

debug=True
os_auth_file='/etc/openrcV3' #where to find authentication bits

def source(script, update=True, clean=True):
    """
    Source variables from a shell script
    import them in the environment (if update==True)
    and report only the script variables (if clean==True)
    """

    global environ
    if clean:
        environ_back = dict(environ)
        environ.clear()

        pipe = Popen(". %s; env" % script, stdout=PIPE, shell=True)
        data = pipe.communicate()[0]

        env = dict((line.split("=", 1) for line in data.splitlines()))

    if clean:
        # remove unwanted minimal vars
        env.pop('LINES', None)
        env.pop('COLUMNS', None)
        environ = dict(environ_back)

    if update:
        environ.update(env)

    return env 

os_auth = source(os_auth_file)


auth = v3.Password(auth_url=os_auth['OS_AUTH_URL'],
                   username=os_auth['OS_USERNAME'],
                   password=os_auth['OS_PASSWORD'],
                   project_domain_name='default',user_domain_name='default',
                   project_name=os_auth['OS_TENANT_NAME'])
sess = session.Session(auth=auth) 

keystone = client.Client(version='v3',session=sess)
users=keystone.users.list()
print users

The addion of version='v3' to the 'client.Client' call is not in the docs but was suggested by Adma Young on IRC and got the code to 'work for him' but oddly makes no change for me.

That 'source' call parses the same shell script fragment I source to use v3 with python-openstackclient cli. My test case is:

keystone.users.list()

I expect a list of users, I get EndpointNotFound.

Trying to force my way through I created an 'identityv3' service and endpoint then specified

endpoint_filter={'service_type': 'identityv3',
                 'interface': 'public',
                 'region_name': 'RegionOne'}

in the session.Session call, which (mis)reading keystoneclient/session.py and http://docs.openstack.org/developer/p... I though t I could put there, but apparently can't ( unexpected keyword argument).

Grasping at straws I moved the endpoint filter to the client.Client call and did not get and unexpected argument error but did still get the EndpointNotFound.

If I make a more direct call (after including the above) I can get a user list...

>>> resp = sess.get('/users', endpoint_filter={'service_type': 'identityv3',
...                  'interface': 'public',
...                  'region_name': 'RegionOne'})

now resp.content has a list of ... (more)

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by jproulx
close date 2015-03-19 09:07:55.016570

4 answers

Sort by ยป oldest newest most voted
0

answered 2015-03-18 14:27:43 -0600

jproulx gravatar image

It seems this is an issue with the version of python-keystoneclient distributed by Ubuntu with 14.04 cloudarchive:juno (version 1:0.10.1-0ubuntu1~cloud0) I get the above described broken behaviour.

Using a pip installed python-keystoneclient (Version: 1.2.0) the above code works as described in the documentation.

edit flag offensive delete link more

Comments

Or not quite....

using the newer python-keystoneclient keystone.users.list() does return a user list but is still using the /v2.0 API endpoint which works with users but not with projects apparently. from server logs:

"GET /v2.0/users HTTP/1.1" 200 
"GET /v2.0/projects HTTP/1.1" 404
jproulx gravatar imagejproulx ( 2015-03-18 15:44:03 -0600 )edit

this secondary problem was due to an old and broken Horizon redirect which was outside it's VirtualHost definition and redirecting '/' on all vhosts to '/horizon' not sure if this was an old packaging fault or an old puppet fault but also verified latest versions do not have this redirect issue.

jproulx gravatar imagejproulx ( 2015-03-19 09:06:27 -0600 )edit
1

answered 2015-03-18 16:03:47 -0600

I was unable to reproduce on my machine. Turns out it was due to an out of date client. Updated client seems to work correctly.

edit flag offensive delete link more
0

answered 2015-03-17 12:32:09 -0600

updated 2015-03-17 12:40:44 -0600

You don't need to create any v3 endpoints. You can use either v3 plugin or generic plugin. If you use generic plugin for auth, then you don't need to specifcy the identity version. In your code, just check what is the value of "auth_url", that determines everything

from keystoneclient.auth.identity import v3
from keystoneclient import session
from keystoneclient.v3 import client

auth = v3.Password(auth_url="http://localhost:35357/v3",
                   username="admin",
                   password="password",
                   project_domain_name='default',user_domain_name='default',
                   project_name="admin")
sess = session.Session(auth=auth)
keystone = client.Client(session=sess)

print keystone.users.list()

print "Using GenericPassword Plugin".center(60)
from keystoneclient.auth.identity.generic.password import Password as GenericPassword

auth = GenericPassword(auth_url="http://localhost:35357",
                   username="admin",
                   password="password",
                   project_domain_name='default',user_domain_name='default',
                   project_name="admin")
sess = session.Session(auth=auth)
keystone = client.Client(session=sess)

print keystone.users.list()

edit flag offensive delete link more

Comments

I would have though auth_url would determine everything but it does not.

If the first half of your example differs from mine, I'm not seeing it (I have the same imoprt I just trimmed them). I did verify that my os_auth['OS_AUTH_URL'] is being parsed into the correct value, which works with the CLI

jproulx gravatar imagejproulx ( 2015-03-17 13:29:42 -0600 )edit

Can you post your environment settings? Are you using openstack client from cli?

Haneef Ali gravatar imageHaneef Ali ( 2015-03-17 13:52:48 -0600 )edit

openstack client from cli works

sourcing same values in the above code does not.

I don't want to post the whole environment, but if you have a specific question I'll answer. You may have missed the edit above, but I can get a user list with those setting and endpoints_fiter but not how I want

jproulx gravatar imagejproulx ( 2015-03-17 14:03:25 -0600 )edit

I'm intreseted in the value of OS_AUTH_URL. Also make sure you have identiy endpoint with "type": "identity. It doesn't have to be v3. BTW when you do list.users() does it list users from all the domains.

Haneef Ali gravatar imageHaneef Ali ( 2015-03-17 14:19:04 -0600 )edit

That might be it? I set service_type "identityv3" out of fear my (majority) v2 clients would get confused if I called it just "identity". Using endpoint_filter parameter to sess.get I can get this, but can't figure how to push it in so all users of the session default to that.

jproulx gravatar imagejproulx ( 2015-03-17 14:46:50 -0600 )edit
0

answered 2015-03-17 10:49:22 -0600

Praveen N gravatar image

Hi, Verify once with command keystone endpoint-list.If not found then you need to create a endpoint.

edit flag offensive delete link more

Comments

resp = sess.get('/users', endpoint_filter={'service_type': 'identityv3', ... 'interface': 'public', ... 'region_name': 'RegionOne'})

resp.content now contains user list, so endpoint is there

jproulx gravatar imagejproulx ( 2015-03-17 13:32:39 -0600 )edit

Get to know Ask OpenStack

Resources for moderators

Question Tools

1 follower

Stats

Asked: 2015-03-17 10:42:04 -0600

Seen: 1,343 times

Last updated: Mar 18 '15