diff options
| author | James E. Blair <jeblair@hp.com> | 2012-02-14 15:54:59 -0800 |
|---|---|---|
| committer | James E. Blair <jeblair@hp.com> | 2012-02-14 15:57:37 -0800 |
| commit | eef1f0d93ae19f04601b75cd7a2514e81b4005b9 (patch) | |
| tree | 2b1b8b4a45f884414bd89c4bec7e31056a20a351 /docs | |
| parent | 9452cf04bc8b0a4dc66dc640615d5ace1ca715f2 (diff) | |
| parent | 90068b0143af788869116d08533d5ebc99874a17 (diff) | |
Merge redux branch (keystone light)
Change-Id: I2cb5b198a06848f42f919ea49e338443131e263e
Diffstat (limited to 'docs')
44 files changed, 6725 insertions, 0 deletions
diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..79861705 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,159 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build +SOURCEDIR = source +SPHINXAPIDOC = sphinx-apidoc + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " autodoc generate the autodoc templates" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +autodoc: + $(SPHINXAPIDOC) -f -o $(SOURCEDIR) ../keystone + +html: autodoc + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/keystone.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/keystone.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/keystone" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/keystone" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/keystone_compat_flows.sdx b/docs/keystone_compat_flows.sdx new file mode 100644 index 00000000..f1fcc5f0 --- /dev/null +++ b/docs/keystone_compat_flows.sdx @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<diagram> +<source><![CDATA[client:client "Client" +compat:compat "Compat" +token:token "Token Service" +identity:identity "Identity Service" +catalog:catalog "Catalog Service" + +[c "Auth, No Tenant"] +client:{token, user, service_catalog}=compat.POST /v2.0/tokens {'username': user, 'password': password} + compat:(user, password, None)=identity.authenticate(user, password, tenant=None) + compat:(id, user, password, None)=token.create_token(user, password, tenant=None) + compat:{service_catalog (includes all tenants)}=catalog.get_catalog(user, None) +[/c] + +[c "Auth, With Tenant"] +client:{scoped_token, user, service_catalog}=compat.POST /v2.0/tokens {'username': user, 'password': password, 'tenant': tenant} + compat:(user, password, tenant)=identity.authenticate(user, password, tenant) + compat:(id, user, password, tenant)=token.create_token(user, password, tenant) + compat:{service_catalog (includes all tenants)}=catalog.get_catalog(user, tenant) +[/c] + +[c "Validate Token, Unscoped"] +client:{token, user, tenant=None}=compat.GET /v2.0/tokens/$token +compat:{token, user, tenant}=token.get_token($token) +[/c] + +[c "Validate Token, With Tenant"] +client:{token, user, tenant}=compat.GET /v2.0/tokens/$token?belongs_to=$tenant +compat:{token, user, tenant}=token.get_token($token) +[/c] + +[c "Tenants for Token"] +client:{tenants}=compat.(X-Auth-Token: $token) GET /v2.0/tenants +compat:{token, user, tenant}=token.get_token($token) +compat:{token, user, tenant}=identity.get_tenants($user) +[/c]]]></source> +<configuration> +<property name="activationBarBorderThickness" value="1"/> +<property name="actorWidth" value="25"/> +<property name="arrowColor" value="-14803256"/> +<property name="arrowSize" value="6"/> +<property name="arrowThickness" value="1"/> +<property name="colorizeThreads" value="true"/> +<property name="destructorWidth" value="30"/> +<property name="explicitReturns" value="false"/> +<property family="Dialog" name="font" size="12" style="0"/> +<property name="fragmentBorderThickness" value="2"/> +<property name="fragmentEdgeColor" value="-16751616"/> +<property name="fragmentLabelBgColor" value="-36"/> +<property name="fragmentMargin" value="8"/> +<property name="fragmentPadding" value="10"/> +<property name="fragmentTextPadding" value="3"/> +<property name="glue" value="10"/> +<property name="headHeight" value="35"/> +<property name="headLabelPadding" value="5"/> +<property name="headWidth" value="100"/> +<property name="initialSpace" value="10"/> +<property name="labeledBoxBgColor" value="-76"/> +<property name="leftMargin" value="5"/> +<property name="lifelineThickness" value="1"/> +<property name="lineWrap" value="false"/> +<property name="lowerMargin" value="5"/> +<property name="mainLifelineWidth" value="8"/> +<property name="messageLabelSpace" value="3"/> +<property name="messagePadding" value="6"/> +<property name="noteBgColor" value="-76"/> +<property name="noteBorderThickness" value="1"/> +<property name="noteMargin" value="6"/> +<property name="notePadding" value="6"/> +<property name="opaqueMessageText" value="false"/> +<property name="returnArrowVisible" value="true"/> +<property name="rightMargin" value="5"/> +<property name="selfMessageHorizontalSpace" value="15"/> +<property name="separatorBottomMargin" value="8"/> +<property name="separatorTopMargin" value="15"/> +<property name="shouldShadowParticipants" value="true"/> +<property name="slackMode" value="false"/> +<property name="spaceBeforeActivation" value="2"/> +<property name="spaceBeforeAnswerToSelf" value="10"/> +<property name="spaceBeforeConstruction" value="6"/> +<property name="spaceBeforeSelfMessage" value="7"/> +<property name="subLifelineWidth" value="6"/> +<property name="tc0" value="-1118482"/> +<property name="tc1" value="-256"/> +<property name="tc2" value="-65536"/> +<property name="tc3" value="-16776961"/> +<property name="tc4" value="-16711936"/> +<property name="tc5" value="-4144960"/> +<property name="tc6" value="-65281"/> +<property name="tc7" value="-14336"/> +<property name="tc8" value="-20561"/> +<property name="tc9" value="-12566464"/> +<property name="threadNumbersVisible" value="false"/> +<property name="threaded" value="true"/> +<property name="upperMargin" value="5"/> +<property name="verticallySplit" value="true"/> +</configuration> +</diagram> diff --git a/docs/source/_templates/.placeholder b/docs/source/_templates/.placeholder new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/docs/source/_templates/.placeholder diff --git a/docs/source/_theme/layout.html b/docs/source/_theme/layout.html new file mode 100644 index 00000000..e3eb54b7 --- /dev/null +++ b/docs/source/_theme/layout.html @@ -0,0 +1,86 @@ +{% extends "sphinxdoc/layout.html" %} +{% set css_files = css_files + ['_static/tweaks.css'] %} +{% set script_files = script_files + ['_static/jquery.tweet.js'] %} +{% block extrahead %} + <script type='text/javascript'> + $(document).ready(function(){ + $("#twitter_feed").tweet({ + username: "openstack", + query: "from:openstack", + avatar_size: 32, + count: 10, + loading_text: "loading tweets..." + }); + }); + </script> +{% endblock %} + +{%- macro sidebar() %} + {%- if not embedded %}{% if not theme_nosidebar|tobool %} + <div class="sphinxsidebar"> + <div class="sphinxsidebarwrapper"> + {%- block sidebarlogo %} + {%- if logo %} + <p class="logo"><a href="{{ pathto(master_doc) }}"> + <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/> + </a></p> + {%- endif %} + {%- endblock %} + {%- block sidebartoc %} + {%- if display_toc %} + <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3> + {{ toc }} + {%- endif %} + {%- endblock %} + {%- block sidebarrel %} + {%- if prev %} + <h4>{{ _('Previous topic') }}</h4> + <p class="topless"><a href="{{ prev.link|e }}" + title="{{ _('previous chapter') }}">{{ prev.title }}</a></p> + {%- endif %} + {%- if next %} + <h4>{{ _('Next topic') }}</h4> + <p class="topless"><a href="{{ next.link|e }}" + title="{{ _('next chapter') }}">{{ next.title }}</a></p> + {%- endif %} + {%- endblock %} + {%- block sidebarsourcelink %} + {%- if show_source and has_source and sourcename %} + <h3>{{ _('This Page') }}</h3> + <ul class="this-page-menu"> + <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}" + rel="nofollow">{{ _('Show Source') }}</a></li> + </ul> + {%- endif %} + {%- endblock %} + {%- if customsidebar %} + {% include customsidebar %} + {%- endif %} + {%- block sidebarsearch %} + {%- if pagename != "search" %} + <div id="searchbox" style="display: none"> + <h3>{{ _('Quick search') }}</h3> + <form class="search" action="{{ pathto('search') }}" method="get"> + <input type="text" name="q" size="18" /> + <input type="submit" value="{{ _('Go') }}" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + <p class="searchtip" style="font-size: 90%"> + {{ _('Enter search terms or a module, class or function name.') }} + </p> + </div> + <script type="text/javascript">$('#searchbox').show(0);</script> + {%- endif %} + + {%- if pagename == "index" %} + <h3>{{ _('Twitter Feed') }}</h3> + <div id="twitter_feed" class='twitter_feed'></div> + {%- endif %} + + + {%- endblock %} + </div> + </div> + {%- endif %}{% endif %} +{%- endmacro %} diff --git a/docs/source/_theme/theme.conf b/docs/source/_theme/theme.conf new file mode 100644 index 00000000..e039fe01 --- /dev/null +++ b/docs/source/_theme/theme.conf @@ -0,0 +1,5 @@ +[theme] +inherit = sphinxdoc +stylesheet = sphinxdoc.css +pygments_style = friendly + diff --git a/docs/source/api_curl_examples.rst b/docs/source/api_curl_examples.rst new file mode 100644 index 00000000..686e8bd5 --- /dev/null +++ b/docs/source/api_curl_examples.rst @@ -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" + } + ] + } diff --git a/docs/source/architecture.rst b/docs/source/architecture.rst new file mode 100644 index 00000000..b308a9e5 --- /dev/null +++ b/docs/source/architecture.rst @@ -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. diff --git a/docs/source/community.rst b/docs/source/community.rst new file mode 100644 index 00000000..d3e32178 --- /dev/null +++ b/docs/source/community.rst @@ -0,0 +1,79 @@ +.. + 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. + +================ +Getting Involved +================ + +The OpenStack community is a very friendly group and there are places online to join in with the +community. Feel free to ask questions. This document points you to some of the places where you can +communicate with people. + +How to Join the Community +========================= + +Our community welcomes all people interested in open source cloud computing, and there are no formal +membership requirements. The best way to join the community is to talk with others online or at a meetup +and offer contributions through Launchpad_, the wiki_, or blogs. We welcome all types of contributions, +from blueprint designs to documentation to testing to deployment scripts. + +.. _Launchpad: https://launchpad.net/keystone +.. _wiki: http://wiki.openstack.org/ + +#openstack on Freenode IRC Network +---------------------------------- + +There is a very active chat channel at `<irc://freenode.net/#openstack>`_. This +is usually the best place to ask questions and find your way around. IRC stands for Internet Relay +Chat and it is a way to chat online in real time. You can also ask a question and come back to the +log files to read the answer later. Logs for the #openstack IRC channel are stored at +`<http://eavesdrop.openstack.org/irclogs/>`_. + +OpenStack Wiki +-------------- + +The wiki is a living source of knowledge. It is edited by the community, and +has collections of links and other sources of information. Typically the pages are a good place +to write drafts for specs or documentation, describe a blueprint, or collaborate with others. + +`OpenStack Wiki <http://wiki.openstack.org/>`_ + +Keystone on Launchpad +--------------------- + +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 + +* `Keystone Project Page on Launchpad <http://launchpad.net/keystone>`_ +* `Keystone Source Repository on GitHub <http://github.com/openstack/keystone>`_ + +OpenStack Blog +-------------- + +The OpenStack blog includes a weekly newsletter that aggregates OpenStack news +from around the internet, as well as providing inside information on upcoming +events and posts from OpenStack contributors. + +`OpenStack Blog <http://openstack.org/blog>`_ + +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 +------- + +Because all the cool kids do it: `@openstack <http://twitter.com/openstack>`_. Also follow the +`#openstack <http://search.twitter.com/search?q=%23openstack>`_ tag for relevant tweets. diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..fc7d9476 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,274 @@ +# -*- coding: utf-8 -*- +# +# keystone documentation build configuration file, created by +# sphinx-quickstart on Mon Jan 9 12:02:59 2012. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('../..')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage'] +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.todo', +# 'sphinx.ect.intersphinx', + 'sphinx.ext.coverage'] + +todo_include_todos = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = [] +if os.getenv('HUDSON_PUBLISH_DOCS'): + templates_path = ['_ga', '_templates'] +else: + templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'keystone' +copyright = u'2012, OpenStack, LLC' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '2012.1' +# The full version, including alpha/beta/rc tags. +release = '2012.1-dev' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +show_authors = True + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +modindex_common_prefix = ['keystone.'] + +# -- Options for man page output -------------------------------------------- + +# Grouping the document tree for man pages. +# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual' + +man_pages = [ + ('man/keystone-manage', 'keystone-manage', u'Keystone Management Utility', + [u'OpenStack'], 1), + ('man/keystone-all', 'keystone-all', u'Keystone Startup Command', + [u'OpenStack'], 1), + ] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme_path = ["."] +html_theme = '_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# 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'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'keystonedoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'keystone.tex', u'Keystone Documentation', + u'OpenStack', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'keystone', u'Keystone Documentation', + [u'OpenStack'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'keystone', u'Keystone Documentation', + u'OpenStack', 'keystone', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# Example configuration for intersphinx: refer to the Python standard library. +#intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = {'python': ('http://docs.python.org/', None), + 'nova': ('http://nova.openstack.org', None), + 'swift': ('http://swift.openstack.org', None), + 'glance': ('http://glance.openstack.org', None)} diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst new file mode 100644 index 00000000..22f3748b --- /dev/null +++ b/docs/source/configuration.rst @@ -0,0 +1,488 @@ +.. + 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 + man/keystone-all + +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]``, ``[sql]``, ``[ec2]`` and then drivers +for the various services are included under their individual sections. + +The services 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 + +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`` + +Running Keystone +================ + +Running keystone is simply starting the services by using the command:: + + keystone-all + +Invoking this command starts up two wsgi.Server instances, configured by the +``keystone.conf`` file as described above. One of these wsgi 'servers' is +``admin`` (the administration API) and the other is ``main`` (the +primary/public API interface). Both of these run in a single process. + +Migrating from legacy versions of keystone +========================================== +Migration support is provided for the following legacy keystone versions: + +* diablo-5 +* stable/diablo +* essex-2 +* essex-3 + +To migrate from legacy versions of keystone, use the following steps: + +Step 1: Configure keystone.conf +------------------------------- +It is important that the database that you specify be different from the one +containing your existing install. + +Step 2: db_sync your new, empty database +---------------------------------------- +Run the following command to configure the most recent schema in your new +keystone installation:: + + keystone-manage db_sync + +Step 3: Import your legacy data +------------------------------- +Use the following command to import your old data:: + + keystone-manage import_legacy [db_url, e.g. 'mysql://root@foobar/keystone'] + +Specify db_url as the connection string that was present in your old +keystone.conf file. + +Step 3: Import your legacy service catalog +------------------------------------------ +While the older keystone stored the service catalog in the database, +the updated version configures the service catalog using a template file. +An example service catalog template file may be found in +etc/default_catalog.templates. + +To import your legacy catalog, run this command:: + + keystone-manage export_legacy_catalog \ + [db_url e.g. 'mysql://root@foobar/keystone'] > \ + [path_to_templates e.g. 'etc/default_catalog.templates'] + +After executing this command, you will need to restart the keystone service to +see your changes. + +Initializing Keystone +===================== + +keystone-manage is designed to execute commands that cannot be administered +through the normal REST api. At the moment, the following calls are supported: + +* ``db_sync``: Sync the database. +* ``import_legacy``: Import a legacy (pre-essex) version of the db. +* ``export_legacy_catalog``: Export service catalog from a legacy (pre-essex) db. + + +Generally, the following is the first step after a source installation:: + + keystone-manage db_sync + +Invoking keystone-manage by itself will give you additional usage information. + +Adding Users, Tenants, and Roles with python-keystoneclient +=========================================================== + +User, tenants, and roles must be administered using admin credentials. +There are two ways to configure python-keystoneclient to use admin +credentials, using the token auth method, or password auth method. + +Token Auth Method +----------------- +To use keystone client using token auth, set the following flags + +* ``--endpoint SERVIVE_ENDPOINT`` : allows you to specify the keystone endpoint to communicate + with. The default endpoint is http://localhost:35357/v2.0' +* ``--token SERVIVE_TOKEN`` : your administrator service token. + +Password Auth Method +-------------------- + +* ``--username OS_USERNAME`` : allows you to specify the keystone endpoint to communicate + with. For example, http://localhost:35357/v2.0' +* ``--password OS_PASSWORD`` : Your administrator password +* ``--tenant_name OS_TENANT_NAME`` : Name of your tenant +* ``--auth_url OS_AUTH_URL`` : url of your keystone auth server, for example +http://localhost:5000/v2.0' + +Example usage +------------- +``keystone`` is set up to expect commands in the general form of +``keystone`` ``command`` ``argument``, followed by flag-like keyword arguments to +provide additional (often optional) information. For example, the command +``user-list`` and ``tenant-create`` can be invoked as follows:: + + # Using token auth env variables + export SERVICE_ENDPOINT=http://127.0.0.1:5000/v2.0/ + export SERVICE_TOKEN=secrete_token + keystone user-list + keystone tenant-create --name=demo + + # Using token auth flags + keystone --token=secrete --endpoint=http://127.0.0.1:5000/v2.0/ user-list + keystone --token=secrete --endpoint=http://127.0.0.1:5000/v2.0/ tenant-create --name=demo + + # Using user + password + tenant_name env variables + export OS_USERNAME=admin + export OS_PASSWORD=secrete + export OS_TENANT_NAME=admin + keystone user-list + keystone tenant-create --name=demo + + # Using user + password + tenant_name flags + keystone --username=admin --password=secrete --tenant_name=admin user-list + keystone --username=admin --password=secrete --tenant_name=admin tenant-create --name=demo + +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 associated with more than one tenant, and each tenant - user pairing can +have a role associated with it. + +``tenant-create`` +^^^^^^^^^^^^^^^^^ + +keyword arguments + +* name +* description (optional, defaults to None) +* enabled (optional, defaults to True) + +example:: + + keystone tenant-create --name=demo + +creates a tenant named "demo". + +``tenant-delete`` +^^^^^^^^^^^^^^^^^ + +arguments + +* tenant_id + +example:: + + keystone tenant-delete f2b7b39c860840dfa47d9ee4adffa0b3 + +``tenant-enable`` +^^^^^^^^^^^^^^^^^ + +arguments + +* tenant_id + +example:: + + keystone tenant-enable f2b7b39c860840dfa47d9ee4adffa0b3 + +``tenant-disable`` +^^^^^^^^^^^^^^^^^ + +arguments + +* tenant_id + +example:: + + keystone tenant-disable f2b7b39c860840dfa47d9ee4adffa0b3 + +Users +----- + +``user-create`` +^^^^^^^^^^^^^^^ + +keyword arguments + +* name +* pass +* email +* default_tenant (optional, defaults to None) +* enabled (optional, defaults to True) + +example:: + + keystone user-create + --name=admin \ + --pass=secrete \ + --email=admin@example.com + +``user-delete`` +^^^^^^^^^^^^^^^ + +keyword arguments + +* user + +example:: + + keystone user-delete f2b7b39c860840dfa47d9ee4adffa0b3 + +``user-list`` +^^^^^^^^^^^^^ + +list users in the system, optionally by a specific tenant (identified by tenant_id) + +arguments + +* tenant_id (optional, defaults to None) + +example:: + + keystone user-list + +``user-update-email`` +^^^^^^^^^^^^^^^^^^^^^ + +arguments +* user_id +* email + + +example:: + + keystone user-update-email 03c84b51574841ba9a0d8db7882ac645 "someone@somewhere.com" + +``user-enable`` +^^^^^^^^^^^^^^^^^^^^^^^ + +arguments + +* user_id + +example:: + + keystone user-enable 03c84b51574841ba9a0d8db7882ac645 + +``user-disable`` +^^^^^^^^^^^^^^^^^^^^^^^ + +arguments + +* user_id + +example:: + + keystone user-disable 03c84b51574841ba9a0d8db7882ac645 + + +``user-update-password`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +arguments + +* user_id +* password + +example:: + + keystone user-update-password 03c84b51574841ba9a0d8db7882ac645 foo + +Roles +----- + +``role-create`` +^^^^^^^^^^^^^^^ + +arguments + +* name + +exmaple:: + + keystone role-create --name=demo + +``role-delete`` +^^^^^^^^^^^^^^^ + +arguments + +* role_id + +exmaple:: + + keystone role-delete 19d1d3344873464d819c45f521ff9890 + +``role-list`` +^^^^^^^^^^^^^^^ + +exmaple:: + + keystone role-list + +``role-get`` +^^^^^^^^^^^^ + +arguments + +* role_id + +exmaple:: + + keystone role-get role=19d1d3344873464d819c45f521ff9890 + + +``add-user-role`` +^^^^^^^^^^^^^^^^^^^^^^ + +arguments + +* role_id +* user_id +* tenant_id + +example:: + + keystone role add-user-role \ + 3a751f78ef4c412b827540b829e2d7dd \ + 03c84b51574841ba9a0d8db7882ac645 \ + 20601a7f1d94447daa4dff438cb1c209 + +``remove-user-role`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +arguments + +* role_id +* user_id +* tenant_id + +example:: + + keystone remove-user-role \ + 19d1d3344873464d819c45f521ff9890 \ + 08741d8ed88242ca88d1f61484a0fe3b \ + 20601a7f1d94447daa4dff438cb1c209 + +Services +-------- + +``service-create`` +^^^^^^^^^^^^^^^^^^ + +keyword arguments + +* name +* type +* description + +example:: + + keystone service create \ + --name=nova \ + --type=compute \ + --description="Nova Compute Service" + +``service-list`` +^^^^^^^^^^^^^^^^ + +arguments + +* service_id + +example:: + + keystone service-list + +``service-get`` +^^^^^^^^^^^^^^^ + +arguments + +* service_id + +example:: + + keystone service-get 08741d8ed88242ca88d1f61484a0fe3b + +``service-delete`` +^^^^^^^^^^^^^^^^^^ + +arguments + +* service_id + +example:: + + keystone service-delete 08741d8ed88242ca88d1f61484a0fe3b + diff --git a/docs/source/configuringservices.rst b/docs/source/configuringservices.rst new file mode 100644 index 00000000..615187ea --- /dev/null +++ b/docs/source/configuringservices.rst @@ -0,0 +1,197 @@ +.. + 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 ``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 configured token is a "shared secret" between keystone and other +openstack services (for example: nova, swift, glance, or horizon), 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 service-create --name=nova \ + --type=compute \ + --description="Nova Compute Service" + keystone service-create --name=ec2 \ + --type=ec2 \ + --description="EC2 Compatibility Layer" + keystone service-create --name=glance \ + --type=image \ + --description="Glance Image Service" + keystone service-create --name=keystone \ + --type=identity \ + --description="Keystone Identity Service" + keystone service-create --name=swift \ + --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. + diff --git a/docs/source/developing.rst b/docs/source/developing.rst new file mode 100644 index 00000000..f7c0b87b --- /dev/null +++ b/docs/source/developing.rst @@ -0,0 +1,150 @@ +.. + 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. + +======================== +Developing with Keystone +======================== + +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 + +Setup +----- + +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 +---------------- + +To run the keystone Admin and API server instances, use:: + + $ tools/with_venv.sh bin/keystone-all + +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, and which keystone itself uses to provide it's command-line interface. + +When initially getting set up, after you've configured which databases to use, +you're probably going to need to run the following to your database schema in place :: + + $ bin/keystone-manage db_sync + + +.. _`python-keystoneclient`: https://github.com/openstack/python-keystoneclient + +Running Tests +============= + +To run the full suites of tests maintained within Keystone, run:: + + $ ./run_tests.sh + +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. + +Test Structure +-------------- + +``./run_test.sh`` uses its 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. + +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. + +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. + +Likewise, ``test_cli.py`` takes advantage of the tests written aainst +``test_keystoneclient`` to verify the same tests function through different +drivers. + +Testing Schema Migrations +------------------------- + +The application of schema migrations can be tested using SQLAlchemy Migrate’s +built-in test runner, one migration at a time. + +.. WARNING:: + + This may leave your database in an inconsistent state; attempt this in non-production environments only! + +This is useful for testing the *next* migration in sequence (both forward & backward) in a database under version control:: + + python keystone/common/sql/migrate_repo/manage.py test \ + --url=sqlite:///test.db \ + --repository=keystone/common/sql/migrate_repo/ + +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. diff --git a/docs/source/images/authComp.svg b/docs/source/images/authComp.svg new file mode 100644 index 00000000..d344b871 --- /dev/null +++ b/docs/source/images/authComp.svg @@ -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> diff --git a/docs/source/images/graphs_305.svg b/docs/source/images/graphs_305.svg new file mode 100644 index 00000000..1dff61a6 --- /dev/null +++ b/docs/source/images/graphs_305.svg @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: Handle305 Pages: 1 --> +<svg width="310pt" height="208pt" + viewBox="0.00 0.00 310.00 208.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 204)"> +<title>Handle305</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-204 307,-204 307,5 -4,5"/> +<!-- AuthComp --> +<g id="node2" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="98,-146 0,-146 0,-106 98,-106 98,-146"/> +<text text-anchor="middle" x="49" y="-129.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="49" y="-113.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Service --> +<g id="node4" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="119,-40 25,-40 25,-0 119,-0 119,-40"/> +<text text-anchor="middle" x="72" y="-23.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="72" y="-7.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<!-- Service->AuthComp --> +<g id="edge5" class="edge"><title>Service:n->AuthComp:n</title> +<path fill="none" stroke="black" d="M72,-40C72,-62.2222 76.6172,-67.8558 86,-88 90.0596,-96.7157 95.2138,-96.7977 98,-106 103.152,-123.015 110.312,-133.175 98,-146 92.6344,-151.589 70.1318,-155.75 57.5709,-153.773"/> +<polygon fill="black" stroke="black" points="59.2494,-150.684 49,-148 55.3388,-156.489 59.2494,-150.684"/> +<text text-anchor="middle" x="144" y="-75.4" font-family="Times,serif" font-size="14.00">305 Use Proxy</text> +<text text-anchor="middle" x="144" y="-60.4" font-family="Times,serif" font-size="14.00">To Redirect to Auth</text> +</g> +<!-- Start --> +<!-- Start->Service --> +<g id="edge7" class="edge"><title>Start:sw->Service</title> +<path fill="none" stroke="black" d="M216,-164C182.398,-130.398 232.934,-94.0727 202,-58 192.167,-46.5338 159.461,-37.0056 129.317,-30.3582"/> +<polygon fill="black" stroke="black" points="129.738,-26.8696 119.229,-28.2156 128.284,-33.7169 129.738,-26.8696"/> +<text text-anchor="middle" x="255.5" y="-128.4" font-family="Times,serif" font-size="14.00">Request</text> +<text text-anchor="middle" x="255.5" y="-113.4" font-family="Times,serif" font-size="14.00">Service Directly</text> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_authComp.svg b/docs/source/images/graphs_authComp.svg new file mode 100644 index 00000000..6be629c1 --- /dev/null +++ b/docs/source/images/graphs_authComp.svg @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: AuthComp Pages: 1 --> +<svg width="510pt" height="118pt" + viewBox="0.00 0.00 510.00 118.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 114)"> +<title>AuthComp</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-114 507,-114 507,5 -4,5"/> +<!-- AuthComp --> +<g id="node2" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="292,-65 194,-65 194,-25 292,-25 292,-65"/> +<text text-anchor="middle" x="243" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="243" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Reject --> +<!-- AuthComp->Reject --> +<g id="edge3" class="edge"><title>AuthComp->Reject</title> +<path fill="none" stroke="black" d="M193.933,-51.2787C157.514,-55.939 108.38,-62.2263 73.8172,-66.649"/> +<polygon fill="black" stroke="black" points="73.0637,-63.2168 63.5888,-67.9578 73.9522,-70.1602 73.0637,-63.2168"/> +<text text-anchor="middle" x="129" y="-97.4" font-family="Times,serif" font-size="14.00">Reject</text> +<text text-anchor="middle" x="129" y="-82.4" font-family="Times,serif" font-size="14.00">Unauthenticated</text> +<text text-anchor="middle" x="129" y="-67.4" font-family="Times,serif" font-size="14.00">Requests</text> +</g> +<!-- Service --> +<g id="node6" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="502,-65 408,-65 408,-25 502,-25 502,-65"/> +<text text-anchor="middle" x="455" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="455" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge5" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M292.17,-45C323.626,-45 364.563,-45 397.52,-45"/> +<polygon fill="black" stroke="black" points="397.917,-48.5001 407.917,-45 397.917,-41.5001 397.917,-48.5001"/> +<text text-anchor="middle" x="350" y="-77.4" font-family="Times,serif" font-size="14.00">Forward</text> +<text text-anchor="middle" x="350" y="-62.4" font-family="Times,serif" font-size="14.00">Authenticated</text> +<text text-anchor="middle" x="350" y="-47.4" font-family="Times,serif" font-size="14.00">Requests</text> +</g> +<!-- Start --> +<!-- Start->AuthComp --> +<g id="edge7" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M59.1526,-21.4745C90.4482,-25.4792 142.816,-32.1802 183.673,-37.4084"/> +<polygon fill="black" stroke="black" points="183.43,-40.9057 193.793,-38.7034 184.318,-33.9623 183.43,-40.9057"/> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_authCompDelegate.svg b/docs/source/images/graphs_authCompDelegate.svg new file mode 100644 index 00000000..4788829a --- /dev/null +++ b/docs/source/images/graphs_authCompDelegate.svg @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: AuthCompDelegate Pages: 1 --> +<svg width="588pt" height="104pt" + viewBox="0.00 0.00 588.00 104.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 100)"> +<title>AuthCompDelegate</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-100 585,-100 585,5 -4,5"/> +<!-- AuthComp --> +<g id="node2" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="338,-65 240,-65 240,-25 338,-25 338,-65"/> +<text text-anchor="middle" x="289" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="289" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Reject --> +<!-- AuthComp->Reject --> +<g id="edge3" class="edge"><title>AuthComp->Reject</title> +<path fill="none" stroke="black" d="M239.6,-50.1899C191.406,-55.2531 118.917,-62.8686 73.5875,-67.6309"/> +<polygon fill="black" stroke="black" points="73.0928,-64.1635 63.5132,-68.6893 73.8242,-71.1252 73.0928,-64.1635"/> +<text text-anchor="middle" x="152" y="-83.4" font-family="Times,serif" font-size="14.00">Reject Requests</text> +<text text-anchor="middle" x="152" y="-68.4" font-family="Times,serif" font-size="14.00">Indicated by the Service</text> +</g> +<!-- Service --> +<g id="node6" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="580,-65 486,-65 486,-25 580,-25 580,-65"/> +<text text-anchor="middle" x="533" y="-48.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="533" y="-32.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge5" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M338.009,-49.0804C344.065,-49.4598 350.172,-49.7828 356,-50 405.743,-51.8535 418.259,-51.9103 468,-50 470.523,-49.9031 473.101,-49.7851 475.704,-49.6504"/> +<polygon fill="black" stroke="black" points="476.03,-53.1374 485.807,-49.0576 475.62,-46.1494 476.03,-53.1374"/> +<text text-anchor="middle" x="412" y="-68.4" font-family="Times,serif" font-size="14.00">Forward Requests</text> +<text text-anchor="middle" x="412" y="-53.4" font-family="Times,serif" font-size="14.00">with Identiy Status</text> +</g> +<!-- Service->AuthComp --> +<g id="edge7" class="edge"><title>Service->AuthComp</title> +<path fill="none" stroke="black" d="M495.062,-24.9037C486.397,-21.2187 477.064,-17.9304 468,-16 419.314,-5.63183 404.743,-5.9037 356,-16 349.891,-17.2653 343.655,-19.116 337.566,-21.2803"/> +<polygon fill="black" stroke="black" points="336.234,-18.0426 328.158,-24.9003 338.748,-24.5757 336.234,-18.0426"/> +<text text-anchor="middle" x="412" y="-33.4" font-family="Times,serif" font-size="14.00">Send Response OR</text> +<text text-anchor="middle" x="412" y="-18.4" font-family="Times,serif" font-size="14.00">Reject Message</text> +</g> +<!-- Start --> +<!-- Start->AuthComp --> +<g id="edge9" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M59.0178,-20.8384C99.2135,-25.0613 175.782,-33.1055 229.492,-38.7482"/> +<polygon fill="black" stroke="black" points="229.265,-42.2435 239.576,-39.8076 229.997,-35.2818 229.265,-42.2435"/> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_both.svg b/docs/source/images/graphs_both.svg new file mode 100644 index 00000000..6aa87612 --- /dev/null +++ b/docs/source/images/graphs_both.svg @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: Both Pages: 1 --> +<svg width="116pt" height="180pt" + viewBox="0.00 0.00 116.00 180.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 176)"> +<title>Both</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-176 113,-176 113,5 -4,5"/> +<!-- AuthComp --> +<g id="node2" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="104,-172 6,-172 6,-132 104,-132 104,-172"/> +<text text-anchor="middle" x="55" y="-155.4" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="55" y="-139.4" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Together --> +<g id="node4" class="node"><title>Together</title> +<polygon fill="white" stroke="white" points="108,-95.5 0,-95.5 0,-0.5 108,-0.5 108,-95.5"/> +<polygon fill="white" stroke="white" points="8,-47 8,-91 101,-91 101,-47 8,-47"/> +<polygon fill="none" stroke="#c00000" points="8,-47 8,-91 101,-91 101,-47 8,-47"/> +<text text-anchor="start" x="38" y="-75.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="start" x="13.5" y="-58.4333" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +<polygon fill="#d1ebf1" stroke="#d1ebf1" points="8,-4 8,-47 101,-47 101,-4 8,-4"/> +<polygon fill="none" stroke="#1f477d" points="8,-4 8,-47 101,-47 101,-4 8,-4"/> +<text text-anchor="start" x="15.5" y="-31.7333" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="start" x="28" y="-14.9333" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Together --> +<g id="edge3" class="edge"><title>AuthComp->Together:OStack:n</title> +<path fill="none" stroke="black" d="M55,-131.871C55,-113.129 55,-84.1127 55,-57.1901"/> +<polygon fill="black" stroke="black" points="58.5001,-57 55,-47 51.5001,-57 58.5001,-57"/> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_delegate_forbiden_basic.svg b/docs/source/images/graphs_delegate_forbiden_basic.svg new file mode 100644 index 00000000..dcd62b77 --- /dev/null +++ b/docs/source/images/graphs_delegate_forbiden_basic.svg @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: DelegateRejectForbidden Pages: 1 --> +<svg width="670pt" height="102pt" + viewBox="0.00 0.00 670.00 101.64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 97.6355)"> +<title>DelegateRejectForbidden</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-97.6355 667,-97.6355 667,5 -4,5"/> +<!-- Start --> +<!-- AuthComp --> +<g id="node4" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="348,-61.6355 250,-61.6355 250,-21.6355 348,-21.6355 348,-61.6355"/> +<text text-anchor="middle" x="299" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="299" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Start->AuthComp --> +<g id="edge3" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M54.0748,-41.6355C97.1107,-41.6355 182.142,-41.6355 239.791,-41.6355"/> +<polygon fill="black" stroke="black" points="239.864,-45.1356 249.863,-41.6355 239.863,-38.1356 239.864,-45.1356"/> +<text text-anchor="middle" x="152" y="-44.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text> +</g> +<!-- AuthComp->Start --> +<g id="edge5" class="edge"><title>AuthComp->Start</title> +<path fill="none" stroke="black" d="M249.934,-26.0577C243.944,-24.6511 237.868,-23.4514 232,-22.6355 161.567,-12.8417 141.697,-8.52478 72,-22.6355 69.1948,-23.2034 66.3471,-23.9518 63.5169,-24.8233"/> +<polygon fill="black" stroke="black" points="62.3066,-21.5388 54.0489,-28.1766 64.6436,-28.1372 62.3066,-21.5388"/> +<text text-anchor="middle" x="152" y="-25.0355" font-family="Times,serif" font-size="14.00">403 Forbidden</text> +</g> +<!-- Service --> +<g id="node7" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="662,-61.6355 568,-61.6355 568,-21.6355 662,-21.6355 662,-61.6355"/> +<text text-anchor="middle" x="615" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="615" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge7" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M348.009,-45.7159C354.065,-46.0953 360.172,-46.4183 366,-46.6355 447.721,-49.6805 468.282,-49.7738 550,-46.6355 552.523,-46.5386 555.101,-46.4206 557.704,-46.2859"/> +<polygon fill="black" stroke="black" points="558.03,-49.7729 567.807,-45.6931 557.62,-42.7849 558.03,-49.7729"/> +<text text-anchor="middle" x="458" y="-81.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text> +<text text-anchor="middle" x="458" y="-66.0355" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text> +<text text-anchor="middle" x="458" y="-51.0355" font-family="Times,serif" font-size="14.00">X-Identity-Status: Confirmed</text> +</g> +<!-- Service->AuthComp --> +<g id="edge9" class="edge"><title>Service->AuthComp</title> +<path fill="none" stroke="black" d="M577.062,-21.5392C568.397,-17.8542 559.064,-14.5658 550,-12.6355 470.016,4.39794 446.078,3.95128 366,-12.6355 359.891,-13.9008 353.655,-15.7515 347.566,-17.9158"/> +<polygon fill="black" stroke="black" points="346.234,-14.6781 338.158,-21.5358 348.748,-21.2112 346.234,-14.6781"/> +<text text-anchor="middle" x="458" y="-30.0355" font-family="Times,serif" font-size="14.00">403 Forbidden</text> +<text text-anchor="middle" x="458" y="-15.0355" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_delegate_forbiden_proxy.svg b/docs/source/images/graphs_delegate_forbiden_proxy.svg new file mode 100644 index 00000000..df53212b --- /dev/null +++ b/docs/source/images/graphs_delegate_forbiden_proxy.svg @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: DelegateForbiddnProxy Pages: 1 --> +<svg width="656pt" height="81pt" + viewBox="0.00 0.00 656.00 81.23" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 77.234)"> +<title>DelegateForbiddnProxy</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-77.234 653,-77.234 653,5 -4,5"/> +<!-- Start --> +<!-- AuthComp --> +<g id="node4" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="348,-48.234 250,-48.234 250,-8.23398 348,-8.23398 348,-48.234"/> +<text text-anchor="middle" x="299" y="-31.634" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="299" y="-15.634" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Start->AuthComp --> +<g id="edge3" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M54.0748,-28.234C97.1107,-28.234 182.142,-28.234 239.791,-28.234"/> +<polygon fill="black" stroke="black" points="239.864,-31.7341 249.863,-28.234 239.863,-24.7341 239.864,-31.7341"/> +<text text-anchor="middle" x="152" y="-30.634" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text> +</g> +<!-- AuthComp->Start --> +<g id="edge5" class="edge"><title>AuthComp->Start</title> +<path fill="none" stroke="black" d="M249.934,-12.6562C243.944,-11.2496 237.868,-10.0499 232,-9.23398 161.567,0.55976 141.697,4.87673 72,-9.23398 69.1948,-9.80192 66.3471,-10.5503 63.5169,-11.4218"/> +<polygon fill="black" stroke="black" points="62.3066,-8.13733 54.0489,-14.7751 64.6436,-14.7357 62.3066,-8.13733"/> +<text text-anchor="middle" x="152" y="-11.634" font-family="Times,serif" font-size="14.00">500 Internal Error</text> +</g> +<!-- Service --> +<g id="node7" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="648,-48.234 554,-48.234 554,-8.23398 648,-8.23398 648,-48.234"/> +<text text-anchor="middle" x="601" y="-31.634" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="601" y="-15.634" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge7" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M348.194,-28.234C401.691,-28.234 487.101,-28.234 543.616,-28.234"/> +<polygon fill="black" stroke="black" points="543.818,-31.7341 553.818,-28.234 543.818,-24.7341 543.818,-31.7341"/> +<text text-anchor="middle" x="451" y="-60.634" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text> +<text text-anchor="middle" x="451" y="-45.634" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text> +<text text-anchor="middle" x="451" y="-30.634" font-family="Times,serif" font-size="14.00">X-Identity-Status: Confirmed</text> +</g> +<!-- Service->AuthComp --> +<g id="edge9" class="edge"><title>Service->AuthComp</title> +<path fill="none" stroke="black" d="M553.774,-12.7435C547.845,-11.2995 541.819,-10.067 536,-9.23398 461.207,1.47328 440.836,1.17187 366,-9.23398 363.341,-9.6037 360.639,-10.0522 357.922,-10.5631"/> +<polygon fill="black" stroke="black" points="357.121,-7.15517 348.066,-12.6562 358.575,-14.0025 357.121,-7.15517"/> +<text text-anchor="middle" x="451" y="-11.634" font-family="Times,serif" font-size="14.00">403 Forbidden</text> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_delegate_reject_basic.svg b/docs/source/images/graphs_delegate_reject_basic.svg new file mode 100644 index 00000000..a33ea095 --- /dev/null +++ b/docs/source/images/graphs_delegate_reject_basic.svg @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: DelegateRejectAuthBasic Pages: 1 --> +<svg width="670pt" height="113pt" + viewBox="0.00 0.00 670.00 112.84" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 108.841)"> +<title>DelegateRejectAuthBasic</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-108.841 667,-108.841 667,5 -4,5"/> +<!-- Start --> +<!-- AuthComp --> +<g id="node4" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="346,-72.8409 248,-72.8409 248,-32.8409 346,-32.8409 346,-72.8409"/> +<text text-anchor="middle" x="297" y="-56.2409" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="297" y="-40.2409" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Start->AuthComp --> +<g id="edge3" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M54.3777,-61.3549C60.1429,-62.8044 66.2278,-64.0845 72,-64.8409 141.627,-73.9651 160.053,-71.0554 230,-64.8409 232.523,-64.6168 235.094,-64.346 237.686,-64.038"/> +<polygon fill="black" stroke="black" points="238.294,-67.4878 247.737,-62.6852 237.36,-60.5504 238.294,-67.4878"/> +<text text-anchor="middle" x="151" y="-72.2409" font-family="Times,serif" font-size="14.00">Authorization: Basic Yjpw</text> +</g> +<!-- AuthComp->Start --> +<g id="edge5" class="edge"><title>AuthComp->Start</title> +<path fill="none" stroke="black" d="M268.012,-32.6508C256.688,-25.9141 243.253,-19.2572 230,-15.8409 162.001,1.68741 138.106,7.84667 72,-15.8409 64.6685,-18.468 57.6762,-22.8621 51.4824,-27.7226"/> +<polygon fill="black" stroke="black" points="48.8781,-25.3457 43.5743,-34.5174 53.44,-30.655 48.8781,-25.3457"/> +<text text-anchor="middle" x="151" y="-48.2409" font-family="Times,serif" font-size="14.00">401 Unauthorized</text> +<text text-anchor="middle" x="151" y="-33.2409" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Basic</text> +<text text-anchor="middle" x="151" y="-18.2409" font-family="Times,serif" font-size="14.00">Realm="API Realm"</text> +</g> +<!-- Service --> +<g id="node7" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="662,-72.8409 568,-72.8409 568,-32.8409 662,-32.8409 662,-72.8409"/> +<text text-anchor="middle" x="615" y="-56.2409" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="615" y="-40.2409" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge7" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M346.009,-56.9214C352.065,-57.3007 358.172,-57.6238 364,-57.8409 446.609,-60.9191 467.394,-61.0134 550,-57.8409 552.523,-57.744 555.101,-57.626 557.704,-57.4913"/> +<polygon fill="black" stroke="black" points="558.03,-60.9783 567.807,-56.8985 557.62,-53.9903 558.03,-60.9783"/> +<text text-anchor="middle" x="457" y="-92.2409" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text> +<text text-anchor="middle" x="457" y="-77.2409" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy b</text> +<text text-anchor="middle" x="457" y="-62.2409" font-family="Times,serif" font-size="14.00">X-Identity-Status: Indeterminate</text> +</g> +<!-- Service->AuthComp --> +<g id="edge9" class="edge"><title>Service->AuthComp</title> +<path fill="none" stroke="black" d="M577.062,-32.7447C568.397,-29.0597 559.064,-25.7713 550,-23.8409 469.146,-6.62237 444.948,-7.07388 364,-23.8409 357.891,-25.1063 351.655,-26.957 345.566,-29.1213"/> +<polygon fill="black" stroke="black" points="344.234,-25.8836 336.158,-32.7413 346.748,-32.4166 344.234,-25.8836"/> +<text text-anchor="middle" x="457" y="-41.2409" font-family="Times,serif" font-size="14.00">401 Unauthorized</text> +<text text-anchor="middle" x="457" y="-26.2409" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_delegate_reject_oauth.svg b/docs/source/images/graphs_delegate_reject_oauth.svg new file mode 100644 index 00000000..760adeb6 --- /dev/null +++ b/docs/source/images/graphs_delegate_reject_oauth.svg @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: DelegateRejectAuthOAuth Pages: 1 --> +<svg width="722pt" height="128pt" + viewBox="0.00 0.00 722.00 127.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 123.504)"> +<title>DelegateRejectAuthOAuth</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-123.504 719,-123.504 719,5 -4,5"/> +<!-- Start --> +<!-- AuthComp --> +<g id="node4" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="398,-87.504 300,-87.504 300,-47.504 398,-47.504 398,-87.504"/> +<text text-anchor="middle" x="349" y="-70.904" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="349" y="-54.904" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Start->AuthComp --> +<g id="edge3" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M54.4752,-81.8682C60.1286,-84.2034 66.1458,-86.2617 72,-87.504 163.3,-106.879 189.647,-100.994 282,-87.504 284.667,-87.1144 287.375,-86.642 290.098,-86.104"/> +<polygon fill="black" stroke="black" points="290.972,-89.4951 299.969,-83.9 289.446,-82.6633 290.972,-89.4951"/> +<text text-anchor="middle" x="177" y="-101.904" font-family="Times,serif" font-size="14.00">Authorization: OAuth 000-999-222</text> +</g> +<!-- AuthComp->Start --> +<g id="edge5" class="edge"><title>AuthComp->Start</title> +<path fill="none" stroke="black" d="M325.91,-47.4946C313.721,-38.2548 297.999,-28.2878 282,-23.504 192.578,3.23327 158.428,11.7282 72,-23.504 62.489,-27.3811 53.8955,-34.3434 46.8279,-41.6023"/> +<polygon fill="black" stroke="black" points="43.8515,-39.6795 39.7866,-49.4636 49.0657,-44.3499 43.8515,-39.6795"/> +<text text-anchor="middle" x="177" y="-70.904" font-family="Times,serif" font-size="14.00">401 Unauthorized</text> +<text text-anchor="middle" x="177" y="-55.904" font-family="Times,serif" font-size="14.00">WWW-Authenticate: OAuth</text> +<text text-anchor="middle" x="177" y="-40.904" font-family="Times,serif" font-size="14.00">Realm=’API Realm’,</text> +<text text-anchor="middle" x="177" y="-25.904" font-family="Times,serif" font-size="14.00">Error=’invalid-token’</text> +</g> +<!-- Service --> +<g id="node7" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="714,-87.504 620,-87.504 620,-47.504 714,-47.504 714,-87.504"/> +<text text-anchor="middle" x="667" y="-70.904" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="667" y="-54.904" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge7" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M398.009,-71.5844C404.065,-71.9638 410.172,-72.2868 416,-72.504 498.609,-75.5822 519.394,-75.6765 602,-72.504 604.523,-72.4071 607.101,-72.2891 609.704,-72.1544"/> +<polygon fill="black" stroke="black" points="610.03,-75.6414 619.807,-71.5616 609.62,-68.6534 610.03,-75.6414"/> +<text text-anchor="middle" x="509" y="-106.904" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text> +<text text-anchor="middle" x="509" y="-91.904" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy</text> +<text text-anchor="middle" x="509" y="-76.904" font-family="Times,serif" font-size="14.00">X-Identity-Status: Indeterminate</text> +</g> +<!-- Service->AuthComp --> +<g id="edge9" class="edge"><title>Service->AuthComp</title> +<path fill="none" stroke="black" d="M629.062,-47.4077C620.397,-43.7227 611.064,-40.4344 602,-38.504 521.146,-21.2854 496.948,-21.7369 416,-38.504 409.891,-39.7693 403.655,-41.62 397.566,-43.7843"/> +<polygon fill="black" stroke="black" points="396.234,-40.5466 388.158,-47.4043 398.748,-47.0797 396.234,-40.5466"/> +<text text-anchor="middle" x="509" y="-55.904" font-family="Times,serif" font-size="14.00">401 Unauthorized</text> +<text text-anchor="middle" x="509" y="-40.904" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_delegate_unimplemented.svg b/docs/source/images/graphs_delegate_unimplemented.svg new file mode 100644 index 00000000..8c4fdc6b --- /dev/null +++ b/docs/source/images/graphs_delegate_unimplemented.svg @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: DelegateUnimplemented Pages: 1 --> +<svg width="670pt" height="102pt" + viewBox="0.00 0.00 670.00 101.64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 97.6355)"> +<title>DelegateUnimplemented</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-97.6355 667,-97.6355 667,5 -4,5"/> +<!-- Start --> +<!-- AuthComp --> +<g id="node4" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="348,-61.6355 250,-61.6355 250,-21.6355 348,-21.6355 348,-61.6355"/> +<text text-anchor="middle" x="299" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="299" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Start->AuthComp --> +<g id="edge3" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M54.0748,-41.6355C97.1107,-41.6355 182.142,-41.6355 239.791,-41.6355"/> +<polygon fill="black" stroke="black" points="239.864,-45.1356 249.863,-41.6355 239.863,-38.1356 239.864,-45.1356"/> +<text text-anchor="middle" x="152" y="-44.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text> +</g> +<!-- AuthComp->Start --> +<g id="edge5" class="edge"><title>AuthComp->Start</title> +<path fill="none" stroke="black" d="M249.934,-26.0577C243.944,-24.6511 237.868,-23.4514 232,-22.6355 161.567,-12.8417 141.697,-8.52478 72,-22.6355 69.1948,-23.2034 66.3471,-23.9518 63.5169,-24.8233"/> +<polygon fill="black" stroke="black" points="62.3066,-21.5388 54.0489,-28.1766 64.6436,-28.1372 62.3066,-21.5388"/> +<text text-anchor="middle" x="152" y="-25.0355" font-family="Times,serif" font-size="14.00">500 Internal Error</text> +</g> +<!-- Service --> +<g id="node7" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="662,-61.6355 568,-61.6355 568,-21.6355 662,-21.6355 662,-61.6355"/> +<text text-anchor="middle" x="615" y="-45.0355" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="615" y="-29.0355" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge7" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M348.009,-45.7159C354.065,-46.0953 360.172,-46.4183 366,-46.6355 447.721,-49.6805 468.282,-49.7738 550,-46.6355 552.523,-46.5386 555.101,-46.4206 557.704,-46.2859"/> +<polygon fill="black" stroke="black" points="558.03,-49.7729 567.807,-45.6931 557.62,-42.7849 558.03,-49.7729"/> +<text text-anchor="middle" x="458" y="-81.0355" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text> +<text text-anchor="middle" x="458" y="-66.0355" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text> +<text text-anchor="middle" x="458" y="-51.0355" font-family="Times,serif" font-size="14.00">X-Identity-Status: Confirmed</text> +</g> +<!-- Service->AuthComp --> +<g id="edge9" class="edge"><title>Service->AuthComp</title> +<path fill="none" stroke="black" d="M577.062,-21.5392C568.397,-17.8542 559.064,-14.5658 550,-12.6355 470.016,4.39794 446.078,3.95128 366,-12.6355 359.891,-13.9008 353.655,-15.7515 347.566,-17.9158"/> +<polygon fill="black" stroke="black" points="346.234,-14.6781 338.158,-21.5358 348.748,-21.2112 346.234,-14.6781"/> +<text text-anchor="middle" x="458" y="-30.0355" font-family="Times,serif" font-size="14.00">501 Unimplemented</text> +<text text-anchor="middle" x="458" y="-15.0355" font-family="Times,serif" font-size="14.00">WWW-Authenticate: Delegated</text> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_mapper.svg b/docs/source/images/graphs_mapper.svg new file mode 100644 index 00000000..52c6c55b --- /dev/null +++ b/docs/source/images/graphs_mapper.svg @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: Mapper Pages: 1 --> +<svg width="174pt" height="264pt" + viewBox="0.00 0.00 174.00 264.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 260)"> +<title>Mapper</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-260 171,-260 171,5 -4,5"/> +<!-- Start --> +<!-- Mapper --> +<g id="node4" class="node"><title>Mapper</title> +<polygon fill="#ebf1de" stroke="#687b37" points="119,-184 49,-184 49,-148 119,-148 119,-184"/> +<text text-anchor="middle" x="84" y="-161.4" font-family="Helvetica,sans-Serif" font-size="14.00">Mapper</text> +</g> +<!-- Start->Mapper --> +<g id="edge3" class="edge"><title>Start->Mapper</title> +<path fill="none" stroke="black" d="M84,-219.831C84,-212.131 84,-202.974 84,-194.417"/> +<polygon fill="black" stroke="black" points="87.5001,-194.413 84,-184.413 80.5001,-194.413 87.5001,-194.413"/> +</g> +<!-- Auths --> +<g id="node6" class="node"><title>Auths</title> +<polygon fill="white" stroke="white" points="166,-112 0,-112 0,-76 166,-76 166,-112"/> +<polygon fill="#fdefe3" stroke="#fdefe3" points="8,-81 8,-106 59,-106 59,-81 8,-81"/> +<polygon fill="none" stroke="#c00000" points="8,-81 8,-106 59,-106 59,-81 8,-81"/> +<text text-anchor="start" x="13.5" y="-90.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth1</text> +<polygon fill="#fdefe3" stroke="#fdefe3" points="59,-81 59,-106 109,-106 109,-81 59,-81"/> +<polygon fill="none" stroke="#c00000" points="59,-81 59,-106 109,-106 109,-81 59,-81"/> +<text text-anchor="start" x="64" y="-90.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth2</text> +<polygon fill="#fdefe3" stroke="#fdefe3" points="109,-81 109,-106 159,-106 159,-81 109,-81"/> +<polygon fill="none" stroke="#c00000" points="109,-81 109,-106 159,-106 159,-81 109,-81"/> +<text text-anchor="start" x="114" y="-90.2333" font-family="Helvetica,sans-Serif" font-size="14.00">Auth3</text> +</g> +<!-- Mapper->Auths --> +<g id="edge5" class="edge"><title>Mapper:sw->Auths:auth1</title> +<path fill="none" stroke="black" d="M49,-148C37.5237,-136.524 34.1339,-129.157 33.2662,-116.083"/> +<polygon fill="black" stroke="black" points="36.7628,-115.904 33,-106 29.7652,-116.089 36.7628,-115.904"/> +</g> +<!-- Mapper->Auths --> +<g id="edge7" class="edge"><title>Mapper:s->Auths:auth2</title> +<path fill="none" stroke="black" d="M84,-148C84,-133.271 84,-127.258 84,-116.207"/> +<polygon fill="black" stroke="black" points="87.5001,-116 84,-106 80.5001,-116 87.5001,-116"/> +</g> +<!-- Mapper->Auths --> +<g id="edge9" class="edge"><title>Mapper:se->Auths:auth3</title> +<path fill="none" stroke="black" d="M119,-148C130.388,-136.612 133.173,-129.088 133.817,-116.035"/> +<polygon fill="black" stroke="black" points="137.317,-116.062 134,-106 130.318,-115.934 137.317,-116.062"/> +</g> +<!-- Service --> +<g id="node10" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="131,-40 37,-40 37,-0 131,-0 131,-40"/> +<text text-anchor="middle" x="84" y="-23.4" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="84" y="-7.4" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- Auths->Service --> +<g id="edge11" class="edge"><title>Auths:auth1->Service</title> +<path fill="none" stroke="black" d="M33,-81C33,-68.2561 39.6326,-56.7707 48.1141,-47.2933"/> +<polygon fill="black" stroke="black" points="50.6575,-49.6992 55.221,-40.1376 45.6908,-44.7664 50.6575,-49.6992"/> +</g> +<!-- Auths->Service --> +<g id="edge13" class="edge"><title>Auths:auth2->Service</title> +<path fill="none" stroke="black" d="M84,-81C84,-70.9674 84,-60.0066 84,-50.1784"/> +<polygon fill="black" stroke="black" points="87.5001,-50.0559 84,-40.056 80.5001,-50.056 87.5001,-50.0559"/> +</g> +<!-- Auths->Service --> +<g id="edge15" class="edge"><title>Auths:auth3->Service</title> +<path fill="none" stroke="black" d="M134,-81C134,-68.4835 127.626,-57.1283 119.429,-47.7009"/> +<polygon fill="black" stroke="black" points="121.686,-45.0006 112.215,-40.2521 116.658,-49.8705 121.686,-45.0006"/> +</g> +</g> +</svg> diff --git a/docs/source/images/graphs_proxyAuth.svg b/docs/source/images/graphs_proxyAuth.svg new file mode 100644 index 00000000..7b94b077 --- /dev/null +++ b/docs/source/images/graphs_proxyAuth.svg @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.27.20101213.0545 (20101213.0545) + --> +<!-- Title: ProxyAuth Pages: 1 --> +<svg width="644pt" height="74pt" + viewBox="0.00 0.00 644.00 73.70" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 69.7025)"> +<title>ProxyAuth</title> +<polygon fill="white" stroke="white" points="-4,5 -4,-69.7025 641,-69.7025 641,5 -4,5"/> +<!-- Start --> +<!-- AuthComp --> +<g id="node4" class="node"><title>AuthComp</title> +<polygon fill="#fdefe3" stroke="#c00000" points="348,-55.7025 250,-55.7025 250,-15.7025 348,-15.7025 348,-55.7025"/> +<text text-anchor="middle" x="299" y="-39.1025" font-family="Helvetica,sans-Serif" font-size="14.00">Auth</text> +<text text-anchor="middle" x="299" y="-23.1025" font-family="Helvetica,sans-Serif" font-size="14.00">Component</text> +</g> +<!-- Start->AuthComp --> +<g id="edge3" class="edge"><title>Start->AuthComp</title> +<path fill="none" stroke="black" d="M54.0748,-35.7025C97.1107,-35.7025 182.142,-35.7025 239.791,-35.7025"/> +<polygon fill="black" stroke="black" points="239.864,-39.2026 249.863,-35.7025 239.863,-32.2026 239.864,-39.2026"/> +<text text-anchor="middle" x="152" y="-38.1025" font-family="Times,serif" font-size="14.00">Authorization: Basic VTpQ</text> +</g> +<!-- AuthComp->Start --> +<g id="edge9" class="edge"><title>AuthComp:w->Start</title> +<path fill="none" stroke="black" d="M250,-35.7025C238.368,-35.7025 242.686,-21.2988 232,-16.7025 166.676,11.3956 141.697,-2.59182 72,-16.7025 69.1948,-17.2705 66.3471,-18.0189 63.5169,-18.8903"/> +<polygon fill="black" stroke="black" points="62.3066,-15.6059 54.0489,-22.2437 64.6436,-22.2043 62.3066,-15.6059"/> +<text text-anchor="middle" x="152" y="-19.1025" font-family="Times,serif" font-size="14.00">500 Internal Error</text> +</g> +<!-- Service --> +<g id="node6" class="node"><title>Service</title> +<polygon fill="#d1ebf1" stroke="#1f477d" points="636,-55.7025 542,-55.7025 542,-15.7025 636,-15.7025 636,-55.7025"/> +<text text-anchor="middle" x="589" y="-39.1025" font-family="Helvetica,sans-Serif" font-size="14.00">OpenStack</text> +<text text-anchor="middle" x="589" y="-23.1025" font-family="Helvetica,sans-Serif" font-size="14.00">Service</text> +</g> +<!-- AuthComp->Service --> +<g id="edge5" class="edge"><title>AuthComp->Service</title> +<path fill="none" stroke="black" d="M348.195,-35.7025C399.052,-35.7025 478.372,-35.7025 531.947,-35.7025"/> +<polygon fill="black" stroke="black" points="531.971,-39.2026 541.971,-35.7025 531.971,-32.2026 531.971,-39.2026"/> +<text text-anchor="middle" x="445" y="-53.1025" font-family="Times,serif" font-size="14.00">Authorization: Basic dTpw</text> +<text text-anchor="middle" x="445" y="-38.1025" font-family="Times,serif" font-size="14.00">X-Authorization: Proxy U</text> +</g> +<!-- Service->AuthComp --> +<g id="edge7" class="edge"><title>Service:w->AuthComp</title> +<path fill="none" stroke="black" d="M542,-35.7025C530.368,-35.7025 534.686,-21.2988 524,-16.7025 459.492,11.0444 435.553,-7.03121 366,-16.7025 363.341,-17.0723 360.639,-17.5208 357.922,-18.0316"/> +<polygon fill="black" stroke="black" points="357.121,-14.6237 348.066,-20.1248 358.575,-21.471 357.121,-14.6237"/> +<text text-anchor="middle" x="445" y="-19.1025" font-family="Times,serif" font-size="14.00">403 Forbidden</text> +</g> +</g> +</svg> diff --git a/docs/source/images/images_layouts.svg b/docs/source/images/images_layouts.svg new file mode 100644 index 00000000..e7fe7a95 --- /dev/null +++ b/docs/source/images/images_layouts.svg @@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="222pt" + height="135pt" + viewBox="0.00 0.00 245.00 135.00" + id="svg3479" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="layouts-full.svg"> + <metadata + id="metadata3492"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs3490" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1680" + inkscape:window-height="1002" + id="namedview3488" + showgrid="false" + inkscape:zoom="1" + inkscape:cx="-0.58191504" + inkscape:cy="23.096747" + inkscape:window-x="0" + inkscape:window-y="22" + inkscape:window-maximized="0" + inkscape:current-layer="svg3479" /> + <g + id="layouts"> + <title + id="title3482">Auth Layouts</title> + <text + text-anchor="middle" + x="58" + y="134" + font-family="Helvetica,sans-Serif" + font-size="14.00" + id="text3484">(a)</text> + <text + text-anchor="middle" + x="178" + y="134" + font-family="Helvetica,sans-Serif" + font-size="14.00" + id="text3486">(b)</text> + </g> + <g + id="graph1" + class="graph" + transform="matrix(0.81928538,0,0,0.77044025,18.190271,97.915731)"> + <title + id="title3172">Together</title> + <polygon + style="fill:#ffffff;stroke:#ffffff" + points="-4,5 -4,5 -4,-100 113,-100 113,5 " + id="polygon3174" /> + <!-- Together --> + <g + id="node2" + class="node"> + <title + id="title3177">Together</title> + <polygon + style="fill:#fdefe3;stroke:#fdefe3" + points="8,-47 8,-47 8,-91 101,-91 101,-47 " + id="polygon3179" /> + <polygon + style="fill:none;stroke:#c00000" + points="8,-47 8,-47 8,-91 101,-91 101,-47 " + id="polygon3181" /> + <text + style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'" + x="38" + y="-75.233299" + font-size="14.00" + id="text3183">Auth</text> + <text + style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'" + x="13.5" + y="-58.4333" + font-size="14.00" + id="text3185">Component</text> + <polygon + style="fill:#d1ebf1;stroke:#d1ebf1" + points="8,-4 8,-4 8,-47 101,-47 101,-4 " + id="polygon3187" /> + <polygon + style="fill:none;stroke:#1f477d" + points="8,-4 8,-4 8,-47 101,-47 101,-4 " + id="polygon3189" /> + <text + style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'" + x="15.5" + y="-31.733299" + font-size="14.00" + id="text3191">OpenStack</text> + <text + style="font-size:14px;text-anchor:start;font-family:'Helvetica,sans-Serif'" + x="28" + y="-14.9333" + font-size="14.00" + id="text3193">Service</text> + </g> + </g> + <g + id="graph2" + class="graph" + transform="matrix(0.84200867,0,0,0.82332332,134.01425,108.66091)"> + <title + id="title3134">Seperate</title> + <polygon + style="fill:#ffffff;stroke:#ffffff" + points="-4,-120 103,-120 103,5 -4,5 -4,5 " + id="polygon3136" /> + <!-- AuthComp --> + <g + id="node2-9" + class="node"> + <title + id="title3139">AuthComp</title> + <polygon + style="fill:#fdefe3;stroke:#c00000" + points="0,-116 0,-76 98,-76 98,-116 98,-116 " + id="polygon3141" /> + <text + style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'" + x="49" + y="-99.400002" + font-size="14.00" + id="text3143">Auth</text> + <text + style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'" + x="49" + y="-83.400002" + font-size="14.00" + id="text3145">Component</text> + </g> + <!-- Service --> + <g + id="node4" + class="node"> + <title + id="title3148">Service</title> + <polygon + style="fill:#d1ebf1;stroke:#1f477d" + points="2,-40 2,0 96,0 96,-40 96,-40 " + id="polygon3150" /> + <text + style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'" + x="49" + y="-23.4" + font-size="14.00" + id="text3152">OpenStack</text> + <text + style="font-size:14px;text-anchor:middle;font-family:'Helvetica,sans-Serif'" + x="49" + y="-7.4000001" + font-size="14.00" + id="text3154">Service</text> + </g> + <!-- AuthComp->Service --> + <g + id="edge3" + class="edge"> + <title + id="title3157">AuthComp->Service</title> + <path + style="fill:none;stroke:#000000" + inkscape:connector-curvature="0" + d="m 49,-75.6334 c 0,7.8148 0,16.9081 0,25.4504" + id="path3159" /> + <polygon + style="fill:#000000;stroke:#000000" + points="52.5001,-50.1593 49,-40.1593 45.5001,-50.1593 52.5001,-50.1593 " + id="polygon3161" /> + </g> + </g> +</svg> diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..5d7c80fa --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,80 @@ +.. + 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. + +==================================================== +Welcome to Keystone, the OpenStack Identity Service! +==================================================== + +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`_. + +.. _`OpenStack's Identity API`: http://docs.openstack.org/api/openstack-identity-service/2.0/content/ +.. _`end-user perspective`: http://docs.openstack.org/ + +This documentation is generated by the Sphinx toolkit and lives in the source +tree. Additional documentation on Keystone and other components of OpenStack can +be found on the `OpenStack wiki`_. Also see the :doc:`community` page for +other ways to interact with the community. + +.. _`OpenStack wiki`: http://wiki.openstack.org + +Getting Started +=============== + +.. toctree:: + :maxdepth: 1 + + setup + configuration + configuringservices + community + +Man Pages +--------- + +.. toctree:: + :maxdepth: 1 + + man/keystone + man/keystone-manage + +Developers Documentation +======================== +.. toctree:: + :maxdepth: 1 + + developing + architecture + api_curl_examples + +Code Documentation +================== +.. toctree:: + :maxdepth: 1 + + modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/source/man/keystone-all.rst b/docs/source/man/keystone-all.rst new file mode 100644 index 00000000..fc2d68d7 --- /dev/null +++ b/docs/source/man/keystone-all.rst @@ -0,0 +1,83 @@ +======== +keystone +======== + +--------------------------- +Keystone Management Utility +--------------------------- + +:Author: keystone@lists.launchpad.net +:Date: 2010-11-16 +:Copyright: OpenStack LLC +:Version: 0.1.2 +:Manual section: 1 +:Manual group: cloud computing + +SYNOPSIS +======== + + keystone-all [options] + +DESCRIPTION +=========== + +keystone-all starts both the service and administrative APIs in a single +process to provide catalog, authorization, and authentication services for +OpenStack. + +USAGE +===== + + ``keystone-all [options]`` + +Common Options: +^^^^^^^^^^^^^^^ + -h, --help show this help message and exit + +The following configuration options are common to all keystone +programs.:: + + -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 +===== + +None + +SEE ALSO +======== + +* `Keystone <http://github.com/openstack/keystone>`__ + +SOURCE +====== + +* Keystone source is managed in GitHub `Keystone <http://github.com/openstack/keystone>`__ +* Keystone bugs are managed at Launchpad `Launchpad Keystone <https://bugs.launchpad.net/keystone>`__ diff --git a/docs/source/man/keystone-manage.rst b/docs/source/man/keystone-manage.rst new file mode 100644 index 00000000..91f2b9e7 --- /dev/null +++ b/docs/source/man/keystone-manage.rst @@ -0,0 +1,97 @@ +=============== +keystone-manage +=============== + +--------------------------- +Keystone Management Utility +--------------------------- + +:Author: keystone@lists.launchpad.net +:Date: 2010-11-16 +:Copyright: OpenStack LLC +:Version: 0.1.2 +:Manual section: 1 +:Manual group: cloud computing + +SYNOPSIS +======== + + keystone-manage [options] + +DESCRIPTION +=========== + +keystone-manage is the command line tool that interacts with the keystone +service to initialize and update data within Keystone. Generally, +keystone-manage is only used for operations that can not be accomplished +with through the keystone REST api, such data import/export and schema +migrations. + + +USAGE +===== + + ``keystone-manage [options] action [additional args]`` + + +General keystone-manage options: +-------------------------------- + +* ``--help`` : display verbose help output. + +Invoking keystone-manage by itself will give you some usage information. + +Available keystone-manage commands: + db_sync: Sync the database. + import_legacy: Import a legacy (pre-essex) version of the db. + export_legacy_catalog: Export service catalog from a legacy (pre-essex) db. + + +OPTIONS +======= + +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. + +FILES +===== + +None + +SEE ALSO +======== + +* `Keystone <http://github.com/openstack/keystone>`__ + +SOURCE +====== + +* Keystone is sourced in GitHub `Keystone <http://github.com/openstack/keystone>`__ +* Keystone bugs are managed at Launchpad `Launchpad Keystone <https://bugs.launchpad.net/keystone>`__ diff --git a/docs/source/middleware_architecture.rst b/docs/source/middleware_architecture.rst new file mode 100644 index 00000000..a8c38f3c --- /dev/null +++ b/docs/source/middleware_architecture.rst @@ -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" + diff --git a/docs/source/nova-api-paste.rst b/docs/source/nova-api-paste.rst new file mode 100644 index 00000000..602895ac --- /dev/null +++ b/docs/source/nova-api-paste.rst @@ -0,0 +1,143 @@ +.. + 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://your_keystone_host.com:5000/ + ;identical to the admin token defined in keystone.conf + admin_token = 999888777666 + ;Uncomment next line and check ip:port to use memcached to cache token requests + ;memcache_hosts = 127.0.0.1:11211 diff --git a/docs/source/old/backends.rst b/docs/source/old/backends.rst new file mode 100644 index 00000000..b3fc2d91 --- /dev/null +++ b/docs/source/old/backends.rst @@ -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. diff --git a/docs/source/old/controllingservers.rst b/docs/source/old/controllingservers.rst new file mode 100644 index 00000000..ba8bfc06 --- /dev/null +++ b/docs/source/old/controllingservers.rst @@ -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 diff --git a/docs/source/old/endpoints.rst b/docs/source/old/endpoints.rst new file mode 100644 index 00000000..84a42e09 --- /dev/null +++ b/docs/source/old/endpoints.rst @@ -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" + } + ] + } diff --git a/docs/source/old/extensions.rst b/docs/source/old/extensions.rst new file mode 100644 index 00000000..539bef39 --- /dev/null +++ b/docs/source/old/extensions.rst @@ -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. diff --git a/docs/source/old/middleware.rst b/docs/source/old/middleware.rst new file mode 100644 index 00000000..69506ee2 --- /dev/null +++ b/docs/source/old/middleware.rst @@ -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. diff --git a/docs/source/old/migration.rst b/docs/source/old/migration.rst new file mode 100644 index 00000000..460d980b --- /dev/null +++ b/docs/source/old/migration.rst @@ -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>`_ diff --git a/docs/source/old/releases.rst b/docs/source/old/releases.rst new file mode 100644 index 00000000..a4b698d7 --- /dev/null +++ b/docs/source/old/releases.rst @@ -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 diff --git a/docs/source/old/services.rst b/docs/source/old/services.rst new file mode 100644 index 00000000..d1c33381 --- /dev/null +++ b/docs/source/old/services.rst @@ -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 diff --git a/docs/source/old/ssl.rst b/docs/source/old/ssl.rst new file mode 100644 index 00000000..839e951e --- /dev/null +++ b/docs/source/old/ssl.rst @@ -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> diff --git a/docs/source/setup.rst b/docs/source/setup.rst new file mode 100644 index 00000000..7d03fd66 --- /dev/null +++ b/docs/source/setup.rst @@ -0,0 +1,171 @@ +.. + 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. + +============================================= +Setting up a Keystone development environment +============================================= + +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 Repository`: http://github.com/openstack/keystone +.. _`User Documentation`: http://docs.openstack.org/ + +Prerequisites +============= + +This document assumes you are using: + +- Ubuntu 11.10, Fedora 15, or Mac OS X Lion +- `Python 2.7`_ + +.. _`Python 2.7`: http://www.python.org/ + +And that you have the following tools available on your system: + +- git_ +- setuptools_ +- pip_ + +**Reminder**: If you're successfully using a different platform, or a +different version of the above, please document your configuration here! + +.. _git: http://git-scm.com/ +.. _setuptools: http://pypi.python.org/pypi/setuptools + +Getting the latest code +======================= + +Make a clone of the code from our `Github repository`:: + + $ git clone https://github.com/openstack/keystone.git + +When that is complete, you can:: + + $ cd keystone + +Installing dependencies +======================= + +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 + +However, your system *may* need additional dependencies that `pip` (and by +extension, PyPi) cannot satisfy. These dependencies should be installed +prior to using `pip`, and the installation method may vary depending on +your platform. + +Ubuntu 11.10:: + + $ sudo apt-get install python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev + +Fedora 15:: + + $ sudo yum install python-sqlite2 python-lxml python-greenlet-devel python-ldap + +Mac OS X Lion (requires MacPorts_):: + + $ sudo port install py-ldap + +.. _MacPorts: http://www.macports.org/ + +PyPi Packages and VirtualEnv +---------------------------- + +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:: + + $ python tools/install_venv.py + +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/ + +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 + + # 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:: + + >>> import keystone + >>> + +If you can import keystone successfully, you should be ready to move on to :doc:`developing` + +Troubleshooting +=============== + +Eventlet segfaults on RedHat / Fedora +------------------------------------- + +[*If this is no longer an issue, please remove this section, thanks!*] + +On some OSes, specifically Fedora 15, the current versions of +greenlet/eventlet segfault when running keystone. To fix this, install +the development versions of greenlet and eventlet:: + + $ pip uninstall greenlet eventlet + $ cd <appropriate working directory> + $ hg clone https://bitbucket.org/ambroff/greenlet + $ cd greenlet + $ sudo python setup.py install + + $ cd <appropriate working directory> + $ hg clone https://bitbucket.org/which_linden/eventlet + $ cd greenlet + $ sudo python setup.py install diff --git a/docs/source/static/basic.css b/docs/source/static/basic.css new file mode 100644 index 00000000..d909ce37 --- /dev/null +++ b/docs/source/static/basic.css @@ -0,0 +1,416 @@ +/** + * Sphinx stylesheet -- basic theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 0; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +/* -- other body styles ----------------------------------------------------- */ + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlight { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} diff --git a/docs/source/static/default.css b/docs/source/static/default.css new file mode 100644 index 00000000..c8091ecb --- /dev/null +++ b/docs/source/static/default.css @@ -0,0 +1,230 @@ +/** + * Sphinx stylesheet -- default theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +div.body p, div.body dd, div.body li { + text-align: left; + line-height: 130%; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: left; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} diff --git a/docs/source/static/jquery.tweet.js b/docs/source/static/jquery.tweet.js new file mode 100644 index 00000000..c93fea87 --- /dev/null +++ b/docs/source/static/jquery.tweet.js @@ -0,0 +1,154 @@ +(function($) { + + $.fn.tweet = function(o){ + var s = { + username: ["seaofclouds"], // [string] required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"] + list: null, //[string] optional name of list belonging to username + avatar_size: null, // [integer] height and width of avatar if displayed (48px max) + count: 3, // [integer] how many tweets to display? + intro_text: null, // [string] do you want text BEFORE your your tweets? + outro_text: null, // [string] do you want text AFTER your tweets? + join_text: null, // [string] optional text in between date and tweet, try setting to "auto" + auto_join_text_default: "i said,", // [string] auto text for non verb: "i said" bullocks + auto_join_text_ed: "i", // [string] auto text for past tense: "i" surfed + auto_join_text_ing: "i am", // [string] auto tense for present tense: "i was" surfing + auto_join_text_reply: "i replied to", // [string] auto tense for replies: "i replied to" @someone "with" + auto_join_text_url: "i was looking at", // [string] auto tense for urls: "i was looking at" http:... + loading_text: null, // [string] optional loading text, displayed while tweets load + query: null // [string] optional search query + }; + + if(o) $.extend(s, o); + + $.fn.extend({ + linkUrl: function() { + var returning = []; + var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi; + this.each(function() { + returning.push(this.replace(regexp,"<a href=\"$1\">$1</a>")); + }); + return $(returning); + }, + linkUser: function() { + var returning = []; + var regexp = /[\@]+([A-Za-z0-9-_]+)/gi; + this.each(function() { + returning.push(this.replace(regexp,"<a href=\"http://twitter.com/$1\">@$1</a>")); + }); + return $(returning); + }, + linkHash: function() { + var returning = []; + var regexp = / [\#]+([A-Za-z0-9-_]+)/gi; + this.each(function() { + returning.push(this.replace(regexp, ' <a href="http://search.twitter.com/search?q=&tag=$1&lang=all&from='+s.username.join("%2BOR%2B")+'">#$1</a>')); + }); + return $(returning); + }, + capAwesome: function() { + var returning = []; + this.each(function() { + returning.push(this.replace(/\b(awesome)\b/gi, '<span class="awesome">$1</span>')); + }); + return $(returning); + }, + capEpic: function() { + var returning = []; + this.each(function() { + returning.push(this.replace(/\b(epic)\b/gi, '<span class="epic">$1</span>')); + }); + return $(returning); + }, + makeHeart: function() { + var returning = []; + this.each(function() { + returning.push(this.replace(/(<)+[3]/gi, "<tt class='heart'>♥</tt>")); + }); + return $(returning); + } + }); + + function relative_time(time_value) { + var parsed_date = Date.parse(time_value); + var relative_to = (arguments.length > 1) ? arguments[1] : new Date(); + var delta = parseInt((relative_to.getTime() - parsed_date) / 1000); + var pluralize = function (singular, n) { + return '' + n + ' ' + singular + (n == 1 ? '' : 's'); + }; + if(delta < 60) { + return 'less than a minute ago'; + } else if(delta < (45*60)) { + return 'about ' + pluralize("minute", parseInt(delta / 60)) + ' ago'; + } else if(delta < (24*60*60)) { + return 'about ' + pluralize("hour", parseInt(delta / 3600)) + ' ago'; + } else { + return 'about ' + pluralize("day", parseInt(delta / 86400)) + ' ago'; + } + } + + function build_url() { + var proto = ('https:' == document.location.protocol ? 'https:' : 'http:'); + if (s.list) { + return proto+"//api.twitter.com/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?"; + } else if (s.query == null && s.username.length == 1) { + return proto+'//twitter.com/status/user_timeline/'+s.username[0]+'.json?count='+s.count+'&callback=?'; + } else { + var query = (s.query || 'from:'+s.username.join('%20OR%20from:')); + return proto+'//search.twitter.com/search.json?&q='+query+'&rpp='+s.count+'&callback=?'; + } + } + + return this.each(function(){ + var list = $('<ul class="tweet_list">').appendTo(this); + var intro = '<p class="tweet_intro">'+s.intro_text+'</p>'; + var outro = '<p class="tweet_outro">'+s.outro_text+'</p>'; + var loading = $('<p class="loading">'+s.loading_text+'</p>'); + + if(typeof(s.username) == "string"){ + s.username = [s.username]; + } + + if (s.loading_text) $(this).append(loading); + $.getJSON(build_url(), function(data){ + if (s.loading_text) loading.remove(); + if (s.intro_text) list.before(intro); + $.each((data.results || data), function(i,item){ + // auto join text based on verb tense and content + if (s.join_text == "auto") { + if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) { + var join_text = s.auto_join_text_reply; + } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) { + var join_text = s.auto_join_text_url; + } else if (item.text.match(/^((\w+ed)|just) .*/im)) { + var join_text = s.auto_join_text_ed; + } else if (item.text.match(/^(\w*ing) .*/i)) { + var join_text = s.auto_join_text_ing; + } else { + var join_text = s.auto_join_text_default; + } + } else { + var join_text = s.join_text; + }; + + var from_user = item.from_user || item.user.screen_name; + var profile_image_url = item.profile_image_url || item.user.profile_image_url; + var join_template = '<span class="tweet_join"> '+join_text+' </span>'; + var join = ((s.join_text) ? join_template : ' '); + var avatar_template = '<a class="tweet_avatar" href="http://twitter.com/'+from_user+'"><img src="'+profile_image_url+'" height="'+s.avatar_size+'" width="'+s.avatar_size+'" alt="'+from_user+'\'s avatar" title="'+from_user+'\'s avatar" border="0"/></a>'; + var avatar = (s.avatar_size ? avatar_template : ''); + var date = '<a href="http://twitter.com/'+from_user+'/statuses/'+item.id+'" title="view tweet on twitter">'+relative_time(item.created_at)+'</a>'; + var text = '<span class="tweet_text">' +$([item.text]).linkUrl().linkUser().linkHash().makeHeart().capAwesome().capEpic()[0]+ '</span>'; + + // until we create a template option, arrange the items below to alter a tweet's display. + list.append('<li>' + avatar + date + join + text + '</li>'); + + list.children('li:first').addClass('tweet_first'); + list.children('li:odd').addClass('tweet_even'); + list.children('li:even').addClass('tweet_odd'); + }); + if (s.outro_text) list.after(outro); + }); + + }); + }; +})(jQuery);
\ No newline at end of file diff --git a/docs/source/static/tweaks.css b/docs/source/static/tweaks.css new file mode 100644 index 00000000..16cd6e76 --- /dev/null +++ b/docs/source/static/tweaks.css @@ -0,0 +1,65 @@ +ul.todo_list { + list-style-type: none; + margin: 0; + padding: 0; +} + +ul.todo_list li { + display: block; + margin: 0; + padding: 7px 0; + border-top: 1px solid #eee; +} + +ul.todo_list li p { + display: inline; +} + +ul.todo_list li p.link { + font-weight: bold; +} + +ul.todo_list li p.details { + font-style: italic; +} + +ul.todo_list li { +} + +div.admonition { + border: 1px solid #8F1000; +} + +div.admonition p.admonition-title { + background-color: #8F1000; + border-bottom: 1px solid #8E8E8E; +} + +a { + color: #CF2F19; +} + +div.related ul li a { + color: #CF2F19; +} + +div.sphinxsidebar h4 { + background-color:#8E8E8E; + border:1px solid #255E6E; + color:white; + font-size:1em; + margin:1em 0 0.5em; + padding:0.1em 0 0.1em 0.5em; +} + +em { + font-style: normal; +} + +table.docutils { + font-size: 11px; +} + +a tt { + color:#CF2F19; +}
\ No newline at end of file |
