Merge redux branch (keystone light)
Change-Id: I2cb5b198a06848f42f919ea49e338443131e263e
This commit is contained in:
commit
eef1f0d93a
28
.gitignore
vendored
28
.gitignore
vendored
@ -1,21 +1,17 @@
|
||||
*.pyc
|
||||
.cache/
|
||||
.project
|
||||
.project/
|
||||
.pydevproject
|
||||
.pydevproject/
|
||||
.settings/
|
||||
.keystone-venv/
|
||||
*.swp
|
||||
vendor
|
||||
.ksl-venv
|
||||
.venv
|
||||
build/
|
||||
dist/
|
||||
doc/source/sourcecode
|
||||
.tox
|
||||
keystone.egg-info/
|
||||
*.db
|
||||
.*.swp
|
||||
*.log
|
||||
*.pid
|
||||
pidfile
|
||||
*.komodoproject
|
||||
run_tests.log
|
||||
.coverage
|
||||
covhtml
|
||||
pep8.txt
|
||||
nosetests.xml
|
||||
bla.db
|
||||
docs/build
|
||||
.DS_Store
|
||||
docs/source/modules.rst
|
||||
docs/source/keystone.*
|
||||
|
16
.mailmap
16
.mailmap
@ -1,16 +0,0 @@
|
||||
<dolph.mathews@rackspace.com> <dolph.mathews@gmail.com>
|
||||
Edouard Thuleau <edouard1.thuleau@orange.com>
|
||||
<jeblair@hp.com> <corvus@gnu.org>
|
||||
<jeblair@hp.com> <james.blair@rackspace.com>
|
||||
<joon.eo@gmail.com> <john.eo@rackspace.com>
|
||||
Khaled Hussein <khaled.hussein@gmail.com> KnightHacker <khaled.hussein@rackspace.com>
|
||||
Khaled Hussein <khaled.hussein@gmail.com> Khaled Hussein <khaled.hussein@rackspace.com>
|
||||
<rjuvvadi@hcl.com> <ramana@venus.lekha.org>
|
||||
<rjuvvadi@hcl.com> <rrjuvvadi@gmail.com>
|
||||
<xtoddx@gmail.com> <todd@rubidine.com>
|
||||
<github@highbridgellc.com> <gihub@highbridgellc.com>
|
||||
<github@highbridgellc.com> <ziad.sawalha@rackspace.com>
|
||||
sirish.bitra <sirish.bitra@gmail.com> sirish bitra <sirish.bitra@gmail.com>
|
||||
sirish.bitra <sirish.bitra@gmail.com> sirishbitra <sirish.bitra@gmail.com>
|
||||
sirish.bitra <sirish.bitra@gmail.com> bsirish <sirish.bitra@gmail.com>
|
||||
sirish.bitra <sirish.bitra@gmail.com> root <root@bsirish.(none)>
|
50
AUTHORS
50
AUTHORS
@ -1,50 +0,0 @@
|
||||
Adipudi Praveena <padipudi@padipudi.(none)>
|
||||
Alex Silva <alex.silva@M1BPAGY.(none)>
|
||||
Anne Gentle <anne@openstack.org>
|
||||
Anthony Young <sleepsonthefloor@gmail.com>
|
||||
Brian Lamar <brian.lamar@gmail.com>
|
||||
Dan Prince <dan.prince@rackspace.com>
|
||||
Dolph Mathews <dolph.mathews@gmail.com>
|
||||
Ed Leafe <ed@leafe.com>
|
||||
Edouard Thuleau <edouard1.thuleau@orange.com>
|
||||
Eoghan Glynn <eglynn@redhat.com>
|
||||
gholt <gholt@brim.net>
|
||||
Ionuț Arțăriși <iartarisi@suse.cz>
|
||||
jabdul <abdulkader.j@hcl.com>
|
||||
James E. Blair <jeblair@hp.com>
|
||||
Jason Cannavale <jason.cannavale@rackspace.com>
|
||||
Jay Pipes <jaypipes@gmail.com>
|
||||
Jenkins <jenkins@review.openstack.org>
|
||||
Jesse Andrews <anotherjesse@gmail.com>
|
||||
Joe Savak <joe.savak@rackspace.com>
|
||||
John Dickinson <me@not.mn>
|
||||
John Eo <joon.eo@gmail.com>
|
||||
Jorge L. Williams <jorge.williams@rackspace.com>
|
||||
Joseph W. Breu <joseph.breu@rackspace.com>
|
||||
Josh Kearney <josh@jk0.org>
|
||||
Julien Danjou <julien.danjou@enovance.com>
|
||||
Justin Shepherd <jshepher@rackspace.com>
|
||||
Kevin L. Mitchell <kevin.mitchell@rackspace.com>
|
||||
Khaled Hussein <khaled.hussein@gmail.com>
|
||||
Kiall Mac Innes <kiall@managedit.ie>
|
||||
Mark Gius <mgius7096@gmail.com>
|
||||
Mark McLoughlin <markmc@redhat.com>
|
||||
Monty Taylor <mordred@inaugust.com>
|
||||
Pádraig Brady <P@draigBrady.com>
|
||||
Paul Voccio <paul@substation9.com>
|
||||
Ramana Juvvadi <rjuvvadi@hcl.com>
|
||||
Robin Norwood <robin.norwood@gmail.com>
|
||||
root <root@newapps.(none)>
|
||||
Sai Krishna <saikrishna1511@gmail.com>
|
||||
Sirish Bitra <sirish.bitra@gmail.com>
|
||||
Sony K. Philip <sony@hcleai.com>
|
||||
termie <github@anarkystic.com>
|
||||
Thierry Carrez <thierry@openstack.org>
|
||||
Todd Willey <xtoddx@gmail.com>
|
||||
Will Kelly <the.william.kelly@gmail.com>
|
||||
Vishvananda Ishaya <vishvananda@gmail.com>
|
||||
Yaguang Tang <heut2008@gmail.com>
|
||||
Yogeshwar Srikrishnan <yoga80@yahoo.com>
|
||||
Yuriy Taraday <yorik.sar@gmail.com>
|
||||
Ziad Sawalha <github@highbridgellc.com>
|
||||
Zhongyue Luo <lzyeval@gmail.com>
|
68
HACKING
68
HACKING
@ -1,68 +0,0 @@
|
||||
Keystone Style Commandments (pilfered from Nova and added to)
|
||||
=============================================================
|
||||
|
||||
Step 1: Read http://www.python.org/dev/peps/pep-0008/
|
||||
Step 2: Read http://www.python.org/dev/peps/pep-0008/ again
|
||||
Step 3: Read on
|
||||
|
||||
Imports
|
||||
-------
|
||||
- thou shalt not import objects, only modules
|
||||
- thou shalt not import more than one module per line
|
||||
- thou shalt not make relative imports
|
||||
- thou shalt organize your imports according to the following template
|
||||
|
||||
::
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
{{stdlib imports in human alphabetical order}}
|
||||
\n
|
||||
{{OpenStack/Keystone imports in human alphabetical order}}
|
||||
\n
|
||||
\n
|
||||
{{begin your code}}
|
||||
|
||||
|
||||
General
|
||||
-------
|
||||
- thou shalt put two newlines twixt toplevel code (funcs, classes, etc)
|
||||
- thou shalt put one newline twixt methods in classes and anywhere else
|
||||
- thou shalt not write "except:", use "except Exception:" at the very least
|
||||
- thou shalt include your name with TODOs as in "TODO(waldo)"
|
||||
- thou shalt not name anything the same name as a builtin or reserved word
|
||||
- thou shouldeth comment profusely
|
||||
- thou shalt not violate causality in our time cone, or else
|
||||
|
||||
|
||||
Human Alphabetical Order Examples
|
||||
---------------------------------
|
||||
::
|
||||
import httplib
|
||||
import logging
|
||||
import random
|
||||
import StringIO
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import keystone.logic.types.fault as fault
|
||||
import keystone.db.sqlalchemy.api as db_api
|
||||
|
||||
Docstrings
|
||||
----------
|
||||
Add them to modules, classes, and functions:
|
||||
"""Summary of the function, class or method, less than 80 characters.
|
||||
|
||||
New paragraph after newline that explains in more detail any general
|
||||
information about the function, class or method. After this, if defining
|
||||
parameters and return types use the Sphinx format. After that an extra
|
||||
newline then close the quotations.
|
||||
|
||||
When writing the docstring for a class, an extra line should be placed
|
||||
after the closing quotations. For more in-depth explanations for these
|
||||
decisions see http://www.python.org/dev/peps/pep-0257/
|
||||
|
||||
:param foo: the foo parameter
|
||||
:param bar: the bar parameter
|
||||
:returns: description of the return value
|
||||
|
||||
"""
|
||||
|
192
HACKING.rst
Normal file
192
HACKING.rst
Normal file
@ -0,0 +1,192 @@
|
||||
Keystone Style Commandments
|
||||
===========================
|
||||
|
||||
- Step 1: Read http://www.python.org/dev/peps/pep-0008/
|
||||
- Step 2: Read http://www.python.org/dev/peps/pep-0008/ again
|
||||
- Step 3: Read on
|
||||
|
||||
|
||||
General
|
||||
-------
|
||||
- Put two newlines between top-level code (funcs, classes, etc)
|
||||
- Put one newline between methods in classes and anywhere else
|
||||
- Do not write "except:", use "except Exception:" at the very least
|
||||
- Include your name with TODOs as in "#TODO(termie)"
|
||||
- Do not name anything the same name as a built-in or reserved word
|
||||
|
||||
TODO vs FIXME
|
||||
-------------
|
||||
|
||||
- TODO(name): implies that something should be done (cleanup, refactoring,
|
||||
etc), but is expected to be functional.
|
||||
- FIXME(name): implies that the method/function/etc shouldn't be used until
|
||||
that code is resolved and bug fixed.
|
||||
|
||||
Imports
|
||||
-------
|
||||
- Do not import objects, only modules
|
||||
- Do not import more than one module per line
|
||||
- Do not make relative imports
|
||||
- Order your imports by the full module path
|
||||
- Organize your imports according to the following template
|
||||
|
||||
Example::
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
{{stdlib imports in human alphabetical order}}
|
||||
\n
|
||||
{{third-party lib imports in human alphabetical order}}
|
||||
\n
|
||||
{{nova imports in human alphabetical order}}
|
||||
\n
|
||||
\n
|
||||
{{begin your code}}
|
||||
|
||||
|
||||
Human Alphabetical Order Examples
|
||||
---------------------------------
|
||||
Example::
|
||||
|
||||
import httplib
|
||||
import logging
|
||||
import random
|
||||
import StringIO
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import eventlet
|
||||
import webob.exc
|
||||
|
||||
import nova.api.ec2
|
||||
from nova.api import openstack
|
||||
from nova.auth import users
|
||||
import nova.flags
|
||||
from nova.endpoint import cloud
|
||||
from nova import test
|
||||
|
||||
|
||||
Docstrings
|
||||
----------
|
||||
Example::
|
||||
|
||||
"""A one line docstring looks like this and ends in a period."""
|
||||
|
||||
|
||||
"""A multiline docstring has a one-line summary, less than 80 characters.
|
||||
|
||||
Then a new paragraph after a newline that explains in more detail any
|
||||
general information about the function, class or method. Example usages
|
||||
are also great to have here if it is a complex class for function.
|
||||
|
||||
When writing the docstring for a class, an extra line should be placed
|
||||
after the closing quotations. For more in-depth explanations for these
|
||||
decisions see http://www.python.org/dev/peps/pep-0257/
|
||||
|
||||
A docstring ends with an empty line before the closing quotations.
|
||||
|
||||
Describe parameters and return values, using the Sphinx format; the
|
||||
appropriate syntax is as follows.
|
||||
|
||||
:param foo: the foo parameter
|
||||
:param bar: the bar parameter
|
||||
:type bar: parameter type for 'bar'
|
||||
:returns: return_type -- description of the return value
|
||||
:returns: description of the return value
|
||||
:raises: AttributeError, KeyError
|
||||
|
||||
"""
|
||||
|
||||
|
||||
Dictionaries/Lists
|
||||
------------------
|
||||
If a dictionary (dict) or list object is longer than 80 characters, its items
|
||||
should be split with newlines. Embedded iterables should have their items
|
||||
indented. Additionally, the last item in the dictionary should have a trailing
|
||||
comma. This increases readability and simplifies future diffs.
|
||||
|
||||
Example::
|
||||
|
||||
my_dictionary = {
|
||||
"image": {
|
||||
"name": "Just a Snapshot",
|
||||
"size": 2749573,
|
||||
"properties": {
|
||||
"user_id": 12,
|
||||
"arch": "x86_64",
|
||||
},
|
||||
"things": [
|
||||
"thing_one",
|
||||
"thing_two",
|
||||
],
|
||||
"status": "ACTIVE",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Calling Methods
|
||||
---------------
|
||||
Calls to methods 80 characters or longer should format each argument with
|
||||
newlines. This is not a requirement, but a guideline::
|
||||
|
||||
unnecessarily_long_function_name('string one',
|
||||
'string two',
|
||||
kwarg1=constants.ACTIVE,
|
||||
kwarg2=['a', 'b', 'c'])
|
||||
|
||||
|
||||
Rather than constructing parameters inline, it is better to break things up::
|
||||
|
||||
list_of_strings = [
|
||||
'what_a_long_string',
|
||||
'not as long',
|
||||
]
|
||||
|
||||
dict_of_numbers = {
|
||||
'one': 1,
|
||||
'two': 2,
|
||||
'twenty four': 24,
|
||||
}
|
||||
|
||||
object_one.call_a_method('string three',
|
||||
'string four',
|
||||
kwarg1=list_of_strings,
|
||||
kwarg2=dict_of_numbers)
|
||||
|
||||
|
||||
Internationalization (i18n) Strings
|
||||
-----------------------------------
|
||||
In order to support multiple languages, we have a mechanism to support
|
||||
automatic translations of exception and log strings.
|
||||
|
||||
Example::
|
||||
|
||||
msg = _("An error occurred")
|
||||
raise HTTPBadRequest(explanation=msg)
|
||||
|
||||
If you have a variable to place within the string, first internationalize the
|
||||
template string then do the replacement.
|
||||
|
||||
Example::
|
||||
|
||||
msg = _("Missing parameter: %s") % ("flavor",)
|
||||
LOG.error(msg)
|
||||
|
||||
If you have multiple variables to place in the string, use keyword parameters.
|
||||
This helps our translators reorder parameters when needed.
|
||||
|
||||
Example::
|
||||
|
||||
msg = _("The server with id %(s_id)s has no key %(m_key)s")
|
||||
LOG.error(msg % {"s_id": "1234", "m_key": "imageId"})
|
||||
|
||||
|
||||
Creating Unit Tests
|
||||
-------------------
|
||||
For every new feature, unit tests should be created that both test and
|
||||
(implicitly) document the usage of said feature. If submitting a patch for a
|
||||
bug that had no unit test, a new passing unit test should be added. If a
|
||||
submitted bug fix does have a unit test, be sure to add a new one that fails
|
||||
without the patch and passes with the patch.
|
||||
|
||||
For more information on creating unit tests and utilizing the testing
|
||||
infrastructure in OpenStack Nova, please read nova/testing/README.rst.
|
202
LICENSE
202
LICENSE
@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
21
MANIFEST.in
21
MANIFEST.in
@ -1,21 +0,0 @@
|
||||
include AUTHORS
|
||||
include HACKING
|
||||
include LICENSE
|
||||
include MANIFEST.in
|
||||
include README.md
|
||||
include pylintrc
|
||||
include run_tests.py
|
||||
include run_tests.sh
|
||||
include setup.py
|
||||
graft bin
|
||||
graft doc
|
||||
prune doc/source/sourcecode
|
||||
graft etc
|
||||
graft examples
|
||||
graft keystone/content
|
||||
graft keystone/test/etc
|
||||
graft tools
|
||||
recursive-include keystone *.json *.xml *.cfg README
|
||||
include keystone/backends/ldap/keystone.ldif
|
||||
include keystone/backends/ldap/keystone.schema
|
||||
global-exclude *.pyc *.sdx *.log *.db *.swp
|
275
README.md
275
README.md
@ -1,275 +0,0 @@
|
||||
# Keystone: OpenStack Identity Service
|
||||
|
||||
Keystone is a Python implementation of the [OpenStack](http://www.openstack.org) identity service API.
|
||||
|
||||
# Documentation
|
||||
|
||||
## For users and sysadmins
|
||||
|
||||
Learn how to install, configure, manage, and interact with the OpenStack
|
||||
Identity Service API at the [OpenStack Documentation](http://docs.openstack.org/) site.
|
||||
|
||||
## For contributors
|
||||
|
||||
Learn how to setup a development environment and then test, run, and contribute to Keystone at the
|
||||
[Contributor Documentation](http://keystone.openstack.org/) site.
|
||||
|
||||
# Questions/Feedback
|
||||
|
||||
Having trouble? We'd like to help!
|
||||
|
||||
* Try the documentation first — it's got answers to many common questions.
|
||||
* Search for information in the archives of the [OpenStack mailing list](http://wiki.openstack.org/MailingLists), or post a question.
|
||||
* Ask a question in the [#openstack IRC channel](http://wiki.openstack.org/UsingIRC).
|
||||
* If you notice errors, please [open a bug](https://bugs.launchpad.net/keystone) and let us know! Please only use the bug tracker for criticisms and improvements. For tech support, use the resources above.
|
||||
|
||||
# For Contributors
|
||||
|
||||
## What's in the box?
|
||||
|
||||
### Services
|
||||
|
||||
* Keystone - identity store and authentication service
|
||||
* Auth_Token - WSGI middleware that can be used to handle token auth protocol (WSGI or remote proxy)
|
||||
* Echo - A sample service that responds by returning call details
|
||||
|
||||
### Also included:
|
||||
|
||||
* Auth_Basic - Stub for WSGI middleware that will be used to handle basic auth
|
||||
* Auth_OpenID - Stub for WSGI middleware that will be used to handle openid auth protocol (to be implemented)
|
||||
* RemoteAuth - WSGI middleware that can be used in services (like Swift, Nova, and Glance) when Auth middleware is running remotely
|
||||
|
||||
### Built-In commands:
|
||||
|
||||
* bin/keystone - Provides HTTP API for users and administrators
|
||||
* bin/keystone-admin - Provides HTTP API for administrators
|
||||
* bin/keystone-service - Provides HTTP API for users
|
||||
* bin/keystone-manage - Provides command-line interface for managing all aspects of Keystone
|
||||
|
||||
## Running Keystone
|
||||
|
||||
Starting both Admin and Service API endpoints:
|
||||
|
||||
$ ./bin/keystone
|
||||
|
||||
Starting the auth server only (exposes the Service API):
|
||||
|
||||
$ ./bin/keystone-auth
|
||||
|
||||
Starting the admin server only (exposes the Admin API):
|
||||
|
||||
$ ./bin/keystone-admin
|
||||
|
||||
By default, configuration parameters (such as the IP and port binding for each service) are parsed from `etc/keystone.conf`.
|
||||
|
||||
## Configuring Keystone
|
||||
|
||||
Keystone gets its configuration from command-line parameters or a `.conf` file. While command line parameters take precedence,
|
||||
Keystone looks in the following location to find a configuration file:
|
||||
|
||||
1. Command line parameter
|
||||
2. /etc/keystone.conf
|
||||
3. /etc/keystone/keystone.conf
|
||||
4. <topdir>/etc/keystone.conf
|
||||
|
||||
Additional configuration templates are maintained in `keystone/test/etc/` that may be useful as a reference.
|
||||
|
||||
### Editing and Building the API Developer Guide
|
||||
|
||||
Users of the Keystone API are often developers making ReSTful API calls to Keystone. The guide to provide them
|
||||
information is therefore called a `Developer Guide`. Developer in this case is not to be confused with contributors
|
||||
working on the Keystone codebase itself.
|
||||
|
||||
The developer guides are automatically generated from XML and other artifacts that live in the
|
||||
[OpenStack Manuals project](https://launchpad.net/openstack-manuals).
|
||||
|
||||
To build the Developer Guide from source, you need [Maven](http://maven.apache.org/). To build the docs and publish a new PDF:
|
||||
|
||||
$ cd to folder with the pom.xml file
|
||||
$ mvn clean generate-sources && cp target/docbkx/pdf/identitydevguide.pdf ../../keystone/content/identitydevguide.pdf
|
||||
|
||||
The output will go into the `target` folder (the source is in `src`). Output generated is PDF and webhelp.
|
||||
|
||||
# Additional Information:
|
||||
|
||||
## Sample data
|
||||
|
||||
A set of sample data can be loaded by running a shell script:
|
||||
|
||||
$ ./bin/sampledata
|
||||
|
||||
The script calls `keystone-manage` to import the sample data.
|
||||
|
||||
After starting keystone or running `keystone-manage` a `keystone.db` sqlite database should be created in the keystone folder,
|
||||
per the default configuration.
|
||||
|
||||
## Demo
|
||||
|
||||
To run client demo (with all auth middleware running locally on sample service):
|
||||
|
||||
$ ./examples/echo/bin/echod
|
||||
$ python examples/echo/echo_client.py
|
||||
|
||||
## CURL commands
|
||||
|
||||
<pre>
|
||||
# Get an unscoped token
|
||||
$ curl -d '{"auth": {"passwordCredentials": {"username": "joeuser", "password": "secrete"}}}' -H "Content-type: application/json" http://localhost:5000/v2.0/tokens
|
||||
|
||||
# Get a token for a tenant
|
||||
$ curl -d '{"auth": {"passwordCredentials": {"username": "joeuser", "password": "secrete"}, "tenantName": "customer-x"}}' -H "Content-type: application/json" http://localhost:5000/v2.0/tokens
|
||||
|
||||
# Get an admin token
|
||||
$ curl -d '{"auth": {"passwordCredentials": {"username": "admin", "password": "secrete"}}}' -H "Content-type: application/json" http://localhost:35357/v2.0/tokens
|
||||
</pre>
|
||||
|
||||
## Load Testing
|
||||
|
||||
<pre>
|
||||
# Create post data
|
||||
$ echo '{"auth": {"passwordCredentials": {"username": "joeuser", "password": "secrete", "tenantName": "customer-x"}}}' > post_data
|
||||
|
||||
# Call Apache Bench
|
||||
$ ab -c 30 -n 1000 -T "application/json" -p post_data http://127.0.0.1:35357/v2.0/tokens
|
||||
</pre>
|
||||
|
||||
## NOVA Integration
|
||||
|
||||
Initial support for using keystone as nova's identity component has been started.
|
||||
|
||||
# clone projects
|
||||
bzr clone lp:nova
|
||||
git clone git://github.com/openstack/keystone.git
|
||||
|
||||
# install keystone on the host which runs nova
|
||||
run "python setup install" to install keystone.
|
||||
|
||||
# run nova-api based on the paste config in keystone
|
||||
nova/bin/nova-api --api_paste_config=keystone/examples/paste/nova-api-paste.ini
|
||||
|
||||
Assuming you added the test data using bin/sampledata, you can then use joeuser/secrete
|
||||
|
||||
## Swift Integration - Quick Start
|
||||
|
||||
1. Install Swift, either from trunk or version 1.4.1 (once it's released) or
|
||||
higher. Do the standard SAIO install with the included TempAuth to be sure
|
||||
you have a working system to start with. This step is beyond the scope of
|
||||
this quick start; see http://swift.openstack.org/development_saio.html for
|
||||
a Swift development set up guide. Once you have a working Swift install, go
|
||||
ahead and shut it down for now (the default Swift install uses the same
|
||||
ports Keystone wants):
|
||||
|
||||
$ swift-init all stop
|
||||
|
||||
2. Obtain and install a source copy of Keystone:
|
||||
|
||||
$ git clone https://github.com/openstack/keystone.git ~/keystone
|
||||
...
|
||||
$ cd ~/keystone && sudo python setup.py develop
|
||||
...
|
||||
|
||||
3. Start up the Keystone service:
|
||||
|
||||
$ cd ~/keystone/bin && ./keystone
|
||||
Starting the Legacy Authentication component
|
||||
Service API listening on 0.0.0.0:5000
|
||||
Admin API listening on 0.0.0.0:35357
|
||||
|
||||
4. In another window, edit the `~/keystone/keystone/test/sampledata.py` file,
|
||||
find the `swift.publicinternets.com` text and replace it with the URL to
|
||||
your Swift cluster using the following format (note that we're going to
|
||||
change Swift to run on port 8888 later):
|
||||
`http://127.0.0.1:8888/v1/AUTH_%tenant_id%`
|
||||
|
||||
5. Create the sample data entries:
|
||||
|
||||
$ cd ~/keystone/bin && ./sampledata
|
||||
...
|
||||
|
||||
6. 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
|
||||
|
||||
[filter:cache]
|
||||
use = egg:swift#memcache
|
||||
set log_name = cache
|
||||
|
||||
[filter:catch_errors]
|
||||
use = egg:swift#catch_errors
|
||||
|
||||
7. Start Swift back up with the new configuration:
|
||||
|
||||
$ swift-init main start
|
||||
...
|
||||
|
||||
8. 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
|
||||
|
||||
**Note: Keystone currently allows any valid token to do anything with any
|
||||
account.**
|
||||
|
||||
But, it works as a demo!
|
||||
|
||||
## LDAP Setup on a Mac
|
||||
|
||||
Using macports:
|
||||
|
||||
sudo port install openldap
|
||||
|
||||
It appears the package `python-ldap` needs to be recompiled to work. So,
|
||||
download it from: http://pypi.python.org/pypi/python-ldap/2.4.1
|
||||
|
||||
After unpacking, edit `setup.cfg` as shown below:
|
||||
|
||||
library_dirs = /opt/local/lib
|
||||
include_dirs = /opt/local/include /usr/include/sasl
|
||||
|
||||
Then, run:
|
||||
|
||||
python setup.py build
|
||||
sudo python setup.py install
|
||||
|
||||
# Relevant Standards and Technologies
|
||||
|
||||
[Overlap of Identity Technologies](https://sites.google.com/site/oauthgoog/Overlap)
|
||||
|
||||
Keystone could potentially integrate with:
|
||||
|
||||
1. [WebID](http://www.w3.org/2005/Incubator/webid/spec/) (See also [FOAF+SSL](http://www.w3.org/wiki/Foaf+ssl))
|
||||
2. [OpenID](http://openid.net/) and/or [OpenIDConnect](http://openidconnect.com/)
|
||||
3. [OAUTH2](http://oauth.net/2/)
|
||||
4. [SAML](http://saml.xml.org/)
|
222
README.rst
Normal file
222
README.rst
Normal file
@ -0,0 +1,222 @@
|
||||
.. image:: http://term.ie/data/medium_ksl.png
|
||||
:alt: Keystone
|
||||
|
||||
.. toctree::
|
||||
:maxdepth 2
|
||||
|
||||
Keystone is an OpenStack project that provides Identity, Token, Catalog and
|
||||
Policy services for use specifically by projects in the OpenStack family.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
-----------
|
||||
Development
|
||||
-----------
|
||||
|
||||
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.
|
||||
|
||||
------------
|
||||
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 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 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.
|
||||
|
||||
|
||||
-----------
|
||||
Still To Do
|
||||
-----------
|
||||
|
||||
* LDAP backend.
|
||||
* Diablo migration.
|
84
bin/keystone
84
bin/keystone
@ -1,84 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
""" This is only a convenience script. It starts two endpoints of Keystone; the
|
||||
first one is a Service API server running on port 5000 (by default), and the
|
||||
second one is an Admin API server running on port 35357 (by default).
|
||||
|
||||
By default, keystone uses bind_host and bind_port to set its litening ports,
|
||||
but since this script runs two endpoints, it uses the following options:
|
||||
|
||||
Setting any of the Admin API values for bind host or port using the
|
||||
admin_* entries in the config file. Specoific to this script only is the
|
||||
-a/--admin-port option on the command-line (nothing else supports that).
|
||||
|
||||
Setting any of the Service API values for bind host or port using the
|
||||
service_* entries in the config file.
|
||||
|
||||
"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import keystone.tools.tracer # @UnusedImport # module runs on import
|
||||
from keystone.common import config
|
||||
from keystone.config import CONF
|
||||
import keystone.server
|
||||
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir, os.pardir))
|
||||
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'keystone', '__init__.py')):
|
||||
sys.path.insert(0, POSSIBLE_TOPDIR)
|
||||
|
||||
|
||||
def get_options():
|
||||
# Initialize a parser for our configuration paramaters
|
||||
# since we have special handling for the -a|--admin-port argument
|
||||
parser = optparse.OptionParser()
|
||||
common_group = config.add_common_options(parser)
|
||||
config.add_log_options(parser)
|
||||
|
||||
# Handle a special argument to support starting two endpoints
|
||||
common_group.add_option(
|
||||
'-a', '--admin-port', dest="admin_port", metavar="PORT",
|
||||
help="specifies port for Admin API to listen on (default is 35357)")
|
||||
|
||||
# Parse CLI arguments and merge with config
|
||||
(options, args) = config.parse_options(parser)
|
||||
return options
|
||||
|
||||
|
||||
def main():
|
||||
# Get merged config and CLI options and admin-specific settings
|
||||
options = get_options()
|
||||
config_file = config.find_config_file(options, sys.argv[1:])
|
||||
CONF(config_files=[config_file])
|
||||
|
||||
# Start services
|
||||
try:
|
||||
# Load Service API Server
|
||||
service = keystone.server.Server(name="Service API",
|
||||
config_name='keystone-legacy-auth')
|
||||
service.start(wait=False)
|
||||
except RuntimeError, e:
|
||||
sys.exit("ERROR: %s" % e)
|
||||
|
||||
try:
|
||||
# Get admin-specific settings
|
||||
port = options.get('admin_port', None)
|
||||
host = options.get('bind_host', None)
|
||||
|
||||
# Load Admin API server
|
||||
admin = keystone.server.Server(name='Admin API', config_name='admin')
|
||||
admin.start(host=host, port=port, wait=True)
|
||||
except RuntimeError, e:
|
||||
sys.exit("ERROR: %s" % e)
|
||||
finally:
|
||||
service.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# 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 Identity Server - Admin API
|
||||
"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
import keystone.tools.tracer # @UnusedImport # module runs on import
|
||||
from keystone.common import config
|
||||
from keystone.config import CONF
|
||||
import keystone.server
|
||||
|
||||
|
||||
def get_options():
|
||||
# Initialize a parser for our configuration paramaters
|
||||
# since we have special handling for the -a|--admin-port argument
|
||||
parser = optparse.OptionParser()
|
||||
common_group = config.add_common_options(parser)
|
||||
config.add_log_options(parser)
|
||||
|
||||
# Parse CLI arguments and merge with config
|
||||
(options, args) = config.parse_options(parser)
|
||||
return options
|
||||
|
||||
|
||||
def main():
|
||||
# Get merged config and CLI options and admin-specific settings
|
||||
options = get_options()
|
||||
config_file = config.find_config_file(options, sys.argv[1:])
|
||||
CONF(config_files=[config_file])
|
||||
try:
|
||||
# Load Admin API server
|
||||
admin = keystone.server.Server(name='Admin API', config_name='admin')
|
||||
admin.start(wait=True)
|
||||
except RuntimeError, e:
|
||||
sys.exit("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
71
bin/keystone-all
Executable file
71
bin/keystone-all
Executable file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import greenlet
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir,
|
||||
'keystone-all',
|
||||
'__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
from paste import deploy
|
||||
|
||||
from keystone import config
|
||||
from keystone.common import wsgi
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def create_server(conf, name, port):
|
||||
app = deploy.loadapp('config:%s' % conf, name=name)
|
||||
return wsgi.Server(app, port)
|
||||
|
||||
|
||||
def serve(*servers):
|
||||
for server in servers:
|
||||
logging.debug("starting server %s on port %s", server.application,
|
||||
server.port)
|
||||
server.start()
|
||||
|
||||
for server in servers:
|
||||
try:
|
||||
server.wait()
|
||||
except greenlet.GreenletExit:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
dev_conf = os.path.join(possible_topdir,
|
||||
'etc',
|
||||
'keystone.conf')
|
||||
config_files = None
|
||||
if os.path.exists(dev_conf):
|
||||
config_files = [dev_conf]
|
||||
|
||||
CONF(config_files=config_files)
|
||||
|
||||
config.setup_logging(CONF)
|
||||
|
||||
# Log the options used when starting if we're in debug mode...
|
||||
if CONF.debug:
|
||||
CONF.log_opt_values(logging.getLogger(CONF.prog), logging.DEBUG)
|
||||
|
||||
options = deploy.appconfig('config:%s' % CONF.config_file[0])
|
||||
|
||||
servers = []
|
||||
servers.append(create_server(CONF.config_file[0],
|
||||
'admin',
|
||||
int(options['admin_port'])))
|
||||
servers.append(create_server(CONF.config_file[0],
|
||||
'main',
|
||||
int(options['public_port'])))
|
||||
serve(*servers)
|
@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 United States Government as represented by the
|
||||
# Administrator of the National Aeronautics and Space Administration.
|
||||
# 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 Identity Server - Service API
|
||||
"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
import keystone.tools.tracer # @UnusedImport # module runs on import
|
||||
from keystone.common import config
|
||||
from keystone.config import CONF
|
||||
import keystone.server
|
||||
|
||||
|
||||
def get_options():
|
||||
# Initialize a parser for our configuration paramaters
|
||||
# since we have special handling for the -a|--admin-port argument
|
||||
parser = optparse.OptionParser()
|
||||
common_group = config.add_common_options(parser)
|
||||
config.add_log_options(parser)
|
||||
|
||||
# Parse CLI arguments and merge with config
|
||||
(options, args) = config.parse_options(parser)
|
||||
return options
|
||||
|
||||
|
||||
def main():
|
||||
# Get merged config and CLI options and admin-specific settings
|
||||
options = get_options()
|
||||
config_file = config.find_config_file(options, sys.argv[1:])
|
||||
CONF(config_files=[config_file])
|
||||
try:
|
||||
# Load Service API server
|
||||
server = keystone.server.Server(name='Service API',
|
||||
config_name='keystone-legacy-auth')
|
||||
server.start(wait=True)
|
||||
except RuntimeError, e:
|
||||
sys.exit("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,235 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Helper script for starting/stopping/reloading Keystone server programs.
|
||||
Copied from Glance. Thanks for some of the code, Swifties ;)
|
||||
"""
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
import errno
|
||||
import gettext
|
||||
import os
|
||||
import optparse
|
||||
import resource
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
|
||||
# If ../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
gettext.install('keystone', unicode=1)
|
||||
|
||||
import keystone.version
|
||||
from keystone.common import config
|
||||
|
||||
ALL_COMMANDS = ['start', 'stop', 'shutdown', 'restart',
|
||||
'reload', 'force-reload']
|
||||
ALL_SERVERS = ['keystone-auth', 'keystone-admin']
|
||||
GRACEFUL_SHUTDOWN_SERVERS = ['keystone-auth', 'keystone-admin']
|
||||
MAX_DESCRIPTORS = 32768
|
||||
MAX_MEMORY = (1024 * 1024 * 1024) * 2 # 2 GB
|
||||
USAGE = """%prog [options] <SERVER> <COMMAND> [CONFPATH]
|
||||
|
||||
Where <SERVER> is one of:
|
||||
|
||||
all, auth, admin
|
||||
|
||||
And command is one of:
|
||||
|
||||
start, stop, shutdown, restart, reload, force-reload
|
||||
|
||||
And CONFPATH is the optional configuration file to use."""
|
||||
|
||||
|
||||
def pid_files(server, options):
|
||||
pid_files = []
|
||||
if options['pid_file']:
|
||||
if os.path.exists(os.path.abspath(options['pid_file'])):
|
||||
pid_files = [os.path.abspath(options['pid_file'])]
|
||||
else:
|
||||
if os.path.exists('/var/run/keystone/%s.pid' % server):
|
||||
pid_files = ['/var/run/keystone/%s.pid' % server]
|
||||
for pid_file in pid_files:
|
||||
pid = int(open(pid_file).read().strip())
|
||||
yield pid_file, pid
|
||||
|
||||
|
||||
def do_start(server, options, args):
|
||||
server_type = '-'.join(server.split('-')[:-1])
|
||||
|
||||
for pid_file, pid in pid_files(server, options):
|
||||
if os.path.exists('/proc/%s' % pid):
|
||||
print "%s appears to already be running: %s" % (server, pid_file)
|
||||
return
|
||||
else:
|
||||
print "Removing stale pid file %s" % pid_file
|
||||
os.unlink(pid_file)
|
||||
|
||||
try:
|
||||
resource.setrlimit(resource.RLIMIT_NOFILE,
|
||||
(MAX_DESCRIPTORS, MAX_DESCRIPTORS))
|
||||
resource.setrlimit(resource.RLIMIT_DATA,
|
||||
(MAX_MEMORY, MAX_MEMORY))
|
||||
except ValueError:
|
||||
print "Unable to increase file descriptor limit. Running as non-root?"
|
||||
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
|
||||
|
||||
def write_pid_file(pid_file, pid):
|
||||
dir, file = os.path.split(pid_file)
|
||||
if not os.path.exists(dir):
|
||||
try:
|
||||
os.makedirs(dir)
|
||||
except OSError, err:
|
||||
if err.errno == errno.EACCES:
|
||||
sys.exit('Unable to create %s. Running as non-root?'
|
||||
% dir)
|
||||
fp = open(pid_file, 'w')
|
||||
fp.write('%d\n' % pid)
|
||||
fp.close()
|
||||
|
||||
def launch(ini_file, pid_file):
|
||||
args = [server, ini_file]
|
||||
print 'Starting %s with %s' % (server, ini_file)
|
||||
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
os.setsid()
|
||||
with open(os.devnull, 'r+b') as nullfile:
|
||||
for desc in (0, 1, 2): # close stdio
|
||||
try:
|
||||
os.dup2(nullfile.fileno(), desc)
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
os.execlp('%s' % server, server, ini_file)
|
||||
except OSError, e:
|
||||
sys.exit('unable to launch %s. Got error: %s'
|
||||
% (server, "%s" % e))
|
||||
sys.exit(0)
|
||||
else:
|
||||
write_pid_file(pid_file, pid)
|
||||
|
||||
if not options['pid_file']:
|
||||
pid_file = '/var/run/keystone/%s.pid' % server
|
||||
else:
|
||||
pid_file = os.path.abspath(options['pid_file'])
|
||||
conf_file = config.find_config_file(options, args)
|
||||
if not conf_file:
|
||||
sys.exit("Could not find any configuration file to use!")
|
||||
launch_args = [(conf_file, pid_file)]
|
||||
|
||||
# start all servers
|
||||
for conf_file, pid_file in launch_args:
|
||||
launch(conf_file, pid_file)
|
||||
|
||||
|
||||
def do_stop(server, options, args, graceful=False):
|
||||
if graceful and server in GRACEFUL_SHUTDOWN_SERVERS:
|
||||
sig = signal.SIGHUP
|
||||
else:
|
||||
sig = signal.SIGTERM
|
||||
|
||||
did_anything = False
|
||||
pfiles = pid_files(server, options)
|
||||
for pid_file, pid in pfiles:
|
||||
did_anything = True
|
||||
try:
|
||||
print 'Stopping %s pid: %s signal: %s' % (server, pid, sig)
|
||||
os.kill(pid, sig)
|
||||
except OSError:
|
||||
print "Process %d not running" % pid
|
||||
try:
|
||||
os.unlink(pid_file)
|
||||
except OSError:
|
||||
pass
|
||||
for pid_file, pid in pfiles:
|
||||
for _junk in xrange(150): # 15 seconds
|
||||
if not os.path.exists('/proc/%s' % pid):
|
||||
break
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
print 'Waited 15 seconds for pid %s (%s) to die; giving up' % \
|
||||
(pid, pid_file)
|
||||
if not did_anything:
|
||||
print 'No %s running' % server
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
oparser = optparse.OptionParser(usage=USAGE, version='%%prog %s'
|
||||
% keystone.version.version())
|
||||
oparser.add_option('--pid-file', default=None, metavar="PATH",
|
||||
help="File to use as pid file. Default: "
|
||||
"/var/run/keystone/$server.pid")
|
||||
config.add_common_options(oparser)
|
||||
(options, args) = config.parse_options(oparser)
|
||||
|
||||
if len(args) < 2:
|
||||
oparser.print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
server = args.pop(0).lower()
|
||||
if server == 'all':
|
||||
servers = ALL_SERVERS
|
||||
else:
|
||||
if not server.startswith('keystone-'):
|
||||
server = 'keystone-%s' % server
|
||||
if server not in ALL_SERVERS:
|
||||
server_list = ", ".join([s.replace('keystone-', '')
|
||||
for s in ALL_SERVERS])
|
||||
msg = ("Unknown server '%(server)s' specified. Please specify "
|
||||
"all, or one of the servers: %(server_list)s" % locals())
|
||||
sys.exit(msg)
|
||||
servers = [server]
|
||||
|
||||
command = args.pop(0).lower()
|
||||
if command not in ALL_COMMANDS:
|
||||
command_list = ", ".join(ALL_COMMANDS)
|
||||
msg = ("Unknown command %(command)s specified. Please specify a "
|
||||
"command in this list: %(command_list)s" % locals())
|
||||
sys.exit(msg)
|
||||
|
||||
if command == 'start':
|
||||
for server in servers:
|
||||
do_start(server, options, args)
|
||||
|
||||
if command == 'stop':
|
||||
for server in servers:
|
||||
do_stop(server, options, args)
|
||||
|
||||
if command == 'shutdown':
|
||||
for server in servers:
|
||||
do_stop(server, options, args, graceful=True)
|
||||
|
||||
if command == 'restart':
|
||||
for server in servers:
|
||||
do_stop(server, options, args)
|
||||
for server in servers:
|
||||
do_start(server, options, args)
|
||||
|
||||
if command == 'reload' or command == 'force-reload':
|
||||
for server in servers:
|
||||
do_stop(server, options, args, graceful=True)
|
||||
do_start(server, options, args)
|
@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (C) 2011 OpenStack LLC.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# This file is to read a export file from Nova that will import users,
|
||||
# tenants and EC2 credentials
|
||||
# The file should be in the keystone-manage format
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shlex
|
||||
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
import keystone.manage
|
||||
|
||||
with open(sys.argv[1], 'r') as line:
|
||||
try:
|
||||
keystone.manage.main(shlex.split(line))
|
||||
except Exception as exc:
|
||||
# Main prints all of the errors we need
|
||||
sys.exit(1)
|
@ -2,35 +2,27 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||
os.pardir))
|
||||
if os.path.exists(os.path.join(possible_topdir, 'keystone', '__init__.py')):
|
||||
if os.path.exists(os.path.join(possible_topdir,
|
||||
'keystone',
|
||||
'__init__.py')):
|
||||
sys.path.insert(0, possible_topdir)
|
||||
|
||||
import keystone.manage
|
||||
import keystone.manage2
|
||||
import keystone.tools.tracer # @UnusedImport # module runs on import
|
||||
|
||||
from keystone import cli
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
while True:
|
||||
if len(args) > 1 and args[0] in keystone.manage.OBJECTS:
|
||||
# the args look like the old 'subject verb' (e.g. 'user add')
|
||||
# (this module is pending deprecation)
|
||||
keystone.manage.main()
|
||||
break
|
||||
elif len(args) > 2 and args[0] == '-c':
|
||||
# Remove -c <config file> and try again
|
||||
del args[0:2]
|
||||
elif len(args) > 1 and args[0] == '-d':
|
||||
# Remove -d and try again
|
||||
del args[0]
|
||||
else:
|
||||
# calls that don't start with a 'subject' go to the new impl
|
||||
# which uses a 'verb_subject' convention (e.g. 'add_user')
|
||||
keystone.manage2.main()
|
||||
break
|
||||
dev_conf = os.path.join(possible_topdir,
|
||||
'etc',
|
||||
'keystone.conf')
|
||||
config_files = None
|
||||
if os.path.exists(dev_conf):
|
||||
config_files = [dev_conf]
|
||||
|
||||
cli.main(argv=sys.argv, config_files=config_files)
|
||||
|
@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
# If ../../keystone/__init__.py exists, add ../ to Python search path, so that
|
||||
# it will override what happens to be installed in /usr/(local/)lib/python...
|
||||
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
||||
os.pardir,
|
||||