keystone.common package

Subpackages

Submodules

keystone.common.authorization module

keystone.common.base64utils module

Python provides the base64 module as a core module but this is mostly limited to encoding and decoding base64 and it’s variants. It is often useful to be able to perform other operations on base64 text. This module is meant to be used in conjunction with the core base64 module.

Standardized base64 is defined in RFC-4648 “The Base16, Base32, and Base64 Data Encodings”.

This module provides the following base64 utility functionality:

  • tests if text is valid base64

  • filter formatting from base64

  • convert base64 between different alphabets

  • Handle padding issues
    • test if base64 is padded
    • removes padding
    • restores padding
  • wraps base64 text into formatted blocks
    • via iterator
    • return formatted string
exception keystone.common.base64utils.InvalidBase64Error[source]

Bases: exceptions.ValueError

keystone.common.base64utils.base64_assure_padding(text, pad='=')[source]

Assure the input text ends with padding.

Base64 text is normally expected to be a multiple of 4 characters. Each 4 character base64 sequence produces 3 octets of binary data. If the binary data is not a multiple of 3 the base64 text is padded at the end with a pad character such that it is always a multiple of 4. Padding is ignored and does not alter the binary data nor it’s length.

In some circumstances it is desirable to omit the padding character due to transport encoding conflicts. Base64 text can still be correctly decoded if the length of the base64 text (consisting only of characters in the desired base64 alphabet) is known, padding is not absolutely necessary.

Some base64 decoders demand correct padding or one may wish to format RFC compliant base64, this function performs this action.

Input is assumed to consist only of members of a base64 alphabet (i.e no whitespace). Iteration yields a sequence of lines. The line does NOT terminate with a line ending.

Use the filter_formatting() function to assure the input text contains only the members of the alphabet.

If the text ends with the pad it is assumed to already be padded. Otherwise the binary length is computed from the input text length and correct number of pad characters are appended.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • pad (string) – pad character (must be single character) (default: ‘=’)
Returns:

string – input base64 text with padding

Raises:

ValueError

keystone.common.base64utils.base64_is_padded(text, pad='=')[source]

Test if the text is base64 padded.

The input text must be in a base64 alphabet. The pad must be a single character. If the text has been percent-encoded (e.g. pad is the string ‘%3D’) you must convert the text back to a base64 alphabet (e.g. if percent-encoded use the function base64url_percent_decode()).

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • pad (string) – pad character (must be single character) (default: ‘=’)
Returns:

bool – True if padded, False otherwise

Raises:

ValueError, InvalidBase64Error

keystone.common.base64utils.base64_strip_padding(text, pad='=')[source]

Remove padding from input base64 text.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • pad (string) – pad character (must be single character) (default: ‘=’)
Returns:

string – base64 text without padding

Raises:

ValueError

keystone.common.base64utils.base64_to_base64url(text)[source]

Convert base64 text to base64url text.

base64url text is designed to be safe for use in file names and URL’s. It is defined in RFC-4648 Section 5.

base64url differs from base64 in the last two alphabet characters at index 62 and 63, these are sometimes referred as the altchars. The ‘+’ character at index 62 is replaced by ‘-‘ (hyphen) and the ‘/’ character at index 63 is replaced by ‘_’ (underscore).

This function only translates the altchars, non-alphabet characters are not filtered out.

WARNING:

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

This function makes no decisions about which padding methodology 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.
Parameters:text (string) – input base64 text
Returns:string – base64url text
keystone.common.base64utils.base64_wrap(text, width=64)[source]

Fold text into lines of text with max line length.

Input is assumed to consist only of members of a base64 alphabet (i.e no whitespace). 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 string.

Use the filter_formatting() function to assure the input text contains only the members of the alphabet.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • width (int) – number of characters in each wrapped line (default: 64)
Returns:

string – wrapped text.

keystone.common.base64utils.base64_wrap_iter(text, width=64)[source]

Fold text into lines of text with max line length.

Input is assumed to consist only of members of a base64 alphabet (i.e no whitespace). Iteration yields a sequence of lines. The line does NOT terminate with a line ending.

Use the filter_formatting() function to assure the input text contains only the members of the alphabet.

Parameters:
  • text (string) – text containing ONLY characters in a base64 alphabet
  • width (int) – number of characters in each wrapped line (default: 64)
Returns:

generator – sequence of lines of base64 text.

keystone.common.base64utils.base64url_percent_decode(text)[source]

Percent-decode base64url padding.

The input text should only contain base64url alphabet characters and the percent-encoded pad character. Any other percent-encoded characters will be subject to percent-decoding.

Parameters:text (string) – base64url alphabet text
Returns:string – percent-decoded base64url text
keystone.common.base64utils.base64url_percent_encode(text)[source]

Percent-encode base64url padding.

The input text should only contain base64url alphabet characters. Any non-base64url alphabet characters will also be subject to percent-encoding.

Parameters:text (string) – text containing ONLY characters in the base64url alphabet
Returns:string – percent-encoded base64url text
Raises:InvalidBase64Error
keystone.common.base64utils.base64url_to_base64(text)[source]

Convert base64url text to base64 text.

See base64_to_base64url() for a description of base64url text and it’s issues.

This function does NOT handle percent-encoded pad characters, they will be left intact. If the input base64url text is percent-encoded you should call

Parameters:text (string) – text in base64url alphabet
Returns:string – text in base64 alphabet
keystone.common.base64utils.filter_formatting(text)[source]

Return base64 text without any formatting, just the base64.

Base64 text is often formatted with whitespace, line endings, etc. This function strips out any formatting, the result will contain only base64 characters.

Note, this function does not filter out all non-base64 alphabet characters, it only removes characters used for formatting.

Parameters:text (string) – input text to filter
Returns:string – filtered text without formatting
keystone.common.base64utils.is_valid_base64(text)[source]

Test if input text can be base64 decoded.

Parameters:text (string) – input base64 text
Returns:bool – True if text can be decoded as base64, False otherwise
keystone.common.base64utils.is_valid_base64url(text)[source]

Test if input text can be base64url decoded.

Parameters:text (string) – input base64 text
Returns:bool – True if text can be decoded as base64url, False otherwise

keystone.common.config module

keystone.common.config.configure(conf=None)[source]
keystone.common.config.list_opts()[source]

Return a list of oslo_config options available in Keystone.

The returned list includes all oslo_config options which are registered as the “FILE_OPTIONS” in keystone.common.config. This list will not include the options from the oslo-incubator library or any options registered dynamically at run time.

Each object in the list is a two element tuple. The first element of each tuple is the name of the group under which the list of options in the second element will be registered. A group name of None corresponds to the [DEFAULT] group in config files.

This function is also discoverable via the ‘oslo_config.opts’ entry point under the ‘keystone.config.opts’ namespace.

The purpose of this is to allow tools like the Oslo sample config file generator to discover the options exposed to users by this library.

Returns:a list of (group_name, opts) tuples
keystone.common.config.setup_authentication(conf=None)[source]

keystone.common.controller module

keystone.common.dependency module

keystone.common.driver_hints module

class keystone.common.driver_hints.Hints[source]

Bases: object

Encapsulate driver hints for listing entities.

Hints are modifiers that affect the return of entities from a list_<entities> operation. They are typically passed to a driver to give direction as to what filtering, pagination or list limiting actions are being requested.

It is optional for a driver to action some or all of the list hints, but any filters that it does satisfy must be marked as such by calling removing the filter from the list.

A Hint object contains filters, which is a list of dicts that can be accessed publicly. Also it contains a dict called limit, which will indicate the amount of data we want to limit our listing to.

Each filter term consists of:

  • name: the name of the attribute being matched

  • value: the value against which it is being matched

  • comparator: the operation, which can be one of equals,

    startswith or endswith

  • case_sensitive: whether any comparison should take account of

    case

  • type: will always be ‘filter’

add_filter(name, value, comparator='equals', case_sensitive=False)[source]

Adds a filter to the filters list, which is publicly accessible.

get_exact_filter_by_name(name)[source]

Return a filter key and value if exact filter exists for name.

set_limit(limit, truncated=False)[source]

Set a limit to indicate the list should be truncated.

keystone.common.extension module

keystone.common.extension.register_admin_extension(url_prefix, extension_data)[source]

Register extension with collection of admin extensions.

Extensions register the information here that will show up in the /extensions page as a way to indicate that the extension is active.

url_prefix: unique key for the extension that will appear in the
urls generated by the extension.
extension_data is a dictionary. The expected fields are:
‘name’: short, human readable name of the extension ‘namespace’: xml namespace ‘alias’: identifier for the extension ‘updated’: date the extension was last updated ‘description’: text description of the extension ‘links’: hyperlinks to documents describing the extension
keystone.common.extension.register_public_extension(url_prefix, extension_data)[source]

Same as register_admin_extension but for public extensions.

keystone.common.json_home module

class keystone.common.json_home.Parameters[source]

Bases: object

Relationships for Common parameters.

DOMAIN_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/domain_id'
ENDPOINT_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/endpoint_id'
GROUP_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/group_id'
POLICY_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/policy_id'
PROJECT_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/project_id'
REGION_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/region_id'
ROLE_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/role_id'
SERVICE_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/service_id'
USER_ID = 'http://docs.openstack.org/api/openstack-identity/3/param/user_id'
class keystone.common.json_home.Status[source]

Bases: object

Status values supported.

DEPRECATED = 'deprecated'
EXPERIMENTAL = 'experimental'
STABLE = 'stable'
classmethod update_resource_data(resource_data, status)[source]
keystone.common.json_home.build_v3_extension_parameter_relation(extension_name, extension_version, parameter_name)[source]
keystone.common.json_home.build_v3_extension_resource_relation(extension_name, extension_version, resource_name)[source]
keystone.common.json_home.build_v3_parameter_relation(parameter_name)[source]
keystone.common.json_home.build_v3_resource_relation(resource_name)[source]
keystone.common.json_home.translate_urls(json_home, new_prefix)[source]

Given a JSON Home document, sticks new_prefix on each of the urls.

keystone.common.manager module

class keystone.common.manager.Manager(driver_name)[source]

Bases: object

Base class for intermediary request layer.

The Manager layer exists to support additional logic that applies to all or some of the methods exposed by a service that are not specific to the HTTP interface.

It also provides a stable entry point to dynamic backends.

An example of a probable use case is logging all the calls.

keystone.common.manager.response_truncated(f)[source]

Truncate the list returned by the wrapped function.

This is designed to wrap Manager list_{entity} methods to ensure that any list limits that are defined are passed to the driver layer. If a hints list is provided, the wrapper will insert the relevant limit into the hints so that the underlying driver call can try and honor it. If the driver does truncate the response, it will update the ‘truncated’ attribute in the ‘limit’ entry in the hints list, which enables the caller of this function to know if truncation has taken place. If, however, the driver layer is unable to perform truncation, the ‘limit’ entry is simply left in the hints list for the caller to handle.

A _get_list_limit() method is required to be present in the object class hierarchy, which returns the limit for this backend to which we will truncate.

If a hints list is not provided in the arguments of the wrapped call then any limits set in the config file are ignored. This allows internal use of such wrapped methods where the entire data set is needed as input for the calculations of some other API (e.g. get role assignments for a given project).

keystone.common.models module

Base model for keystone internal services

Unless marked otherwise, all fields are strings.

class keystone.common.models.Domain[source]

Bases: keystone.common.models.Model

Domain object.

Required keys:
id name

Optional keys:

description enabled (bool, default True)
optional_keys = ('description', 'enabled')
required_keys = ('id', 'name')
class keystone.common.models.Endpoint[source]

Bases: keystone.common.models.Model

Endpoint object

Required keys:
id region service_id
Optional keys:
internalurl publicurl adminurl
optional_keys = ('internalurl', 'publicurl', 'adminurl')
required_keys = ('id', 'region', 'service_id')
class keystone.common.models.Group[source]

Bases: keystone.common.models.Model

Group object.

Required keys:
id name domain_id

Optional keys:

description
optional_keys = ('description',)
required_keys = ('id', 'name', 'domain_id')
class keystone.common.models.Model[source]

Bases: dict

Base model class.

known_keys[source]
class keystone.common.models.Project[source]

Bases: keystone.common.models.Model

Project object.

Required keys:
id name domain_id
Optional Keys:
description enabled (bool, default True)
optional_keys = ('description', 'enabled')
required_keys = ('id', 'name', 'domain_id')
class keystone.common.models.Role[source]

Bases: keystone.common.models.Model

Role object.

Required keys:
id name
optional_keys = ()
required_keys = ('id', 'name')
class keystone.common.models.Service[source]

Bases: keystone.common.models.Model

Service object.

Required keys:
id type name

Optional keys:

optional_keys = ()
required_keys = ('id', 'type', 'name')
class keystone.common.models.Token[source]

Bases: keystone.common.models.Model

Token object.

Required keys:
id expires (datetime)
Optional keys:
user tenant metadata trust_id
optional_keys = ('extra',)
required_keys = ('id', 'expires')
class keystone.common.models.Trust[source]

Bases: keystone.common.models.Model

Trust object.

Required keys:
id trustor_user_id trustee_user_id project_id
optional_keys = ('expires_at',)
required_keys = ('id', 'trustor_user_id', 'trustee_user_id', 'project_id')
class keystone.common.models.User[source]

Bases: keystone.common.models.Model

User object.

Required keys:
id name domain_id
Optional keys:
password description email enabled (bool, default True) default_project_id
optional_keys = ('password', 'description', 'email', 'enabled', 'default_project_id')
required_keys = ('id', 'name', 'domain_id')

keystone.common.openssl module

keystone.common.pemutils module

PEM formatted data is used frequently in conjunction with X509 PKI as a data exchange mechanism for binary data. The acronym PEM stands for Privacy Enhanced Mail as defined in RFC-1421. Contrary to expectation the PEM format in common use has little to do with RFC-1421. Instead what we know as PEM format grew out of the need for a data exchange mechanism largely by the influence of OpenSSL. Other X509 implementations have adopted it.

Unfortunately PEM format has never been officially standarized. It’s basic format is as follows:

1) A header consisting of 5 hyphens followed by the word BEGIN and a single space. Then an upper case string describing the contents of the PEM block, this is followed by 5 hyphens and a newline.

2) Binary data (typically in DER ASN.1 format) encoded in base64. The base64 text is line wrapped so that each line of base64 is 64 characters long and terminated with a newline. The last line of base64 text may be less than 64 characters. The content and format of the binary data is entirely dependent upon the type of data announced in the header and footer.

3) A footer in the exact same as the header except the word BEGIN is replaced by END. The content name in both the header and footer should exactly match.

The above is called a PEM block. It is permissible for multiple PEM blocks to appear in a single file or block of text. This is often used when specifying multiple X509 certificates.

An example PEM block for a certificate is:

—–BEGIN CERTIFICATE—– MIIC0TCCAjqgAwIBAgIJANsHKV73HYOwMA0GCSqGSIb3DQEBBQUAMIGeMQowCAYD VQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1bm55 dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTElMCMG CSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxMLU2Vs ZiBTaWduZWQwIBcNMTIxMTA1MTgxODI0WhgPMjA3MTA0MzAxODE4MjRaMIGeMQow CAYDVQQFEwE1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVN1 bm55dmFsZTESMBAGA1UEChMJT3BlblN0YWNrMREwDwYDVQQLEwhLZXlzdG9uZTEl MCMGCSqGSIb3DQEJARYWa2V5c3RvbmVAb3BlbnN0YWNrLm9yZzEUMBIGA1UEAxML U2VsZiBTaWduZWQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALzI17ExCaqd r7xY2Q5CBZ1bW1lsrXxS8eNJRdQtskDuQVAluY03/OGZd8HQYiiY/ci2tYy7BNIC bh5GaO95eqTDykJR3liOYE/tHbY6puQlj2ZivmhlSd2d5d7lF0/H28RQsLu9VktM uw6q9DpDm35jfrr8LgSeA3MdVqcS/4OhAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB Af8wDQYJKoZIhvcNAQEFBQADgYEAjSQND7i1dNZtLKpWgX+JqMr3BdVlM15mFeVr C26ZspZjZVY5okdozO9gU3xcwRe4Cg30sKFOe6EBQKpkTZucFOXwBtD3h6dWJrdD c+m/CL/rs0GatDavbaIT2vv405SQUQooCdVh72LYel+4/a6xmRd7fQx3iEXN9QYj vmHJUcA= —–END CERTIFICATE—–

PEM format is safe for transmission in 7-bit ASCII systems (i.e. standard email). Since 7-bit ASCII is a proper subset of UTF-8 and Latin-1 it is not affected by transcoding between those charsets. Nor is PEM format affected by the choice of line endings. This makes PEM format particularity attractive for transport and storage of binary data.

This module provides a number of utilities supporting the generation and consumption of PEM formatted data including:

  • parse text and find all PEM blocks contained in the text. Information on the location of the block in the text, the type of PEM block, and it’s base64 and binary data contents.
  • parse text assumed to contain PEM data and return the binary data.
  • test if a block of text is a PEM block
  • convert base64 text into a formatted PEM block
  • convert binary data into a formatted PEM block
  • access to the valid PEM types and their headers
class keystone.common.pemutils.PEMParseResult(pem_type=None, pem_header=None, pem_start=None, pem_end=None, base64_start=None, base64_end=None, binary_data=None)[source]

Bases: object

Information returned when a PEM block is found in text.

PEMParseResult contains information about a PEM block discovered while parsing text. The following properties are defined:

pem_type
A short hand name for the type of the PEM data, e.g. cert, csr, crl, cms, key. Valid pem_types are listed in pem_types. When the pem_type is set the pem_header is updated to match it.
pem_header

The text following ‘—–BEGIN ‘ in the PEM header. Common examples are:

—–BEGIN CERTIFICATE—– —–BEGIN CMS—–

Thus the pem_header would be CERTIFICATE and CMS respectively. When the pem_header is set the pem_type is updated to match it.

pem_start, pem_end
The beginning and ending positions of the PEM block including the PEM header and footer.
base64_start, base64_end
The beginning and ending positions of the base64 data contained inside the PEM header and footer. Includes trailing new line
binary_data
The decoded base64 data. None if not decoded.
pem_header[source]
pem_type[source]
keystone.common.pemutils.base64_to_pem(base64_text, pem_type='cert')[source]

Format string of base64 text into PEM format

Input is assumed to consist only of members of the base64 alphabet (i.e no whitepace). Use one of the filter functions from base64utils to assure the input is clean (i.e. strip_whitespace()).

Parameters:
  • base64_text (string) – text containing ONLY base64 alphabet characters to be inserted into PEM output.
  • pem_type (string) – Produce a PEM block for this type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

string – PEM formatted text

keystone.common.pemutils.binary_to_pem(binary_data, pem_type='cert')[source]

Format binary data into PEM format

Example:

# get the certificate binary data in DER format der_data = certificate.der # convert the DER binary data into a PEM pem = binary_to_pem(der_data, ‘cert’)
Parameters:
  • binary_data (buffer) – binary data to encapsulate into PEM
  • pem_type (string) – Produce a PEM block for this type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

string – PEM formatted text

keystone.common.pemutils.get_pem_data(text, pem_type='cert')[source]

Scan text for PEM data, return binary contents

The input text is scanned for a PEM block which matches the pem_type. If found the binary data contained in the PEM block is returned. If no PEM block is found or it does not match the specified pem type None is returned.

Parameters:
  • text (string) – The text to search for the PEM block
  • pem_type (string) – Only return data for this pem_type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

binary data or None if not found.

keystone.common.pemutils.is_pem(text, pem_type='cert')[source]

Does this text contain a PEM block.

Check for the existence of a PEM formatted block in the text, if one is found verify it’s contents can be base64 decoded, if so return True. Return False otherwise.

Parameters:
  • text (string) – The text to search for PEM blocks
  • pem_type (string) – Only return data for this pem_type. Valid types are: csr, cert, crl, cms, key. (default: ‘cert’)
Returns:

bool – True if text contains PEM matching the pem_type, False otherwise.

keystone.common.pemutils.parse_pem(text, pem_type=None, max_items=None)[source]

Scan text for PEM data, return list of PEM items

The input text is scanned for PEM blocks, for each one found a PEMParseResult is constructed and added to the return list.

pem_type operates as a filter on the type of PEM desired. If pem_type is specified only those PEM blocks which match will be included. The pem_type is a logical name, not the actual text in the pem header (e.g. ‘cert’). If the pem_type is None all PEM blocks are returned.

If max_items is specified the result is limited to that number of items.

The return value is a list of PEMParseResult objects. The PEMParseResult provides complete information about the PEM block including the decoded binary data for the PEM block. The list is ordered in the same order as found in the text.

Examples:

# Get all certs
certs = parse_pem(text, 'cert')

# Get the first cert
try:
    binary_cert = parse_pem(text, 'cert', 1)[0].binary_data
except IndexError:
    raise ValueError('no cert found')
Parameters:
  • text (string) – The text to search for PEM blocks
  • pem_type (string or None) – Only return data for this pem_type. Valid types are: csr, cert, crl, cms, key. If pem_type is None no filtering is performed. (default: None)
  • max_items (int or None) – Limit the number of blocks returned. (default: None)
Returns:

List of PEMParseResult, one for each PEM block found

Raises:

ValueError, InvalidBase64Error

Search for a block of PEM formatted data

Search for a PEM block in a text string. The search begins at start. If a PEM block is found a PEMParseResult object is returned, otherwise if no PEM block is found None is returned.

If the pem_type is not the same in both the header and footer a ValueError is raised.

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:

start = 0
while True:
    block = pem_search(text, start)
    if block is None:
        break
    base64_data = text[block.base64_start : block.base64_end]
    start = block.pem_end
Parameters:
  • text (string) – the text to search for PEM blocks
  • start (int) – the position in text to start searching from (default: 0)
Returns:

PEMParseResult or None if not found

Raises:

ValueError

keystone.common.router module

keystone.common.utils module

keystone.common.wsgi module

Module contents