Documentation cleanup

Several warnings and errors were reported when building
documentation. This makes it difficult for developers to
validate that new changes to don't have problems.

Most of the warnings and errors are fixed with this change.

Change-Id: Ifb9edffce66dde27fbe72bb1ce1b997b041786ae
This commit is contained in:
Brant Knudson 2013-12-20 18:15:17 -06:00
parent ea53d7a26a
commit 97b0627d80
17 changed files with 133 additions and 89 deletions

View File

@ -260,14 +260,14 @@ development environment, there's a couple of things you need to do.
1. Build the message files. Run the following command in your keystone
directory::
$ python setup.py compile_catalog
$ python setup.py compile_catalog
This will generate .mo files like keystone/locale/[lang]/LC_MESSAGES/[lang].mo
2. When running Keystone, set the ``KEYSTONE_LOCALEDIR`` environment variable
to the keystone/locale directory. For example::
$ KEYSTONE_LOCALEDIR=/opt/stack/keystone/keystone/locale keystone-all
$ KEYSTONE_LOCALEDIR=/opt/stack/keystone/keystone/locale keystone-all
Now you can get a translated error response::

View File

@ -133,33 +133,32 @@ def base64_to_base64url(text):
This function only translates the altchars, non-alphabet
characters are not filtered out.
WARNING
-------
WARNING::
base64url continues to use the '=' pad character which is NOT URL
safe. RFC-4648 suggests two alternate methods to deal with this.
base64url continues to use the '=' pad character which is NOT URL
safe. RFC-4648 suggests two alternate methods to deal with this:
percent-encode
percent-encode the pad character (e.g. '=' becomes
'%3D'). This makes the base64url text fully safe. But
percent-enconding has the downside of requiring
percent-decoding prior to feeding the base64url text into a
base64url decoder since most base64url decoders do not
recognize %3D as a pad character and most decoders require
correct padding.
percent-encode
percent-encode the pad character (e.g. '=' becomes
'%3D'). This makes the base64url text fully safe. But
percent-enconding has the downside of requiring
percent-decoding prior to feeding the base64url text into a
base64url decoder since most base64url decoders do not
recognize %3D as a pad character and most decoders require
correct padding.
no-padding
padding is not strictly necessary to decode base64 or
base64url text, the pad can be computed from the input text
length. However many decoders demand padding and will consider
non-padded text to be malformed. If one wants to omit the
trailing pad character(s) for use in URL's it can be added back
using the base64_assure_padding() function.
no-padding
padding is not strictly necessary to decode base64 or
base64url text, the pad can be computed from the input text
length. However many decoders demand padding and will consider
non-padded text to be malformed. If one wants to omit the
trailing pad character(s) for use in URL's it can be added back
using the base64_assure_padding() function.
This function makes no decisions about which padding methodolgy to
use. One can either call base64_strip_padding() to remove any pad
characters (restoring later with base64_assure_padding()) or call
base64url_percent_encode() to percent-encode the pad characters.
This function makes no decisions about which padding methodolgy to
use. One can either call base64_strip_padding() to remove any pad
characters (restoring later with base64_assure_padding()) or call
base64url_percent_encode() to percent-encode the pad characters.
:param text: input base64 text
:type text: string
@ -373,7 +372,7 @@ def base64_wrap(text, width=64):
Input is assumed to consist only of members of a base64
alphabet (i.e no whitepace). Fold the text into lines whose
line length is width chars long, terminate each line with line
ending (default is '\n'). Return the wrapped text as a single
ending (default is '\\n'). Return the wrapped text as a single
string.
Use the filter_formatting() function to assure the input text

View File

@ -160,7 +160,7 @@ def should_cache_fn(section):
decorator if caching for that driver is enabled. To properly use this
with the decorator, pass this function the configuration section and assign
the result to a variable. Pass the new variable to the caching decorator
as the named argument ``should_cache_fn``. e.g.:
as the named argument ``should_cache_fn``. e.g.::
from keystone.common import cache

View File

@ -75,39 +75,40 @@ def is_ans1_token(token):
thx to ayoung for sorting this out.
base64 decoded hex representation of MII is 3082
In [3]: binascii.hexlify(base64.b64decode('MII='))
Out[3]: '3082'
| base64 decoded hex representation of MII is 3082
| In [3]: binascii.hexlify(base64.b64decode('MII='))
| Out[3]: '3082'
re: http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
pg4: For tags from 0 to 30 the first octet is the identifier
pg10: Hex 30 means sequence, followed by the length of that sequence.
pg5: Second octet is the length octet
first bit indicates short or long form, next 7 bits encode the number
of subsequent octets that make up the content length octets as an
unsigned binary int
82 = 10000010 (first bit indicates long form)
0000010 = 2 octets of content length
so read the next 2 octets to get the length of the content.
| pg4: For tags from 0 to 30 the first octet is the identifier
| pg10: Hex 30 means sequence, followed by the length of that sequence.
| pg5: Second octet is the length octet
| first bit indicates short or long form, next 7 bits encode the
number of subsequent octets that make up the content length octets
as an unsigned binary int
|
| 82 = 10000010 (first bit indicates long form)
| 0000010 = 2 octets of content length
| so read the next 2 octets to get the length of the content.
In the case of a very large content length there could be a requirement to
have more than 2 octets to designate the content length, therefore
requiring us to check for MIM, MIQ, etc.
In [4]: base64.b64encode(binascii.a2b_hex('3083'))
Out[4]: 'MIM='
In [5]: base64.b64encode(binascii.a2b_hex('3084'))
Out[5]: 'MIQ='
Checking for MI would become invalid at 16 octets of content length
10010000 = 90
In [6]: base64.b64encode(binascii.a2b_hex('3090'))
Out[6]: 'MJA='
Checking for just M is insufficient
| In [4]: base64.b64encode(binascii.a2b_hex('3083'))
| Out[4]: 'MIM='
| In [5]: base64.b64encode(binascii.a2b_hex('3084'))
| Out[5]: 'MIQ='
| Checking for MI would become invalid at 16 octets of content length
| 10010000 = 90
| In [6]: base64.b64encode(binascii.a2b_hex('3090'))
| Out[6]: 'MJA='
| Checking for just M is insufficient
But we will only check for MII:
Max length of the content using 2 octets is 7FFF or 32767
It's not practical to support a token of this length or greater in http
Max length of the content using 2 octets is 7FFF or 32767.
It's not practical to support a token of this length or greater in http;
therefore, we will check for MII only and ignore the case of larger tokens
"""
return token[:3] == PKI_ANS1_PREFIX

View File

@ -46,7 +46,7 @@ def provider(name):
When 'provider' is used to decorate a class, members of that class will
register themselves as providers for the named dependency. As an example,
In the code fragment:
In the code fragment::
@dependency.provider('foo_api')
class Foo:
@ -102,7 +102,7 @@ def requires(*dependencies):
The required providers will be made available to instances of the decorated
class via an attribute with the same name as the provider. For example,
in the code fragment:
in the code fragment::
@dependency.requires('foo_api', 'bar_api')
class FooBarClient:

View File

@ -264,7 +264,7 @@ def pem_search(text, start=0):
The start and end positions are suitable for use as slices into
the text. To search for multiple PEM blocks pass pem_end as the
start position for the next iteration. Terminate the iteration
when None is returned. Example:
when None is returned. Example::
start = 0
while True:
@ -335,7 +335,7 @@ def parse_pem(text, pem_type=None, max_items=None):
including the decoded binary data for the PEM block. The list is
ordered in the same order as found in the text.
Examples:
Examples::
# Get all certs
certs = parse_pem(text, 'cert')

View File

@ -170,7 +170,7 @@ class Driver(object):
def list_consumers(self):
"""List consumers.
returns: list of consumers
:returns: list of consumers
"""
raise exception.NotImplemented()
@ -219,7 +219,7 @@ class Driver(object):
:param user_id: search for access tokens authorized by given user id
:type user_id: string
returns: list of access tokens the user has authorized
:returns: list of access tokens the user has authorized
"""
raise exception.NotImplemented()
@ -232,7 +232,7 @@ class Driver(object):
:type user_id: string
:param access_token_id: access token to delete
:type access_token_id: string
returns: None
:returns: None
"""
raise exception.NotImplemented()
@ -248,7 +248,7 @@ class Driver(object):
:type requested_project_id: string
:param request_token_duration: duration of request token
:type request_token_duration: string
returns: request_token_ref
:returns: request_token_ref
"""
raise exception.NotImplemented()
@ -259,7 +259,7 @@ class Driver(object):
:param request_token_id: the id of the request token
:type request_token_id: string
returns: request_token_ref
:returns: request_token_ref
"""
raise exception.NotImplemented()
@ -270,7 +270,7 @@ class Driver(object):
:param access_token_id: the id of the access token
:type access_token_id: string
returns: access_token_ref
:returns: access_token_ref
"""
raise exception.NotImplemented()
@ -285,7 +285,7 @@ class Driver(object):
:type user_id: string
:param role_ids: list of role ids to authorize
:type role_ids: list
returns: verifier
:returns: verifier
"""
raise exception.NotImplemented()
@ -298,7 +298,7 @@ class Driver(object):
:type request_id: string
:param access_token_duration: duration of an access token
:type access_token_duration: string
returns: access_token_ref
:returns: access_token_ref
"""
raise exception.NotImplemented()

View File

@ -27,7 +27,7 @@ class OAuth1Extension(wsgi.ExtensionRouter):
on behalf of that user. This is done using an oauth-similar flow and
api.
The API looks like:
The API looks like::
# Basic admin-only consumer crud
POST /OS-OAUTH1/consumers

View File

@ -82,6 +82,7 @@ class DomainConfigs(dict):
For each file, the domain_name will be turned into a domain_id and then
this class will:
- Create a new config structure, adding in the specific additional options
defined in this config file
- Initialise a new instance of the required driver with this new config.

View File

@ -188,7 +188,7 @@ def skip_if_cache_disabled(*sections):
"""This decorator is used to skip a test if caching is disabled either
globally or for the specific section.
In the code fragment:
In the code fragment::
@skip_if_cache_is_disabled('assignment', 'token')
def test_method(*args):

View File

@ -458,6 +458,7 @@ class IdentityTests(object):
"""Test for unfiltered listing role assignments.
Test Plan:
- Create a domain, with a user, group & project
- Find how many role assignments already exist (from default
fixtures)
@ -563,6 +564,7 @@ class IdentityTests(object):
"""Test for get role by user and project, user was added into a group.
Test Plan:
- Create a user, a project & a group, add this user to group
- Create roles and grant them to user and project
- Check the role list get by the user and project was as expected
@ -626,6 +628,7 @@ class IdentityTests(object):
"""Test for getting roles for user on a domain.
Test Plan:
- Create a domain, with 2 users
- Check no roles yet exit
- Give user1 two roles on the domain, user2 one role
@ -682,6 +685,7 @@ class IdentityTests(object):
"""Test errors raised when getting roles for user on a domain.
Test Plan:
- Check non-existing user gives UserNotFound
- Check non-existing domain gives DomainNotFound
@ -1287,6 +1291,7 @@ class IdentityTests(object):
"""Test multiple group roles for user on project and domain.
Test Plan:
- Create 6 roles
- Create a domain, with a project, user and two groups
- Make the user a member of both groups
@ -3562,6 +3567,7 @@ class InheritanceTests(object):
"""Test inherited user roles.
Test Plan:
- Enable OS-INHERIT extension
- Create 3 roles
- Create a domain, with a project and a user
@ -3637,6 +3643,7 @@ class InheritanceTests(object):
"""Test inherited group roles.
Test Plan:
- Enable OS-INHERIT extension
- Create 4 roles
- Create a domain, with a project, user and two groups
@ -3720,6 +3727,7 @@ class InheritanceTests(object):
"""Test inherited group roles.
Test Plan:
- Enable OS-INHERIT extension
- Create a domain, with two projects and a user
- Assign an inherited user role on the domain, as well as a direct
@ -3759,6 +3767,7 @@ class InheritanceTests(object):
"""Test inherited group roles.
Test Plan:
- Enable OS-INHERIT extension
- Create two domains, each with two projects
- Create a user and group

View File

@ -1170,6 +1170,7 @@ class MultiLDAPandSQLIdentity(sql.Base, tests.TestCase, BaseLDAPIdentity):
"""Test that separate configs have segregated the domain.
Test Plan:
- Create a user in each of the domains
- Make sure that you can only find a given user in its
relevant domain

View File

@ -15,15 +15,22 @@
# under the License.
"""
To run these tests against a live database:
1. Modify the file `tests/backend_sql.conf` to use the connection for your
live database
2. Set up a blank, live database.
3. run the tests using
::
./run_tests.sh -N test_sql_upgrade
WARNING::
Your database will be wiped.
Do not do this against a Database with valuable data as
all data will be lost.
WARNING::
Your database will be wiped.
Do not do this against a Database with valuable data as
all data will be lost.
"""

View File

@ -645,6 +645,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
"""Test deleting a user grant revokes token.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Delete the grant user1 has on ProjectA
- Check token is no longer valid
@ -676,6 +677,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
"""Test deleting a role revokes token.
Test Plan:
- Add some additional test data, namely:
- A third project (project C)
- Three additional users - user4 owned by domainB and user5 and 6
@ -805,6 +807,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
"""Test user-domain role assignment maintains existing token.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Create a grant for user1 on DomainB
- Check token is still valid
@ -897,6 +900,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
"""Test deleting a group grant revokes tokens.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Get a token for user2, scoped to ProjectA
- Get a token for user3, scoped to ProjectA
@ -958,6 +962,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
"""Test domain-group role assignment maintains existing token.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Create a grant for group1 on DomainB
- Check token is still longer valid
@ -989,6 +994,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
"""Test add/removal to/from group revokes token.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Get a token for user2, scoped to ProjectA
- Remove user1 from group1
@ -1379,6 +1385,7 @@ class TestAuthJSON(test_v3.RestfulTestCase):
"""Test correct roles are returned in scoped token.
Test Plan:
- Create a domain, with 1 project, 2 users (user1 and user2)
and 2 groups (group1 and group2)
- Make user1 a member of group1, user2 a member of group2

View File

@ -246,6 +246,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
by the delete.
Test Plan:
- Create domain2 and a 2nd set of entities
- Disable domain2
- Delete domain2
@ -359,7 +360,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
self.assertValidProjectResponse(r, ref)
def test_delete_project(self):
"""Call ``DELETE /projects/{project_id}
"""Call ``DELETE /projects/{project_id}``
As well as making sure the delete succeeds, we ensure
that any credentials that reference this projects are
@ -749,6 +750,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
and delete the role assignments we use the old grant APIs.
Test Plan:
- Create extra user for tests
- Get a list of all existing role assignments
- Add a new assignment for each of the four combinations, i.e.
@ -838,6 +840,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
"""Call ``GET /role_assignments?effective``.
Test Plan:
- Create two extra user for tests
- Add these users to a group
- Add a role assignment for the group on a domain
@ -908,6 +911,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
policy checking on query/filter parameters.
Test Plan:
- Create two extra user for tests
- Add these users to a group
- Add a role assignment for the group on a domain
@ -981,6 +985,7 @@ class IdentityTestCase(test_v3.RestfulTestCase):
"""Call ``GET /role_assignments?filters``.
Test Plan:
- Create extra users, group, role and project for tests
- Make the following assignments:
Give group1, role1 on project1 and domain
@ -1188,6 +1193,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase):
"""Call ``GET /role_assignments with inherited domain grants``.
Test Plan:
- Create 4 roles
- Create a domain with a user and two projects
- Assign two direct roles to project1
@ -1281,6 +1287,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase):
"""Call ``GET /role_assignments with inherited domain grants``.
Test Plan:
- Issue the URL to add inherited role to the domain
- Issue the URL to check effective roles on project include the
inherited role
@ -1373,6 +1380,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase):
"""Call ``GET /role_assignments with inherited group domain grants``.
Test Plan:
- Create 4 roles
- Create a domain with a user and two projects
- Assign two direct roles to project1
@ -1477,6 +1485,7 @@ class IdentityInheritanceTestCase(test_v3.RestfulTestCase):
"""Call ``GET /role_assignments?scope.OS-INHERIT:inherited_to``.
Test Plan:
- Create 5 roles
- Create a domain with a user, group and two projects
- Assign three direct spoiler roles to projects

View File

@ -130,6 +130,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /users (unprotected)
Test Plan:
- Update policy so api is unprotected
- Use an un-scoped token to make sure we can get back all
the users independent of domain
@ -146,6 +147,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /users?domain_id=mydomain (filtered)
Test Plan:
- Update policy so api is unprotected
- Use an un-scoped token to make sure we can filter the
users by domainB, getting back the 2 users in that domain
@ -163,6 +165,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /users/{id} (match payload)
Test Plan:
- Update policy to protect api by user_id
- List users with user_id of user1 as filter, to check that
this will correctly match user_id in the flattened
@ -182,6 +185,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /users/{id} (match target)
Test Plan:
- Update policy to protect api by domain_id
- Try and read a user who is in DomainB with a token scoped
to Domain A - this should fail
@ -213,6 +217,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""DELETE /domains/{id}/users/{id}/roles/{id} (match target)
Test Plan:
- Update policy to protect api by domain_id of entities in
the grant
- Try and delete the existing grant that has a user who is
@ -251,6 +256,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /users?domain_id=mydomain (protected)
Test Plan:
- Update policy to protect api by domain_id
- List groups using a token scoped to domainA with a filter
specifying domainA - we should only get back the one user
@ -281,6 +287,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /groups?domain_id=mydomain (protected)
Test Plan:
- Update policy to protect api by domain_id
- List groups using a token scoped to domainA and make sure
we only get back the two groups that are in domainA
@ -311,6 +318,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /groups?domain_id=mydomain&name=myname (protected)
Test Plan:
- Update policy to protect api by domain_id
- List groups using a token scoped to domainA with a filter
specifying both domainA and the name of group.
@ -337,6 +345,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /domains?enabled=0
Test Plan:
- Update policy for no protection on api
- Filter by the 'enabled' boolean to get disabled domains, which
should return just domainC
@ -372,6 +381,7 @@ class IdentityTestProtectedCase(test_v3.RestfulTestCase):
"""GET /domains?enabled&name=myname
Test Plan:
- Update policy for no protection on api
- Filter by the 'enabled' boolean and name - this should
return a single domain

View File

@ -85,27 +85,27 @@ class V2TokenDataHelper(object):
@classmethod
def format_catalog(cls, catalog_ref):
"""Munge catalogs from internal to output format
Internal catalogs look like:
Internal catalogs look like::
{$REGION: {
{$SERVICE: {
$key1: $value1,
{$REGION: {
{$SERVICE: {
$key1: $value1,
...
}
}
}
The legacy api wants them to look like::
[{'name': $SERVICE[name],
'type': $SERVICE,
'endpoints': [{
'tenantId': $tenant_id,
...
}
}
}
The legacy api wants them to look like
[{'name': $SERVICE[name],
'type': $SERVICE,
'endpoints': [{
'tenantId': $tenant_id,
...
'region': $REGION,
}],
'endpoints_links': [],
}]
'region': $REGION,
}],
'endpoints_links': [],
}]
"""
if not catalog_ref: