Merge pull request #26 from 4P/moredoc

copy over a bunch of docs from keystone, will probably have to be proofread a bit after
This commit is contained in:
Andy Smith 2012-01-30 15:51:19 -08:00
commit 826319befd
45 changed files with 4733 additions and 377 deletions

View File

@ -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"
}
]
}

View File

@ -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.

View File

@ -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
-------

View File

@ -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.

View File

@ -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"

View File

@ -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.

View File

@ -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 Migrates 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.

View File

@ -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

View File

@ -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&#45;&gt;Service -->
<!-- Service&#45;&gt;AuthComp -->
<g id="edge5" class="edge"><title>Service:n&#45;&gt;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&#45;&gt;Service -->
<g id="edge7" class="edge"><title>Start:sw&#45;&gt;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

View File

@ -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&#45;&gt;Reject -->
<g id="edge3" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;Service -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;AuthComp -->
<g id="edge7" class="edge"><title>Start&#45;&gt;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

View File

@ -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&#45;&gt;Reject -->
<g id="edge3" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;Service -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;AuthComp -->
<g id="edge7" class="edge"><title>Service&#45;&gt;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&#45;&gt;AuthComp -->
<g id="edge9" class="edge"><title>Start&#45;&gt;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

View File

@ -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&#45;&gt;Together -->
<g id="edge3" class="edge"><title>AuthComp&#45;&gt;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

View File

@ -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&#45;&gt;AuthComp -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;&gt;Start -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;Service -->
<g id="edge7" class="edge"><title>AuthComp&#45;&gt;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&#45;Authorization: Proxy U</text>
<text text-anchor="middle" x="458" y="-51.0355" font-family="Times,serif" font-size="14.00">X&#45;Identity&#45;Status: Confirmed</text>
</g>
<!-- Service&#45;&gt;AuthComp -->
<g id="edge9" class="edge"><title>Service&#45;&gt;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&#45;Authenticate: Delegated</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -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&#45;&gt;AuthComp -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;&gt;Start -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;Service -->
<g id="edge7" class="edge"><title>AuthComp&#45;&gt;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&#45;Authorization: Proxy U</text>
<text text-anchor="middle" x="451" y="-30.634" font-family="Times,serif" font-size="14.00">X&#45;Identity&#45;Status: Confirmed</text>
</g>
<!-- Service&#45;&gt;AuthComp -->
<g id="edge9" class="edge"><title>Service&#45;&gt;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

View File

@ -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&#45;&gt;AuthComp -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;&gt;Start -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;Authenticate: Basic</text>
<text text-anchor="middle" x="151" y="-18.2409" font-family="Times,serif" font-size="14.00">Realm=&quot;API Realm&quot;</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&#45;&gt;Service -->
<g id="edge7" class="edge"><title>AuthComp&#45;&gt;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&#45;Authorization: Proxy b</text>
<text text-anchor="middle" x="457" y="-62.2409" font-family="Times,serif" font-size="14.00">X&#45;Identity&#45;Status: Indeterminate</text>
</g>
<!-- Service&#45;&gt;AuthComp -->
<g id="edge9" class="edge"><title>Service&#45;&gt;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&#45;Authenticate: Delegated</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -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&#45;&gt;AuthComp -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;999&#45;222</text>
</g>
<!-- AuthComp&#45;&gt;Start -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;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&#45;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&#45;&gt;Service -->
<g id="edge7" class="edge"><title>AuthComp&#45;&gt;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&#45;Authorization: Proxy</text>
<text text-anchor="middle" x="509" y="-76.904" font-family="Times,serif" font-size="14.00">X&#45;Identity&#45;Status: Indeterminate</text>
</g>
<!-- Service&#45;&gt;AuthComp -->
<g id="edge9" class="edge"><title>Service&#45;&gt;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&#45;Authenticate: Delegated</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -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&#45;&gt;AuthComp -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;&gt;Start -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;&gt;Service -->
<g id="edge7" class="edge"><title>AuthComp&#45;&gt;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&#45;Authorization: Proxy U</text>
<text text-anchor="middle" x="458" y="-51.0355" font-family="Times,serif" font-size="14.00">X&#45;Identity&#45;Status: Confirmed</text>
</g>
<!-- Service&#45;&gt;AuthComp -->
<g id="edge9" class="edge"><title>Service&#45;&gt;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&#45;Authenticate: Delegated</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -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&#45;&gt;Mapper -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;&gt;Auths -->
<g id="edge5" class="edge"><title>Mapper:sw&#45;&gt;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&#45;&gt;Auths -->
<g id="edge7" class="edge"><title>Mapper:s&#45;&gt;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&#45;&gt;Auths -->
<g id="edge9" class="edge"><title>Mapper:se&#45;&gt;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&#45;&gt;Service -->
<g id="edge11" class="edge"><title>Auths:auth1&#45;&gt;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&#45;&gt;Service -->
<g id="edge13" class="edge"><title>Auths:auth2&#45;&gt;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&#45;&gt;Service -->
<g id="edge15" class="edge"><title>Auths:auth3&#45;&gt;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

View File

@ -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&#45;&gt;AuthComp -->
<g id="edge3" class="edge"><title>Start&#45;&gt;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&#45;&gt;Start -->
<g id="edge9" class="edge"><title>AuthComp:w&#45;&gt;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&#45;&gt;Service -->
<g id="edge5" class="edge"><title>AuthComp&#45;&gt;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&#45;Authorization: Proxy U</text>
</g>
<!-- Service&#45;&gt;AuthComp -->
<g id="edge7" class="edge"><title>Service:w&#45;&gt;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

View File

@ -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&#45;&gt;Service -->
<g
id="edge3"
class="edge">
<title
id="title3157">AuthComp-&gt;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

View File

@ -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
==================

View File

@ -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
=====

View File

@ -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
=====

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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"
}
]
}

View File

@ -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.

View File

@ -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.

View File

@ -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>`_

View File

@ -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

View File

@ -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

118
docs/source/old/ssl.rst Normal file
View File

@ -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>

View File

@ -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
===============

View File

@ -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 Migrates 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

View File

@ -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
"""

View File

@ -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,

View File

@ -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',

View File

@ -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

View File

@ -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.