diff --git a/doc/ext/support_matrix.py b/doc/ext/support_matrix.py deleted file mode 100644 index c7e53fc13b..0000000000 --- a/doc/ext/support_matrix.py +++ /dev/null @@ -1,513 +0,0 @@ -# Copyright (C) 2014 Red Hat, Inc. -# -# 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. - -"""Feature support matrix extension for Sphinx. - -This provides a sphinx extension able to render support matrix INI files into -the developer documentation. - -It is used via a single directive in the .rst file - - .. support_matrix:: - -""" - -import re - -from six.moves import configparser - -from docutils import nodes -from docutils.parsers import rst - - -class SupportMatrix(object): - """Represent the entire support matrix.""" - - def __init__(self): - # List of SupportMatrixFeature instances, describing - # all the features present in Nova virt drivers - self.features = [] - - # Dict of (name, SupportMatrixTarget) enumerating - # all the hypervisor drivers that have data recorded - # for them in self.features. The 'name' dict key is - # the value from the SupportMatrixTarget.key attribute - self.targets = {} - - -class SupportMatrixFeature(object): - - STATUS_MANDATORY = "mandatory" - STATUS_CHOICE = "choice" - STATUS_CONDITION = "condition" - STATUS_OPTIONAL = "optional" - - STATUS_ALL = [STATUS_MANDATORY, STATUS_CHOICE, - STATUS_CONDITION, STATUS_OPTIONAL] - - def __init__(self, key, title, status=STATUS_OPTIONAL, - group=None, notes=None, cli=None): - if cli is None: - cli = list() - # A unique key (eg 'foo.bar.wizz') to identify the feature - self.key = key - # A human friendly short title for the feature - self.title = title - # One of the status constants - self.status = status - # Detail string if status was choice/condition - self.group = group - # Arbitrarily long string describing the feature in detail - self.notes = notes - # Dict of (name, SupportMatrixImplementation) detailing - # the implementation for each hypervisor driver. The - # 'name' dict key is the value from SupportMatrixTarget.key - # for the hypervisor in question - self.implementations = {} - # A list of CLI commands which are related to that feature - self.cli = cli - - -class SupportMatrixImplementation(object): - - STATUS_COMPLETE = "complete" - STATUS_PARTIAL = "partial" - STATUS_MISSING = "missing" - STATUS_UKNOWN = "unknown" - - STATUS_ALL = [STATUS_COMPLETE, STATUS_PARTIAL, STATUS_MISSING, - STATUS_UKNOWN] - - def __init__(self, status=STATUS_MISSING, notes=None): - # One of the status constants detailing the implementation - # level - self.status = status - # Arbitrary string describing any caveats of the implementation. - # Mandatory if status is 'partial', optional otherwise. - self.notes = notes - - -class SupportMatrixTarget(object): - - def __init__(self, key, title, driver, hypervisor=None, architecture=None): - """Initialize a SupportMatrixTarget instance. - - :param key: Unique identifier for the hypervisor driver - :param title: Human friendly name of the hypervisor - :param driver: Name of the Nova driver - :param hypervisor: (optional) Name of the hypervisor, if many - :param architecture: (optional) Name of the architecture, if many - """ - self.key = key - self.title = title - self.driver = driver - self.hypervisor = hypervisor - self.architecture = architecture - - -class SupportMatrixDirective(rst.Directive): - - # The argument is the filename, e.g. support-matrix.ini - required_arguments = 1 - - def run(self): - matrix = self._load_support_matrix() - return self._build_markup(matrix) - - def _load_support_matrix(self): - """Load a support matrix from a configuration file. - - Reads the support-matrix.ini file and populates an instance of the - SupportMatrix class with all the data. - - :returns: SupportMatrix instance - """ - cfg = configparser.ConfigParser() - env = self.state.document.settings.env - fname = self.arguments[0] - rel_fpath, fpath = env.relfn2path(fname) - with open(fpath) as fp: - cfg.readfp(fp) - - # This ensures that the docs are rebuilt whenever the - # .ini file changes - env.note_dependency(rel_fpath) - - matrix = SupportMatrix() - matrix.targets = self._get_targets(cfg) - matrix.features = self._get_features(cfg, matrix.targets) - - return matrix - - def _get_targets(self, cfg): - # The 'targets' section is special - it lists all the - # hypervisors that this file records data for - - targets = {} - - for item in cfg.options("targets"): - if not item.startswith("driver-impl-"): - continue - - # The driver string will optionally contain - # a hypervisor and architecture qualifier - # so we expect between 1 and 3 components - # in the name - key = item[12:] - title = cfg.get("targets", item) - name = key.split("-") - if len(name) == 1: - target = SupportMatrixTarget(key, - title, - name[0]) - elif len(name) == 2: - target = SupportMatrixTarget(key, - title, - name[0], - name[1]) - elif len(name) == 3: - target = SupportMatrixTarget(key, - title, - name[0], - name[1], - name[2]) - else: - raise Exception("'%s' field is malformed in '[%s]' section" % - (item, "DEFAULT")) - - targets[key] = target - - return targets - - def _get_features(self, cfg, targets): - # All sections except 'targets' describe some feature of - # the Nova hypervisor driver implementation - - features = [] - - for section in cfg.sections(): - if section == "targets": - continue - if not cfg.has_option(section, "title"): - raise Exception( - "'title' field missing in '[%s]' section" % section) - - title = cfg.get(section, "title") - - status = SupportMatrixFeature.STATUS_OPTIONAL - if cfg.has_option(section, "status"): - # The value is a string "status(group)" where - # the 'group' part is optional - status = cfg.get(section, "status") - offset = status.find("(") - group = None - if offset != -1: - group = status[offset + 1:-1] - status = status[0:offset] - - if status not in SupportMatrixFeature.STATUS_ALL: - raise Exception( - "'status' field value '%s' in ['%s']" - "section must be %s" % - (status, section, - ",".join(SupportMatrixFeature.STATUS_ALL))) - - notes = None - if cfg.has_option(section, "notes"): - notes = cfg.get(section, "notes") - cli = [] - if cfg.has_option(section, "cli"): - cli = cfg.get(section, "cli") - feature = SupportMatrixFeature(section, - title, - status, - group, - notes, - cli) - - # Now we've got the basic feature details, we must process - # the hypervisor driver implementation for each feature - for item in cfg.options(section): - if not item.startswith("driver-impl-"): - continue - - key = item[12:] - if key not in targets: - raise Exception( - "Driver impl '%s' in '[%s]' not declared" % - (item, section)) - - status = cfg.get(section, item) - if status not in SupportMatrixImplementation.STATUS_ALL: - raise Exception( - "'%s' value '%s' in '[%s]' section must be %s" % - (item, status, section, - ",".join(SupportMatrixImplementation.STATUS_ALL))) - - noteskey = "driver-notes-" + item[12:] - notes = None - if cfg.has_option(section, noteskey): - notes = cfg.get(section, noteskey) - - target = targets[key] - impl = SupportMatrixImplementation(status, - notes) - feature.implementations[target.key] = impl - - for key in targets: - if key not in feature.implementations: - raise Exception("'%s' missing in '[%s]' section" % - (target.key, section)) - - features.append(feature) - - return features - - def _build_markup(self, matrix): - """Construct the docutils content for the support matrix.""" - content = [] - self._build_summary(matrix, content) - self._build_details(matrix, content) - # FIXME(dolph): Do not render hardcoded notes that are specific to - # Nova. - # self._build_notes(content) - return content - - def _build_summary(self, matrix, content): - """Construct the docutils content for the support matrix summary. - - The summary consists of a giant table, with one row for each feature, - and a column for each hypervisor driver. It provides an 'at a glance' - summary of the status of each driver - """ - summarytitle = nodes.subtitle(text="Summary") - summary = nodes.table() - cols = len(matrix.targets.keys()) - cols += 2 - summarygroup = nodes.tgroup(cols=cols) - summarybody = nodes.tbody() - summaryhead = nodes.thead() - - for i in range(cols): - summarygroup.append(nodes.colspec(colwidth=1)) - summarygroup.append(summaryhead) - summarygroup.append(summarybody) - summary.append(summarygroup) - content.append(summarytitle) - content.append(summary) - - # This sets up all the column headers - two fixed - # columns for feature name & status - header = nodes.row() - blank = nodes.entry() - blank.append(nodes.emphasis(text="Feature")) - header.append(blank) - blank = nodes.entry() - blank.append(nodes.emphasis(text="Status")) - header.append(blank) - summaryhead.append(header) - - # then one column for each hypervisor driver - impls = sorted(matrix.targets.keys()) - for key in impls: - target = matrix.targets[key] - implcol = nodes.entry() - header.append(implcol) - implcol.append(nodes.strong(text=target.title)) - - # We now produce the body of the table, one row for - # each feature to report on - for feature in matrix.features: - item = nodes.row() - - # the hyperlink target name linking to details - id = re.sub("[^a-zA-Z0-9_]", "_", - feature.key) - - # first the to fixed columns for title/status - keycol = nodes.entry() - item.append(keycol) - keyref = nodes.reference(refid=id) - keytxt = nodes.inline() - keycol.append(keytxt) - keytxt.append(keyref) - keyref.append(nodes.strong(text=feature.title)) - - statuscol = nodes.entry() - item.append(statuscol) - statuscol.append(nodes.inline( - text=feature.status, - classes=["sp_feature_" + feature.status])) - - # and then one column for each hypervisor driver - impls = sorted(matrix.targets.keys()) - for key in impls: - target = matrix.targets[key] - impl = feature.implementations[key] - implcol = nodes.entry() - item.append(implcol) - - id = re.sub("[^a-zA-Z0-9_]", "_", - feature.key + "_" + key) - - implref = nodes.reference(refid=id) - impltxt = nodes.inline() - implcol.append(impltxt) - impltxt.append(implref) - - status = "" - if impl.status == SupportMatrixImplementation.STATUS_COMPLETE: - status = u"\u2714" - elif impl.status == SupportMatrixImplementation.STATUS_MISSING: - status = u"\u2716" - elif impl.status == SupportMatrixImplementation.STATUS_PARTIAL: - status = u"\u2714" - elif impl.status == SupportMatrixImplementation.STATUS_UKNOWN: - status = u"?" - - implref.append(nodes.literal( - text=status, - classes=["sp_impl_summary", "sp_impl_" + impl.status])) - - summarybody.append(item) - - def _build_details(self, matrix, content): - """Construct the docutils content for the support matrix details. - - This is generated as a bullet list of features. Against each feature we - provide the description of the feature and then the details of the - hypervisor impls, with any driver specific notes that exist - """ - detailstitle = nodes.subtitle(text="Details") - details = nodes.bullet_list() - - content.append(detailstitle) - content.append(details) - - # One list entry for each feature we're reporting on - for feature in matrix.features: - item = nodes.list_item() - - status = feature.status - if feature.group is not None: - status += "(" + feature.group + ")" - - # The hypervisor target name linked from summary table - id = re.sub("[^a-zA-Z0-9_]", "_", - feature.key) - - # Highlight the feature title name - item.append(nodes.strong(text=feature.title, - ids=[id])) - - para = nodes.paragraph() - para.append(nodes.strong(text="Status: " + status + ". ")) - if feature.notes is not None: - para.append(nodes.inline(text=feature.notes)) - item.append(para) - - if feature.cli: - item.append(self._create_cli_paragraph(feature)) - - para_divers = nodes.paragraph() - para_divers.append(nodes.strong(text="drivers:")) - # A sub-list giving details of each hypervisor target - impls = nodes.bullet_list() - for key in feature.implementations: - target = matrix.targets[key] - impl = feature.implementations[key] - subitem = nodes.list_item() - - id = re.sub("[^a-zA-Z0-9_]", "_", - feature.key + "_" + key) - subitem += [ - nodes.strong(text=target.title + ": "), - nodes.literal(text=impl.status, - classes=["sp_impl_" + impl.status], - ids=[id]), - ] - if impl.notes is not None: - subitem.append(self._create_notes_paragraph(impl.notes)) - impls.append(subitem) - - para_divers.append(impls) - item.append(para_divers) - details.append(item) - - def _build_notes(self, content): - """Construct a list of notes content for the support matrix. - - This is generated as a bullet list. - """ - notestitle = nodes.subtitle(text="Notes") - notes = nodes.bullet_list() - - content.append(notestitle) - content.append(notes) - - NOTES = [ - "Virtuozzo was formerly named Parallels in this document" - ] - - for note in NOTES: - item = nodes.list_item() - item.append(nodes.strong(text=note)) - notes.append(item) - - def _create_cli_paragraph(self, feature): - """Create a paragraph which represents the CLI commands of the feature. - - The paragraph will have a bullet list of CLI commands. - """ - para = nodes.paragraph() - para.append(nodes.strong(text="CLI commands:")) - commands = nodes.bullet_list() - for c in feature.cli.split(";"): - cli_command = nodes.list_item() - cli_command += nodes.literal(text=c, classes=["sp_cli"]) - commands.append(cli_command) - para.append(commands) - return para - - def _create_notes_paragraph(self, notes): - """Construct a paragraph which represents the implementation notes. - - The paragraph consists of text and clickable URL nodes if links were - given in the notes. - """ - para = nodes.paragraph() - # links could start with http:// or https:// - link_idxs = [m.start() for m in re.finditer('https?://', notes)] - start_idx = 0 - for link_idx in link_idxs: - # assume the notes start with text (could be empty) - para.append(nodes.inline(text=notes[start_idx:link_idx])) - # create a URL node until the next text or the end of the notes - link_end_idx = notes.find(" ", link_idx) - if link_end_idx == -1: - # In case the notes end with a link without a blank - link_end_idx = len(notes) - uri = notes[link_idx:link_end_idx + 1] - para.append(nodes.reference("", uri, refuri=uri)) - start_idx = link_end_idx + 1 - - # get all text after the last link (could be empty) or all of the - # text if no link was given - para.append(nodes.inline(text=notes[start_idx:])) - return para - - -def setup(app): - app.add_directive('support_matrix', SupportMatrixDirective) - app.add_stylesheet('support-matrix.css') diff --git a/doc/requirements.txt b/doc/requirements.txt index 7247e6aee8..bb72f5df94 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -5,6 +5,7 @@ openstackdocstheme>=1.18.1 # Apache-2.0 sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD sphinxcontrib-apidoc>=0.2.0 # BSD sphinxcontrib-seqdiag>=0.8.4 # BSD +sphinx-feature-classification>=0.3.2 # Apache-2.0 reno>=2.5.0 # Apache-2.0 os-api-ref>=1.4.0 # Apache-2.0 python-ldap>=3.0.0 # PSF diff --git a/doc/source/admin/identity-support-matrix.ini b/doc/source/admin/identity-support-matrix.ini index 7e6ef1e943..8e9418e724 100644 --- a/doc/source/admin/identity-support-matrix.ini +++ b/doc/source/admin/identity-support-matrix.ini @@ -21,18 +21,18 @@ # - operation: Public API operations. # - feature: Features of the driver. # -# When considering which capabilities should be marked as mandatory, consider +# When considering which capabilities should be marked as required, consider # the following guiding principles. # # The 'status' field takes possible values: # -# - mandatory: Unconditionally required to be implemented. +# - required: Unconditionally required to be implemented. # - optional: Optional to support, but nice to have. # - choice(group): At least one of the options within the named group # must be implemented. # - conditional(cond): Required, if the referenced condition is met. # -# The value against each 'impl-XXXX' entry refers to the level of the +# The value against each 'driver.XXXX' entry refers to the level of the # implementation of the feature in that driver: # # - complete: Fully implemented, expected to work at all times. @@ -42,79 +42,89 @@ # - missing: Not implemented at all. # # In the case of the driver being marked as 'partial', then -# 'notes-XXX' entry should be used to explain the caveats around the +# 'notes' entry should be used to explain the caveats around the # implementation. # # The 'cli' field takes a list of client commands, separated by semicolon. -# These CLi commands are related to that feature. +# These CLi commands are related to that operation. # Example: # cli=openstack domain list;openstack domain show # -[targets] # List of driver implementations for which we are going to track the status of # features. This list only covers drivers that are in tree. Out of tree # drivers should maintain their own equivalent document, and merge it with this # when their code merges into core. -driver-impl-sql=SQL -driver-impl-ldap=LDAP -driver-impl-oauth1=OAuth v1.0a -driver-impl-external=REMOTE_USER -driver-impl-oidc=OpenID Connect -driver-impl-samlv2=SAML v2 +[driver.sql] +title=SQL -[feature.local_authentication] +[driver.ldap] +title=LDAP + +[driver.oauth1] +title=OAuth v1.0a + +[driver.external] +title=REMOTE_USER + +[driver.oidc] +title=OpenID Connect + +[driver.samlv2] +title=SAML v2 + +[operation.local_authentication] title=Local authentication status=optional notes=Authenticate with keystone by providing credentials directly to keystone. -driver-impl-sql=complete -driver-impl-ldap=complete -driver-impl-oauth1=complete -driver-impl-external=missing -driver-impl-oidc=missing -driver-impl-samlv2=missing +driver.sql=complete +driver.ldap=complete +driver.oauth1=complete +driver.external=missing +driver.oidc=missing +driver.samlv2=missing -[feature.external_authentication] +[operation.external_authentication] title=External authentication status=optional notes=Authenticate with keystone by providing credentials to an external system that keystone trusts (as with federation). -driver-impl-sql=missing -driver-impl-ldap=missing -driver-impl-oauth1=missing -driver-impl-external=complete -driver-impl-oidc=complete -driver-impl-samlv2=complete +driver.sql=missing +driver.ldap=missing +driver.oauth1=missing +driver.external=complete +driver.oidc=complete +driver.samlv2=complete -[feature.identity_crud] +[operation.identity_crud] title=Identity management status=optional notes=Create, update, enable/disable, and delete users via Keystone's HTTP API. -driver-impl-sql=complete -driver-impl-ldap=partial -driver-impl-oauth1=complete -driver-impl-external=missing -driver-impl-oidc=missing -driver-impl-samlv2=missing +driver.sql=complete +driver.ldap=partial +driver.oauth1=complete +driver.external=missing +driver.oidc=missing +driver.samlv2=missing -[feature.pci_controls] +[operation.pci_controls] title=PCI-DSS controls status=optional notes=Configure keystone to enforce PCI-DSS compliant security controls. -driver-impl-sql=complete -driver-impl-ldap=partial -driver-impl-oauth1=missing -driver-impl-external=partial -driver-impl-oidc=missing -driver-impl-samlv2=missing +driver.sql=complete +driver.ldap=partial +driver.oauth1=missing +driver.external=partial +driver.oidc=missing +driver.samlv2=missing -[feature.auditing] +[operation.auditing] title=Auditing status=optional notes=Audit authentication flows using PyCADF. -driver-impl-sql=complete -driver-impl-ldap=complete -driver-impl-oauth1=missing -driver-impl-external=missing -driver-impl-oidc=complete -driver-impl-samlv2=complete +driver.sql=complete +driver.ldap=complete +driver.oauth1=missing +driver.external=missing +driver.oidc=complete +driver.samlv2=complete diff --git a/doc/source/admin/token-support-matrix.ini b/doc/source/admin/token-support-matrix.ini index 2c4ee4a834..6b38b378e4 100644 --- a/doc/source/admin/token-support-matrix.ini +++ b/doc/source/admin/token-support-matrix.ini @@ -10,53 +10,16 @@ # License for the specific language governing permissions and limitations # under the License. -# This file contains a specification of what feature capabilities each driver -# is able to support. Feature capabilities include what API operations are -# supported, what backend behaviors features can be used and what aspects of -# the driver implementation can be configured. The capabilities can be -# considered to be structured into nested groups, but in this file they have -# been flattened for ease of representation. The section names represent the -# group structure. At the top level there are the following groups defined: +# For information about the format of this file, refer to the documentation +# for sphinx-feature-classification: # -# - operation: Public API operations. -# - feature: Features of the token format. -# -# When considering which capabilities should be marked as mandatory, consider -# the following guiding principles. -# -# The 'status' field takes possible values: -# -# - mandatory: Unconditionally required to be implemented. -# - optional: Optional to support, but nice to have. -# - choice(group): At least one of the options within the named group -# must be implemented. -# - conditional(cond): Required, if the referenced condition is met. -# -# The value against each 'driver-impl-XXXX' entry refers to the level of the -# implementation of the feature in that driver: -# -# - complete: Fully implemented, expected to work at all times. -# - partial: Implemented, but with caveats about when it will work. -# For example, some configurations or hardware or guest OS may not -# support it. -# - missing: Not implemented at all. -# -# In the case of the driver being marked as 'partial', then -# 'driver-notes-XXX' entry should be used to explain the caveats around the -# implementation. -# -# The 'cli' field takes a list of client commands, separated by semicolon. -# These CLi commands are related to that feature. -# Example: -# cli=openstack domain list;openstack domain show -# -[targets] -# List of driver implementations for which we are going to track the status of -# features. This list only covers drivers that are in tree. Out of tree -# drivers should maintain their own equivalent document, and merge it with this -# when their code merges into core. -driver-impl-fernet=Fernet tokens -driver-impl-jws=JWS tokens +# https://docs.openstack.org/sphinx-feature-classification/latest/ + +[driver.fernet] +title=Fernet tokens + +[driver.jws] +title=JWS tokens [operation.create_unscoped_token] title=Create unscoped token @@ -65,8 +28,8 @@ notes=All token providers must be capable of issuing tokens without an explicit scope of authorization. cli=openstack --os-username= --os-user-domain-name= --os-password= token issue -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [operation.create_system_token] title=Create system-scoped token @@ -74,8 +37,8 @@ status=mandatory notes=All token providers must be capable of issuing system-scoped tokens. cli=openstack --os-username= --os-user-domain-name= --os-system-scope all token issue -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [operation.create_project_scoped_token] title=Create project-scoped token @@ -84,8 +47,8 @@ notes=All token providers must be capable of issuing project-scoped tokens. cli=openstack --os-username= --os-user-domain-name= --os-password= --os-project-name= --os-project-domain-name= token issue -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [operation.create_domain_scoped_token] title=Create domain-scoped token @@ -94,8 +57,8 @@ notes=Domain-scoped tokens are not required for all use cases, and for some use cases, projects can be used instead. cli=openstack --os-username= --os-user-domain-name= --os-password= --os-domain-name= token issue -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [operation.create_trust_scoped_token] title=Create trust-scoped token @@ -104,16 +67,16 @@ notes=Tokens scoped to a trust convey only the user impersonation and project-based authorization attributes included in the delegation. cli=openstack --os-username= --os-user-domain-name= --os-password= --os-trust-id= token issue -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [operation.create_token_using_oauth] title=Create a token given an OAuth access token status=optional notes=OAuth access tokens can be exchanged for keystone tokens. cli= -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [operation.revoke_token] title=Revoke a token @@ -123,8 +86,8 @@ notes=Tokens may be individually revoked, such as when a user logs out of single token may be revoked as a result of this operation (such as when the revoked token was previously used to create additional tokens). cli=openstack token revoke -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [feature.online_validation] title=Online validation @@ -132,8 +95,8 @@ status=mandatory notes=Keystone must be able to validate the tokens that it issues when presented with a token that it previously issued. cli= -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete [feature.offline_validation] title=Offline validation @@ -142,8 +105,8 @@ notes=Services using Keystone for authentication may want to validate tokens themselves, rather than calling back to keystone, in order to improve performance and scalability. cli= -driver-impl-fernet=missing -driver-impl-jws=missing +driver.fernet=missing +driver.jws=missing [feature.non_persistent] title=Non-persistent @@ -153,5 +116,5 @@ notes=If a token format does not require persistence (such as to a SQL keystone can issue at once, and there is no need to perform clean up operations such as `keystone-manage token_flush`. cli= -driver-impl-fernet=complete -driver-impl-jws=complete +driver.fernet=complete +driver.jws=complete diff --git a/doc/source/conf.py b/doc/source/conf.py index 2977b63482..01d94c00bd 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -24,19 +24,6 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import os -import sys - -# NOTE(dstanek): adds _ to the builtins so keystone modules can be imported -__builtins__['_'] = str - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('../../')) -sys.path.insert(0, os.path.abspath('../')) -sys.path.insert(0, os.path.abspath('./')) - # -- General configuration ---------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. @@ -52,9 +39,9 @@ extensions = ['sphinx.ext.coverage', 'oslo_policy.sphinxpolicygen', 'openstackdocstheme', 'oslo_policy.sphinxext', - 'ext.support_matrix', 'sphinxcontrib.apidoc', 'sphinxcontrib.seqdiag', + 'sphinx_feature_classification.support_matrix', ] # sphinxcontrib.apidoc options