Merge pull request #26 from 4P/moredoc
copy over a bunch of docs from keystone, will probably have to be proofread a bit after
|
@ -0,0 +1,442 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
|
||||
===============================
|
||||
Service API Examples Using Curl
|
||||
===============================
|
||||
|
||||
The service API is defined to be a subset of the Admin API and, by
|
||||
default, runs on port 5000.
|
||||
|
||||
GET /
|
||||
=====
|
||||
|
||||
This call is identical to that documented for the Admin API, except
|
||||
that it uses port 5000, instead of port 35357, by default::
|
||||
|
||||
$ curl http://0.0.0.0:5000
|
||||
|
||||
or::
|
||||
|
||||
$ curl http://0.0.0.0:5000/v2.0/
|
||||
|
||||
See the `Admin API Examples Using Curl`_ for more info.
|
||||
|
||||
.. _`Admin API Examples Using Curl`: adminAPI_curl_examples.html
|
||||
|
||||
GET /extensions
|
||||
===============
|
||||
|
||||
This call is identical to that documented for the Admin API.
|
||||
|
||||
POST /tokens
|
||||
============
|
||||
|
||||
This call is identical to that documented for the Admin API.
|
||||
|
||||
GET /tenants
|
||||
============
|
||||
|
||||
List all of the tenants your token can access::
|
||||
|
||||
$ curl -H "X-Auth-Token:887665443383838" http://localhost:5000/v2.0/tenants
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"tenants_links": [],
|
||||
"tenants": [
|
||||
{
|
||||
"enabled": true,
|
||||
"description": "None",
|
||||
"name": "customer-x",
|
||||
"id": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
=============================
|
||||
Admin API Examples Using Curl
|
||||
=============================
|
||||
|
||||
These examples assume a default port value of 35357, and depend on the
|
||||
``sampledata`` bundled with keystone.
|
||||
|
||||
GET /
|
||||
=====
|
||||
|
||||
Disover API version information, links to documentation (PDF, HTML, WADL),
|
||||
and supported media types::
|
||||
|
||||
$ curl http://0.0.0.0:35357
|
||||
|
||||
or::
|
||||
|
||||
$ curl http://0.0.0.0:35357/v2.0/
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"version":{
|
||||
"id":"v2.0",
|
||||
"status":"beta",
|
||||
"updated":"2011-11-19T00:00:00Z",
|
||||
"links":[
|
||||
{
|
||||
"rel":"self",
|
||||
"href":"http://127.0.0.1:35357/v2.0/"
|
||||
},
|
||||
{
|
||||
"rel":"describedby",
|
||||
"type":"text/html",
|
||||
"href":"http://docs.openstack.org/api/openstack-identity-service/2.0/content/"
|
||||
},
|
||||
{
|
||||
"rel":"describedby",
|
||||
"type":"application/pdf",
|
||||
"href":"http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf"
|
||||
},
|
||||
{
|
||||
"rel":"describedby",
|
||||
"type":"application/vnd.sun.wadl+xml",
|
||||
"href":"http://127.0.0.1:35357/v2.0/identity-admin.wadl"
|
||||
}
|
||||
],
|
||||
"media-types":[
|
||||
{
|
||||
"base":"application/xml",
|
||||
"type":"application/vnd.openstack.identity-v2.0+xml"
|
||||
},
|
||||
{
|
||||
"base":"application/json",
|
||||
"type":"application/vnd.openstack.identity-v2.0+json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
GET /extensions
|
||||
===============
|
||||
|
||||
Discover the API extensions enabled at the endpoint::
|
||||
|
||||
$ curl http://0.0.0.0:35357/extensions
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"extensions":{
|
||||
"values":[]
|
||||
}
|
||||
}
|
||||
|
||||
POST /tokens
|
||||
============
|
||||
|
||||
Authenticate by exchanging credentials for an access token::
|
||||
|
||||
$ curl -d '{"auth":{"passwordCredentials":{"username": "joeuser", "password": "secrete"}}}' -H "Content-type: application/json" http://localhost:35357/v2.0/tokens
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"access":{
|
||||
"token":{
|
||||
"expires":"2012-02-05T00:00:00",
|
||||
"id":"887665443383838",
|
||||
"tenant":{
|
||||
"id":"1",
|
||||
"name":"customer-x"
|
||||
}
|
||||
},
|
||||
"serviceCatalog":[
|
||||
{
|
||||
"endpoints":[
|
||||
{
|
||||
"adminURL":"http://swift.admin-nets.local:8080/",
|
||||
"region":"RegionOne",
|
||||
"internalURL":"http://127.0.0.1:8080/v1/AUTH_1",
|
||||
"publicURL":"http://swift.publicinternets.com/v1/AUTH_1"
|
||||
}
|
||||
],
|
||||
"type":"object-store",
|
||||
"name":"swift"
|
||||
},
|
||||
{
|
||||
"endpoints":[
|
||||
{
|
||||
"adminURL":"http://cdn.admin-nets.local/v1.1/1",
|
||||
"region":"RegionOne",
|
||||
"internalURL":"http://127.0.0.1:7777/v1.1/1",
|
||||
"publicURL":"http://cdn.publicinternets.com/v1.1/1"
|
||||
}
|
||||
],
|
||||
"type":"object-store",
|
||||
"name":"cdn"
|
||||
}
|
||||
],
|
||||
"user":{
|
||||
"id":"1",
|
||||
"roles":[
|
||||
{
|
||||
"tenantId":"1",
|
||||
"id":"3",
|
||||
"name":"Member"
|
||||
}
|
||||
],
|
||||
"name":"joeuser"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
Take note of the value ['access']['token']['id'] value produced here (``887665443383838``, above), as you can use it in the calls below.
|
||||
|
||||
GET /tokens/{token_id}
|
||||
======================
|
||||
|
||||
.. note::
|
||||
|
||||
This call refers to a token known to be valid, ``887665443383838`` in this case.
|
||||
|
||||
Validate a token::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tokens/887665443383838
|
||||
|
||||
If the token is valid, returns::
|
||||
|
||||
{
|
||||
"access":{
|
||||
"token":{
|
||||
"expires":"2012-02-05T00:00:00",
|
||||
"id":"887665443383838",
|
||||
"tenant":{
|
||||
"id":"1",
|
||||
"name":"customer-x"
|
||||
}
|
||||
},
|
||||
"user":{
|
||||
"name":"joeuser",
|
||||
"tenantName":"customer-x",
|
||||
"id":"1",
|
||||
"roles":[
|
||||
{
|
||||
"serviceId":"1",
|
||||
"id":"3",
|
||||
"name":"Member"
|
||||
}
|
||||
],
|
||||
"tenantId":"1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HEAD /tokens/{token_id}
|
||||
=======================
|
||||
|
||||
This is a high-performance variant of the GET call documented above, which
|
||||
by definition, returns no response body::
|
||||
|
||||
$ curl -I -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tokens/887665443383838
|
||||
|
||||
... which returns ``200``, indicating the token is valid::
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 0
|
||||
Content-Type: None
|
||||
Date: Tue, 08 Nov 2011 23:07:44 GMT
|
||||
|
||||
GET /tokens/{token_id}/endpoints
|
||||
================================
|
||||
|
||||
List all endpoints for a token::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tokens/887665443383838/endpoints
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"endpoints_links": [
|
||||
{
|
||||
"href": "http://127.0.0.1:35357/tokens/887665443383838/endpoints?'marker=5&limit=10'",
|
||||
"rel": "next"
|
||||
}
|
||||
],
|
||||
"endpoints": [
|
||||
{
|
||||
"internalURL": "http://127.0.0.1:8080/v1/AUTH_1",
|
||||
"name": "swift",
|
||||
"adminURL": "http://swift.admin-nets.local:8080/",
|
||||
"region": "RegionOne",
|
||||
"tenantId": 1,
|
||||
"type": "object-store",
|
||||
"id": 1,
|
||||
"publicURL": "http://swift.publicinternets.com/v1/AUTH_1"
|
||||
},
|
||||
{
|
||||
"internalURL": "http://localhost:8774/v1.0",
|
||||
"name": "nova_compat",
|
||||
"adminURL": "http://127.0.0.1:8774/v1.0",
|
||||
"region": "RegionOne",
|
||||
"tenantId": 1,
|
||||
"type": "compute",
|
||||
"id": 2,
|
||||
"publicURL": "http://nova.publicinternets.com/v1.0/"
|
||||
},
|
||||
{
|
||||
"internalURL": "http://localhost:8774/v1.1",
|
||||
"name": "nova",
|
||||
"adminURL": "http://127.0.0.1:8774/v1.1",
|
||||
"region": "RegionOne",
|
||||
"tenantId": 1,
|
||||
"type": "compute",
|
||||
"id": 3,
|
||||
"publicURL": "http://nova.publicinternets.com/v1.1/
|
||||
},
|
||||
{
|
||||
"internalURL": "http://127.0.0.1:9292/v1.1/",
|
||||
"name": "glance",
|
||||
"adminURL": "http://nova.admin-nets.local/v1.1/",
|
||||
"region": "RegionOne",
|
||||
"tenantId": 1,
|
||||
"type": "image",
|
||||
"id": 4,
|
||||
"publicURL": "http://glance.publicinternets.com/v1.1/"
|
||||
},
|
||||
{
|
||||
"internalURL": "http://127.0.0.1:7777/v1.1/1",
|
||||
"name": "cdn",
|
||||
"adminURL": "http://cdn.admin-nets.local/v1.1/1",
|
||||
"region": "RegionOne",
|
||||
"tenantId": 1,
|
||||
"versionId": "1.1",
|
||||
"versionList": "http://127.0.0.1:7777/",
|
||||
"versionInfo": "http://127.0.0.1:7777/v1.1",
|
||||
"type": "object-store",
|
||||
"id": 5,
|
||||
"publicURL": "http://cdn.publicinternets.com/v1.1/1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
GET /tenants
|
||||
============
|
||||
|
||||
List all of the tenants in the system (requires an Admin ``X-Auth-Token``)::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tenants
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"tenants_links": [],
|
||||
"tenants": [
|
||||
{
|
||||
"enabled": false,
|
||||
"description": "None",
|
||||
"name": "project-y",
|
||||
"id": "3"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"description": "None",
|
||||
"name": "ANOTHER:TENANT",
|
||||
"id": "2"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"description": "None",
|
||||
"name": "customer-x",
|
||||
"id": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
GET /tenants/{tenant_id}
|
||||
========================
|
||||
|
||||
Retrieve information about a tenant, by tenant ID::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tenants/1
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"tenant":{
|
||||
"enabled":true,
|
||||
"description":"None",
|
||||
"name":"customer-x",
|
||||
"id":"1"
|
||||
}
|
||||
}
|
||||
|
||||
GET /tenants/{tenant_id}/users/{user_id}/roles
|
||||
==============================================
|
||||
|
||||
List the roles a user has been granted on a tenant::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/tenants/1/users/1/roles
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"roles_links":[],
|
||||
"roles":[
|
||||
{
|
||||
"id":"3",
|
||||
"name":"Member"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
GET /users/{user_id}
|
||||
====================
|
||||
|
||||
Retrieve information about a user, by user ID::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/users/1
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"user":{
|
||||
"tenantId":"1",
|
||||
"enabled":true,
|
||||
"id":"1",
|
||||
"name":"joeuser"
|
||||
}
|
||||
}
|
||||
|
||||
GET /users/{user_id}/roles
|
||||
==========================
|
||||
|
||||
Retrieve the roles granted to a user, given a user ID::
|
||||
|
||||
$ curl -H "X-Auth-Token:999888777666" http://localhost:35357/v2.0/users/4/roles
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"roles_links":[],
|
||||
"roles":[
|
||||
{
|
||||
"id":"2",
|
||||
"name":"KeystoneServiceAdmin"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Keystone Architecture
|
||||
=====================
|
||||
|
||||
Much of the design is precipitated from the expectation that the auth backends
|
||||
for most deployments will actually be shims in front of existing user systems.
|
||||
|
||||
------------
|
||||
The Services
|
||||
------------
|
||||
|
||||
Keystone is organized as a group of services exposed on one or many endpoints.
|
||||
Many of these services are used in a combined fashion by the frontend, for
|
||||
example an authenticate call will validate user/tenant credentials with the
|
||||
Identity service and, upon success, create and return a token with the Token
|
||||
service.
|
||||
|
||||
|
||||
Identity
|
||||
--------
|
||||
|
||||
The Identity service provides auth credential validation and data about Users,
|
||||
Tenants and Roles, as well as any associated metadata.
|
||||
|
||||
In the basic case all this data is managed by the service, allowing the service
|
||||
to manage all the CRUD associated with the data.
|
||||
|
||||
In other cases, this data is pulled, by varying degrees, from an authoritative
|
||||
backend service. An example of this would be when backending on LDAP. See
|
||||
`LDAP Backend` below for more details.
|
||||
|
||||
|
||||
Token
|
||||
-----
|
||||
|
||||
The Token service validates and manages Tokens used for authenticating requests
|
||||
once a user/tenant's credentials have already been verified.
|
||||
|
||||
|
||||
Catalog
|
||||
-------
|
||||
|
||||
The Catalog service provides an endpoint registry used for endpoint discovery.
|
||||
|
||||
|
||||
Policy
|
||||
------
|
||||
|
||||
The Policy service provides a rule-based authorization engine and the
|
||||
associated rule management interface.
|
||||
|
||||
----------
|
||||
Data Model
|
||||
----------
|
||||
|
||||
Keystone was designed from the ground up to be amenable to multiple styles of
|
||||
backends and as such many of the methods and data types will happily accept
|
||||
more data than they know what to do with and pass them on to a backend.
|
||||
|
||||
There are a few main data types:
|
||||
|
||||
* **User**: has account credentials, is associated with one or more tenants
|
||||
* **Tenant**: unit of ownership in openstack, contains one or more users
|
||||
* **Role**: a first-class piece of metadata associated with many user-tenant pairs.
|
||||
* **Token**: identifying credential associated with a user or user and tenant
|
||||
* **Extras**: bucket of key-value metadata associated with a user-tenant pair.
|
||||
* **Rule**: describes a set of requirements for performing an action.
|
||||
|
||||
While the general data model allows a many-to-many relationship between Users
|
||||
and Tenants and a many-to-one relationship between Extras and User-Tenant pairs,
|
||||
the actual backend implementations take varying levels of advantage of that
|
||||
functionality.
|
||||
|
||||
|
||||
KVS Backend
|
||||
-----------
|
||||
|
||||
A simple backend interface meant to be further backended on anything that can
|
||||
support primary key lookups, the most trivial implementation being an in-memory
|
||||
dict.
|
||||
|
||||
Supports all features of the general data model.
|
||||
|
||||
|
||||
PAM Backend
|
||||
-----------
|
||||
|
||||
Extra simple backend that uses the current system's PAM service to authenticate,
|
||||
providing a one-to-one relationship between Users and Tenants with the `root`
|
||||
User also having the 'admin' role.
|
||||
|
||||
|
||||
Templated Backend
|
||||
-----------------
|
||||
|
||||
Largely designed for a common use case around service catalogs in the Keystone
|
||||
project, a Catalog backend that simply expands pre-configured templates to
|
||||
provide catalog data.
|
||||
|
||||
Example paste.deploy config (uses $ instead of % to avoid ConfigParser's
|
||||
interpolation)::
|
||||
|
||||
[DEFAULT]
|
||||
catalog.RegionOne.identity.publicURL = http://localhost:$(public_port)s/v2.0
|
||||
catalog.RegionOne.identity.adminURL = http://localhost:$(public_port)s/v2.0
|
||||
catalog.RegionOne.identity.internalURL = http://localhost:$(public_port)s/v2.0
|
||||
catalog.RegionOne.identity.name = 'Identity Service'
|
||||
|
||||
|
||||
----------------
|
||||
Approach to CRUD
|
||||
----------------
|
||||
|
||||
While it is expected that any "real" deployment at a large company will manage
|
||||
their users, tenants and other metadata in their existing user systems, a
|
||||
variety of CRUD operations are provided for the sake of development and testing.
|
||||
|
||||
CRUD is treated as an extension or additional feature to the core feature set in
|
||||
that it is not required that a backend support it.
|
||||
|
||||
|
||||
----------------------------------
|
||||
Approach to Authorization (Policy)
|
||||
----------------------------------
|
||||
|
||||
Various components in the system require that different actions are allowed
|
||||
based on whether the user is authorized to perform that action.
|
||||
|
||||
For the purposes of Keystone Light there are only a couple levels of
|
||||
authorization being checked for:
|
||||
|
||||
* Require that the performing user is considered an admin.
|
||||
* Require that the performing user matches the user being referenced.
|
||||
|
||||
Other systems wishing to use the policy engine will require additional styles
|
||||
of checks and will possibly write completely custom backends. Backends included
|
||||
in Keystone Light are:
|
||||
|
||||
|
||||
Trivial True
|
||||
------------
|
||||
|
||||
Allows all actions.
|
||||
|
||||
|
||||
Simple Match
|
||||
------------
|
||||
|
||||
Given a list of matches to check for, simply verify that the credentials
|
||||
contain the matches. For example::
|
||||
|
||||
credentials = {'user_id': 'foo', 'is_admin': 1, 'roles': ['nova:netadmin']}
|
||||
|
||||
# An admin only call:
|
||||
policy_api.can_haz(('is_admin:1',), credentials)
|
||||
|
||||
# An admin or owner call:
|
||||
policy_api.can_haz(('is_admin:1', 'user_id:foo'),
|
||||
credentials)
|
||||
|
||||
# A netadmin call:
|
||||
policy_api.can_haz(('roles:nova:netadmin',),
|
||||
credentials)
|
||||
|
||||
|
||||
Credentials are generally built from the user metadata in the 'extras' part
|
||||
of the Identity API. So, adding a 'role' to the user just means adding the role
|
||||
to the user metadata.
|
||||
|
||||
|
||||
Capability RBAC
|
||||
---------------
|
||||
|
||||
(Not yet implemented.)
|
||||
|
||||
Another approach to authorization can be action-based, with a mapping of roles
|
||||
to which capabilities are allowed for that role. For example::
|
||||
|
||||
credentials = {'user_id': 'foo', 'is_admin': 1, 'roles': ['nova:netadmin']}
|
||||
|
||||
# add a policy
|
||||
policy_api.add_policy('action:nova:add_network', ('roles:nova:netadmin',))
|
||||
|
||||
policy_api.can_haz(('action:nova:add_network',), credentials)
|
||||
|
||||
|
||||
In the backend this would look up the policy for 'action:nova:add_network' and
|
||||
then do what is effectively a 'Simple Match' style match against the creds.
|
|
@ -33,20 +33,6 @@ from blueprint designs to documentation to testing to deployment scripts.
|
|||
.. _Launchpad: https://launchpad.net/keystone
|
||||
.. _wiki: http://wiki.openstack.org/
|
||||
|
||||
|
||||
|
||||
Contributing Code
|
||||
-----------------
|
||||
|
||||
To contribute code, sign up for a Launchpad account and sign a contributor license agreement,
|
||||
available on the `<http://wiki.openstack.org/CLA>`_. Once the CLA is signed you
|
||||
can contribute code through the Gerrit version control system which is related to your Launchpad account.
|
||||
|
||||
To contribute tests, docs, code, etc, refer to our `Gerrit-Jenkins-Github Workflow`_.
|
||||
|
||||
.. _`Gerrit-Jenkins-Github Workflow`: http://wiki.openstack.org/GerritJenkinsGithub
|
||||
|
||||
|
||||
#openstack on Freenode IRC Network
|
||||
----------------------------------
|
||||
|
||||
|
@ -68,10 +54,10 @@ to write drafts for specs or documentation, describe a blueprint, or collaborate
|
|||
Keystone on Launchpad
|
||||
---------------------
|
||||
|
||||
Launchpad is a code hosting service that hosts the Keystone source code. From
|
||||
Launchpad you can report bugs, ask questions, and register blueprints (feature requests).
|
||||
Launchpad is a code hosting that OpenStack is using to track bugs, feature work, and releases of OpenStack. Like other OpenStack projects, Keystone source code is hosted on GitHub
|
||||
|
||||
* `Launchpad Keystone Page <http://launchpad.net/keystone>`_
|
||||
* `Keystone Project Page on Launchpad <http://launchpad.net/keystone>`_
|
||||
* `Keystone Source Repository on GitHub <http://github.com/openstack/keystone>`_
|
||||
|
||||
OpenStack Blog
|
||||
--------------
|
||||
|
@ -82,9 +68,9 @@ events and posts from OpenStack contributors.
|
|||
|
||||
`OpenStack Blog <http://openstack.org/blog>`_
|
||||
|
||||
See also: `Planet OpenStack <http://planet.openstack.org/>`_, aggregating blogs
|
||||
about OpenStack from around the internet into a single feed. If you'd like to contribute to this blog
|
||||
aggregation with your blog posts, there are instructions for `adding your blog <http://wiki.openstack.org/AddingYourBlog>`_.
|
||||
See also: `Planet OpenStack <http://planet.openstack.org/>`_, an aggregation of blogs
|
||||
about OpenStack from around the internet, combined into a web site and RSS feed. If you'd like to
|
||||
contribute with your blog posts, there are instructions for `adding your blog <http://wiki.openstack.org/AddingYourBlog>`_.
|
||||
|
||||
Twitter
|
||||
-------
|
||||
|
|
|
@ -144,7 +144,7 @@ html_theme = '_theme'
|
|||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static', 'images']
|
||||
html_static_path = ['static', 'images']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
====================
|
||||
Configuring Keystone
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
man/keystone-manage
|
||||
|
||||
Once Keystone is installed, it is configured via a primary configuration file
|
||||
(``etc/keystone.conf``), possibly a separate logging configuration file, and
|
||||
initializing data into keystone using the command line client.
|
||||
|
||||
|
||||
Keystone Configuration File
|
||||
===========================
|
||||
|
||||
The keystone configuration file is an 'ini' file format with sections,
|
||||
extended from Paste_, a common system used to configure python WSGI based
|
||||
applications. In addition to the paste config entries, general configuration
|
||||
values are stored under [DEFAULT] and [sql], and then drivers for the various
|
||||
backend components are included under their individual sections.
|
||||
|
||||
The driver sections include:
|
||||
* ``[identity]`` - the python module that backends the identity system
|
||||
* ``[catalog]`` - the python module that backends the service catalog
|
||||
* ``[token]`` - the python module that backends the token providing mechanisms
|
||||
* ``[policy]`` - the python module that drives the policy system for RBAC
|
||||
* ``[ec2]`` - the python module providing the EC2 translations for OpenStack
|
||||
|
||||
The keystone configuration file is expected to be named ``keystone.conf``.
|
||||
When starting up Keystone, you can specify a different configuration file to
|
||||
use with ``--config-file``. If you do **not** specify a configuration file,
|
||||
keystone will look in the following directories for a configuration file, in
|
||||
order:
|
||||
|
||||
* ``~/.keystone``
|
||||
* ``~/``
|
||||
* ``/etc/keystone``
|
||||
* ``/etc``
|
||||
|
||||
Logging is configured externally to the rest of keystone, the file specifying
|
||||
the logging configuration is in the [DEFAULT] section of the keystone conf
|
||||
file under ``log_config``. If you wish to route all your logging through
|
||||
syslog, there is a ``use_syslog`` option also in the [DEFAULT] section that
|
||||
easy.
|
||||
|
||||
A sample logging file is available with the project in the directory ``etc/logging.conf.sample``. Like other OpenStack projects, keystone uses the
|
||||
`python logging module`, which includes extensive configuration options for
|
||||
choosing the output levels and formats.
|
||||
|
||||
In addition to this documentation page, you can check the ``etc/keystone.conf``
|
||||
sample configuration files distributed with keystone for example configuration
|
||||
files for each server application.
|
||||
|
||||
.. _Paste: http://pythonpaste.org/
|
||||
.. _`python logging module`: http://docs.python.org/library/logging.html
|
||||
|
||||
Sample Configuration Files
|
||||
--------------------------
|
||||
|
||||
* ``etc/keystone.conf``
|
||||
* ``etc/logging.conf.sample``
|
||||
|
||||
Initializing Keystone
|
||||
=====================
|
||||
|
||||
Keystone must be running in order to initialize data within it. This is
|
||||
because the keystone-manage commands are all used the same REST API that other
|
||||
OpenStack systems utilize.
|
||||
|
||||
General keystone-manage options:
|
||||
--------------------------------
|
||||
|
||||
* ``--id-only`` : causes ``keystone-manage`` to return only the UUID result
|
||||
from the API call.
|
||||
|
||||
* ``--endpoint`` : allows you to specify the keystone endpoint to communicate
|
||||
with. The default endpoint is http://localhost:35357/v2.0'
|
||||
|
||||
* ``--auth-token`` : provides the authorization token
|
||||
|
||||
``keystone-manage`` is set up to expect commands in the general form of
|
||||
``keystone-manage`` ``command`` ``subcommand``, with keyword arguments to
|
||||
provide additional information to the command. For example, the command
|
||||
``tenant`` has the subcommand ``create``, which takes the required keyword
|
||||
``tenant_name``::
|
||||
|
||||
keystone-manage tenant create tenant_name=example_tenant
|
||||
|
||||
Invoking keystone-manage by itself will give you some usage information.
|
||||
|
||||
Available keystone-manage commands:
|
||||
|
||||
* ``db_sync``: Sync the database.
|
||||
* ``ec2``: no docs
|
||||
* ``role``: Role CRUD functions.
|
||||
* ``service``: Service CRUD functions.
|
||||
* ``tenant``: Tenant CRUD functions.
|
||||
* ``token``: Token CRUD functions.
|
||||
* ``user``: User CRUD functions.
|
||||
|
||||
Tenants
|
||||
-------
|
||||
|
||||
Tenants are the high level grouping within Keystone that represent groups of
|
||||
users. A tenant is the grouping that owns virtual machines within Nova, or
|
||||
containers within Swift. A tenant can have zero or more users, Users can be assocaited with more than one tenant, and each tenant - user pairing can have a role associated with it.
|
||||
|
||||
``tenant create``
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* tenant_name
|
||||
* id (optional)
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage --id-only tenant create tenant_name=admin
|
||||
|
||||
creates a tenant named "admin".
|
||||
|
||||
``tenant delete``
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* tenant_id
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage tenant delete tenant_id=f2b7b39c860840dfa47d9ee4adffa0b3
|
||||
|
||||
``tenant update``
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* description
|
||||
* name
|
||||
* tenant_id
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage tenant update \
|
||||
tenant_id=f2b7b39c860840dfa47d9ee4adffa0b3 \
|
||||
description="those other guys" \
|
||||
name=tog
|
||||
|
||||
Users
|
||||
-----
|
||||
|
||||
``user create``
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* name
|
||||
* password
|
||||
* email
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage user --ks-id-only create \
|
||||
name=admin \
|
||||
password=secrete \
|
||||
email=admin@example.com
|
||||
|
||||
``user delete``
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
``user list``
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
``user update_email``
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
``user update_enabled``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
``user update_password``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
``user update_tenant``
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
Roles
|
||||
-----
|
||||
|
||||
``role create``
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* name
|
||||
|
||||
exmaple::
|
||||
|
||||
keystone-manage role --ks-id-only create name=Admin
|
||||
|
||||
``role add_user_to_tenant``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* role_id
|
||||
* user_id
|
||||
* tenant_id
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage role add_user_to_tenant \
|
||||
role_id=19d1d3344873464d819c45f521ff9890 \
|
||||
user_id=08741d8ed88242ca88d1f61484a0fe3b \
|
||||
tenant_id=20601a7f1d94447daa4dff438cb1c209
|
||||
|
||||
``role remove_user_from_tenant``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``role get_user_role_refs``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Services
|
||||
--------
|
||||
|
||||
``service create``
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
keyword arguments
|
||||
|
||||
* name
|
||||
* service_type
|
||||
* description
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage service create \
|
||||
name=nova \
|
||||
service_type=compute \
|
||||
description="Nova Compute Service"
|
|
@ -0,0 +1,174 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
==========================================
|
||||
Configuring Services to work with Keystone
|
||||
==========================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
nova-api-paste
|
||||
middleware_architecture
|
||||
|
||||
Once Keystone is installed and running (see :doc:`configuration`), services need to be configured to work
|
||||
with it. To do this, we primarily install and configure middleware for the OpenStack service to handle authentication tasks or otherwise interact with Keystone.
|
||||
|
||||
In general:
|
||||
* Clients making calls to the service will pass in an authentication token.
|
||||
* The Keystone middleware will look for and validate that token, taking the appropriate action.
|
||||
* It will also retrive additional information from the token such as user name, id, tenant name, id, roles, etc...
|
||||
|
||||
The middleware will pass those data down to the service as headers. More details on the architecture of
|
||||
that setup is described in :doc:`middleware_architecture`
|
||||
|
||||
Setting up credentials
|
||||
======================
|
||||
|
||||
Admin Token
|
||||
-----------
|
||||
|
||||
For a default installation of Keystone, before you can use the REST API, you
|
||||
need to define an authorization token. This is configured in the keystone.conf file under the section ``[DEFAULT]``. In the sample file provided with the keystone project, the line defining this token is
|
||||
|
||||
[DEFAULT]
|
||||
admin_token = ADMIN
|
||||
|
||||
This is a "shared secret" between keystone and other openstack services, and will need to be set the
|
||||
same between those services in order for keystone services to function correctly.
|
||||
|
||||
Setting up tenants, users, and roles
|
||||
------------------------------------
|
||||
|
||||
You need to minimally define a tenant, user, and role to link the tenant and user as the most basic set of details to get other services authenticating and authorizing with keystone. See doc:`configuration` for a walk through on how to create tenants, users, and roles.
|
||||
|
||||
Setting up services
|
||||
===================
|
||||
|
||||
Defining Services
|
||||
-----------------
|
||||
|
||||
Keystone also acts as a service catalog to let other OpenStack systems know
|
||||
where relevant API endpoints exist for OpenStack Services. The OpenStack
|
||||
Dashboard, in particular, uses this heavily - and this **must** be configured
|
||||
for the OpenStack Dashboard to properly function.
|
||||
|
||||
Here's how we define the services::
|
||||
|
||||
keystone-manage service create name=nova service_type=compute description="Nova Compute Service"
|
||||
keystone-manage service create name=ec2 service_type=ec2 description="EC2 Compatibility Layer"
|
||||
keystone-manage service create name=glance service_type=image description="Glance Image Service"
|
||||
keystone-manage service create name=keystone service_type=identity description="Keystone Identity Service"
|
||||
keystone-manage service create name=swift service_type=object-store description="Swift Service"
|
||||
|
||||
The endpoints for these services are defined in a template, an example of which is in the project as the file ``etc/default_catalog.templates``.
|
||||
|
||||
Setting Up Middleware
|
||||
=====================
|
||||
|
||||
Keystone Auth-Token Middleware
|
||||
--------------------------------
|
||||
|
||||
The Keystone auth_token middleware is a WSGI component that can be inserted in
|
||||
the WSGI pipeline to handle authenticating tokens with Keystone.
|
||||
|
||||
Configuring Nova to use Keystone
|
||||
--------------------------------
|
||||
|
||||
To configure Nova to use Keystone for authentication, the Nova API service
|
||||
can be run against the api-paste file provided by Keystone. This is most
|
||||
easily accomplished by setting the `--api_paste_config` flag in nova.conf to
|
||||
point to `examples/paste/nova-api-paste.ini` from Keystone. This paste file
|
||||
included references to the WSGI authentication middleware provided with the
|
||||
keystone installation.
|
||||
|
||||
When configuring Nova, it is important to create a admin service token for
|
||||
the service (from the Configuration step above) and include that as the key
|
||||
'admin_token' in the nova-api-paste.ini. See the documented
|
||||
:doc:`nova-api-paste` file for references.
|
||||
|
||||
Configuring Swift to use Keystone
|
||||
---------------------------------
|
||||
|
||||
Similar to Nova, swift can be configured to use Keystone for authentication
|
||||
rather than it's built in 'tempauth'.
|
||||
|
||||
1. Add a service endpoint for Swift to Keystone
|
||||
|
||||
2. Configure the paste file for swift-proxy (`/etc/swift/swift-proxy.conf`)
|
||||
|
||||
3. Reconfigure Swift's proxy server to use Keystone instead of TempAuth.
|
||||
Here's an example `/etc/swift/proxy-server.conf`::
|
||||
|
||||
[DEFAULT]
|
||||
bind_port = 8888
|
||||
user = <user>
|
||||
|
||||
[pipeline:main]
|
||||
pipeline = catch_errors cache keystone proxy-server
|
||||
|
||||
[app:proxy-server]
|
||||
use = egg:swift#proxy
|
||||
account_autocreate = true
|
||||
|
||||
[filter:keystone]
|
||||
use = egg:keystone#tokenauth
|
||||
auth_protocol = http
|
||||
auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
admin_token = 999888777666
|
||||
delay_auth_decision = 0
|
||||
service_protocol = http
|
||||
service_host = 127.0.0.1
|
||||
service_port = 8100
|
||||
service_pass = dTpw
|
||||
cache = swift.cache
|
||||
|
||||
[filter:cache]
|
||||
use = egg:swift#memcache
|
||||
set log_name = cache
|
||||
|
||||
[filter:catch_errors]
|
||||
use = egg:swift#catch_errors
|
||||
|
||||
Note that the optional "cache" property in the keystone filter allows any
|
||||
service (not just Swift) to register its memcache client in the WSGI
|
||||
environment. If such a cache exists, Keystone middleware will utilize it
|
||||
to store validated token information, which could result in better overall
|
||||
performance.
|
||||
|
||||
4. Restart swift
|
||||
|
||||
5. Verify that keystone is providing authentication to Swift
|
||||
|
||||
Use `swift` to check everything works (note: you currently have to create a
|
||||
container or upload something as your first action to have the account
|
||||
created; there's a Swift bug to be fixed soon)::
|
||||
|
||||
$ swift -A http://127.0.0.1:5000/v1.0 -U joeuser -K secrete post container
|
||||
$ swift -A http://127.0.0.1:5000/v1.0 -U joeuser -K secrete stat -v
|
||||
StorageURL: http://127.0.0.1:8888/v1/AUTH_1234
|
||||
Auth Token: 74ce1b05-e839-43b7-bd76-85ef178726c3
|
||||
Account: AUTH_1234
|
||||
Containers: 1
|
||||
Objects: 0
|
||||
Bytes: 0
|
||||
Accept-Ranges: bytes
|
||||
X-Trans-Id: tx25c1a6969d8f4372b63912f411de3c3b
|
||||
|
||||
.. WARNING::
|
||||
Keystone currently allows any valid token to do anything with any account.
|
||||
|
|
@ -18,33 +18,22 @@
|
|||
Developing with Keystone
|
||||
========================
|
||||
|
||||
Get your development environment set up according to :doc:`setup`.
|
||||
Contributing Code
|
||||
=================
|
||||
|
||||
Running a development instance
|
||||
==============================
|
||||
To contribute code, sign up for a Launchpad account and sign a contributor license agreement,
|
||||
available on the `<http://wiki.openstack.org/CLA>`_. Once the CLA is signed you
|
||||
can contribute code through the Gerrit version control system which is related to your Launchpad account.
|
||||
|
||||
Setting up a virtualenv
|
||||
-----------------------
|
||||
To contribute tests, docs, code, etc, refer to our `Gerrit-Jenkins-Github Workflow`_.
|
||||
|
||||
We recommend establishing a virtualenv to run keystone within. To establish
|
||||
this environment, use the command::
|
||||
.. _`Gerrit-Jenkins-Github Workflow`: http://wiki.openstack.org/GerritJenkinsGithub
|
||||
|
||||
$ python tools/install_venv.py
|
||||
Setup
|
||||
-----
|
||||
|
||||
This will create a local virtual environment in the directory ``.venv``.
|
||||
Once created, you can activate this virtualenv for your current shell using::
|
||||
|
||||
$ source .venv/bin/activate
|
||||
|
||||
The virtual environment can be disabled using the command::
|
||||
|
||||
$ deactivate
|
||||
|
||||
You can also use ``tools\with_venv.sh`` to prefix commands so that they run
|
||||
within the virtual environment. For more information on virtual environments,
|
||||
see virtualenv_.
|
||||
|
||||
.. _virtualenv: http://www.virtualenv.org/
|
||||
Get your development environment set up according to :doc:`setup`. The instructions from here will
|
||||
assume that you have installed keystone into a virtualenv. If you chose not to, simply exclude "tools/with_venv.sh" from the example commands below.
|
||||
|
||||
Running Keystone
|
||||
----------------
|
||||
|
@ -52,84 +41,92 @@ Running Keystone
|
|||
To run the keystone Admin and API server instances, use::
|
||||
|
||||
$ tools/with_venv.sh bin/keystone
|
||||
|
||||
Running a demo service that uses Keystone
|
||||
-----------------------------------------
|
||||
|
||||
To run client demo (with all auth middleware running locally on sample service)::
|
||||
|
||||
$ tools/with_venv.sh examples/echo/bin/echod
|
||||
|
||||
which spins up a simple "echo" service on port 8090. To use a simple echo client::
|
||||
|
||||
$ python examples/echo/echo_client.py
|
||||
|
||||
this runs keystone with the configuration the etc/ directory of the project. See :doc:`configuration` for details on how Keystone is configured.
|
||||
|
||||
Interacting with Keystone
|
||||
=========================
|
||||
-------------------------
|
||||
|
||||
You can interact with Keystone through the command line using :doc:`man/keystone-manage`
|
||||
which allows you to establish tenants, users, etc.
|
||||
|
||||
You can also interact with Keystone through it's REST API. There is a python
|
||||
keystone client library python-keystoneclient_ which interacts exclusively through
|
||||
the REST API.
|
||||
keystone client library `python-keystoneclient`_ which interacts exclusively through
|
||||
the REST API, and which keystone itself uses to provide it's command-line interface.
|
||||
|
||||
.. _python-keystoneclient: https://github.com/4P/python-keystoneclient
|
||||
.. _`python-keystoneclient`: https://github.com/openstack/python-keystoneclient
|
||||
|
||||
The easiest way to establish some base information in Keystone to interact with is
|
||||
to invoke::
|
||||
Running Tests
|
||||
=============
|
||||
|
||||
$ tools/with_venv.sh bin/sampledata
|
||||
To run the full suites of tests maintained within Keystone, run::
|
||||
|
||||
You can see the details of what that creates in ``keystone/test/sampledata.py``
|
||||
$ ./run_tests.sh
|
||||
|
||||
Enabling debugging middleware
|
||||
-----------------------------
|
||||
This shows realtime feedback during test execution, iterates over
|
||||
multiple configuration variations, and uses external projects to do
|
||||
light integration testing to verify the keystone API against other projects.
|
||||
|
||||
You can enable a huge amount of additional data (debugging information) about
|
||||
the request and repsonse objects flowing through Keystone using the debugging
|
||||
WSGI middleware.
|
||||
Test Structure
|
||||
--------------
|
||||
|
||||
To enable this, just modify the pipelines in ``etc/keystone.conf``, from::
|
||||
``./run_test.sh`` uses it's python cohort (``run_tests.py``) to iterate through the ``tests`` directory, using Nosetest to collect the tests and invoke them using an
|
||||
OpenStack custom test running that displays the tests as well as the time taken to
|
||||
run those tests.
|
||||
|
||||
[pipeline:admin]
|
||||
pipeline =
|
||||
urlnormalizer
|
||||
admin_api
|
||||
Within the tests directory, the general structure of the tests is a basic set of tests represented under a test class, and then subclasses of those tests under other classes with different configurations to drive different backends through the APIs.
|
||||
|
||||
[pipeline:keystone-legacy-auth]
|
||||
pipeline =
|
||||
urlnormalizer
|
||||
legacy_auth
|
||||
d5_compat
|
||||
service_api
|
||||
For example, ``test_backend.py`` has a sequence of tests under the class ``IdentityTests`` that will work with the default drivers as configured in this projects etc/ directory. ``test_backend_sql.py`` subclasses those tests, changing the configuration by overriding with configuration files stored in the tests directory aimed at enabling the SQL backend for the Identity module.
|
||||
|
||||
... to::
|
||||
Likewise, ``test_cli.py`` takes advantage of the tests written aainst ``test_keystoneclient`` to verify the same tests function through different drivers.
|
||||
|
||||
[pipeline:admin]
|
||||
pipeline =
|
||||
debug
|
||||
urlnormalizer
|
||||
d5_compat
|
||||
admin_api
|
||||
Testing Schema Migrations
|
||||
-------------------------
|
||||
|
||||
[pipeline:keystone-legacy-auth]
|
||||
pipeline =
|
||||
debug
|
||||
urlnormalizer
|
||||
legacy_auth
|
||||
d5_compat
|
||||
service_api
|
||||
The application of schema migrations can be tested using SQLAlchemy Migrate’s built-in test runner, one migration at a time.
|
||||
|
||||
Two simple and easy debugging tools are using the ``-d`` when you start keystone::
|
||||
.. WARNING::
|
||||
|
||||
$ ./keystone -d
|
||||
This may leave your database in an inconsistent state; attempt this in non-production environments only!
|
||||
|
||||
and the `--trace-calls` flag::
|
||||
This is useful for testing the *next* migration in sequence (both forward & backward) in a database under version control::
|
||||
|
||||
$ ./keystone -trace-calls
|
||||
python keystone/common/sql/migrate_repo/manage.py test \
|
||||
--url=sqlite:///test.db \
|
||||
--repository=keystone/common/sql/migrate_repo/
|
||||
|
||||
The ``-d`` flag outputs debug information to the console. The ``--trace-calls`` flag
|
||||
outputs extensive, nested trace calls to the console and highlights any errors
|
||||
in red.
|
||||
This command references to a SQLite database (test.db) to be used. Depending on the migration, this command alone does not make assertions as to the integrity of your data during migration.
|
||||
|
||||
Writing Tests
|
||||
-------------
|
||||
|
||||
To add tests covering all drivers, update the base test class (``test_backend.py``, ``test_legacy_compat.py``, and ``test_keystoneclient.py``).
|
||||
|
||||
To add new drivers, subclass the ``test_backend.py`` (look towards ``test_backend_sql.py`` or ``test_backend_kvs.py`` for examples) and update the configuration of the test class in ``setUp()``.
|
||||
|
||||
Further Testing
|
||||
---------------
|
||||
|
||||
devstack_ is the *best* way to quickly deploy keystone with the rest of the
|
||||
OpenStack universe and should be critical step in your development workflow!
|
||||
|
||||
You may also be interested in either the `OpenStack Continuous Integration Project`_
|
||||
or the `OpenStack Integration Testing Project`_.
|
||||
|
||||
.. _devstack: http://devstack.org/
|
||||
.. _OpenStack Continuous Integration Project: https://github.com/openstack/openstack-ci
|
||||
.. _OpenStack Integration Testing Project: https://github.com/openstack/tempest
|
||||
|
||||
Building the Documentation
|
||||
==========================
|
||||
|
||||
The documentation is all generated with Sphinx from within the docs directory.
|
||||
To generate the full set of HTML documentation:
|
||||
|
||||
cd docs
|
||||
make autodoc
|
||||
make html
|
||||
make man
|
||||
|
||||
the results are in the docs/build/html and docs/build/man directories
|
||||
respectively.
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="131.44359"
|
||||
height="154.62857"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="New document 1">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98901497"
|
||||
inkscape:cx="111.31439"
|
||||
inkscape:cy="-34.431283"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="912"
|
||||
inkscape:window-height="842"
|
||||
inkscape:window-x="66"
|
||||
inkscape:window-y="87"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-263.68561,-343.30233)">
|
||||
<g
|
||||
id="1"
|
||||
transform="translate(262.49833,342.08712)">
|
||||
<path
|
||||
d="m 1.85,49.6 0,28.8 67.2,0 0,-28.8 -67.2,0 z"
|
||||
style="fill:#fdefe3;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="2"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 1.85,78.4 67.2,0 0,-28.8 -67.2,0 0,28.8 z"
|
||||
style="fill:none;stroke:#c00000;stroke-width:1.29999995px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="3"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
style="font-size:9.60000038px;font-style:normal;font-weight:bold;text-align:start;text-anchor:start;fill:#000000;font-family:Arial"
|
||||
y="60.799999"
|
||||
x="24.799999"
|
||||
xml:space="preserve"
|
||||
id="4">Auth</text>
|
||||
<text
|
||||
style="font-size:9.60000038px;font-style:normal;font-weight:bold;text-align:start;text-anchor:start;fill:#000000;font-family:Arial"
|
||||
y="72.800003"
|
||||
x="8.8000002"
|
||||
xml:space="preserve"
|
||||
id="5">Component</text>
|
||||
<path
|
||||
d="m 1.85,126.4 0,28.8 67.2,0 0,-28.8 -67.2,0 z"
|
||||
style="fill:#d1ebf1;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="6"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 1.85,155.2 67.2,0 0,-28.8 -67.2,0 0,28.8 z"
|
||||
style="fill:none;stroke:#1f477d;stroke-width:1.29999995px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="7"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
style="font-size:9.60000038px;font-style:normal;font-weight:bold;text-align:start;text-anchor:start;fill:#000000;font-family:Arial"
|
||||
y="137.60001"
|
||||
x="10.4"
|
||||
xml:space="preserve"
|
||||
id="8">OpenStack</text>
|
||||
<text
|
||||
style="font-size:9.60000038px;font-style:normal;font-weight:bold;text-align:start;text-anchor:start;fill:#000000;font-family:Arial"
|
||||
y="149.60001"
|
||||
x="18.4"
|
||||
xml:space="preserve"
|
||||
id="9">Service</text>
|
||||
<path
|
||||
d="m 35.45,78.4 0,38.5"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.75px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="10"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 38.9,116.05 35.45,126.4 32,116.05 l 6.9,0 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="11"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 16.25,1.6 15.7,39.2"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.75px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="12"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 34.8,38.7 35.45,49.6 28.4,41.25 34.8,38.7 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="13"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 41.05,49.6 56.75,10.45"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.75px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="14"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 53.2,9.95 60.25,1.6 59.6,12.5 53.2,9.95 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||
id="15"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
style="font-size:8.80000019px;font-style:italic;font-weight:normal;text-align:start;text-anchor:start;fill:#1f477d;font-family:Arial"
|
||||
y="18.4"
|
||||
x="69.599998"
|
||||
xml:space="preserve"
|
||||
id="16">Reject</text>
|
||||
<text
|
||||
style="font-size:8.80000019px;font-style:italic;font-weight:normal;text-align:start;text-anchor:start;fill:#1f477d;font-family:Arial"
|
||||
y="28.799999"
|
||||
x="69.599998"
|
||||
xml:space="preserve"
|
||||
id="17">unauthenticated</text>
|
||||
<text
|
||||
style="font-size:8.80000019px;font-style:italic;font-weight:normal;text-align:start;text-anchor:start;fill:#1f477d;font-family:Arial"
|
||||
y="39.200001"
|
||||
x="69.599998"
|
||||
xml:space="preserve"
|
||||
id="18">requests</text>
|
||||
<text
|
||||
style="font-size:8.80000019px;font-style:italic;font-weight:normal;text-align:start;text-anchor:start;fill:#1f477d;font-family:Arial"
|
||||
y="95.199997"
|
||||
x="52"
|
||||
xml:space="preserve"
|
||||
id="19">Forward</text>
|
||||
<text
|
||||
style="font-size:8.80000019px;font-style:italic;font-weight:normal;text-align:start;text-anchor:start;fill:#1f477d;font-family:Arial"
|
||||
y="105.6"
|
||||
x="52"
|
||||
xml:space="preserve"
|
||||
id="20">authenticated</text>
|
||||
<text
|
||||
style="font-size:8.80000019px;font-style:italic;font-weight:normal;text-align:start;text-anchor:start;fill:#1f477d;font-family:Arial"
|
||||
y="116"
|
||||
x="52"
|
||||
xml:space="preserve"
|
||||
id="21">requests</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.6 KiB |
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: Handle305 Pages: 1 -->
|
||||
<svg width="310pt" height="208pt"
|
||||
viewBox="0.00 0.00 310.00 208.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 204)">
|
||||
<title>Handle305</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-204 307,-204 307,5 -4,5"/>
|
||||
<!-- AuthComp -->
|
||||
<g id="node2" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="98,-146 0,-146 0,-106 98,-106 98,-146"/>
|
||||
<text text-anchor="middle" x="49" y="-129.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="49" y="-113.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node4" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="119,-40 25,-40 25,-0 119,-0 119,-40"/>
|
||||
<text text-anchor="middle" x="72" y="-23.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="72" y="-7.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge5" class="edge"><title>Service:n->AuthComp:n</title>
|
||||
<path fill="none" stroke="black" d="M72,-40C72,-62.2222 76.6172,-67.8558 86,-88 90.0596,-96.7157 95.2138,-96.7977 98,-106 103.152,-123.015 110.312,-133.175 98,-146 92.6344,-151.589 70.1318,-155.75 57.5709,-153.773"/>
|
||||
<polygon fill="black" stroke="black" points="59.2494,-150.684 49,-148 55.3388,-156.489 59.2494,-150.684"/>
|
||||
<text text-anchor="middle" x="144" y="-75.4" font-family="Times,serif" font-size="14.00">305 Use Proxy</text>
|
||||
<text text-anchor="middle" x="144" y="-60.4" font-family="Times,serif" font-size="14.00">To Redirect to Auth</text>
|
||||
</g>
|
||||
<!-- Start -->
|
||||
<!-- Start->Service -->
|
||||
<g id="edge7" class="edge"><title>Start:sw->Service</title>
|
||||
<path fill="none" stroke="black" d="M216,-164C182.398,-130.398 232.934,-94.0727 202,-58 192.167,-46.5338 159.461,-37.0056 129.317,-30.3582"/>
|
||||
<polygon fill="black" stroke="black" points="129.738,-26.8696 119.229,-28.2156 128.284,-33.7169 129.738,-26.8696"/>
|
||||
<text text-anchor="middle" x="255.5" y="-128.4" font-family="Times,serif" font-size="14.00">Request</text>
|
||||
<text text-anchor="middle" x="255.5" y="-113.4" font-family="Times,serif" font-size="14.00">Service Directly</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: AuthComp Pages: 1 -->
|
||||
<svg width="510pt" height="118pt"
|
||||
viewBox="0.00 0.00 510.00 118.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 114)">
|
||||
<title>AuthComp</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-114 507,-114 507,5 -4,5"/>
|
||||
<!-- AuthComp -->
|
||||
<g id="node2" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="292,-65 194,-65 194,-25 292,-25 292,-65"/>
|
||||
<text text-anchor="middle" x="243" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="243" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Reject -->
|
||||
<!-- AuthComp->Reject -->
|
||||
<g id="edge3" class="edge"><title>AuthComp->Reject</title>
|
||||
<path fill="none" stroke="black" d="M193.933,-51.2787C157.514,-55.939 108.38,-62.2263 73.8172,-66.649"/>
|
||||
<polygon fill="black" stroke="black" points="73.0637,-63.2168 63.5888,-67.9578 73.9522,-70.1602 73.0637,-63.2168"/>
|
||||
<text text-anchor="middle" x="129" y="-97.4" font-family="Times,serif" font-size="14.00">Reject</text>
|
||||
<text text-anchor="middle" x="129" y="-82.4" font-family="Times,serif" font-size="14.00">Unauthenticated</text>
|
||||
<text text-anchor="middle" x="129" y="-67.4" font-family="Times,serif" font-size="14.00">Requests</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node6" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="502,-65 408,-65 408,-25 502,-25 502,-65"/>
|
||||
<text text-anchor="middle" x="455" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="455" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M292.17,-45C323.626,-45 364.563,-45 397.52,-45"/>
|
||||
<polygon fill="black" stroke="black" points="397.917,-48.5001 407.917,-45 397.917,-41.5001 397.917,-48.5001"/>
|
||||
<text text-anchor="middle" x="350" y="-77.4" font-family="Times,serif" font-size="14.00">Forward</text>
|
||||
<text text-anchor="middle" x="350" y="-62.4" font-family="Times,serif" font-size="14.00">Authenticated</text>
|
||||
<text text-anchor="middle" x="350" y="-47.4" font-family="Times,serif" font-size="14.00">Requests</text>
|
||||
</g>
|
||||
<!-- Start -->
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge7" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M59.1526,-21.4745C90.4482,-25.4792 142.816,-32.1802 183.673,-37.4084"/>
|
||||
<polygon fill="black" stroke="black" points="183.43,-40.9057 193.793,-38.7034 184.318,-33.9623 183.43,-40.9057"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: AuthCompDelegate Pages: 1 -->
|
||||
<svg width="588pt" height="104pt"
|
||||
viewBox="0.00 0.00 588.00 104.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 100)">
|
||||
<title>AuthCompDelegate</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-100 585,-100 585,5 -4,5"/>
|
||||
<!-- AuthComp -->
|
||||
<g id="node2" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="338,-65 240,-65 240,-25 338,-25 338,-65"/>
|
||||
<text text-anchor="middle" x="289" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="289" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Reject -->
|
||||
<!-- AuthComp->Reject -->
|
||||
<g id="edge3" class="edge"><title>AuthComp->Reject</title>
|
||||
<path fill="none" stroke="black" d="M239.6,-50.1899C191.406,-55.2531 118.917,-62.8686 73.5875,-67.6309"/>
|
||||
<polygon fill="black" stroke="black" points="73.0928,-64.1635 63.5132,-68.6893 73.8242,-71.1252 73.0928,-64.1635"/>
|
||||
<text text-anchor="middle" x="152" y="-83.4" font-family="Times,serif" font-size="14.00">Reject Requests</text>
|
||||
<text text-anchor="middle" x="152" y="-68.4" font-family="Times,serif" font-size="14.00">Indicated by the Service</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node6" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="580,-65 486,-65 486,-25 580,-25 580,-65"/>
|
||||
<text text-anchor="middle" x="533" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="533" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M338.009,-49.0804C344.065,-49.4598 350.172,-49.7828 356,-50 405.743,-51.8535 418.259,-51.9103 468,-50 470.523,-49.9031 473.101,-49.7851 475.704,-49.6504"/>
|
||||
<polygon fill="black" stroke="black" points="476.03,-53.1374 485.807,-49.0576 475.62,-46.1494 476.03,-53.1374"/>
|
||||
<text text-anchor="middle" x="412" y="-68.4" font-family="Times,serif" font-size="14.00">Forward Requests</text>
|
||||
<text text-anchor="middle" x="412" y="-53.4" font-family="Times,serif" font-size="14.00">with Identiy Status</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge7" class="edge"><title>Service->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M495.062,-24.9037C486.397,-21.2187 477.064,-17.9304 468,-16 419.314,-5.63183 404.743,-5.9037 356,-16 349.891,-17.2653 343.655,-19.116 337.566,-21.2803"/>
|
||||
<polygon fill="black" stroke="black" points="336.234,-18.0426 328.158,-24.9003 338.748,-24.5757 336.234,-18.0426"/>
|
||||
<text text-anchor="middle" x="412" y="-33.4" font-family="Times,serif" font-size="14.00">Send Response OR</text>
|
||||
<text text-anchor="middle" x="412" y="-18.4" font-family="Times,serif" font-size="14.00">Reject Message</text>
|
||||
</g>
|
||||
<!-- Start -->
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge9" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M59.0178,-20.8384C99.2135,-25.0613 175.782,-33.1055 229.492,-38.7482"/>
|
||||
<polygon fill="black" stroke="black" points="229.265,-42.2435 239.576,-39.8076 229.997,-35.2818 229.265,-42.2435"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: Both Pages: 1 -->
|
||||
<svg width="116pt" height="180pt"
|
||||
viewBox="0.00 0.00 116.00 180.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 176)">
|
||||
<title>Both</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-176 113,-176 113,5 -4,5"/>
|
||||
<!-- AuthComp -->
|
||||
<g id="node2" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="104,-172 6,-172 6,-132 104,-132 104,-172"/>
|
||||
<text text-anchor="middle" x="55" y="-155.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="55" y="-139.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Together -->
|
||||
<g id="node4" class="node"><title>Together</title>
|
||||
<polygon fill="white" stroke="white" points="108,-95.5 0,-95.5 0,-0.5 108,-0.5 108,-95.5"/>
|
||||
<polygon fill="white" stroke="white" points="8,-47 8,-91 101,-91 101,-47 8,-47"/>
|
||||
<polygon fill="none" stroke="#c00000" points="8,-47 8,-91 101,-91 101,-47 8,-47"/>
|
||||
<text text-anchor="start" x="38" y="-75.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="start" x="13.5" y="-58.4333" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
<polygon fill="#d1ebf1" stroke="#d1ebf1" points="8,-4 8,-47 101,-47 101,-4 8,-4"/>
|
||||
<polygon fill="none" stroke="#1f477d" points="8,-4 8,-47 101,-47 101,-4 8,-4"/>
|
||||
<text text-anchor="start" x="15.5" y="-31.7333" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="start" x="28" y="-14.9333" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Together -->
|
||||
<g id="edge3" class="edge"><title>AuthComp->Together:OStack:n</title>
|
||||
<path fill="none" stroke="black" d="M55,-131.871C55,-113.129 55,-84.1127 55,-57.1901"/>
|
||||
<polygon fill="black" stroke="black" points="58.5001,-57 55,-47 51.5001,-57 58.5001,-57"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: DelegateRejectForbidden Pages: 1 -->
|
||||
<svg width="670pt" height="102pt"
|
||||
viewBox="0.00 0.00 670.00 101.64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 97.6355)">
|
||||
<title>DelegateRejectForbidden</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-97.6355 667,-97.6355 667,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- AuthComp -->
|
||||
<g id="node4" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="348,-61.6355 250,-61.6355 250,-21.6355 348,-21.6355 348,-61.6355"/>
|
||||
<text text-anchor="middle" x="299" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="299" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge3" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-41.6355C97.1107,-41.6355 182.142,-41.6355 239.791,-41.6355"/>
|
||||
<polygon fill="black" stroke="black" points="239.864,-45.1356 249.863,-41.6355 239.863,-38.1356 239.864,-45.1356"/>
|
||||
<text text-anchor="middle" x="152" y="-44.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text>
|
||||
</g>
|
||||
<!-- AuthComp->Start -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Start</title>
|
||||
<path fill="none" stroke="black" d="M249.934,-26.0577C243.944,-24.6511 237.868,-23.4514 232,-22.6355 161.567,-12.8417 141.697,-8.52478 72,-22.6355 69.1948,-23.2034 66.3471,-23.9518 63.5169,-24.8233"/>
|
||||
<polygon fill="black" stroke="black" points="62.3066,-21.5388 54.0489,-28.1766 64.6436,-28.1372 62.3066,-21.5388"/>
|
||||
<text text-anchor="middle" x="152" y="-25.0355" font-family="Times,serif" font-size="14.00">403 Forbidden</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node7" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="662,-61.6355 568,-61.6355 568,-21.6355 662,-21.6355 662,-61.6355"/>
|
||||
<text text-anchor="middle" x="615" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="615" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge7" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M348.009,-45.7159C354.065,-46.0953 360.172,-46.4183 366,-46.6355 447.721,-49.6805 468.282,-49.7738 550,-46.6355 552.523,-46.5386 555.101,-46.4206 557.704,-46.2859"/>
|
||||
<polygon fill="black" stroke="black" points="558.03,-49.7729 567.807,-45.6931 557.62,-42.7849 558.03,-49.7729"/>
|
||||
<text text-anchor="middle" x="458" y="-81.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text>
|
||||
<text text-anchor="middle" x="458" y="-66.0355" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text>
|
||||
<text text-anchor="middle" x="458" y="-51.0355" font-family="Times,serif" font-size="14.00">X-Identity-Status: Confirmed</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge9" class="edge"><title>Service->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M577.062,-21.5392C568.397,-17.8542 559.064,-14.5658 550,-12.6355 470.016,4.39794 446.078,3.95128 366,-12.6355 359.891,-13.9008 353.655,-15.7515 347.566,-17.9158"/>
|
||||
<polygon fill="black" stroke="black" points="346.234,-14.6781 338.158,-21.5358 348.748,-21.2112 346.234,-14.6781"/>
|
||||
<text text-anchor="middle" x="458" y="-30.0355" font-family="Times,serif" font-size="14.00">403 Forbidden</text>
|
||||
<text text-anchor="middle" x="458" y="-15.0355" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: DelegateForbiddnProxy Pages: 1 -->
|
||||
<svg width="656pt" height="81pt"
|
||||
viewBox="0.00 0.00 656.00 81.23" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 77.234)">
|
||||
<title>DelegateForbiddnProxy</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-77.234 653,-77.234 653,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- AuthComp -->
|
||||
<g id="node4" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="348,-48.234 250,-48.234 250,-8.23398 348,-8.23398 348,-48.234"/>
|
||||
<text text-anchor="middle" x="299" y="-31.634" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="299" y="-15.634" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge3" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-28.234C97.1107,-28.234 182.142,-28.234 239.791,-28.234"/>
|
||||
<polygon fill="black" stroke="black" points="239.864,-31.7341 249.863,-28.234 239.863,-24.7341 239.864,-31.7341"/>
|
||||
<text text-anchor="middle" x="152" y="-30.634" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text>
|
||||
</g>
|
||||
<!-- AuthComp->Start -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Start</title>
|
||||
<path fill="none" stroke="black" d="M249.934,-12.6562C243.944,-11.2496 237.868,-10.0499 232,-9.23398 161.567,0.55976 141.697,4.87673 72,-9.23398 69.1948,-9.80192 66.3471,-10.5503 63.5169,-11.4218"/>
|
||||
<polygon fill="black" stroke="black" points="62.3066,-8.13733 54.0489,-14.7751 64.6436,-14.7357 62.3066,-8.13733"/>
|
||||
<text text-anchor="middle" x="152" y="-11.634" font-family="Times,serif" font-size="14.00">500 Internal Error</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node7" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="648,-48.234 554,-48.234 554,-8.23398 648,-8.23398 648,-48.234"/>
|
||||
<text text-anchor="middle" x="601" y="-31.634" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="601" y="-15.634" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge7" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M348.194,-28.234C401.691,-28.234 487.101,-28.234 543.616,-28.234"/>
|
||||
<polygon fill="black" stroke="black" points="543.818,-31.7341 553.818,-28.234 543.818,-24.7341 543.818,-31.7341"/>
|
||||
<text text-anchor="middle" x="451" y="-60.634" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text>
|
||||
<text text-anchor="middle" x="451" y="-45.634" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text>
|
||||
<text text-anchor="middle" x="451" y="-30.634" font-family="Times,serif" font-size="14.00">X-Identity-Status: Confirmed</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge9" class="edge"><title>Service->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M553.774,-12.7435C547.845,-11.2995 541.819,-10.067 536,-9.23398 461.207,1.47328 440.836,1.17187 366,-9.23398 363.341,-9.6037 360.639,-10.0522 357.922,-10.5631"/>
|
||||
<polygon fill="black" stroke="black" points="357.121,-7.15517 348.066,-12.6562 358.575,-14.0025 357.121,-7.15517"/>
|
||||
<text text-anchor="middle" x="451" y="-11.634" font-family="Times,serif" font-size="14.00">403 Forbidden</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: DelegateRejectAuthBasic Pages: 1 -->
|
||||
<svg width="670pt" height="113pt"
|
||||
viewBox="0.00 0.00 670.00 112.84" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 108.841)">
|
||||
<title>DelegateRejectAuthBasic</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-108.841 667,-108.841 667,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- AuthComp -->
|
||||
<g id="node4" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="346,-72.8409 248,-72.8409 248,-32.8409 346,-32.8409 346,-72.8409"/>
|
||||
<text text-anchor="middle" x="297" y="-56.2409" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="297" y="-40.2409" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge3" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M54.3777,-61.3549C60.1429,-62.8044 66.2278,-64.0845 72,-64.8409 141.627,-73.9651 160.053,-71.0554 230,-64.8409 232.523,-64.6168 235.094,-64.346 237.686,-64.038"/>
|
||||
<polygon fill="black" stroke="black" points="238.294,-67.4878 247.737,-62.6852 237.36,-60.5504 238.294,-67.4878"/>
|
||||
<text text-anchor="middle" x="151" y="-72.2409" font-family="Times,serif" font-size="14.00">Authorization: Basic Yjpw</text>
|
||||
</g>
|
||||
<!-- AuthComp->Start -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Start</title>
|
||||
<path fill="none" stroke="black" d="M268.012,-32.6508C256.688,-25.9141 243.253,-19.2572 230,-15.8409 162.001,1.68741 138.106,7.84667 72,-15.8409 64.6685,-18.468 57.6762,-22.8621 51.4824,-27.7226"/>
|
||||
<polygon fill="black" stroke="black" points="48.8781,-25.3457 43.5743,-34.5174 53.44,-30.655 48.8781,-25.3457"/>
|
||||
<text text-anchor="middle" x="151" y="-48.2409" font-family="Times,serif" font-size="14.00">401 Unauthorized</text>
|
||||
<text text-anchor="middle" x="151" y="-33.2409" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Basic</text>
|
||||
<text text-anchor="middle" x="151" y="-18.2409" font-family="Times,serif" font-size="14.00">Realm="API Realm"</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node7" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="662,-72.8409 568,-72.8409 568,-32.8409 662,-32.8409 662,-72.8409"/>
|
||||
<text text-anchor="middle" x="615" y="-56.2409" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="615" y="-40.2409" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge7" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M346.009,-56.9214C352.065,-57.3007 358.172,-57.6238 364,-57.8409 446.609,-60.9191 467.394,-61.0134 550,-57.8409 552.523,-57.744 555.101,-57.626 557.704,-57.4913"/>
|
||||
<polygon fill="black" stroke="black" points="558.03,-60.9783 567.807,-56.8985 557.62,-53.9903 558.03,-60.9783"/>
|
||||
<text text-anchor="middle" x="457" y="-92.2409" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text>
|
||||
<text text-anchor="middle" x="457" y="-77.2409" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy b</text>
|
||||
<text text-anchor="middle" x="457" y="-62.2409" font-family="Times,serif" font-size="14.00">X-Identity-Status: Indeterminate</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge9" class="edge"><title>Service->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M577.062,-32.7447C568.397,-29.0597 559.064,-25.7713 550,-23.8409 469.146,-6.62237 444.948,-7.07388 364,-23.8409 357.891,-25.1063 351.655,-26.957 345.566,-29.1213"/>
|
||||
<polygon fill="black" stroke="black" points="344.234,-25.8836 336.158,-32.7413 346.748,-32.4166 344.234,-25.8836"/>
|
||||
<text text-anchor="middle" x="457" y="-41.2409" font-family="Times,serif" font-size="14.00">401 Unauthorized</text>
|
||||
<text text-anchor="middle" x="457" y="-26.2409" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: DelegateRejectAuthOAuth Pages: 1 -->
|
||||
<svg width="722pt" height="128pt"
|
||||
viewBox="0.00 0.00 722.00 127.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 123.504)">
|
||||
<title>DelegateRejectAuthOAuth</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-123.504 719,-123.504 719,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- AuthComp -->
|
||||
<g id="node4" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="398,-87.504 300,-87.504 300,-47.504 398,-47.504 398,-87.504"/>
|
||||
<text text-anchor="middle" x="349" y="-70.904" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="349" y="-54.904" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge3" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M54.4752,-81.8682C60.1286,-84.2034 66.1458,-86.2617 72,-87.504 163.3,-106.879 189.647,-100.994 282,-87.504 284.667,-87.1144 287.375,-86.642 290.098,-86.104"/>
|
||||
<polygon fill="black" stroke="black" points="290.972,-89.4951 299.969,-83.9 289.446,-82.6633 290.972,-89.4951"/>
|
||||
<text text-anchor="middle" x="177" y="-101.904" font-family="Times,serif" font-size="14.00">Authorization: OAuth 000-999-222</text>
|
||||
</g>
|
||||
<!-- AuthComp->Start -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Start</title>
|
||||
<path fill="none" stroke="black" d="M325.91,-47.4946C313.721,-38.2548 297.999,-28.2878 282,-23.504 192.578,3.23327 158.428,11.7282 72,-23.504 62.489,-27.3811 53.8955,-34.3434 46.8279,-41.6023"/>
|
||||
<polygon fill="black" stroke="black" points="43.8515,-39.6795 39.7866,-49.4636 49.0657,-44.3499 43.8515,-39.6795"/>
|
||||
<text text-anchor="middle" x="177" y="-70.904" font-family="Times,serif" font-size="14.00">401 Unauthorized</text>
|
||||
<text text-anchor="middle" x="177" y="-55.904" font-family="Times,serif" font-size="14.00">WWW-Authenticate: OAuth</text>
|
||||
<text text-anchor="middle" x="177" y="-40.904" font-family="Times,serif" font-size="14.00">Realm=’API Realm’,</text>
|
||||
<text text-anchor="middle" x="177" y="-25.904" font-family="Times,serif" font-size="14.00">Error=’invalid-token’</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node7" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="714,-87.504 620,-87.504 620,-47.504 714,-47.504 714,-87.504"/>
|
||||
<text text-anchor="middle" x="667" y="-70.904" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="667" y="-54.904" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge7" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M398.009,-71.5844C404.065,-71.9638 410.172,-72.2868 416,-72.504 498.609,-75.5822 519.394,-75.6765 602,-72.504 604.523,-72.4071 607.101,-72.2891 609.704,-72.1544"/>
|
||||
<polygon fill="black" stroke="black" points="610.03,-75.6414 619.807,-71.5616 609.62,-68.6534 610.03,-75.6414"/>
|
||||
<text text-anchor="middle" x="509" y="-106.904" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text>
|
||||
<text text-anchor="middle" x="509" y="-91.904" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy</text>
|
||||
<text text-anchor="middle" x="509" y="-76.904" font-family="Times,serif" font-size="14.00">X-Identity-Status: Indeterminate</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge9" class="edge"><title>Service->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M629.062,-47.4077C620.397,-43.7227 611.064,-40.4344 602,-38.504 521.146,-21.2854 496.948,-21.7369 416,-38.504 409.891,-39.7693 403.655,-41.62 397.566,-43.7843"/>
|
||||
<polygon fill="black" stroke="black" points="396.234,-40.5466 388.158,-47.4043 398.748,-47.0797 396.234,-40.5466"/>
|
||||
<text text-anchor="middle" x="509" y="-55.904" font-family="Times,serif" font-size="14.00">401 Unauthorized</text>
|
||||
<text text-anchor="middle" x="509" y="-40.904" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: DelegateUnimplemented Pages: 1 -->
|
||||
<svg width="670pt" height="102pt"
|
||||
viewBox="0.00 0.00 670.00 101.64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 97.6355)">
|
||||
<title>DelegateUnimplemented</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-97.6355 667,-97.6355 667,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- AuthComp -->
|
||||
<g id="node4" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="348,-61.6355 250,-61.6355 250,-21.6355 348,-21.6355 348,-61.6355"/>
|
||||
<text text-anchor="middle" x="299" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="299" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge3" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-41.6355C97.1107,-41.6355 182.142,-41.6355 239.791,-41.6355"/>
|
||||
<polygon fill="black" stroke="black" points="239.864,-45.1356 249.863,-41.6355 239.863,-38.1356 239.864,-45.1356"/>
|
||||
<text text-anchor="middle" x="152" y="-44.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text>
|
||||
</g>
|
||||
<!-- AuthComp->Start -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Start</title>
|
||||
<path fill="none" stroke="black" d="M249.934,-26.0577C243.944,-24.6511 237.868,-23.4514 232,-22.6355 161.567,-12.8417 141.697,-8.52478 72,-22.6355 69.1948,-23.2034 66.3471,-23.9518 63.5169,-24.8233"/>
|
||||
<polygon fill="black" stroke="black" points="62.3066,-21.5388 54.0489,-28.1766 64.6436,-28.1372 62.3066,-21.5388"/>
|
||||
<text text-anchor="middle" x="152" y="-25.0355" font-family="Times,serif" font-size="14.00">500 Internal Error</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node7" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="662,-61.6355 568,-61.6355 568,-21.6355 662,-21.6355 662,-61.6355"/>
|
||||
<text text-anchor="middle" x="615" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="615" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge7" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M348.009,-45.7159C354.065,-46.0953 360.172,-46.4183 366,-46.6355 447.721,-49.6805 468.282,-49.7738 550,-46.6355 552.523,-46.5386 555.101,-46.4206 557.704,-46.2859"/>
|
||||
<polygon fill="black" stroke="black" points="558.03,-49.7729 567.807,-45.6931 557.62,-42.7849 558.03,-49.7729"/>
|
||||
<text text-anchor="middle" x="458" y="-81.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text>
|
||||
<text text-anchor="middle" x="458" y="-66.0355" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text>
|
||||
<text text-anchor="middle" x="458" y="-51.0355" font-family="Times,serif" font-size="14.00">X-Identity-Status: Confirmed</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge9" class="edge"><title>Service->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M577.062,-21.5392C568.397,-17.8542 559.064,-14.5658 550,-12.6355 470.016,4.39794 446.078,3.95128 366,-12.6355 359.891,-13.9008 353.655,-15.7515 347.566,-17.9158"/>
|
||||
<polygon fill="black" stroke="black" points="346.234,-14.6781 338.158,-21.5358 348.748,-21.2112 346.234,-14.6781"/>
|
||||
<text text-anchor="middle" x="458" y="-30.0355" font-family="Times,serif" font-size="14.00">501 Unimplemented</text>
|
||||
<text text-anchor="middle" x="458" y="-15.0355" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.9 KiB |
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: Mapper Pages: 1 -->
|
||||
<svg width="174pt" height="264pt"
|
||||
viewBox="0.00 0.00 174.00 264.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 260)">
|
||||
<title>Mapper</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-260 171,-260 171,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- Mapper -->
|
||||
<g id="node4" class="node"><title>Mapper</title>
|
||||
<polygon fill="#ebf1de" stroke="#687b37" points="119,-184 49,-184 49,-148 119,-148 119,-184"/>
|
||||
<text text-anchor="middle" x="84" y="-161.4" font-family="Helvetica,sans-Serif" font-size="14.00">Mapper</text>
|
||||
</g>
|
||||
<!-- Start->Mapper -->
|
||||
<g id="edge3" class="edge"><title>Start->Mapper</title>
|
||||
<path fill="none" stroke="black" d="M84,-219.831C84,-212.131 84,-202.974 84,-194.417"/>
|
||||
<polygon fill="black" stroke="black" points="87.5001,-194.413 84,-184.413 80.5001,-194.413 87.5001,-194.413"/>
|
||||
</g>
|
||||
<!-- Auths -->
|
||||
<g id="node6" class="node"><title>Auths</title>
|
||||
<polygon fill="white" stroke="white" points="166,-112 0,-112 0,-76 166,-76 166,-112"/>
|
||||
<polygon fill="#fdefe3" stroke="#fdefe3" points="8,-81 8,-106 59,-106 59,-81 8,-81"/>
|
||||
<polygon fill="none" stroke="#c00000" points="8,-81 8,-106 59,-106 59,-81 8,-81"/>
|
||||
<text text-anchor="start" x="13.5" y="-90.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth1</text>
|
||||
<polygon fill="#fdefe3" stroke="#fdefe3" points="59,-81 59,-106 109,-106 109,-81 59,-81"/>
|
||||
<polygon fill="none" stroke="#c00000" points="59,-81 59,-106 109,-106 109,-81 59,-81"/>
|
||||
<text text-anchor="start" x="64" y="-90.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth2</text>
|
||||
<polygon fill="#fdefe3" stroke="#fdefe3" points="109,-81 109,-106 159,-106 159,-81 109,-81"/>
|
||||
<polygon fill="none" stroke="#c00000" points="109,-81 109,-106 159,-106 159,-81 109,-81"/>
|
||||
<text text-anchor="start" x="114" y="-90.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth3</text>
|
||||
</g>
|
||||
<!-- Mapper->Auths -->
|
||||
<g id="edge5" class="edge"><title>Mapper:sw->Auths:auth1</title>
|
||||
<path fill="none" stroke="black" d="M49,-148C37.5237,-136.524 34.1339,-129.157 33.2662,-116.083"/>
|
||||
<polygon fill="black" stroke="black" points="36.7628,-115.904 33,-106 29.7652,-116.089 36.7628,-115.904"/>
|
||||
</g>
|
||||
<!-- Mapper->Auths -->
|
||||
<g id="edge7" class="edge"><title>Mapper:s->Auths:auth2</title>
|
||||
<path fill="none" stroke="black" d="M84,-148C84,-133.271 84,-127.258 84,-116.207"/>
|
||||
<polygon fill="black" stroke="black" points="87.5001,-116 84,-106 80.5001,-116 87.5001,-116"/>
|
||||
</g>
|
||||
<!-- Mapper->Auths -->
|
||||
<g id="edge9" class="edge"><title>Mapper:se->Auths:auth3</title>
|
||||
<path fill="none" stroke="black" d="M119,-148C130.388,-136.612 133.173,-129.088 133.817,-116.035"/>
|
||||
<polygon fill="black" stroke="black" points="137.317,-116.062 134,-106 130.318,-115.934 137.317,-116.062"/>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node10" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="131,-40 37,-40 37,-0 131,-0 131,-40"/>
|
||||
<text text-anchor="middle" x="84" y="-23.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="84" y="-7.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- Auths->Service -->
|
||||
<g id="edge11" class="edge"><title>Auths:auth1->Service</title>
|
||||
<path fill="none" stroke="black" d="M33,-81C33,-68.2561 39.6326,-56.7707 48.1141,-47.2933"/>
|
||||
<polygon fill="black" stroke="black" points="50.6575,-49.6992 55.221,-40.1376 45.6908,-44.7664 50.6575,-49.6992"/>
|
||||
</g>
|
||||
<!-- Auths->Service -->
|
||||
<g id="edge13" class="edge"><title>Auths:auth2->Service</title>
|
||||
<path fill="none" stroke="black" d="M84,-81C84,-70.9674 84,-60.0066 84,-50.1784"/>
|
||||
<polygon fill="black" stroke="black" points="87.5001,-50.0559 84,-40.056 80.5001,-50.056 87.5001,-50.0559"/>
|
||||
</g>
|
||||
<!-- Auths->Service -->
|
||||
<g id="edge15" class="edge"><title>Auths:auth3->Service</title>
|
||||
<path fill="none" stroke="black" d="M134,-81C134,-68.4835 127.626,-57.1283 119.429,-47.7009"/>
|
||||
<polygon fill="black" stroke="black" points="121.686,-45.0006 112.215,-40.2521 116.658,-49.8705 121.686,-45.0006"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545)
|
||||
-->
|
||||
<!-- Title: ProxyAuth Pages: 1 -->
|
||||
<svg width="644pt" height="74pt"
|
||||
viewBox="0.00 0.00 644.00 73.70" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 69.7025)">
|
||||
<title>ProxyAuth</title>
|
||||
<polygon fill="white" stroke="white" points="-4,5 -4,-69.7025 641,-69.7025 641,5 -4,5"/>
|
||||
<!-- Start -->
|
||||
<!-- AuthComp -->
|
||||
<g id="node4" class="node"><title>AuthComp</title>
|
||||
<polygon fill="#fdefe3" stroke="#c00000" points="348,-55.7025 250,-55.7025 250,-15.7025 348,-15.7025 348,-55.7025"/>
|
||||
<text text-anchor="middle" x="299" y="-39.1025" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text>
|
||||
<text text-anchor="middle" x="299" y="-23.1025" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text>
|
||||
</g>
|
||||
<!-- Start->AuthComp -->
|
||||
<g id="edge3" class="edge"><title>Start->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-35.7025C97.1107,-35.7025 182.142,-35.7025 239.791,-35.7025"/>
|
||||
<polygon fill="black" stroke="black" points="239.864,-39.2026 249.863,-35.7025 239.863,-32.2026 239.864,-39.2026"/>
|
||||
<text text-anchor="middle" x="152" y="-38.1025" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text>
|
||||
</g>
|
||||
<!-- AuthComp->Start -->
|
||||
<g id="edge9" class="edge"><title>AuthComp:w->Start</title>
|
||||
<path fill="none" stroke="black" d="M250,-35.7025C238.368,-35.7025 242.686,-21.2988 232,-16.7025 166.676,11.3956 141.697,-2.59182 72,-16.7025 69.1948,-17.2705 66.3471,-18.0189 63.5169,-18.8903"/>
|
||||
<polygon fill="black" stroke="black" points="62.3066,-15.6059 54.0489,-22.2437 64.6436,-22.2043 62.3066,-15.6059"/>
|
||||
<text text-anchor="middle" x="152" y="-19.1025" font-family="Times,serif" font-size="14.00">500 Internal Error</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g id="node6" class="node"><title>Service</title>
|
||||
<polygon fill="#d1ebf1" stroke="#1f477d" points="636,-55.7025 542,-55.7025 542,-15.7025 636,-15.7025 636,-55.7025"/>
|
||||
<text text-anchor="middle" x="589" y="-39.1025" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text>
|
||||
<text text-anchor="middle" x="589" y="-23.1025" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g id="edge5" class="edge"><title>AuthComp->Service</title>
|
||||
<path fill="none" stroke="black" d="M348.195,-35.7025C399.052,-35.7025 478.372,-35.7025 531.947,-35.7025"/>
|
||||
<polygon fill="black" stroke="black" points="531.971,-39.2026 541.971,-35.7025 531.971,-32.2026 531.971,-39.2026"/>
|
||||
<text text-anchor="middle" x="445" y="-53.1025" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text>
|
||||
<text text-anchor="middle" x="445" y="-38.1025" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text>
|
||||
</g>
|
||||
<!-- Service->AuthComp -->
|
||||
<g id="edge7" class="edge"><title>Service:w->AuthComp</title>
|
||||
<path fill="none" stroke="black" d="M542,-35.7025C530.368,-35.7025 534.686,-21.2988 524,-16.7025 459.492,11.0444 435.553,-7.03121 366,-16.7025 363.341,-17.0723 360.639,-17.5208 357.922,-18.0316"/>
|
||||
<polygon fill="black" stroke="black" points="357.121,-14.6237 348.066,-20.1248 358.575,-21.471 357.121,-14.6237"/>
|
||||
<text text-anchor="middle" x="445" y="-19.1025" font-family="Times,serif" font-size="14.00">403 Forbidden</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="222pt"
|
||||
height="135pt"
|
||||
viewBox="0.00 0.00 245.00 135.00"
|
||||
id="svg3479"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="layouts-full.svg">
|
||||
<metadata
|
||||
id="metadata3492">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs3490" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1002"
|
||||
id="namedview3488"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="-0.58191504"
|
||||
inkscape:cy="23.096747"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="22"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg3479" />
|
||||
<g
|
||||
id="layouts">
|
||||
<title
|
||||
id="title3482">Auth Layouts</title>
|
||||
<text
|
||||
text-anchor="middle"
|
||||
x="58"
|
||||
y="134"
|
||||
font-family="Helvetica,sans-Serif"
|
||||
font-size="14.00"
|
||||
id="text3484">(a)</text>
|
||||
<text
|
||||
text-anchor="middle"
|
||||
x="178"
|
||||
y="134"
|
||||
font-family="Helvetica,sans-Serif"
|
||||
font-size="14.00"
|
||||
id="text3486">(b)</text>
|
||||
</g>
|
||||
<g
|
||||
id="graph1"
|
||||
class="graph"
|
||||
transform="matrix(0.81928538,0,0,0.77044025,18.190271,97.915731)">
|
||||
<title
|
||||
id="title3172">Together</title>
|
||||
<polygon
|
||||
style="fill:#ffffff;stroke:#ffffff"
|
||||
points="-4,5 -4,5 -4,-100 113,-100 113,5 "
|
||||
id="polygon3174" />
|
||||
<!-- Together -->
|
||||
<g
|
||||
id="node2"
|
||||
class="node">
|
||||
<title
|
||||
id="title3177">Together</title>
|
||||
<polygon
|
||||
style="fill:#fdefe3;stroke:#fdefe3"
|
||||
points="8,-47 8,-47 8,-91 101,-91 101,-47 "
|
||||
id="polygon3179" />
|
||||
<polygon
|
||||
style="fill:none;stroke:#c00000"
|
||||
points="8,-47 8,-47 8,-91 101,-91 101,-47 "
|
||||
id="polygon3181" />
|
||||
<text
|
||||
style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'"
|
||||
x="38"
|
||||
y="-75.233299"
|
||||
font-size="14.00"
|
||||
id="text3183">Auth</text>
|
||||
<text
|
||||
style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'"
|
||||
x="13.5"
|
||||
y="-58.4333"
|
||||
font-size="14.00"
|
||||
id="text3185">Component</text>
|
||||
<polygon
|
||||
style="fill:#d1ebf1;stroke:#d1ebf1"
|
||||
points="8,-4 8,-4 8,-47 101,-47 101,-4 "
|
||||
id="polygon3187" />
|
||||
<polygon
|
||||
style="fill:none;stroke:#1f477d"
|
||||
points="8,-4 8,-4 8,-47 101,-47 101,-4 "
|
||||
id="polygon3189" />
|
||||
<text
|
||||
style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'"
|
||||
x="15.5"
|
||||
y="-31.733299"
|
||||
font-size="14.00"
|
||||
id="text3191">OpenStack</text>
|
||||
<text
|
||||
style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'"
|
||||
x="28"
|
||||
y="-14.9333"
|
||||
font-size="14.00"
|
||||
id="text3193">Service</text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="graph2"
|
||||
class="graph"
|
||||
transform="matrix(0.84200867,0,0,0.82332332,134.01425,108.66091)">
|
||||
<title
|
||||
id="title3134">Seperate</title>
|
||||
<polygon
|
||||
style="fill:#ffffff;stroke:#ffffff"
|
||||
points="-4,-120 103,-120 103,5 -4,5 -4,5 "
|
||||
id="polygon3136" />
|
||||
<!-- AuthComp -->
|
||||
<g
|
||||
id="node2-9"
|
||||
class="node">
|
||||
<title
|
||||
id="title3139">AuthComp</title>
|
||||
<polygon
|
||||
style="fill:#fdefe3;stroke:#c00000"
|
||||
points="0,-116 0,-76 98,-76 98,-116 98,-116 "
|
||||
id="polygon3141" />
|
||||
<text
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'"
|
||||
x="49"
|
||||
y="-99.400002"
|
||||
font-size="14.00"
|
||||
id="text3143">Auth</text>
|
||||
<text
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'"
|
||||
x="49"
|
||||
y="-83.400002"
|
||||
font-size="14.00"
|
||||
id="text3145">Component</text>
|
||||
</g>
|
||||
<!-- Service -->
|
||||
<g
|
||||
id="node4"
|
||||
class="node">
|
||||
<title
|
||||
id="title3148">Service</title>
|
||||
<polygon
|
||||
style="fill:#d1ebf1;stroke:#1f477d"
|
||||
points="2,-40 2,0 96,0 96,-40 96,-40 "
|
||||
id="polygon3150" />
|
||||
<text
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'"
|
||||
x="49"
|
||||
y="-23.4"
|
||||
font-size="14.00"
|
||||
id="text3152">OpenStack</text>
|
||||
<text
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'"
|
||||
x="49"
|
||||
y="-7.4000001"
|
||||
font-size="14.00"
|
||||
id="text3154">Service</text>
|
||||
</g>
|
||||
<!-- AuthComp->Service -->
|
||||
<g
|
||||
id="edge3"
|
||||
class="edge">
|
||||
<title
|
||||
id="title3157">AuthComp->Service</title>
|
||||
<path
|
||||
style="fill:none;stroke:#000000"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 49,-75.6334 c 0,7.8148 0,16.9081 0,25.4504"
|
||||
id="path3159" />
|
||||
<polygon
|
||||
style="fill:#000000;stroke:#000000"
|
||||
points="52.5001,-50.1593 49,-40.1593 45.5001,-50.1593 52.5001,-50.1593 "
|
||||
id="polygon3161" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
|
@ -18,9 +18,9 @@
|
|||
Welcome to Keystone, the OpenStack Identity Service!
|
||||
====================================================
|
||||
|
||||
Keystone is a cloud identity service written in Python, which provides
|
||||
authentication, authorization, and an OpenStack service catalog. It
|
||||
implements `OpenStack's Identity API`_.
|
||||
Keystone is an OpenStack project that provides Identity, Token, Catalog and
|
||||
Policy services for use specifically by projects in the OpenStack family.
|
||||
It implements `OpenStack's Identity API`_.
|
||||
|
||||
This document describes Keystone for contributors of the project, and assumes
|
||||
that you are already familiar with Keystone from an `end-user perspective`_.
|
||||
|
@ -42,9 +42,18 @@ Getting Started
|
|||
:maxdepth: 1
|
||||
|
||||
setup
|
||||
configuration
|
||||
configuringservices
|
||||
community
|
||||
testing
|
||||
|
||||
Man Pages
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
man/keystone
|
||||
man/keystone-manage
|
||||
|
||||
Developers Documentation
|
||||
========================
|
||||
|
@ -53,7 +62,14 @@ Developers Documentation
|
|||
|
||||
developing
|
||||
architecture
|
||||
sourcecode/autoindex
|
||||
api_curl_examples
|
||||
|
||||
Code Documentation
|
||||
==================
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
modules
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
|
|
@ -22,159 +22,202 @@ DESCRIPTION
|
|||
===========
|
||||
|
||||
keystone-manage is the command line tool that interacts with the keystone
|
||||
service to configure Keystone
|
||||
service to initialize and update data within Keystone. Keystone *must* be
|
||||
opertional for the keystone-manage commands to function correctly.
|
||||
|
||||
USAGE
|
||||
=====
|
||||
|
||||
``keystone-manage [options] type action [additional args]``
|
||||
|
||||
user
|
||||
----
|
||||
|
||||
* **user add** [username] [password]
|
||||
General keystone-manage options:
|
||||
--------------------------------
|
||||
|
||||
adds a user to Keystone's data store
|
||||
* ``--id-only`` : causes ``keystone-manage`` to return only the UUID result
|
||||
from the API call.
|
||||
* ``--endpoint`` : allows you to specify the keystone endpoint to communicate with. The default endpoint is http://localhost:35357/v2.0'
|
||||
* ``--auth-token`` : provides the authorization token
|
||||
|
||||
* **user list**
|
||||
``keystone-manage`` is set up to expect commands in the general form of ``keystone-manage`` ``command`` ``subcommand``, with keyword arguments to provide additional information to the command. For example, the command
|
||||
``tenant`` has the subcommand ``create``, which takes the required keyword ``tenant_name``::
|
||||
|
||||
lists all users
|
||||
keystone-manage tenant create tenant_name=example_tenant
|
||||
|
||||
* **user disable** [username]
|
||||
Invoking keystone-manage by itself will give you some usage information.
|
||||
|
||||
disables the user *username*
|
||||
Available keystone-manage commands:
|
||||
db_sync: Sync the database.
|
||||
ec2: no docs
|
||||
role: Role CRUD functions.
|
||||
service: Service CRUD functions.
|
||||
tenant: Tenant CRUD functions.
|
||||
token: Token CRUD functions.
|
||||
user: User CRUD functions.
|
||||
|
||||
tenant
|
||||
------
|
||||
|
||||
* **tenant add** [tenant_name]
|
||||
|
||||
adds a tenant to Keystone's data store
|
||||
|
||||
* **tenant list**
|
||||
|
||||
lists all users
|
||||
|
||||
* **tenant disable** [tenant_name]
|
||||
|
||||
role
|
||||
----
|
||||
|
||||
Roles are used to associated users to tenants. Two roles are defined related
|
||||
to the Keystone service in it's configuration file :doc:`../keystone.conf`
|
||||
|
||||
* **role add** [role_name]
|
||||
|
||||
adds a role
|
||||
|
||||
* **role list** ([tenant_name])
|
||||
|
||||
lists all roles, or all roles for tenant, if tenant_name is provided
|
||||
|
||||
* **role grant** [role_name] [username] ([tenant])
|
||||
|
||||
grants a role to a specific user. Granted globally if tenant_name is not
|
||||
provided or granted for a specific tenant if tenant_name is provided.
|
||||
|
||||
service
|
||||
Tenants
|
||||
-------
|
||||
|
||||
* **service add** [name] [type] [description] [owner_id]
|
||||
Tenants are the high level grouping within Keystone that represent groups of
|
||||
users. A tenant is the grouping that owns virtual machines within Nova, or
|
||||
containers within Swift. A tenant can have zero or more users, Users can be assocaited with more than one tenant, and each tenant - user pairing can have a role associated with it.
|
||||
|
||||
adds a service
|
||||
* tenant create
|
||||
|
||||
* **service list**
|
||||
keyword arguments
|
||||
* tenant_name
|
||||
* id (optional)
|
||||
|
||||
lists all services with id, name, and type
|
||||
example::
|
||||
keystone-manage --id-only tenant create tenant_name=admin
|
||||
|
||||
endpointTemplate
|
||||
----------------
|
||||
creates a tenant named "admin".
|
||||
|
||||
* **endpointTemplate add** [region] [service_name] [public_url] [admin_url] [internal_url] [enabled] [is_global]
|
||||
* tenant delete
|
||||
|
||||
Add a service endpoint for keystone.
|
||||
keyword arguments
|
||||
* tenant_id
|
||||
|
||||
example::
|
||||
keystone-manage tenant delete tenant_id=f2b7b39c860840dfa47d9ee4adffa0b3
|
||||
|
||||
example::
|
||||
* tenant update
|
||||
|
||||
keystone-manage endpointTemplates add RegionOne \
|
||||
keystone \
|
||||
http://keystone_host:5000/v2.0 \
|
||||
http://keystone_host:35357/v2.0 \
|
||||
http://keystone_host:5000/v2.0 \
|
||||
1 1
|
||||
keyword arguments
|
||||
* description
|
||||
* name
|
||||
* tenant_id
|
||||
|
||||
* **endpointTemplate list** ([tenant_name])
|
||||
example::
|
||||
keystone-manage tenant update \
|
||||
tenant_id=f2b7b39c860840dfa47d9ee4adffa0b3 \
|
||||
description="those other guys" \
|
||||
name=tog
|
||||
|
||||
lists endpoint templates with service, region, and public_url. Restricted to
|
||||
tenant endpoints if tenant_name is provided.
|
||||
|
||||
token
|
||||
Users
|
||||
-----
|
||||
|
||||
* **token add** [token] [username] [tenant] [expiration]
|
||||
* user create
|
||||
|
||||
adds a token for a given user and tenant with an expiration
|
||||
keyword arguments
|
||||
* name
|
||||
* password
|
||||
* email
|
||||
|
||||
example::
|
||||
keystone-manage user --ks-id-only create \
|
||||
name=admin \
|
||||
password=secrete \
|
||||
email=admin@example.com
|
||||
|
||||
* user delete
|
||||
|
||||
* **token list**
|
||||
keyword arguments
|
||||
|
||||
lists all tokens
|
||||
* user list
|
||||
|
||||
* **token delete** [token]
|
||||
keyword arguments
|
||||
|
||||
deletes the identified token
|
||||
* user update_email
|
||||
|
||||
endpoint
|
||||
keyword arguments
|
||||
|
||||
* user update_enabled
|
||||
|
||||
keyword arguments
|
||||
|
||||
* user update_password
|
||||
|
||||
keyword arguments
|
||||
|
||||
* user update_tenant
|
||||
|
||||
keyword arguments
|
||||
|
||||
Roles
|
||||
-----
|
||||
|
||||
* role create
|
||||
|
||||
keyword arguments
|
||||
* name
|
||||
|
||||
exmaple::
|
||||
keystone-manage role --ks-id-only create name=Admin
|
||||
|
||||
* role add_user_to_tenant
|
||||
|
||||
keyword arguments
|
||||
* role_id
|
||||
* user_id
|
||||
* tenant_id
|
||||
|
||||
example::
|
||||
|
||||
keystone-manage role add_user_to_tenant \
|
||||
role_id=19d1d3344873464d819c45f521ff9890 \
|
||||
user_id=08741d8ed88242ca88d1f61484a0fe3b \
|
||||
tenant_id=20601a7f1d94447daa4dff438cb1c209
|
||||
|
||||
* role remove_user_from_tenant
|
||||
|
||||
* role get_user_role_refs
|
||||
|
||||
Services
|
||||
--------
|
||||
|
||||
* **endpoint add** [tenant_name] [endpoint_template]
|
||||
* service create
|
||||
|
||||
adds a tenant-specific endpoint
|
||||
keyword arguments
|
||||
* name
|
||||
* service_type
|
||||
* description
|
||||
|
||||
credentials
|
||||
-----------
|
||||
example::
|
||||
keystone-manage service create \
|
||||
name=nova \
|
||||
service_type=compute \
|
||||
description="Nova Compute Service"
|
||||
|
||||
* **credentials add** [username] [type] [key] [password] ([tenant_name])
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
--version show program's version number and exit
|
||||
-h, --help show this help message and exit
|
||||
-v, --verbose Print more verbose output
|
||||
-d, --debug Print debugging output to console
|
||||
-c PATH, --config-file=PATH Path to the config file to use. When not
|
||||
specified (the default), we generally look at
|
||||
the first argument specified to be a config
|
||||
file, and if that is also missing, we search
|
||||
standard directories for a config file.
|
||||
-p BIND_PORT, --port=BIND_PORT, --bind-port=BIND_PORT
|
||||
specifies port to listen on (default is 5000)
|
||||
--host=BIND_HOST, --bind-host=BIND_HOST
|
||||
specifies host address to listen on (default
|
||||
is all or 0.0.0.0)
|
||||
-t, --trace-calls Turns on call tracing for troubleshooting
|
||||
-a PORT, --admin-port=PORT Specifies port for Admin API to listen on
|
||||
(default is 35357)
|
||||
|
||||
Logging Options:
|
||||
================
|
||||
|
||||
The following configuration options are specific to logging
|
||||
functionality for this program.
|
||||
|
||||
--log-config=PATH If this option is specified, the logging
|
||||
configuration file specified is used and
|
||||
overrides any other logging options specified.
|
||||
Please see the Python logging module
|
||||
documentation for details on logging
|
||||
configuration files.
|
||||
--log-date-format=FORMAT Format string for %(asctime)s in log records.
|
||||
Default: %Y-%m-%d %H:%M:%S
|
||||
--log-file=PATH (Optional) Name of log file to output to. If
|
||||
not set, logging will go to stdout.
|
||||
--log-dir=LOG_DIR (Optional) The directory to keep log files in
|
||||
(will be prepended to --logfile)
|
||||
|
||||
Options:
|
||||
-h, --help show this help message and exit
|
||||
--config-file=PATH Path to a config file to use. Multiple config files
|
||||
can be specified, with values in later files taking
|
||||
precedence. The default files used are: []
|
||||
-d, --debug Print debugging output
|
||||
--nodebug Print debugging output
|
||||
-v, --verbose Print more verbose output
|
||||
--noverbose Print more verbose output
|
||||
--log-config=PATH If this option is specified, the logging configuration
|
||||
file specified is used and overrides any other logging
|
||||
options specified. Please see the Python logging
|
||||
module documentation for details on logging
|
||||
configuration files.
|
||||
--log-format=FORMAT A logging.Formatter log message format string which
|
||||
may use any of the available logging.LogRecord
|
||||
attributes. Default: none
|
||||
--log-date-format=DATE_FORMAT
|
||||
Format string for %(asctime)s in log records. Default:
|
||||
none
|
||||
--log-file=PATH (Optional) Name of log file to output to. If not set,
|
||||
logging will go to stdout.
|
||||
--log-dir=LOG_DIR (Optional) The directory to keep log files in (will be
|
||||
prepended to --logfile)
|
||||
--syslog-log-facility=SYSLOG_LOG_FACILITY
|
||||
(Optional) The syslog facility to use when logging to
|
||||
syslog (defaults to LOG_USER)
|
||||
--use-syslog Use syslog for logging.
|
||||
--nouse-syslog Use syslog for logging.
|
||||
--endpoint=ENDPOINT
|
||||
--auth-token=AUTH_TOKEN
|
||||
authorization token
|
||||
--id-only
|
||||
--noid-only
|
||||
|
||||
FILES
|
||||
=====
|
||||
|
||||
|
|
|
@ -21,9 +21,7 @@ SYNOPSIS
|
|||
DESCRIPTION
|
||||
===========
|
||||
|
||||
keystone starts both the service and administrative API servers for Keystone.
|
||||
Use :doc:`keystone-control` to stop/start/restart and manage those services
|
||||
once started.
|
||||
keystone starts both the service and administrative APIs for Keystone.
|
||||
|
||||
USAGE
|
||||
=====
|
||||
|
@ -32,47 +30,40 @@ USAGE
|
|||
|
||||
Common Options:
|
||||
^^^^^^^^^^^^^^^
|
||||
--version show program's version number and exit
|
||||
-h, --help show this help message and exit
|
||||
|
||||
The following configuration options are common to all keystone
|
||||
programs.::
|
||||
|
||||
-v, --verbose Print more verbose output
|
||||
-d, --debug Print debugging output to console
|
||||
-c PATH, --config-file=PATH Path to the config file to use. When not
|
||||
specified (the default), we generally look at
|
||||
the first argument specified to be a config
|
||||
file, and if that is also missing, we search
|
||||
standard directories for a config file.
|
||||
-p BIND_PORT, --port=BIND_PORT, --bind-port=BIND_PORT
|
||||
specifies port to listen on (default is 5000)
|
||||
--host=BIND_HOST, --bind-host=BIND_HOST
|
||||
specifies host address to listen on (default
|
||||
is all or 0.0.0.0)
|
||||
-t, --trace-calls Turns on call tracing for troubleshooting
|
||||
-a PORT, --admin-port=PORT Specifies port for Admin API to listen on
|
||||
(default is 35357)
|
||||
|
||||
Logging Options:
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The following configuration options are specific to logging
|
||||
functionality for this program.::
|
||||
|
||||
--log-config=PATH If this option is specified, the logging
|
||||
configuration file specified is used and
|
||||
overrides any other logging options specified.
|
||||
Please see the Python logging module
|
||||
documentation for details on logging
|
||||
configuration files.
|
||||
--log-date-format=FORMAT Format string for %(asctime)s in log records.
|
||||
Default: %Y-%m-%d %H:%M:%S
|
||||
--log-file=PATH (Optional) Name of log file to output to. If
|
||||
not set, logging will go to stdout.
|
||||
--log-dir=LOG_DIR (Optional) The directory to keep log files in
|
||||
(will be prepended to --logfile)
|
||||
|
||||
-h, --help show this help message and exit
|
||||
--config-file=PATH Path to a config file to use. Multiple config files
|
||||
can be specified, with values in later files taking
|
||||
precedence. The default files used are: []
|
||||
-d, --debug Print debugging output
|
||||
--nodebug Print debugging output
|
||||
-v, --verbose Print more verbose output
|
||||
--noverbose Print more verbose output
|
||||
--log-config=PATH If this option is specified, the logging configuration
|
||||
file specified is used and overrides any other logging
|
||||
options specified. Please see the Python logging
|
||||
module documentation for details on logging
|
||||
configuration files.
|
||||
--log-format=FORMAT A logging.Formatter log message format string which
|
||||
may use any of the available logging.LogRecord
|
||||
attributes. Default: none
|
||||
--log-date-format=DATE_FORMAT
|
||||
Format string for %(asctime)s in log records. Default:
|
||||
none
|
||||
--log-file=PATH (Optional) Name of log file to output to. If not set,
|
||||
logging will go to stdout.
|
||||
--log-dir=LOG_DIR (Optional) The directory to keep log files in (will be
|
||||
prepended to --logfile)
|
||||
--syslog-log-facility=SYSLOG_LOG_FACILITY
|
||||
(Optional) The syslog facility to use when logging to
|
||||
syslog (defaults to LOG_USER)
|
||||
--use-syslog Use syslog for logging.
|
||||
--nouse-syslog Use syslog for logging.
|
||||
|
||||
FILES
|
||||
=====
|
||||
|
||||
|
|
|
@ -0,0 +1,529 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
=======================
|
||||
Middleware Architecture
|
||||
=======================
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
The Keystone middleware architecture supports multiple authentication protocols
|
||||
in a pluggable manner in OpenStack. By providing support for authentication via
|
||||
pluggable authentication components, this architecture allows OpenStack
|
||||
services to be integrated easily into existing deployment environments. It also
|
||||
provides a path by which to implement support for emerging authentication
|
||||
standards such as OAUTH.
|
||||
|
||||
Rationale and Goals
|
||||
===================
|
||||
|
||||
Keystone is the Identity service for OpenStack. To support the easy integrating
|
||||
of OpenStack with existing authentication and identity management systems,
|
||||
Keystone supports talking to multiple backends like LDAP.
|
||||
And to support different deployment needs, it can support multiple
|
||||
authentication protocols via pluggable 'authentication components' implemented
|
||||
as WSGI middleware.
|
||||
|
||||
In this document, we describe the responsibilities of the authentication
|
||||
middleware. We describe how these interact with underlying OpenStack services
|
||||
and how existing services can be modified to take advantage of pluggable
|
||||
authentication. The goal is to allow OpenStack services to be integrated easily
|
||||
into existing deployment environments and to provide a path by which to
|
||||
implement support for emerging authentication standards such as OAUTH.
|
||||
|
||||
Specification Overview
|
||||
======================
|
||||
|
||||
'Authentication' is the process of determining that users are who they say they
|
||||
are. Typically, 'authentication protocols' such as HTTP Basic Auth, Digest
|
||||
Access, public key, token, etc, are used to verify a user's identity. In this
|
||||
document, we define an ''authentication component'' as a software module that
|
||||
implements an authentication protocol for an OpenStack service.
|
||||
|
||||
At a high level, an authentication component is simply a reverse proxy that
|
||||
intercepts HTTP calls from clients. Once it has verified a user's identity, the
|
||||
authentication component extends the call with information about the current
|
||||
user and forwards the request to the OpenStack service. Otherwise, if a user's
|
||||
identity is not verified, the message is rejected before it gets to the
|
||||
service. This is illustrated in :ref:`authComponent`.
|
||||
|
||||
.. _authComponent:
|
||||
|
||||
Authentication Component
|
||||
------------------------
|
||||
|
||||
Figure 1. Authentication Component
|
||||
|
||||
.. image:: images/graphs_authComp.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: An Authentication Component
|
||||
|
||||
Authentication components may operate in 'delegated mode'. In this mode, the
|
||||
decision reject an unauthenticated client is delegated to the OpenStack
|
||||
service. Delegated mode is illustrated in :ref:`authComponentDelegated`.
|
||||
|
||||
Here, requests are forwarded to the OpenStack service with an identity status
|
||||
message that indicates whether the client's identity has been confirmed or is
|
||||
indeterminate. It is the OpenStack service that decides whether or not a reject
|
||||
message should be sent to the client. Note that it is always the responsibility
|
||||
of the Authentication Component to transmit reject messages to the client.
|
||||
|
||||
.. _authComponentDelegated:
|
||||
|
||||
Authentication Component (Delegated Mode)
|
||||
-----------------------------------------
|
||||
|
||||
Figure 2. Authentication Component (Delegated Mode)
|
||||
|
||||
.. image:: images/graphs_authCompDelegate.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: An Authentication Component (Delegated Mode)
|
||||
|
||||
In this architecture, we define interactions between the authentication component
|
||||
and the OpenStack service. Interactions between the client and the
|
||||
authentication component are defined only for exceptional cases. For example,
|
||||
we define the message that should be returned when the OpenStack service is
|
||||
down. Other interactions, however, are defined by the underlying authentication
|
||||
protocol and the OpenStack service and are considered out of scope.
|
||||
|
||||
.. _deployStrategies:
|
||||
|
||||
Deployment Strategies
|
||||
=====================
|
||||
|
||||
An authentication component may be integrated directly into the service
|
||||
implementation, or it may be deployed separately as an HTTP reverse proxy. This
|
||||
is illustrated in :ref:`deployment`, showing both approaches to
|
||||
authentication, labeled Option (a) and Option (b).
|
||||
|
||||
.. _deployment:
|
||||
|
||||
Authentication Component Deployments Options
|
||||
--------------------------------------------
|
||||
|
||||
Figure 3. Authentication Component Deployments Options
|
||||
|
||||
.. image:: images/images_layouts.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Authentication Component Deployments Options
|
||||
|
||||
In Option (a), the component is integrated into the service implementation. In
|
||||
this case, communication between the authentication component and the service
|
||||
can be efficiently implemented via a method call. In Option (b), the component
|
||||
is deployed separately and communication between the service and the component
|
||||
involves an HTTP request. In both cases, unauthenticated requests are filtered
|
||||
before they reach the service.
|
||||
|
||||
Each approach offers some benefits. Option (a) offers low latency and ease of
|
||||
initial implementation, making it possibly most appropriate as a starting point
|
||||
for simple configurations. Option (b) offers several key advantages that may be
|
||||
of particular value in complex and dynamic configurations. It offers the
|
||||
ability to scale horizontally in cases where authentication is computationally
|
||||
expensive, such as when verifying digital signatures. Option (b) also allows
|
||||
authentication components to be written in different programming languages.
|
||||
Finally, Option (b) allows multiple authentication components to be deployed in
|
||||
front of the same service.
|
||||
|
||||
OpenStack services can support both embedded (Option (a)) and external (Option
|
||||
(b)) deployment strategies. Individual authentication components should support
|
||||
either strategy or they |may| support both strategies. In order to support
|
||||
option (a), authentication components written in the Python programming
|
||||
language should be written as WSGI middleware components (in accordance with
|
||||
the Web Server Gateway Interface (WSGI) standard [PEP-333]_.
|
||||
|
||||
Additionally, services should support the ability to swap between different
|
||||
embedded or external authentication components via configuration options.
|
||||
|
||||
Exchanging User Information
|
||||
===========================
|
||||
|
||||
If a request is successfully authenticated, the authentication component must
|
||||
extend the request by adding an ``X-Authorization`` header. The header |must|
|
||||
be formatted as illustrated in :ref:`xAuthHeader`.
|
||||
|
||||
.. _xAuthHeader:
|
||||
|
||||
X-Authorization Header
|
||||
----------------------
|
||||
|
||||
Example 1. X-Authorization Header::
|
||||
|
||||
X-Authorization: Proxy JoeUser
|
||||
|
||||
Here, `Proxy` denotes that the authentication occurred via a proxy (in this
|
||||
case authentication component) and ''JoeUser'' is the name of the user who
|
||||
issued the request.
|
||||
|
||||
.. note:
|
||||
|
||||
We considered using an ``Authorization`` header rather than an
|
||||
``X-Authorization``, thereby following normal HTTP semantics. There are some
|
||||
cases, however, where multiple ``Authorization`` headers need to be transmitted
|
||||
in a single request. We want to assure ourselves that this will not break
|
||||
common clients before we recommend the approach.
|
||||
|
||||
Authentication components |may| extend the request with additional
|
||||
information. For example, an authentication system may add additional headers
|
||||
or modify the target URI to pass authentication information to the back-end
|
||||
service. Additionally, an authentication component |may| strip sensitive
|
||||
information — a plain text password, for example — from the request. That said,
|
||||
an authentication component |should| pass the majority of the request
|
||||
unmodified.
|
||||
|
||||
Reverse Proxy Authentication
|
||||
----------------------------
|
||||
|
||||
An OpenStack service |should| verify that it is receiving requests from a
|
||||
trusted authentication component. This is particularly important in cases where
|
||||
the authentication component and the OpenStack service are deployed separately.
|
||||
In order to trust incoming requests, the OpenStack service should therefore
|
||||
authenticate the authentication component. To avoid confusion, we call this
|
||||
'reverse proxy authentication', since in this case the authentication
|
||||
component is acting as an HTTP reverse proxy.
|
||||
|
||||
Any HTTP-based authentication scheme may be used for reverse proxy
|
||||
authentication; however, all OpenStack services and all authentication
|
||||
components |must| support HTTP Basic Authentication as defined in
|
||||
[RFC-2617]_.
|
||||
|
||||
Whether or not reverse proxy authentication is required is strictly a
|
||||
deployment concern. For example, an operations team may opt to utilize firewall
|
||||
rules instead of an authentication protocol to verify the integrity of incoming
|
||||
request. Because of this, both OpenStack services and authentication components
|
||||
|must| also allow for unauthenticated communication.
|
||||
|
||||
In cases where reverse proxy authentication is used, the authorization
|
||||
component may receive an HTTP 401 authentication error or an HTTP 403
|
||||
authorization error. These errors indicate that the component does not have
|
||||
access to the underlying OpenStack service. The authentication component
|
||||
|must not| return these errors to the client application. Instead, the
|
||||
component |must| return a 500 internal error. This is illustrated in
|
||||
:ref:`proxyAuth` and :ref:`proxyAuthDelegated` below. The component
|
||||
|should| format the errors in a manner that does not break the service
|
||||
contract defined by the OpenStack service. :ref:`proxyAuthDelegated`
|
||||
illustrates proxy authorization in delegated mode. Delegated mode is discussed
|
||||
in detail in the next section.
|
||||
|
||||
.. _proxyAuth:
|
||||
|
||||
Reverse Proxy Authentication
|
||||
----------------------------
|
||||
|
||||
Figure 4. Reverse Proxy Authentication
|
||||
|
||||
.. image:: images/graphs_proxyAuth.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Reverse Proxy Authentication
|
||||
|
||||
.. _proxyAuthDelegated:
|
||||
|
||||
Reverse Proxy Authentication (Delegated Mode)
|
||||
---------------------------------------------
|
||||
|
||||
Figure 5. Reverse Proxy Authentication (Delegated Mode)
|
||||
|
||||
.. image:: images/graphs_delegate_forbiden_proxy.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Reverse Proxy Authentication (Delegated Mode)
|
||||
|
||||
Delegated Mode
|
||||
==============
|
||||
In some cases, the decision to reject an unauthenticated request should be
|
||||
delegated to the OpenStack service. An unauthenticated request may be
|
||||
appropriate in cases when anonymous access is allowed. In order to support
|
||||
these cases, an authentication component may be placed in Delegated Mode. In
|
||||
this mode, the component forwards requests to the OpenStack service when the
|
||||
client's identity has been confirmed or is indeterminate — that is when
|
||||
credentials are missing. The authentication component directly rejects requests
|
||||
with invalid credentials. Authentication components |must| extend the
|
||||
request by adding an `X-Identity-Status` header. The identity status header
|
||||
|must| contain one of the following values:
|
||||
|
||||
Identity Status Values
|
||||
----------------------
|
||||
|
||||
Confirmed
|
||||
A `confirmed` value indicates that valid credentials were sent and identity
|
||||
has been confirmed. The service can trust that the request has been sent on
|
||||
behalf of the user specified in the `X-Authorization` header.
|
||||
|
||||
Indeterminate
|
||||
An `indeterminate` value indicates that no credentials were sent and
|
||||
identity has not been confirmed. In this case, the service will receive an
|
||||
`X-Authorization` header with no user entry as illustrated in
|
||||
:ref:`xauth-header-indeterminate`.
|
||||
|
||||
.. _xauth-header-indeterminate:
|
||||
|
||||
Indeterminate Identity Headers
|
||||
------------------------------
|
||||
|
||||
Example 2. Indeterminate Identity Headers::
|
||||
|
||||
X-Identity-Status: Indeterminate
|
||||
X-Authorization: Proxy
|
||||
|
||||
Services |may| reject a delegated request by issuing an HTTP 401
|
||||
authentication error or an HTTP 403 authorization error. These responses
|
||||
|must| contain an ``WWW-Authenticate`` header with a value of ``Delegated`` as
|
||||
illustrated in :ref:`unauthHeaders`.
|
||||
|
||||
X-Identity-Status
|
||||
Provides information on whether the request was authenticated or not.
|
||||
|
||||
X-Tenant
|
||||
Provides the tenant ID (as it appears in the URL in Keystone). This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants.
|
||||
|
||||
X-Tenant-Id
|
||||
The unique, immutable tenant Id
|
||||
|
||||
X-Tenant-Name
|
||||
The unique, but mutable (it can change) tenant name.
|
||||
|
||||
X-User-Id
|
||||
The user id of the user used to log in
|
||||
|
||||
X-User-Name
|
||||
The username used to log in
|
||||
|
||||
X-User
|
||||
The username used to log in. This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants.
|
||||
|
||||
X-Roles
|
||||
The roles associated with that user
|
||||
|
||||
.. _unauthHeaders:
|
||||
|
||||
Delegated WWW-Authenticate Header
|
||||
---------------------------------
|
||||
|
||||
::
|
||||
|
||||
WWW-Authenticate: Delegated
|
||||
|
||||
It is important to note that the actual reject message will likely be modified
|
||||
by the authentication component in order to comply with the authentication
|
||||
scheme it is implementing. This is illustrated in :ref:`delegateRejectBasic` and
|
||||
:ref:`delegateRejectOAuth` below.
|
||||
|
||||
.. _delegateRejectBasic:
|
||||
|
||||
Delegated Reject Basic Auth
|
||||
---------------------------
|
||||
|
||||
.. image:: images/graphs_delegate_reject_basic.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Delegated Reject Basic Auth
|
||||
|
||||
.. _delegateRejectOAuth:
|
||||
|
||||
Delegated Reject OAuth
|
||||
----------------------
|
||||
|
||||
.. image:: images/graphs_delegate_reject_oauth.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Delegated Reject OAuth
|
||||
|
||||
The presence of the `WWW-Authenticate` header with a value of `Delegated`
|
||||
distinguishes a client authentication/authorization failure from a component
|
||||
failure. For example, compare :ref:`delegateForbidden` with :ref:`proxyAuthDelegated`. In
|
||||
:ref:`delegateForbidden`, the client is not allowed to access the OpenStack service.
|
||||
In :ref:`proxyAuthDelegated`, it is the authentication component itself which is
|
||||
unauthorized.
|
||||
|
||||
.. _delegateForbidden:
|
||||
|
||||
Delegated Reject Forbidden
|
||||
--------------------------
|
||||
|
||||
Figure 8. Delegated Reject Forbidden
|
||||
|
||||
.. image:: images/graphs_delegate_forbiden_basic.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Delegated Reject Forbidden
|
||||
|
||||
Authentication components |must| support both delegated and undelegated
|
||||
(standard) modes. Delegated mode |should| be configured via a configuration
|
||||
option. Delegated mode |should| be disabled by default.
|
||||
|
||||
OpenStack services are not required to support delegated mode. If a service
|
||||
does not support delegated mode, it |must| respond with a 501 not implemented
|
||||
error and an `WWW-Authenticate` header with a value of `Delegated`. The
|
||||
authentication component |must not| return the error to the client
|
||||
application. Instead, the component |must| return a 500 internal error; this is
|
||||
illustrated in :ref:`delegateUnimplemented`. The component |should|
|
||||
format the error in a manner that does not break the service contract defined
|
||||
by the OpenStack service. The component should also log the error such that it
|
||||
that will inform operators of the misconfiguration.
|
||||
|
||||
.. _delegateUnimplemented:
|
||||
|
||||
Unimplemented Delegated Mode
|
||||
----------------------------
|
||||
|
||||
.. image:: images/graphs_delegate_unimplemented.svg
|
||||
:width: 100%
|
||||
:height: 180
|
||||
:alt: Unimplemented Delegated Mode
|
||||
|
||||
Handling Direct Client Connections
|
||||
==================================
|
||||
|
||||
Requests from the authentication component to an OpenStack service |must|
|
||||
contain an ``X-Authorization`` header. If the header is missing, and reverse
|
||||
proxy authentication fails or is switched off, the OpenStack service |may|
|
||||
assume that the request is coming directly from a client application. In this
|
||||
case, the OpenStack service |must| redirect the request to the authentication
|
||||
component by issuing an HTTP 305 User Proxy redirect. This is illustrated in
|
||||
:ref:`redirect`. Note that the redirect response |must| include a ``Location`` header
|
||||
specifying the authentication component's URL as shown in :ref:`redirect-response`.
|
||||
|
||||
.. _redirect:
|
||||
|
||||
Auth Component Redirect
|
||||
-----------------------
|
||||
|
||||
.. image:: images/graphs_305.svg
|
||||
:width: 100%
|
||||
:height: 280
|
||||
:alt: Auth Component Redirect
|
||||
|
||||
.. _redirect-response:
|
||||
|
||||
Auth Component Redirect Response
|
||||
--------------------------------
|
||||
|
||||
::
|
||||
|
||||
HTTP/1.1 305 Use Proxy
|
||||
Date: Thu, 28 Oct 2011 07:41:16 GMT
|
||||
Location: http://sample.auth.openstack.com/path/to/resource
|
||||
|
||||
Using Multiple Authentication Components
|
||||
========================================
|
||||
|
||||
There are some use cases when a service provider might want to consider using
|
||||
multiple authentication components for different purposes. For instance, a
|
||||
service provider may have one authentication scheme to authenticate the users
|
||||
of the service and another one to authenticate the administrators or operations
|
||||
personnel that maintain the service. For such scenarios, we propose using a
|
||||
mapper as illustrated in :ref:`multiAuth`.
|
||||
|
||||
.. _multiAuth:
|
||||
|
||||
Multiple Authentication Components
|
||||
----------------------------------
|
||||
|
||||
.. image:: images/graphs_mapper.svg
|
||||
:width: 100%
|
||||
:height: 320
|
||||
:alt: Multiple Authentication Components
|
||||
|
||||
At a high level, a mapper is a simple reverse proxy that intercepts HTTP calls
|
||||
from clients and routes the request to the appropriate authentication
|
||||
component. A mapper can make the routing decisions based on a number of routing
|
||||
rules that map a resource to a specific authentication component. For example,
|
||||
a request URI may determine whether a call should be authenticated via one
|
||||
authentication component or another.
|
||||
|
||||
Note that neither the authentication component nor the OpenStack service need
|
||||
be aware of the mapper. Any external authentication component can be used
|
||||
alongside others. Mappers may provide a means by which to offer support for
|
||||
anonymous or guest access to a subset of service resources. A mapper may be
|
||||
implemented via a traditional reverse proxy server such as Pound or Zeus.
|
||||
|
||||
The Default Component
|
||||
=====================
|
||||
|
||||
Individual services |must| be distributed with a simple integrated
|
||||
authentication component by default. Providing such a component lowers barriers
|
||||
to the deployment of individual services. This is especially important to]
|
||||
developers who may want to deploy OpenStack services on their own machines.
|
||||
Also, since there is no direct dependency on an external authentication system,
|
||||
OpenStack services can be deployed individually, without the need to stand up
|
||||
and configure additional services. Finally, having a standard authentication
|
||||
component that all services share promotes a separation of concerns. That is,
|
||||
as a community we are explicitly stating that services should not develop their
|
||||
own authentication mechanisms. Additional authentication components may be
|
||||
developed, of course, but these components should not be intimately coupled to
|
||||
any one particular service.
|
||||
|
||||
As discussed in :ref:`deployStrategies`, an authentication component may be
|
||||
integrated directly into the service implementation (Option (a)), or it may be
|
||||
deployed separately as an HTTP reverse proxy (Option (b)). The default
|
||||
component should be implemented to support Option (a) and services should
|
||||
maintain support for Option (b). One way to achieve this is to provide a
|
||||
method that allows the disabling of the default authentication component via
|
||||
configuration. This is illustrated in :ref:`both`. Here, requests are
|
||||
sent directly to the OpenStack service when the default authentication
|
||||
component is disabled.
|
||||
|
||||
We will discuss the design of the default component in an upcoming blueprint.
|
||||
|
||||
.. _both:
|
||||
|
||||
Disabled Embedded Component
|
||||
---------------------------
|
||||
|
||||
.. image:: images/graphs_both.svg
|
||||
:width: 100%
|
||||
:height: 250
|
||||
:alt: Disabled Embedded Component
|
||||
|
||||
Questions and Answers
|
||||
=====================
|
||||
|
||||
#. Why do authentication components send reject messages? Why not have
|
||||
OpenStack services reject requests themselves?
|
||||
|
||||
The content and format of an authentication failed message is determined by
|
||||
the authentication scheme (or protocol). For the service to respond
|
||||
appropriately, it would have to be aware of the authentication scheme in
|
||||
which it participates; this defeats the purpose of pluggable authentication
|
||||
components.
|
||||
|
||||
#. Why require support for deploying authentication components in separate
|
||||
nodes?
|
||||
|
||||
The deployment strategy is very flexible. It allows for authentication
|
||||
components to be horizontally scalable. It allows for components to be written
|
||||
in different languages. Finally, it allows different authentication components
|
||||
to be deployed simultaneously as described above.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [PEP-333] pep0333 Phillip J Eby. 'Python Web Server Gateway Interface
|
||||
v1.0.'' http://www.python.org/dev/peps/pep-0333/.
|
||||
|
||||
.. [RFC-2617] rfc2617 J Franks. P Hallam-Baker. J Hostetler. S Lawrence.
|
||||
P Leach. A Luotonen. L Stewart. ''HTTP Authentication: Basic and Digest
|
||||
Access Authentication.'' http://tools.ietf.org/html/rfc2617.
|
||||
|
||||
.. |must| replace:: must must
|
||||
.. |should| replace:: should should
|
||||
.. |may| replace:: may may
|
||||
.. |must not| replace:: "must not" "must not"
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
nova-api-paste example
|
||||
======================
|
||||
::
|
||||
|
||||
#######
|
||||
# EC2 #
|
||||
#######
|
||||
|
||||
[composite:ec2]
|
||||
use = egg:Paste#urlmap
|
||||
/: ec2versions
|
||||
/services/Cloud: ec2cloud
|
||||
/services/Admin: ec2admin
|
||||
/latest: ec2metadata
|
||||
/2007-01-19: ec2metadata
|
||||
/2007-03-01: ec2metadata
|
||||
/2007-08-29: ec2metadata
|
||||
/2007-10-10: ec2metadata
|
||||
/2007-12-15: ec2metadata
|
||||
/2008-02-01: ec2metadata
|
||||
/2008-09-01: ec2metadata
|
||||
/2009-04-04: ec2metadata
|
||||
/1.0: ec2metadata
|
||||
|
||||
[pipeline:ec2cloud]
|
||||
pipeline = logrequest totoken authtoken keystonecontext cloudrequest authorizer ec2executor
|
||||
|
||||
[pipeline:ec2admin]
|
||||
pipeline = logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor
|
||||
|
||||
[pipeline:ec2metadata]
|
||||
pipeline = logrequest ec2md
|
||||
|
||||
[pipeline:ec2versions]
|
||||
pipeline = logrequest ec2ver
|
||||
|
||||
[filter:logrequest]
|
||||
paste.filter_factory = nova.api.ec2:RequestLogging.factory
|
||||
|
||||
[filter:ec2lockout]
|
||||
paste.filter_factory = nova.api.ec2:Lockout.factory
|
||||
|
||||
[filter:totoken]
|
||||
paste.filter_factory = keystone.middleware.ec2_token:EC2Token.factory
|
||||
|
||||
[filter:ec2noauth]
|
||||
paste.filter_factory = nova.api.ec2:NoAuth.factory
|
||||
|
||||
[filter:authenticate]
|
||||
paste.filter_factory = nova.api.ec2:Authenticate.factory
|
||||
|
||||
[filter:cloudrequest]
|
||||
controller = nova.api.ec2.cloud.CloudController
|
||||
paste.filter_factory = nova.api.ec2:Requestify.factory
|
||||
|
||||
[filter:adminrequest]
|
||||
controller = nova.api.ec2.admin.AdminController
|
||||
paste.filter_factory = nova.api.ec2:Requestify.factory
|
||||
|
||||
[filter:authorizer]
|
||||
paste.filter_factory = nova.api.ec2:Authorizer.factory
|
||||
|
||||
[app:ec2executor]
|
||||
paste.app_factory = nova.api.ec2:Executor.factory
|
||||
|
||||
[app:ec2ver]
|
||||
paste.app_factory = nova.api.ec2:Versions.factory
|
||||
|
||||
[app:ec2md]
|
||||
paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory
|
||||
|
||||
#############
|
||||
# Openstack #
|
||||
#############
|
||||
|
||||
[composite:osapi]
|
||||
use = egg:Paste#urlmap
|
||||
/: osversions
|
||||
/v1.1: openstackapi
|
||||
|
||||
[pipeline:openstackapi]
|
||||
pipeline = faultwrap authtoken keystonecontext ratelimit extensions osapiapp
|
||||
|
||||
[filter:faultwrap]
|
||||
paste.filter_factory = nova.api.openstack:FaultWrapper.factory
|
||||
|
||||
[filter:auth]
|
||||
paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory
|
||||
|
||||
[filter:noauth]
|
||||
paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory
|
||||
|
||||
[filter:ratelimit]
|
||||
paste.filter_factory = nova.api.openstack.limits:RateLimitingMiddleware.factory
|
||||
|
||||
[filter:extensions]
|
||||
paste.filter_factory = nova.api.openstack.extensions:ExtensionMiddleware.factory
|
||||
|
||||
[app:osapiapp]
|
||||
paste.app_factory = nova.api.openstack:APIRouter.factory
|
||||
|
||||
[pipeline:osversions]
|
||||
pipeline = faultwrap osversionapp
|
||||
|
||||
[app:osversionapp]
|
||||
paste.app_factory = nova.api.openstack.versions:Versions.factory
|
||||
|
||||
##########
|
||||
# Shared #
|
||||
##########
|
||||
|
||||
[filter:keystonecontext]
|
||||
paste.filter_factory = keystone.middleware.nova_keystone_context:NovaKeystoneContext.factory
|
||||
|
||||
[filter:authtoken]
|
||||
paste.filter_factory = keystone.middleware.auth_token:filter_factory
|
||||
service_protocol = http
|
||||
service_host = 127.0.0.1
|
||||
service_port = 5000
|
||||
auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
auth_protocol = http
|
||||
auth_uri = http://127.0.0.1:5000/
|
||||
admin_token = 999888777666
|
||||
;Uncomment next line and check ip:port to use memcached to cache token requests
|
||||
;memcache_hosts = 127.0.0.1:11211
|
|
@ -0,0 +1,188 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
========
|
||||
Backends
|
||||
========
|
||||
|
||||
Keystone supports multiple types of data stores for things like users, tenants, and
|
||||
tokens, including SQL, LDAP, and memcache.
|
||||
|
||||
SQL
|
||||
===
|
||||
|
||||
In the default backend configuration (SQL-only), Keystone depends on the following database tables.
|
||||
|
||||
``users``
|
||||
---------
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``name``
|
||||
Unqiue username used for authentication via ``passwordCredentials``.
|
||||
``password``
|
||||
Password used for authentication via ``passwordCredentials``.
|
||||
|
||||
Salted and hashed using ``passlib``.
|
||||
``email``
|
||||
Email address (uniqueness is expected, but not enforced).
|
||||
``enabled``
|
||||
If false, the user is unable to authenticate and the user's tokens will fail validation.
|
||||
``tenant_id``
|
||||
Default tenant for the user.
|
||||
|
||||
``tokens``
|
||||
----------
|
||||
|
||||
``id``
|
||||
The actual token provided after successful authentication (*plaintext*).
|
||||
``user_id``
|
||||
References the user who owns the token.
|
||||
``tenant_id``
|
||||
(*optional*) References the tenant the token is scoped to.
|
||||
``expires``
|
||||
Indicates the expiration date of the token, after which the token can no longer be validated successfully.
|
||||
|
||||
``tenants``
|
||||
-----------
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``name``
|
||||
Unique string identifying the tenant.
|
||||
``desc``
|
||||
Description of the tenant.
|
||||
``enabled``
|
||||
If false, users are unable to scope to the tenant.
|
||||
|
||||
``roles``
|
||||
---------
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``name``
|
||||
Name of the role.
|
||||
|
||||
If the role is owned by a service, the role name **must** follow the convention::
|
||||
|
||||
serviceName:roleName
|
||||
``desc``
|
||||
Description of the role.
|
||||
``service_id``
|
||||
(*optional*) References the service that owns the role.
|
||||
|
||||
``user_roles``
|
||||
--------------
|
||||
|
||||
Maps users to the roles that have been granted to them (*optionally*, within the scope of a tenant).
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``user_id``
|
||||
References the user the role is granted to.
|
||||
``role_id``
|
||||
References the granted role.
|
||||
``tenant_id``
|
||||
(*optional*) References a tenant upon which this grant is applies.
|
||||
|
||||
``services``
|
||||
------------
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``name``
|
||||
Unique name of the service.
|
||||
``type``
|
||||
Indicates the type of service (e.g. ``compute``, ``object``, ``identity``, etc).
|
||||
|
||||
This can also be extended to support non-core services. Extended services
|
||||
follow the naming convention ``extension:type`` (e.g. ``dnsextension:dns``).
|
||||
``desc``
|
||||
Describes the service.
|
||||
``owner_id``
|
||||
(*optional*) References the user who owns the service.
|
||||
|
||||
``credentials``
|
||||
---------------
|
||||
|
||||
Currently only used for Amazon EC2 credential storage, this table is designed to support multiple
|
||||
types of credentials in the future.
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``user_id``
|
||||
References the user who owns the credential.
|
||||
``tenant_id``
|
||||
References the tenant upon which the credential is valid.
|
||||
``types``
|
||||
Indicates the type of credential (e.g. ``Password``, ``APIKey``, ``EC2``).
|
||||
``key``
|
||||
Amazon EC2 access key.
|
||||
``secret``
|
||||
Amazon EC2 secret key.
|
||||
|
||||
``endpoints``
|
||||
-------------
|
||||
|
||||
Tenant-specific endpoints map endpoint templates to specific tenants.
|
||||
The ``tenant_id`` which appears here replaces the
|
||||
``%tenant_id%`` template variable in the specified endpoint template.
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``tenant_id``
|
||||
References the tenant this endpoint applies to.
|
||||
``endpoint_template_id``
|
||||
The endpoint template to appear in the user's service catalog.
|
||||
|
||||
``endpoint_templates``
|
||||
----------------------
|
||||
|
||||
A multi-purpose model for the service catalog which can be:
|
||||
|
||||
- Provided to users of a specific tenants via ``endpoints``, when ``is_global`` is false.
|
||||
- Provided to all users as-is, when ``is_global`` is true.
|
||||
|
||||
``id``
|
||||
Auto-incremented primary key.
|
||||
``region``
|
||||
Identifies the geographic region the endpoint is physically located within.
|
||||
``service_id``
|
||||
TODO: References the service which owns the endpoints?
|
||||
``public_url``
|
||||
Appears in the service catalog [#first]_.
|
||||
|
||||
Represents an endpoint available on the public Internet.
|
||||
``admin_url``
|
||||
Appears in the service catalog [#first]_.
|
||||
|
||||
Users of this endpoint must have an Admin or ServiceAdmin role.
|
||||
``internal_url``
|
||||
Appears in the service catalog [#first]_.
|
||||
|
||||
Represents an endpoint on an internal, unmetered network.
|
||||
``enabled``
|
||||
If false, this endpoint template will not appear in the service catalog.
|
||||
``is_global``
|
||||
If true, this endpoint can not be mapped to tenant-specific endpoints, and ``%tenant_id%`` will not be substituted in endpoint URL's. Additionally, this endpoint will appear for all users.
|
||||
``version_id``
|
||||
Identifies the version of the API contract that endpoint supports.
|
||||
``version_list``
|
||||
A URL which lists versions supported by the endpoint.
|
||||
``version_info``
|
||||
A URL which provides detailed version info regarding the service.
|
||||
|
||||
.. [#first] ``%tenant_id%`` may be replaced by actual tenant references, depending on the value of ``is_global`` and the existence of a corresponding ``endpoints`` record.
|
|
@ -0,0 +1,288 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
============================
|
||||
Controlling Keystone Servers
|
||||
============================
|
||||
|
||||
This section describes the ways to start, stop, and reload the Keystone
|
||||
services.
|
||||
|
||||
Keystone Services
|
||||
-----------------
|
||||
|
||||
Keystone can serve a number of REST APIs and extensions on different TCP/IP
|
||||
ports.
|
||||
|
||||
The Service API
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The core Keystone
|
||||
API is primarily a read-only API (the only write operation being POST /tokens
|
||||
which authenticates a client, and returns a generated token).
|
||||
This API is sufficient to use OpenStack if all users, roles, endpoints already
|
||||
exist. This is often the case if Keystone is using an enterprise backend
|
||||
and the backend is managed through other entperrise tools and business
|
||||
processes. This core API is called the Service API and can be started
|
||||
separately from the more complete Admin API. By default, Keystone runs
|
||||
this API on port 5000. This is not an IANA assigned port and should not
|
||||
be relied upon (instead, use the Admin API on port 35357 to look for
|
||||
this endpoint - more on this later)
|
||||
|
||||
The Service API is started using this command in the /bin directory::
|
||||
|
||||
$ ./keystone-auth
|
||||
|
||||
The Admin API
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Inn order for Keystone to be a fully functional service out of the box,
|
||||
API extensions that provide full CRUD operations is included with Keystone.
|
||||
This full set of API calls includes the OS-KSCATALOG, OS-KSADM, and OS-KSEC2
|
||||
extensions. These extensions provide a full set of create, read, update, delete
|
||||
(CRUD) operations that can be used to manage Keystone objects through REST
|
||||
calls. By default Keystone runs this full REST API on TCP/IP port 35357
|
||||
(assigned by IANA to Keystone).
|
||||
|
||||
The Admin API is started using this command in the /bin directory::
|
||||
|
||||
$ ./keystone-admin
|
||||
|
||||
|
||||
Both APIs can be loaded simultaneously (on different ports) using this command::
|
||||
|
||||
$ ./keystone
|
||||
|
||||
Starting a server
|
||||
-----------------
|
||||
|
||||
There are two ways to start a Keystone service (either the Service API server
|
||||
or the Admin API server):
|
||||
|
||||
- Manually calling the server program
|
||||
- Using the ``keystone-control`` server daemon wrapper program
|
||||
|
||||
We recommend using the second way in production and the first for development
|
||||
and debugging.
|
||||
|
||||
Manually starting the server
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The first is by directly calling the server program, passing in command-line
|
||||
options and a single argument for a ``paste.deploy`` configuration file to
|
||||
use when configuring the server application.
|
||||
|
||||
.. note::
|
||||
|
||||
Keystone ships with an ``etc/`` directory that contains a sample ``paste.deploy``
|
||||
configuration files that you can copy to a standard configuration directory and
|
||||
adapt for your own uses.
|
||||
|
||||
If you do `not` specify a configuration file on the command line, Keystone will
|
||||
do its best to locate a configuration file in one of the
|
||||
following directories, stopping at the first config file it finds:
|
||||
|
||||
- ``$CWD``
|
||||
- ``~/.keystone``
|
||||
- ``~/``
|
||||
- ``/etc/keystone``
|
||||
- ``/etc``
|
||||
|
||||
The filename that is searched for is ``keystone.conf`` by default.
|
||||
|
||||
If no configuration file is found, you will see an error, like::
|
||||
|
||||
$ keystone
|
||||
ERROR: Unable to locate any configuration file. Cannot load application keystone
|
||||
|
||||
Here is an example showing how you can manually start the ``keystone-auth`` server and ``keystone-registry`` in a shell::
|
||||
|
||||
$ ./keystone -d
|
||||
keystone-legacy-auth: INFO **************************************************
|
||||
keystone-legacy-auth: INFO Configuration options gathered from config file:
|
||||
keystone-legacy-auth: INFO /Users/ziadsawalha/Documents/Code/keystone/etc/keystone.conf
|
||||
keystone-legacy-auth: INFO ================================================
|
||||
keystone-legacy-auth: INFO admin_host 0.0.0.0
|
||||
keystone-legacy-auth: INFO admin_port 35357
|
||||
keystone-legacy-auth: INFO admin_ssl False
|
||||
keystone-legacy-auth: INFO backends keystone.backends.sqlalchemy
|
||||
keystone-legacy-auth: INFO ca_certs /etc/keystone/ssl/certs/ca.pem
|
||||
keystone-legacy-auth: INFO cert_required True
|
||||
keystone-legacy-auth: INFO certfile /etc/keystone/ssl/certs/keystone.pem
|
||||
keystone-legacy-auth: INFO debug True
|
||||
keystone-legacy-auth: INFO default_store sqlite
|
||||
keystone-legacy-auth: INFO extensions osksadm,oskscatalog,hpidm
|
||||
keystone-legacy-auth: INFO hash-password True
|
||||
keystone-legacy-auth: INFO keyfile /etc/keystone/ssl/private/keystonekey.pem
|
||||
keystone-legacy-auth: INFO keystone-admin-role Admin
|
||||
keystone-legacy-auth: INFO keystone-service-admin-role KeystoneServiceAdmin
|
||||
keystone-legacy-auth: INFO log_dir .
|
||||
keystone-legacy-auth: INFO log_file keystone.log
|
||||
keystone-legacy-auth: INFO service-header-mappings {
|
||||
'nova' : 'X-Server-Management-Url',
|
||||
'swift' : 'X-Storage-Url',
|
||||
'cdn' : 'X-CDN-Management-Url'}
|
||||
keystone-legacy-auth: INFO service_host 0.0.0.0
|
||||
keystone-legacy-auth: INFO service_port 5000
|
||||
keystone-legacy-auth: INFO service_ssl False
|
||||
keystone-legacy-auth: INFO verbose False
|
||||
keystone-legacy-auth: INFO **************************************************
|
||||
passlib.registry: INFO registered crypt handler 'sha512_crypt': <class 'passlib.handlers.sha2_crypt.sha512_crypt'>
|
||||
Starting the RAX-KEY extension
|
||||
Starting the Legacy Authentication component
|
||||
admin : INFO **************************************************
|
||||
admin : INFO Configuration options gathered from config file:
|
||||
admin : INFO /Users/ziadsawalha/Documents/Code/keystone/etc/keystone.conf
|
||||
admin : INFO ================================================
|
||||
admin : INFO admin_host 0.0.0.0
|
||||
admin : INFO admin_port 35357
|
||||
admin : INFO admin_ssl False
|
||||
admin : INFO backends keystone.backends.sqlalchemy
|
||||
admin : INFO ca_certs /etc/keystone/ssl/certs/ca.pem
|
||||
admin : INFO cert_required True
|
||||
admin : INFO certfile /etc/keystone/ssl/certs/keystone.pem
|
||||
admin : INFO debug True
|
||||
admin : INFO default_store sqlite
|
||||
admin : INFO extensions osksadm,oskscatalog,hpidm
|
||||
admin : INFO hash-password True
|
||||
admin : INFO keyfile /etc/keystone/ssl/private/keystonekey.pem
|
||||
admin : INFO keystone-admin-role Admin
|
||||
admin : INFO keystone-service-admin-role KeystoneServiceAdmin
|
||||
admin : INFO log_dir .
|
||||
admin : INFO log_file keystone.log
|
||||
admin : INFO service-header-mappings {
|
||||
'nova' : 'X-Server-Management-Url',
|
||||
'swift' : 'X-Storage-Url',
|
||||
'cdn' : 'X-CDN-Management-Url'}
|
||||
admin : INFO service_host 0.0.0.0
|
||||
admin : INFO service_port 5000
|
||||
admin : INFO service_ssl False
|
||||
admin : INFO verbose False
|
||||
admin : INFO **************************************************
|
||||
Using config file: /Users/ziadsawalha/Documents/Code/keystone/etc/keystone.conf
|
||||
Service API (ssl=False) listening on 0.0.0.0:5000
|
||||
Admin API (ssl=False) listening on 0.0.0.0:35357
|
||||
eventlet.wsgi.server: DEBUG (77128) wsgi starting up on http://0.0.0.0:5000/
|
||||
eventlet.wsgi.server: DEBUG (77128) wsgi starting up on http://0.0.0.0:35357/
|
||||
|
||||
$ sudo keystone-registry keystone-registry.conf &
|
||||
jsuh@mc-ats1:~$ 2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] PRAGMA table_info("images")
|
||||
2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] ()
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk')
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (0, u'created_at', u'DATETIME', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (1, u'updated_at', u'DATETIME', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (2, u'deleted_at', u'DATETIME', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (3, u'deleted', u'BOOLEAN', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (4, u'id', u'INTEGER', 1, None, 1)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (5, u'name', u'VARCHAR(255)', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (6, u'disk_format', u'VARCHAR(20)', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (7, u'container_format', u'VARCHAR(20)', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (8, u'size', u'INTEGER', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (9, u'status', u'VARCHAR(30)', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (10, u'is_public', u'BOOLEAN', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (11, u'location', u'TEXT', 0, None, 0)
|
||||
2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] PRAGMA table_info("image_properties")
|
||||
2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] ()
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk')
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (0, u'created_at', u'DATETIME', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (1, u'updated_at', u'DATETIME', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (2, u'deleted_at', u'DATETIME', 0, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (3, u'deleted', u'BOOLEAN', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (4, u'id', u'INTEGER', 1, None, 1)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (5, u'image_id', u'INTEGER', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (6, u'key', u'VARCHAR(255)', 1, None, 0)
|
||||
2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (7, u'value', u'TEXT', 0, None, 0)
|
||||
|
||||
$ ps aux | grep keystone
|
||||
myuser 77148 0.0 0.0 2434892 472 s012 U+ 11:50AM 0:00.01 grep keystone
|
||||
myuser 77128 0.0 0.6 2459356 25360 s011 S+ 11:48AM 0:00.82 python ./keystone -d
|
||||
|
||||
Simply supply the configuration file as the first argument
|
||||
and then any common options
|
||||
you want to use (``-d`` was used above to show some of the debugging
|
||||
output that the server shows when starting up. Call the server program
|
||||
with ``--help`` to see all available options you can specify on the
|
||||
command line.)
|
||||
|
||||
Using ``--trace-calls`` is useful for showing a trace of calls (errors in red)
|
||||
for debugging.
|
||||
|
||||
For more information on configuring the server via the ``paste.deploy``
|
||||
configuration files, see the section entitled
|
||||
:doc:`Configuring Keystone <configuration>`
|
||||
|
||||
Note that the server `daemonizes` itself by using the standard
|
||||
shell backgrounding indicator, ``&``, in the previous example. For most use cases, we recommend
|
||||
using the ``keystone-control`` server daemon wrapper for daemonizing. See below
|
||||
for more details on daemonization with ``keystone-control``.
|
||||
|
||||
Using ``keystone-control`` to start the server
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The second way to start up a Keystone server is to use the ``keystone-control``
|
||||
program. ``keystone-control`` is a wrapper script that allows the user to
|
||||
start, stop, restart, and reload the other Keystone server programs in
|
||||
a fashion that is more conducive to automation and scripting.
|
||||
|
||||
Servers started via the ``keystone-control`` program are always `daemonized`,
|
||||
meaning that the server program process runs in the background.
|
||||
|
||||
To start a Keystone server with ``keystone-control``, simply call
|
||||
``keystone-control`` with a server and the word "start", followed by
|
||||
any command-line options you wish to provide. Start the server with ``keystone-control``
|
||||
in the following way::
|
||||
|
||||
$ sudo keystone-control <SERVER> start [CONFPATH]
|
||||
|
||||
.. note::
|
||||
|
||||
You must use the ``sudo`` program to run ``keystone-control`` currently, as the
|
||||
pid files for the server programs are written to /var/run/keystone/
|
||||
|
||||
Start the ``keystone-admin`` server using ``keystone-control``::
|
||||
|
||||
$ sudo keystone-control admin start
|
||||
Starting keystone-admin with /etc/keystone.conf
|
||||
|
||||
The same ``paste.deploy`` configuration files are used by ``keystone-control``
|
||||
to start the Keystone server programs, and you can specify (as the example above
|
||||
shows) a configuration file when starting the server.
|
||||
|
||||
Stopping a server
|
||||
-----------------
|
||||
|
||||
If you started a Keystone server manually and did not use the ``&`` backgrounding
|
||||
function, simply send a terminate signal to the server process by typing
|
||||
``Ctrl-C``
|
||||
|
||||
If you started the Keystone server using ``keystone-control``, you can
|
||||
use the ``keystone-control`` program to stop it::
|
||||
|
||||
$ sudo keystone-control <SERVER> stop
|
||||
|
||||
For example::
|
||||
|
||||
$ sudo keystone-control auth stop
|
||||
Stopping keystone-auth pid: 77401 signal: 15
|
||||
|
||||
Restarting a server
|
||||
-------------------
|
||||
|
||||
Restart the Keystone server using ``keystone-control``::
|
||||
|
||||
$ sudo keystone-control admin restart /etc/keystone.conf
|
||||
Stopping keystone-admin pid: 77401 signal: 15
|
||||
Starting keystone-admin with /etc/keystone.conf
|
|
@ -0,0 +1,430 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
================================
|
||||
Endpoints and Endpoint Templates
|
||||
================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
What are Endpoints?
|
||||
-------------------
|
||||
|
||||
Simply, endpoints are URLs that point to OpenStack services. When you
|
||||
authenticate to Keystone you get back a token which has a service catalog in
|
||||
it. The service catalog is basically a list of the OpenStack services that
|
||||
you have access to and the URLs you can use to get to them; their endpoints.
|
||||
|
||||
Here is an example response from Keystone when you authenticate::
|
||||
|
||||
{
|
||||
"access":{
|
||||
"token":{
|
||||
"id":"ab48a9efdfedb23ty3494",
|
||||
"expires":"2010-11-01T03:32:15-05:00",
|
||||
"tenant":{
|
||||
"id": "t1000",
|
||||
"name": "My Project"
|
||||
}
|
||||
},
|
||||
"user":{
|
||||
"id":"u123",
|
||||
"name":"jqsmith",
|
||||
"roles":[{
|
||||
"id":"100",
|
||||
"name":"compute:admin"
|
||||
},
|
||||
{
|
||||
"id":"101",
|
||||
"name":"object-store:admin",
|
||||
"tenantId":"t1000"
|
||||
}
|
||||
],
|
||||
"roles_links":[]
|
||||
},
|
||||
"serviceCatalog":[{
|
||||
"name":"Nova",
|
||||
"type":"compute",
|
||||
"endpoints":[{
|
||||
"tenantId":"t1000",
|
||||
"publicURL":"https://compute.north.host.com/v1/t1000",
|
||||
"internalURL":"https://compute.north.internal/v1/t1000",
|
||||
"region":"North",
|
||||
"versionId":"1",
|
||||
"versionInfo":"https://compute.north.host.com/v1/",
|
||||
"versionList":"https://compute.north.host.com/"
|
||||
},
|
||||
{
|
||||
"tenantId":"t1000",
|
||||
"publicURL":"https://compute.north.host.com/v1.1/t1000",
|
||||
"internalURL":"https://compute.north.internal/v1.1/t1000",
|
||||
"region":"North",
|
||||
"versionId":"1.1",
|
||||
"versionInfo":"https://compute.north.host.com/v1.1/",
|
||||
"versionList":"https://compute.north.host.com/"
|
||||
}
|
||||
],
|
||||
"endpoints_links":[]
|
||||
},
|
||||
{
|
||||
"name":"Swift",
|
||||
"type":"object-store",
|
||||
"endpoints":[{
|
||||
"tenantId":"t1000",
|
||||
"publicURL":"https://storage.north.host.com/v1/t1000",
|
||||
"internalURL":"https://storage.north.internal/v1/t1000",
|
||||
"region":"North",
|
||||
"versionId":"1",
|
||||
"versionInfo":"https://storage.north.host.com/v1/",
|
||||
"versionList":"https://storage.north.host.com/"
|
||||
},
|
||||
{
|
||||
"tenantId":"t1000",
|
||||
"publicURL":"https://storage.south.host.com/v1/t1000",
|
||||
"internalURL":"https://storage.south.internal/v1/t1000",
|
||||
"region":"South",
|
||||
"versionId":"1",
|
||||
"versionInfo":"https://storage.south.host.com/v1/",
|
||||
"versionList":"https://storage.south.host.com/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"DNS-as-a-Service",
|
||||
"type":"dnsextension:dns",
|
||||
"endpoints":[{
|
||||
"tenantId":"t1000",
|
||||
"publicURL":"https://dns.host.com/v2.0/t1000",
|
||||
"versionId":"2.0",
|
||||
"versionInfo":"https://dns.host.com/v2.0/",
|
||||
"versionList":"https://dns.host.com/"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Note the following about this response:
|
||||
|
||||
#. There are two endpoints given to the Nova compute service. The only
|
||||
difference between them is the version (1.0 vs. 1.1). This allows for code
|
||||
written to look for the version 1.0 endpoint to still work even after the 1.1
|
||||
version is released.
|
||||
|
||||
#. There are two endpoints for the Swift object-store service. The difference
|
||||
between them is they are in different regions (North and South).
|
||||
|
||||
#. Note the DNS service is global; it does not have a Region. Also, since DNS
|
||||
is not a core OpenStack service, the endpoint type is "dnsextension:dns"
|
||||
showing it is coming from an extension to the Keystone service.
|
||||
|
||||
#. The Region, Tenant, and versionId are listed under the endpoint. You do not
|
||||
(and should not) have to parse those out of the URL. In fact, they may not be
|
||||
embedded in the URL if the service developer so chooses.
|
||||
|
||||
|
||||
What do the fields in an Endpoint mean?
|
||||
---------------------------------------
|
||||
|
||||
The schema definition for an endpoint is in endpoints.xsd under
|
||||
keystone/content/common/xsd in the Keystone code repo. The fields are:
|
||||
|
||||
id
|
||||
A unique ID for the endpoint.
|
||||
|
||||
type
|
||||
The OpenStack-registered type (ex. 'compute', 'object-store', 'image service')
|
||||
This can also be extended using the OpenStack Extension mechanism to support
|
||||
non-core services. Extended services will be in the form ``extension:type``
|
||||
(e.g. ``dnsextension:dns``)
|
||||
|
||||
name
|
||||
This can be anything that the operator of OpenStack chooses. It could be a
|
||||
brand or marketing name (ex. Rackspace Cloud Servers).
|
||||
|
||||
region
|
||||
This is a string that identifies the region where this endpoint exists.
|
||||
Examples are 'North America', 'Europe', 'Asia'. Or 'North' and 'South'. Or
|
||||
'Data Center 1', 'Data Center 2'.
|
||||
The list of regions and what a region means is decided by the operator. The
|
||||
spec treats them as opaque strings.
|
||||
|
||||
publicURL
|
||||
This is the URL to use to access that endpoint over the internet.
|
||||
|
||||
internalURL
|
||||
This is the URL to use to communicate between services. This is genenrally
|
||||
a way to communicate between services over a high bandwidth, low latency,
|
||||
unmetered (free, no bandwidth charges) network. An example would be if you
|
||||
want to access a swift cluster from inside your Nova VMs and want to make
|
||||
sure the communication stays local and does not go over a public network
|
||||
and rack up your bandwidth charges.
|
||||
|
||||
adminURL
|
||||
This is the URL to use to administer the service. In Keystone, this URL
|
||||
is only shown to users with the appropriate rights.
|
||||
|
||||
tenantId
|
||||
If an endpoint is specific to a tenant, the tenantId field identifies the
|
||||
tenant that URL applies to. Some operators include the tenant in the
|
||||
URLs for a service, while others may provide one endpoint and use some
|
||||
other mechanism to identify the tenant. This field is therefore optional.
|
||||
Having this field also means you do not have to parse the URL to identify
|
||||
a tenant if the operator includes it in the URL.
|
||||
|
||||
versionId
|
||||
This identifies the version of the API contract that endpoint supports.
|
||||
While many APIs include the version in the URL (ex: https://compute.host/v1),
|
||||
this field allows you to identify the version without parsing the URL. It
|
||||
therefore also allows operators and service developers to publish endpoints
|
||||
that do not have versions embedded in the URL.
|
||||
|
||||
versionInfo
|
||||
This is the URL to call to get some information on the version. This returns
|
||||
information in this format::
|
||||
|
||||
{
|
||||
"version": {
|
||||
"id": "v2.0",
|
||||
"status": "CURRENT",
|
||||
"updated": "2011-01-21T11:33:21-06:00",
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "http://identity.api.openstack.org/v2.0/"
|
||||
}, {
|
||||
"rel": "describedby",
|
||||
"type": "application/pdf",
|
||||
"href": "http://docs.openstack.org/identity/api/v2.0/identity-latest.pdf"
|
||||
}, {
|
||||
"rel": "describedby",
|
||||
"type": "application/vnd.sun.wadl+xml",
|
||||
"href": "http://docs.openstack.org/identity/api/v2.0/identity.wadl"
|
||||
}
|
||||
],
|
||||
"media-types": [
|
||||
{
|
||||
"base": "application/xml",
|
||||
"type": "application/vnd.openstack.identity+xml;version=2.0"
|
||||
}, {
|
||||
"base": "application/json",
|
||||
"type": "application/vnd.openstack.identity+json;version=2.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
versionList
|
||||
|
||||
This is the URL to call to find out which versions are supported at that
|
||||
endpoint. The response is in this format::
|
||||
|
||||
{
|
||||
"versions":[{
|
||||
"id":"v1.0",
|
||||
"status":"DEPRECATED",
|
||||
"updated":"2009-10-09T11:30:00Z",
|
||||
"links":[{
|
||||
"rel":"self",
|
||||
"href":"http://identity.api.openstack.org/v1.0/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"v1.1",
|
||||
"status":"CURRENT",
|
||||
"updated":"2010-12-12T18:30:02.25Z",
|
||||
"links":[{
|
||||
"rel":"self",
|
||||
"href":"http://identity.api.openstack.org/v1.1/"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":"v2.0",
|
||||
"status":"BETA",
|
||||
"updated":"2011-05-27T20:22:02.25Z",
|
||||
"links":[{
|
||||
"rel":"self",
|
||||
"href":"http://identity.api.openstack.org/v2.0/"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"versions_links":[]
|
||||
}
|
||||
|
||||
Here, the response shows that the endpoint supports version 1.0, 1.1, and 2.0.
|
||||
It also shows that 1.0 is in DEPRECTAED status and 2.0 is in BETA.
|
||||
|
||||
What are Endpoint Templates?
|
||||
----------------------------
|
||||
|
||||
Endpoint Templates are a way for an administrator to manage endpoints en masse.
|
||||
They provide a way to define Endpoints that apply to many or all tenants
|
||||
without having to a create each endpoint on each tenant manually. Without
|
||||
Endpoint Templates, if I wanted to create Endpoints for each tenant in my
|
||||
OpenStack deployment, I'd have to manually create a bunch of endpoints on
|
||||
each tenant (probably when I created the tenant). And then I'd have to go change
|
||||
them all whenever a service changed versions or I added a new service.
|
||||
|
||||
To provide a simpler mechanism to manage endpoints on tenants, Keystone uses
|
||||
Endpoint Templates. I can, for example, define a template with parametrized URLs
|
||||
and set it's `global` to true and that will show up as an endpoint on all the tenants
|
||||
I have. Here is an example:
|
||||
|
||||
Define a global Endpoint Template::
|
||||
|
||||
$ ./keystone-manage endpointTemplates add North nova https://compute.north.example.com/v1/%tenant_id%/ https://compute.north.example.corp/v1/ https://compute.north.example.local/v1/%tenant_id%/ 1 1
|
||||
|
||||
The arguments are: object_type action 'region' 'service_name' 'publicURL' 'adminURL' 'internalURL' 'enabled' 'global'
|
||||
|
||||
This creates a global endpoint (global means it gets applied to all tenants automatically).
|
||||
|
||||
Now, when a user authenticates, they get that endpoint in their service catalog. Here's an example
|
||||
authentication request for use against tenant 1::
|
||||
|
||||
$ curl -H "Content-type: application/json" -d '{"auth":{"passwordCredentials":{"username":"joeuser","password":"secrete"}, "tenantId": "1"}}' http://localhost:5000/v2.0/tokens
|
||||
|
||||
The response is::
|
||||
|
||||
{
|
||||
"access": {
|
||||
"serviceCatalog": [
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"internalURL": "https://compute.north.example.local",
|
||||
"publicURL": "https://compute.north.example.com/v1/1/",
|
||||
"region": "North"
|
||||
}
|
||||
],
|
||||
"name": "nova",
|
||||
"type": "compute"
|
||||
}
|
||||
],
|
||||
"token": {
|
||||
"expires": "2012-02-05T00:00:00",
|
||||
"id": "887665443383838",
|
||||
"tenant": {
|
||||
"id": "1",
|
||||
"name": "customer-x"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": "1",
|
||||
"name": "joeuser",
|
||||
"roles": [
|
||||
{
|
||||
"id": "3",
|
||||
"name": "Member",
|
||||
"tenantId": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Notice the adminURL is not showing (this user is a regular user and does not
|
||||
have rights to see the adminURL) and the tenant ID has been substituted in the
|
||||
URL::
|
||||
|
||||
"publicURL": "https://compute.north.example.com/v1/1/",
|
||||
|
||||
This endpoint will show up for all tenants. The OpenStack administrator does
|
||||
not need to create the endpoint manually.
|
||||
|
||||
.. note:: Endpoint Templates are not part of the core Keystone API (but Endpoints are).
|
||||
|
||||
|
||||
What parameters can I use in a Template URL
|
||||
-------------------------------------------
|
||||
|
||||
Currently the only parameterization available is %tenant_id% which gets
|
||||
substituted by the Tenant ID.
|
||||
|
||||
|
||||
Endpoint Template Types: Global or not
|
||||
--------------------------------------
|
||||
|
||||
When the global flag is set to true on an Endpoint Template, it means it should
|
||||
be available to all tenants. Whenever someone authenticates to a tenant, they
|
||||
will see the Endpoint generated by that template.
|
||||
|
||||
When the global flag is not set, the template only shows up when it is added to
|
||||
a tenant manually. To add an endpoint to a tenant manually, you must create
|
||||
the Endpoint and supply the Endpoint Template ID:
|
||||
|
||||
Create the Endpoint Template::
|
||||
|
||||
$ ./keystone-manage endpointTemplates add West nova https://compute.west.example.com/v1/%tenant_id%/ https://compute.west.example.corp https://compute.west.example.local 1 0
|
||||
|
||||
Note the 0 at the end - this Endpoint Template is not global. So it will not show up for users authenticating.
|
||||
|
||||
Find the Endpoint Template ID::
|
||||
|
||||
$ ./keystone-manage endpointTemplates list
|
||||
|
||||
All EndpointTemplates
|
||||
id service type region enabled is_global Public URL Admin URL
|
||||
-------------------------------------------------------------------------------
|
||||
15 nova compute North True True https://compute.north.example.com/v1/%tenant_id%/ https://compute.north.example.corp
|
||||
16 nova compute West True False https://compute.west.example.com/v1/%tenant_id%/ https://compute.west.example.corp
|
||||
|
||||
Add the Endpoint to the tenant::
|
||||
|
||||
$ ./keystone-manage endpoint add customer-x 16
|
||||
|
||||
Now, when the user authenticates, they get the endpoint::
|
||||
|
||||
{
|
||||
"internalURL": "https://compute.west.example.local",
|
||||
"publicURL": "https://compute.west.example.com/v1/1/",
|
||||
"region": "West"
|
||||
}
|
||||
|
||||
Who can see the AdminURL?
|
||||
-------------------------
|
||||
|
||||
Users who have the Keystone `Admin` or `Service Admin` roles will see the
|
||||
AdminURL when they authenticate or when they retrieve token information:
|
||||
|
||||
Using an administrator token to authenticate, GET a client token's endpoints::
|
||||
|
||||
$ curl -H "X-Auth-Token: 999888777666" http://localhost:35357/v2.0/tokens/887665443383838/endpoints
|
||||
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"adminURL": "https://compute.west.example.corp",
|
||||
"id": 6,
|
||||
"internalURL": "https://compute.west.example.local",
|
||||
"name": "nova",
|
||||
"publicURL": "https://compute.west.example.com/v1/1/",
|
||||
"region": "West",
|
||||
"tenantId": 1,
|
||||
"type": "compute"
|
||||
}
|
||||
],
|
||||
"endpoints_links": [
|
||||
{
|
||||
"href": "http://127.0.0.1:35357/tokens/887665443383838/endpoints?marker=6&limit=10",
|
||||
"rel": "next"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
==========
|
||||
Extensions
|
||||
==========
|
||||
|
||||
Extensions support adding features and functions to OpenStack APIs at any time, without prior
|
||||
approval or waiting for a new API and release cycles.
|
||||
|
||||
The extension framework is in development and documented in extensions_ and extensionspresentation_.
|
||||
|
||||
This document describes the extensions included with Keystone, how to enable and disable them,
|
||||
and briefly touches on how to write your own extensions.
|
||||
|
||||
.. _extensions: http://docs.openstack.org/trunk/openstack-compute/developer/openstack-api-extensions/content/ch02s01.html
|
||||
.. _extensionspresentation: http://www.slideshare.net/RackerWilliams/openstack-extensions
|
||||
|
||||
Built-in Extensions
|
||||
-------------------
|
||||
|
||||
Keystone ships with a number of extensions found under the
|
||||
``keystone/contib/extensions`` folder.
|
||||
|
||||
The following built-in extensions are included:
|
||||
|
||||
OS-KSADM
|
||||
|
||||
This is an extensions that supports managing users, tenants, and roles
|
||||
through the API. Without this extensions, the ony way to manage those
|
||||
objects is through keystone-manage or directly in the underlying database.
|
||||
|
||||
This is an Admin API extension only.
|
||||
|
||||
OS-KSCATALOG
|
||||
|
||||
This extensions supports managing Endpoints and prrovides the Endpoint
|
||||
Template mechanism for managing bulk endpoints.
|
||||
|
||||
This is an Admin API extension only.
|
||||
|
||||
OS-EC2
|
||||
|
||||
This extension adds support for EC2 credentials.
|
||||
|
||||
This is an Admin and Service API extension.
|
||||
|
||||
RAX-GRP
|
||||
|
||||
This extension adds functionality the enables groups.
|
||||
|
||||
This is an Admin and Service API extension.
|
||||
|
||||
RAX-KEY
|
||||
|
||||
This extensions adds support for authentication with an API Key (the core
|
||||
Keystone API only supports username/password credentials)
|
||||
|
||||
This is an Admin and Service API extension.
|
||||
|
||||
HP-IDM
|
||||
|
||||
This extension adds capability to filter roles with optional service IDs
|
||||
for token validation to mitigate security risks with role name conflicts.
|
||||
See https://bugs.launchpad.net/keystone/+bug/890411 for more details.
|
||||
|
||||
This is an Admin API extension. Applicable to validate token (GET)
|
||||
and check token (HEAD) APIs only.
|
||||
|
||||
OS-KSVALIDATE
|
||||
|
||||
This extensions supports admin calls to /tokens without having to specify
|
||||
the token ID in the URL. Instead, the ID is supplied in a header called
|
||||
X-Subject-Token. This is provided as an alternative to address any security
|
||||
concerns that arise when token IDs are passed as part of the URL which is
|
||||
often (and by default) logged to insecure media.
|
||||
|
||||
This is an Admin API extension only.
|
||||
|
||||
.. note::
|
||||
|
||||
The included extensions are in the process of being rewritten. Currently
|
||||
osksadm, oskscatalog, hpidm, and osksvalidate work with this new
|
||||
extensions design.
|
||||
|
||||
|
||||
Enabling & Disabling Extensions
|
||||
-------------------------------
|
||||
|
||||
The Keystone conf file has a property called extensions. This property holds
|
||||
the list of supported extensions that you want enabled. If you want to
|
||||
add/remove an extension from being supported, add/remove the extension key
|
||||
from this property. The key is the name of the folder of the extension
|
||||
under the keystone/contrib/extensions folder.
|
||||
|
||||
.. note::
|
||||
|
||||
If you want to load different extensions in the service API than the Admin API
|
||||
you need to use different config files.
|
||||
|
||||
Creating New Extensions
|
||||
-----------------------
|
||||
|
||||
#. **Adopt a unique organization abbreviation.**
|
||||
|
||||
This prefix should uniquely identify your organization within the community.
|
||||
The goal is to avoid schema and resource collisions with similiar extensions.
|
||||
(e.g. ``OS`` for OpenStack, ``RAX`` for Rackspace, or ``HP`` for Hewlett-Packard)
|
||||
|
||||
#. **Adopt a unique extension abbreviation.**
|
||||
|
||||
Select an abbreviation to identify your extension, and append to
|
||||
your organization prefix using a hyphen (``-``), by convention
|
||||
(e.g. ``OS-KSADM`` (for OpenStack's Keystone Administration extension).
|
||||
|
||||
This combination is referred to as your extension's prefix.
|
||||
|
||||
#. **Determine the scope of your extension.**
|
||||
|
||||
Extensions can enhance the Admin API, Service API or both.
|
||||
|
||||
#. **Create a new module.**
|
||||
|
||||
Create a module to isolate your namespace based on the extension prefix
|
||||
you selected::
|
||||
|
||||
keystone/contrib/extensions/admin
|
||||
|
||||
... and/or::
|
||||
|
||||
keystone/contrib/extensions/service/
|
||||
|
||||
... based on which API you are enhancing.
|
||||
|
||||
.. note::
|
||||
|
||||
In the future, we will support loading external extensions.
|
||||
|
||||
#. Add static extension files for JSON (``*.json``) and XML
|
||||
(``*.xml``) to the new extension module.
|
||||
|
||||
Refer to `Service Guide <https://github.com/openstack/keystone/blob/master/keystone/content/admin/identityadminguide.pdf?raw=true>`_
|
||||
`Sample extension XML <https://github.com/openstack/keystone/blob/master/keystone/content/common/samples/extension.json>`_
|
||||
`Sample extension JSON <https://github.com/openstack/keystone/blob/master/keystone/content/common/samples/extension.xml>`_ for the the content and structure.
|
||||
|
||||
#. If your extension is adding additional methods override the base class
|
||||
``BaseExtensionHandler``, name it ``ExtensionHandler``, and add your methods.
|
||||
|
||||
#. **Document your work.**
|
||||
|
||||
Provide documentation to support your extension.
|
||||
|
||||
Extensions documentation, WADL, and XSD files can be stored in the
|
||||
``keystone/content`` folder.
|
||||
|
||||
#. Add your extension name to the list of supported extensions in The
|
||||
``keystone.conf`` file.
|
||||
|
||||
Which extensions are enabled?
|
||||
-----------------------------
|
||||
|
||||
Discover which extensions are available (service API)::
|
||||
|
||||
curl http://localhost:5000/v2.0/extensions
|
||||
|
||||
... or (admin API)::
|
||||
|
||||
curl http://localhost:35357/v2.0/extensions
|
||||
|
||||
The response will list the extensions available.
|
|
@ -0,0 +1,169 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
==========
|
||||
Middleware
|
||||
==========
|
||||
|
||||
The Keystone middleware sits in front of an OpenStack service and handles authenticating
|
||||
incoming requests. The middleware was designed according to `this spec`.
|
||||
|
||||
The middleware is found in source under Keystone/middleware.
|
||||
|
||||
The middleware supports two interfaces; WSGI and REST/HTTP.
|
||||
|
||||
.. _`this spec`: http://wiki.openstack.org/openstack-authn
|
||||
|
||||
REST & HTTP API
|
||||
===============
|
||||
|
||||
If an unauthenticated call comes in, the middleware will respond with a 401 Unauthorized error. As per
|
||||
HTTP standards, it will also return a WWW-Authenticate header informing the caller
|
||||
of what protocols are supported. For Keystone authentication, the response syntax will be::
|
||||
|
||||
WWW-Authenticate: Keystone uri="url to Keystone server"
|
||||
|
||||
The client can then make the necessary calls to the Keystone server, obtain a token, and retry the call with the token.
|
||||
|
||||
The token is passed in using ther X-Auth-Token header.
|
||||
|
||||
WSGI API (Headers)
|
||||
==================
|
||||
|
||||
Upon successful authentication the middleware sends the following
|
||||
headers to the downstream WSGI app:
|
||||
|
||||
X-Identity-Status
|
||||
Provides information on whether the request was authenticated or not.
|
||||
|
||||
X-Tenant
|
||||
Provides the tenant ID (as it appears in the URL in Keystone). This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants.
|
||||
|
||||
X-Tenant-Id
|
||||
The unique, immutable tenant Id
|
||||
|
||||
X-Tenant-Name
|
||||
The unique, but mutable (it can change) tenant name.
|
||||
|
||||
X-User-Id
|
||||
The user id of the user used to log in
|
||||
|
||||
X-User-Name
|
||||
The username used to log in
|
||||
|
||||
X-User
|
||||
The username used to log in. This is to support any legacy implementations before Keystone switched to an ID/Name schema for tenants.
|
||||
|
||||
X-Roles
|
||||
The roles associated with that user
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
The middleware is configured within the config file of the main application as
|
||||
a WSGI component. Example for the auth_token middleware::
|
||||
|
||||
[app:myService]
|
||||
paste.app_factory = myService:app_factory
|
||||
|
||||
[pipeline:main]
|
||||
pipeline =
|
||||
tokenauth
|
||||
myService
|
||||
|
||||
[filter:tokenauth]
|
||||
paste.filter_factory = keystone.middleware.auth_token:filter_factory
|
||||
auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
auth_protocol = http
|
||||
auth_uri = http://127.0.0.1:5000/
|
||||
admin_token = 999888777666
|
||||
;Uncomment next line and check ip:port to use memcached to cache token requests
|
||||
;memcache_hosts = 127.0.0.1:11211
|
||||
|
||||
*The required configuration entries are:*
|
||||
|
||||
auth_host
|
||||
The IP address or DNS name of the Keystone server
|
||||
|
||||
auth_port
|
||||
The TCP/IP port of the Keystone server
|
||||
|
||||
auth_protocol
|
||||
The protocol of the Keystone server ('http' or 'https')
|
||||
|
||||
auth_uri
|
||||
The externally accessible URL of the Keystone server. This will be where unauthenticated
|
||||
clients are redirected to. This is in the form of a URL. For example, if they make an
|
||||
unauthenticated call, they get this response::
|
||||
|
||||
HTTP/1.1 401 Unauthorized
|
||||
Www-Authenticate: Keystone uri='https://auth.example.com/'
|
||||
Content-Length: 381
|
||||
|
||||
In this case, the auth_uri setting is set to https://auth.example.com/
|
||||
|
||||
admin_token
|
||||
This is the long-lived token issued to the service to authenticate itself when calling
|
||||
Keystone. See :doc:`configuration` for more information on setting this up.
|
||||
|
||||
|
||||
*Optional parameters are:*
|
||||
|
||||
delay_auth_decision
|
||||
Whether the middleware should reject invalid or unauthenticated calls directly or not. If not,
|
||||
it will send all calls down to the service to decide, but it will set the HTTP-X-IDENTITY-STATUS
|
||||
header appropriately (set to'Confirmed' or 'Indeterminate' based on validation) and the
|
||||
service can then decide if it wants to honor the call or not. This is useful if the service offers
|
||||
some resources publicly, for example.
|
||||
|
||||
auth_timeout
|
||||
The amount of time to wait before timing out a call to Keystone (in seconds)
|
||||
|
||||
memcache_hosts
|
||||
This is used to point to a memcached server (in ip:port format). If supplied,
|
||||
the middleware will cache tokens and data retrieved from Keystone in memcached
|
||||
to minimize calls made to Keystone and optimize performance.
|
||||
|
||||
.. warning::
|
||||
Tokens are cached for the duration of their validity. If they are revoked eariler in Keystone,
|
||||
the service will not know and will continue to honor the token as it has them stored in memcached.
|
||||
Also note that tokens and data stored in memcached are not encrypted. The memcached server must
|
||||
be trusted and on a secure network.
|
||||
|
||||
|
||||
*Parameters needed in a distributed topology.* In this configuration, the middleware is running
|
||||
on a separate machine or cluster than the protected service (not common - see :doc:`middleware_architecture`
|
||||
for details on different deployment topologies):
|
||||
|
||||
service_host
|
||||
The IP address or DNS name of the location of the service (since it is remote
|
||||
and not automatically down the WSGI chain)
|
||||
|
||||
service_port
|
||||
The TCP/IP port of the remote service.
|
||||
|
||||
service_protocol
|
||||
The protocol of the service ('http' or 'https')
|
||||
|
||||
service_pass
|
||||
The basic auth password used to authenticate to the service (so the service
|
||||
knows the call is coming from a server that has validated the token and not from
|
||||
an untrusted source or spoofer)
|
||||
|
||||
service_timeout
|
||||
The amount of time to wait for the service to respond before timing out.
|
|
@ -0,0 +1,126 @@
|
|||
===================
|
||||
Database Migrations
|
||||
===================
|
||||
|
||||
Keystone uses SQLAlchemy Migrate (``sqlalchemy-migrate``) to manage
|
||||
migrations.
|
||||
|
||||
Migrations are tracked using a metadata table (``migrate_version``), which
|
||||
allows keystone to compare the state of your database to the state it
|
||||
expects, and to move between versions.
|
||||
|
||||
.. WARNING::
|
||||
|
||||
Backup your database before applying migrations. Migrations may
|
||||
attempt to modify both your schema and data, and could result in data
|
||||
loss.
|
||||
|
||||
Always review the behavior of migrations in a staging environment
|
||||
before applying them in production.
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
Your initial approach to migrations should depend on whether you have an
|
||||
empty database or a schema full of data.
|
||||
|
||||
Starting with an empty database
|
||||
-------------------------------
|
||||
|
||||
If you have an empty database for keystone to work with, you can simply
|
||||
run::
|
||||
|
||||
$ ./bin/keystone-manage database sync
|
||||
|
||||
This command will initialize your metadata table, and run through all the
|
||||
schema & data migrations necessary to bring your database in sync with
|
||||
keystone. That's it!
|
||||
|
||||
Starting with an existing database
|
||||
----------------------------------
|
||||
|
||||
Place an existing database under version control to enable migration
|
||||
support::
|
||||
|
||||
$ ./bin/keystone-manage database version_control
|
||||
|
||||
This command simply creates a ``migrate_version`` table, set at
|
||||
``version_number`` 0, which indicates that no migrations have been applied.
|
||||
|
||||
If you are starting with an existing schema, you can jump to a specific
|
||||
schema version without performing migrations using the ``database goto``
|
||||
command. For example, if you're starting from a diablo-compatible
|
||||
database, set your current database ``version_number`` to ``1`` using::
|
||||
|
||||
$ ./bin/keystone-manage database goto <version_number>
|
||||
|
||||
Determine your appropriate database ``version_number`` by referencing the
|
||||
following table:
|
||||
|
||||
+------------+-------------+
|
||||
| Release | ``version`` |
|
||||
+============+=============+
|
||||
| pre-diablo | (see below) |
|
||||
+------------+-------------+
|
||||
| diablo | 1 |
|
||||
+------------+-------------+
|
||||
| essex-m1 | 3 |
|
||||
+------------+-------------+
|
||||
| essex-m2 | 4 |
|
||||
+------------+-------------+
|
||||
|
||||
From there, you can upgrade normally (see :ref:`upgrading`).
|
||||
|
||||
Starting with a pre-diablo database (cactus)
|
||||
--------------------------------------------
|
||||
|
||||
You'll need to manually migrate your database to a diablo-compatible
|
||||
schema, and continue forward from there (if desired) using migrations.
|
||||
|
||||
.. _upgrading:
|
||||
|
||||
Upgrading & Downgrading
|
||||
=======================
|
||||
|
||||
.. note::
|
||||
|
||||
Attempting to start keystone with an outdated schema will cause
|
||||
keystone to abort, to avoid corrupting your data.
|
||||
|
||||
Upgrade to the latest version automatically::
|
||||
|
||||
$ ./bin/keystone-manage database sync
|
||||
|
||||
Check your current schema version::
|
||||
|
||||
$ ./bin/keystone-manage database version
|
||||
|
||||
Jump to a specific version without performing migrations::
|
||||
|
||||
$ ./bin/keystone-manage database goto <version_number>
|
||||
|
||||
Upgrade to a specific version::
|
||||
|
||||
$ ./bin/keystone-manage database upgrade <version_number>
|
||||
|
||||
Downgrade to a specific version (will likely result in data loss!)::
|
||||
|
||||
$ ./bin/keystone-manage database downgrade <version_number>
|
||||
|
||||
Opting Out of Migrations
|
||||
========================
|
||||
|
||||
If you don't want to use migrations (e.g. if you want to manage your
|
||||
schema manually), keystone will complain in your logs on startup, but
|
||||
won't actually stop you from doing so.
|
||||
|
||||
It's recommended that you use migrations to get up and running, but if
|
||||
you want to manage migrations manually after that, simply drop the
|
||||
``migrate_version`` table::
|
||||
|
||||
DROP TABLE migrate_version;
|
||||
|
||||
Useful Links
|
||||
============
|
||||
|
||||
Principles to follow when developing migrations `OpenStack Deployability <http://wiki.openstack.org/OpenstackDeployability>`_
|
|
@ -0,0 +1,36 @@
|
|||
=============
|
||||
Release notes
|
||||
=============
|
||||
|
||||
|
||||
E3 (January 26, 2012)
|
||||
==========================================
|
||||
* Contract compliance: version response and ATOM, 300 multiple choice
|
||||
* Global endpoints returned for unscoped calls
|
||||
* adminUrl only shown to admin clients
|
||||
* Endpoints have unique ID
|
||||
* Auth-N/Auth-Z for S3 API (OS-KSS3 extension)
|
||||
* Default tenant scope optionally returned when authenticating
|
||||
* Vary header returned for caching proxies
|
||||
|
||||
* Portable identifiers: modifiable, string identifiers in database backend
|
||||
* Much improved keystone-manage command (see --help and docs)
|
||||
* OS-KSVALIDATE extension to support not passing tokens in URL
|
||||
* OS-KSEC2 and OS-KSS3 extensions respond on /tokens
|
||||
* HP-IDM extension to filter roles to a given service ID
|
||||
* Additional caching options in middleware (memcache and swift cache)
|
||||
|
||||
* Enhanced configuration management (in line with other OpenStack projects)
|
||||
* Additional logging
|
||||
* Enhanced tracer tool (-t or --trace-calls)
|
||||
|
||||
See comprehensive list here https://launchpad.net/keystone/+milestone/essex-3
|
||||
|
||||
|
||||
E2 (December 15, 2011)
|
||||
========================
|
||||
* D5 compatibility middleware
|
||||
* Database versioning
|
||||
* Much more documentation: http://keystone.openstack.org
|
||||
|
||||
See https://launchpad.net/keystone/+milestone/essex-2
|
|
@ -0,0 +1,92 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
================
|
||||
Services
|
||||
================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
|
||||
What are services?
|
||||
==================
|
||||
|
||||
Keystone includes service registry and service catalog functionality which it
|
||||
uses to respond to client authentication requests with information useful to
|
||||
clients in locating the list of available services they can access.
|
||||
|
||||
The Service entity in Keystone represents an OpenStack service that is integrated
|
||||
with Keystone. The Service entity is also used as a reference from roles, endpoints,
|
||||
and endpoint templates.
|
||||
|
||||
Keystone also includes an authorization mechanism to allow a service to own
|
||||
its own roles and endpoints and prevent other services from changing or
|
||||
modifying them.
|
||||
|
||||
Who can create services?
|
||||
========================
|
||||
|
||||
Any user with the Admin or Service Admin roles in Keystone may create services.
|
||||
|
||||
How are services created?
|
||||
=========================
|
||||
|
||||
Services can be created using ``keystone-manage`` or through the REST API using
|
||||
the OS-KSADM extension calls.
|
||||
|
||||
Using ``keystone-manage`` (see :doc:`man/keystone-manage` for details)::
|
||||
|
||||
$ keystone-manage add service compute nova 'This is a sample compute service'
|
||||
|
||||
Using the REST API (see `extensions dev guide <https://github.com/openstack/keystone/blob/master/keystone/content/admin/OS-KSADM-admin-devguide.pdf?raw=true>`_ for details)::
|
||||
|
||||
$ curl -H "Content-type: application/json" -X POST -d '{
|
||||
"OS-KSADM:service": {
|
||||
"name": "nova",
|
||||
"type": "compute",
|
||||
"description": "This is a sample compute service"
|
||||
}
|
||||
}' -H "X-Auth-Token: 999888777666" http://localhost:35357/v2.0/OS-KSADM/services/
|
||||
|
||||
How is service ownership determined?
|
||||
====================================
|
||||
|
||||
Currently, the way to assign ownership to a service is to provide the owner's
|
||||
user id in the keystone-manage add command::
|
||||
|
||||
$ keystone-manage add service nova compute 'This is a sample compute service' joeuser
|
||||
|
||||
This will assign ownership to the new service to joeuser.
|
||||
|
||||
When a service has an owner, then only that owner (or a global Admin) can create and manage
|
||||
roles that start with that service name (ex: "nova:admin") and manage endpoints
|
||||
and endpoint templates associated with that service.
|
||||
|
||||
Listing services
|
||||
================
|
||||
|
||||
Using ``keystone-manage``, the list of services and their owners can be listed::
|
||||
|
||||
$ keystone-manage service list
|
||||
|
||||
id name type owner_id description
|
||||
-------------------------------------------------------------------------------
|
||||
1 compute nova joeuser This is a sample compute service
|
||||
|
||||
Using the REST API, call ``GET /v2.0/OS-KSADM/services``
|
||||
|
||||
.. note: The rest API does not yet support service ownership
|
|
@ -0,0 +1,118 @@
|
|||
..
|
||||
Copyright 2011 OpenStack, LLC
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
not use this file except in compliance with the License. You may obtain
|
||||
a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
===========================
|
||||
x.509 Client Authentication
|
||||
===========================
|
||||
|
||||
Purpose
|
||||
=======
|
||||
|
||||
Allows the Keystone middleware to authenticate itself with the Keystone server
|
||||
via an x.509 client certificate. Both Service API and Admin API may be secured
|
||||
with this feature.
|
||||
|
||||
Certificates
|
||||
============
|
||||
|
||||
The following types of certificates are required. A set of certficates is provided
|
||||
in the examples/ssl directory with the Keystone distribution for testing. Here
|
||||
is the description of each of them and their purpose:
|
||||
|
||||
ca.pem
|
||||
Certificate Authority chain to validate against.
|
||||
|
||||
keystone.pem
|
||||
Public certificate for Keystone server.
|
||||
|
||||
middleware-key.pem
|
||||
Public and private certificate for Keystone middleware.
|
||||
|
||||
cakey.pem
|
||||
Private key for the CA.
|
||||
|
||||
keystonekey.pem
|
||||
Private key for the Keystone server.
|
||||
|
||||
Note that you may choose whatever names you want for these certificates, or combine
|
||||
the public/private keys in the same file if you wish. These certificates are just
|
||||
provided as an example.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
By default, the Keystone server does not use SSL. To enable SSL with client authentication,
|
||||
modify the etc/keystone.conf file accordingly:
|
||||
|
||||
1. To enable SSL for Service API::
|
||||
|
||||
service_ssl = True
|
||||
|
||||
2. To enable SSL for Admin API::
|
||||
|
||||
admin_ssl = True
|
||||
|
||||
3. To enable SSL client authentication::
|
||||
|
||||
cert_required = True
|
||||
|
||||
4. Set the location of the Keystone certificate file (example)::
|
||||
|
||||
certfile = /etc/keystone/ca/certs/keystone.pem
|
||||
|
||||
5. Set the location of the Keystone private file (example)::
|
||||
|
||||
keyfile = /etc/keystone/ca/private/keystonekey.pem
|
||||
|
||||
6. Set the location of the CA chain::
|
||||
|
||||
ca_certs = /etc/keystone/ca/certs/ca.pem
|
||||
|
||||
Middleware
|
||||
==========
|
||||
|
||||
Add the following to your middleware configuration to support x.509 client authentication.
|
||||
If ``cert_required`` is set to ``False`` on the keystone server, the certfile and keyfile parameters
|
||||
in steps 3) and 4) may be commented out.
|
||||
|
||||
1. Specify 'https' as the auth_protocol::
|
||||
|
||||
auth_protocol = https
|
||||
|
||||
2. Modify the protocol in 'auth_uri' to be 'https' as well, if the service API is configured
|
||||
for SSL::
|
||||
|
||||
auth_uri = https://localhost:5000/
|
||||
|
||||
3. Set the location of the middleware certificate file (example)::
|
||||
|
||||
certfile = /etc/keystone/ca/certs/middleware-key.pem
|
||||
|
||||
4. Set the location of the Keystone private file (example)::
|
||||
|
||||
keyfile = /etc/keystone/ca/certs/middleware-key.pem
|
||||
|
||||
For an example, take a look at the ``echo.ini`` middleware configuration for the 'echo' example
|
||||
service in the examples/echo directory.
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
You can test out how it works by using the ``echo`` example service in the ``examples/echo`` directory
|
||||
and the certficates included in the ``examples/ssl`` directory. Invoke the ``echo_client.py`` with
|
||||
the path to the client certificate::
|
||||
|
||||
python echo_client.py -s <path to client certificate>
|
|
@ -18,12 +18,12 @@
|
|||
Setting up a Keystone development environment
|
||||
=============================================
|
||||
|
||||
This document describes setting up keystone directly from GitHub_
|
||||
This document describes getting the source from keystone's `GitHub repository`_
|
||||
for development purposes.
|
||||
|
||||
To install keystone from packaging, refer instead to Keystone's `User Documentation`_.
|
||||
|
||||
.. _GitHub: http://github.com/openstack/keystone
|
||||
.. _`GitHub Repository`: http://github.com/openstack/keystone
|
||||
.. _`User Documentation`: http://docs.openstack.org/
|
||||
|
||||
Prerequisites
|
||||
|
@ -51,7 +51,7 @@ different version of the above, please document your configuration here!
|
|||
Getting the latest code
|
||||
=======================
|
||||
|
||||
You can clone our latest code from our `Github repository`::
|
||||
Make a clone of the code from our `Github repository`::
|
||||
|
||||
$ git clone https://github.com/openstack/keystone.git
|
||||
|
||||
|
@ -59,13 +59,17 @@ When that is complete, you can::
|
|||
|
||||
$ cd keystone
|
||||
|
||||
.. _`Github repository`: https://github.com/openstack/keystone
|
||||
|
||||
Installing dependencies
|
||||
=======================
|
||||
|
||||
Keystone maintains a list of PyPi_ dependencies, designed for use by
|
||||
pip_.
|
||||
Keystone maintains two lists of dependencies:
|
||||
|
||||
tools/pip-requires
|
||||
tools/pip-requires-test
|
||||
|
||||
The first is the list of dependencies needed for running keystone, the second list includes dependencies used for active development and testing of keystone itself.
|
||||
|
||||
These depdendencies can be installed from PyPi_ using the python tool pip_.
|
||||
|
||||
.. _PyPi: http://pypi.python.org/
|
||||
.. _pip: http://pypi.python.org/pypi/pip
|
||||
|
@ -89,29 +93,51 @@ Mac OS X Lion (requires MacPorts_)::
|
|||
|
||||
.. _MacPorts: http://www.macports.org/
|
||||
|
||||
PyPi Packages
|
||||
-------------
|
||||
PyPi Packages and VirtualEnv
|
||||
----------------------------
|
||||
|
||||
Assuming you have any necessary binary packages & header files available
|
||||
on your system, you can then install PyPi dependencies.
|
||||
We recommend establishing a virtualenv to run keystone within. Virtualenv limits the python environment
|
||||
to just what you're installing as depdendencies, useful to keep a clean environment for working on
|
||||
Keystone. The tools directory in keystone has a script already created to make this very simple::
|
||||
|
||||
You may also need to prefix `pip install` with `sudo`, depending on your
|
||||
environment::
|
||||
$ python tools/install_venv.py
|
||||
|
||||
# Describe dependencies (including non-PyPi dependencies)
|
||||
$ cat tools/pip-requires
|
||||
This will create a local virtual environment in the directory ``.venv``.
|
||||
Once created, you can activate this virtualenv for your current shell using::
|
||||
|
||||
# Install all PyPi dependencies (for production, testing, and development)
|
||||
$ source .venv/bin/activate
|
||||
|
||||
The virtual environment can be disabled using the command::
|
||||
|
||||
$ deactivate
|
||||
|
||||
You can also use ``tools\with_venv.sh`` to prefix commands so that they run
|
||||
within the virtual environment. For more information on virtual environments,
|
||||
see virtualenv_.
|
||||
|
||||
.. _virtualenv: http://www.virtualenv.org/
|
||||
|
||||
If you want to run keystone outside of a virtualenv, you can install the dependencies directly
|
||||
into your system from the requires files::
|
||||
|
||||
# Install the dependencies for running keystone
|
||||
$ pip install -r tools/pip-requires
|
||||
|
||||
Updating your PYTHONPATH
|
||||
========================
|
||||
|
||||
There are a number of methods for getting Keystone into your PYTHON PATH,
|
||||
the easiest of which is::
|
||||
|
||||
# Install the dependencies for developing, testing, and running keystone
|
||||
$ pip install -r tools/pip-requires-test
|
||||
|
||||
# Fake-install the project by symlinking Keystone into your Python site-packages
|
||||
$ python setup.py develop
|
||||
|
||||
|
||||
Verifying Keystone is set up
|
||||
============================
|
||||
|
||||
Once set up, either directly or within a virtualenv, you should be able to invoke python and import
|
||||
the libraries. If you're using a virtualenv, don't forget to activate it::
|
||||
|
||||
$ source .venv/bin/activate
|
||||
$ python
|
||||
|
||||
You should then be able to `import keystone` from your Python shell
|
||||
without issue::
|
||||
|
@ -124,8 +150,7 @@ If you want to check the version of Keystone you are running:
|
|||
>>> print keystone.version.version()
|
||||
2012.1-dev
|
||||
|
||||
|
||||
If you can import keystone successfully, you should be ready to move on to :doc:`testing`.
|
||||
If you can import keystone successfully, you should be ready to move on to :doc:`developing`
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
================
|
||||
Testing Keystone
|
||||
================
|
||||
|
||||
Keystone uses a number of testing methodologies to ensure correctness.
|
||||
|
||||
Running Built-In Tests
|
||||
======================
|
||||
|
||||
To run the full suites of tests maintained within Keystone, run::
|
||||
|
||||
$ ./run_tests.sh --with-progress
|
||||
|
||||
This shows realtime feedback during test execution, and iterates over
|
||||
multiple configuration variations.
|
||||
|
||||
This differs from how tests are executed from the continuous integration
|
||||
environment. Specifically, Jenkins doesn't care about realtime progress,
|
||||
and aborts after the first test failure (a fail-fast behavior)::
|
||||
|
||||
$ ./run_tests.sh
|
||||
|
||||
Testing Schema Migrations
|
||||
=========================
|
||||
|
||||
The application of schema migrations can be tested using SQLAlchemy Migrate’s built-in test runner, one migration at a time.
|
||||
|
||||
.. WARNING::
|
||||
|
||||
This may leave your database in an inconsistent state; attempt this in non-production environments only!
|
||||
|
||||
This is useful for testing the *next* migration in sequence (both forward & backward) in a database under version control::
|
||||
|
||||
$ python keystone/backends/sqlalchemy/migrate_repo/manage.py test --url=sqlite:///test.db --repository=keystone/backends/sqlalchemy/migrate_repo/
|
||||
|
||||
This command refers to a SQLite database used for testing purposes. Depending on the migration, this command alone does not make assertions as to the integrity of your data during migration.
|
||||
|
||||
Writing Tests
|
||||
=============
|
||||
|
||||
Tests are maintained in the ``keystone.test`` module. Unit tests are
|
||||
isolated from functional tests.
|
||||
|
||||
Functional Tests
|
||||
----------------
|
||||
|
||||
The ``keystone.test.functional.common`` module provides a ``unittest``-based
|
||||
``httplib`` client which you can extend and use for your own tests.
|
||||
Generally, functional tests should serve to illustrate intended use cases
|
||||
and API behaviors. To help make your tests easier to read, the test client:
|
||||
|
||||
- Authenticates with a known user name and password combination
|
||||
- Asserts 2xx HTTP status codes (unless told otherwise)
|
||||
- Abstracts keystone REST verbs & resources into single function calls
|
||||
|
||||
Testing Multiple Configurations
|
||||
-------------------------------
|
||||
|
||||
Several variations of the default configuration are iterated over to
|
||||
ensure test coverage of mutually exclusive featuresets, such as the
|
||||
various backend options.
|
||||
|
||||
These configuration templates are maintained in ``keystone/test/etc`` and
|
||||
are iterated over by ``run_tests.py``.
|
||||
|
||||
Further Testing
|
||||
===============
|
||||
|
||||
devstack_ is the *best* way to quickly deploy keystone with the rest of the
|
||||
OpenStack universe and should be critical step in your development workflow!
|
||||
|
||||
You may also be interested in either the `OpenStack Continuous Integration Project`_
|
||||
or the `OpenStack Integration Testing Project`_.
|
||||
|
||||
.. _devstack: http://devstack.org/
|
||||
.. _OpenStack Continuous Integration Project: https://github.com/openstack/openstack-ci
|
||||
.. _OpenStack Integration Testing Project: https://github.com/openstack/openstack-integration-tests
|
|
@ -32,8 +32,11 @@ class TemplatedCatalog(kvs.Catalog):
|
|||
|
||||
name - the name of the service, most likely repeated for all services of
|
||||
the same type, across regions.
|
||||
|
||||
adminURL - the url of the admin endpoint
|
||||
|
||||
publicURL - the url of the public endpoint
|
||||
|
||||
internalURL - the url of the internal endpoint
|
||||
|
||||
"""
|
||||
|
|
|
@ -24,7 +24,7 @@ config.register_cli_str('endpoint',
|
|||
config.register_cli_str('auth-token',
|
||||
default='$admin_token',
|
||||
#group='ks',
|
||||
help='asdasd',
|
||||
help='authorization token',
|
||||
conf=CONF)
|
||||
config.register_cli_bool('id-only',
|
||||
default=False,
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
r"""
|
||||
Configuration options which may be set on the command line or in config files.
|
||||
|
||||
The schema for each option is defined using the Opt sub-classes e.g.
|
||||
The schema for each option is defined using the Opt sub-classes e.g.::
|
||||
|
||||
common_opts = [
|
||||
cfg.StrOpt('bind_host',
|
||||
|
@ -28,7 +28,7 @@ The schema for each option is defined using the Opt sub-classes e.g.
|
|||
help='Port number to listen on')
|
||||
]
|
||||
|
||||
Options can be strings, integers, floats, booleans, lists or 'multi strings':
|
||||
Options can be strings, integers, floats, booleans, lists or 'multi strings'::
|
||||
|
||||
enabled_apis_opt = \
|
||||
cfg.ListOpt('enabled_apis',
|
||||
|
@ -43,7 +43,7 @@ Options can be strings, integers, floats, booleans, lists or 'multi strings':
|
|||
default=DEFAULT_EXTENSIONS)
|
||||
|
||||
Option schemas are registered with with the config manager at runtime, but
|
||||
before the option is referenced:
|
||||
before the option is referenced::
|
||||
|
||||
class ExtensionManager(object):
|
||||
|
||||
|
@ -59,7 +59,7 @@ before the option is referenced:
|
|||
....
|
||||
|
||||
A common usage pattern is for each option schema to be defined in the module or
|
||||
class which uses the option:
|
||||
class which uses the option::
|
||||
|
||||
opts = ...
|
||||
|
||||
|
@ -74,7 +74,7 @@ class which uses the option:
|
|||
|
||||
An option may optionally be made available via the command line. Such options
|
||||
must registered with the config manager before the command line is parsed (for
|
||||
the purposes of --help and CLI arg validation):
|
||||
the purposes of --help and CLI arg validation)::
|
||||
|
||||
cli_opts = [
|
||||
cfg.BoolOpt('verbose',
|
||||
|
@ -90,7 +90,7 @@ the purposes of --help and CLI arg validation):
|
|||
def add_common_opts(conf):
|
||||
conf.register_cli_opts(cli_opts)
|
||||
|
||||
The config manager has a single CLI option defined by default, --config-file:
|
||||
The config manager has a single CLI option defined by default, --config-file::
|
||||
|
||||
class ConfigOpts(object):
|
||||
|
||||
|
@ -104,7 +104,7 @@ The config manager has a single CLI option defined by default, --config-file:
|
|||
|
||||
Option values are parsed from any supplied config files using SafeConfigParser.
|
||||
If none are specified, a default set is used e.g. glance-api.conf and
|
||||
glance-common.conf:
|
||||
glance-common.conf::
|
||||
|
||||
glance-api.conf:
|
||||
[DEFAULT]
|
||||
|
@ -119,7 +119,7 @@ are parsed in order, with values in later files overriding those in earlier
|
|||
files.
|
||||
|
||||
The parsing of CLI args and config files is initiated by invoking the config
|
||||
manager e.g.
|
||||
manager e.g.::
|
||||
|
||||
conf = ConfigOpts()
|
||||
conf.register_opt(BoolOpt('verbose', ...))
|
||||
|
@ -127,7 +127,7 @@ manager e.g.
|
|||
if conf.verbose:
|
||||
...
|
||||
|
||||
Options can be registered as belonging to a group:
|
||||
Options can be registered as belonging to a group::
|
||||
|
||||
rabbit_group = cfg.OptionGroup(name='rabbit',
|
||||
title='RabbitMQ options')
|
||||
|
@ -154,7 +154,7 @@ Options can be registered as belonging to a group:
|
|||
conf.register_opt(rabbit_ssl_opt, group=rabbit_group)
|
||||
|
||||
If no group is specified, options belong to the 'DEFAULT' section of config
|
||||
files:
|
||||
files::
|
||||
|
||||
glance-api.conf:
|
||||
[DEFAULT]
|
||||
|
@ -175,7 +175,7 @@ Command-line options in a group are automatically prefixed with the group name:
|
|||
|
||||
Option values in the default group are referenced as attributes/properties on
|
||||
the config manager; groups are also attributes on the config manager, with
|
||||
attributes for each of the options associated with the group:
|
||||
attributes for each of the options associated with the group::
|
||||
|
||||
server.start(app, conf.bind_port, conf.bind_host, conf)
|
||||
|
||||
|
@ -184,7 +184,7 @@ attributes for each of the options associated with the group:
|
|||
port=conf.rabbit.port,
|
||||
...)
|
||||
|
||||
Option values may reference other values using PEP 292 string substitution:
|
||||
Option values may reference other values using PEP 292 string substitution::
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('state_path',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import json
|
||||
import webob
|
||||
|
||||
from keystone import config
|
||||
from keystone.common import wsgi
|
||||
|
@ -98,3 +99,40 @@ class JsonBodyMiddleware(wsgi.Middleware):
|
|||
params[k] = v
|
||||
|
||||
request.environ[PARAMS_ENV] = params
|
||||
|
||||
|
||||
class Debug(wsgi.Middleware):
|
||||
"""
|
||||
Middleware that produces stream debugging traces to the console (stdout)
|
||||
for HTTP requests and responses flowing through it.
|
||||
"""
|
||||
|
||||
@webob.dec.wsgify
|
||||
def __call__(self, req):
|
||||
print ("*" * 40) + " REQUEST ENVIRON"
|
||||
for key, value in req.environ.items():
|
||||
print key, "=", value
|
||||
print
|
||||
resp = req.get_response(self.application)
|
||||
|
||||
print ("*" * 40) + " RESPONSE HEADERS"
|
||||
for (key, value) in resp.headers.iteritems():
|
||||
print key, "=", value
|
||||
print
|
||||
|
||||
resp.app_iter = self.print_generator(resp.app_iter)
|
||||
|
||||
return resp
|
||||
|
||||
@staticmethod
|
||||
def print_generator(app_iter):
|
||||
"""
|
||||
Iterator that prints the contents of a wrapper string iterator
|
||||
when iterated.
|
||||
"""
|
||||
print ("*" * 40) + " BODY"
|
||||
for part in app_iter:
|
||||
sys.stdout.write(part)
|
||||
sys.stdout.flush()
|
||||
yield part
|
||||
print
|
||||
|
|
|
@ -109,17 +109,17 @@ class TokenController(wsgi.Application):
|
|||
def authenticate(self, context, auth=None):
|
||||
"""Authenticate credentials and return a token.
|
||||
|
||||
Accept auth as a dict that looks like:
|
||||
Accept auth as a dict that looks like::
|
||||
|
||||
{
|
||||
"auth":{
|
||||
"passwordCredentials":{
|
||||
"username":"test_user",
|
||||
"password":"mypass"
|
||||
},
|
||||
"tenantName":"customer-x"
|
||||
{
|
||||
"auth":{
|
||||
"passwordCredentials":{
|
||||
"username":"test_user",
|
||||
"password":"mypass"
|
||||
},
|
||||
"tenantName":"customer-x"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
In this case, tenant is optional, if not provided the token will be
|
||||
considered "unscoped" and can later be used to get a scoped token.
|
||||
|
|