[openstack-dev] [nova] path forward on making project_id optional in API URLs
Sean Dague
sean at dague.net
Wed Jan 13 14:06:44 UTC 2016
There is a snag at the moment in making project_id optional in API URLs
because of how python routes modules works.
When we call mapper.resource(...) it's creating a series of
mapper.connect(...) calls to setup routes. This just adds items to a
dictionary. When we later use the mapper to match a route it builds a
master regex out of everything in that dictionary, which it applies to
the inbound url. (Note: this is an extremely large regex in the case of
Nova).
Today our use of the mapper captures the {project_id} here -
https://github.com/openstack/nova/blob/21f7dabd01e5b4d771de4b88114878d93ffa9b18/nova/api/openstack/__init__.py#L200
The issue is that by default mapper captured variables are set to the
regex ([^\/]+) (i.e. match anything that's not a slash).
This makes for an ambiguous route when we consider the following url:
/v2.1/extensions/os-agents
Because it could match extensions/{name} or it could match
{project_id}/os-agents. There are about a dozen extensions which create
a top level resource.
Because this regex is built from a dictionary, hash seed matters, and it
is not stable which will get precedence.
** Proposal for restriction of project_id **
There is a wrinkle here that, strictly speaking, project_id has no
schema in OpenStack.
If you are using upstream Keystone, your project_id is going to be a 32
character hex uuid. Unless you hack keystone really hard it's not
possible to get another answer.
RAX doesn't use Keystone, their project_id is an int.
I'd like to propose for Nova we restrict project_id in the URL to
[0-9a-f]+, which is any valid hex string. Ints are a subset of this so
RAX will be fine. This will be enough to prevent the collision in the
case of extensions. I tried to float a question out to the operators
list about this, but I actually think this is sufficiently obscure
internals that most people aren't even aware that project_id isn't
always a uuid.
This collision only happens when both sets of routes (with and without
project_id) are being run. That's what we're going to do for a while for
client compatibility. Either route set on it's own is fine.
This was caught by one stray functional test and took a while to figure
out what was going on. But if we come up with a resolution here we can
move forward on this work (which is part of what's needed in revising
the service catalog).
-Sean
--
Sean Dague
http://dague.net
More information about the OpenStack-dev
mailing list