From c21ef89a88b0f547a5a3c80caf7c5fed61f49e6c Mon Sep 17 00:00:00 2001 From: Jamie Lennox Date: Tue, 10 Jan 2017 22:56:46 +1100 Subject: [PATCH] Add a full listing of all auth plugins and there options A commonly requested document is what auth plugins are available and what parameters do they accept. Create an extension that can iterate through the stevedore namespace and render all its available options. Change-Id: Id0d0983c9803ce4e0ce201310a1603bc0ff30ca0 --- doc/ext/__init__.py | 0 doc/ext/list_plugins.py | 93 +++++++++++++++++++ doc/source/conf.py | 3 + doc/source/index.rst | 1 + doc/source/plugin-options.rst | 92 ++++++++++++++++++ keystoneauth1/loading/_plugins/admin_token.py | 11 +++ .../loading/_plugins/identity/generic.py | 21 +++++ 7 files changed, 221 insertions(+) create mode 100644 doc/ext/__init__.py create mode 100644 doc/ext/list_plugins.py create mode 100644 doc/source/plugin-options.rst diff --git a/doc/ext/__init__.py b/doc/ext/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/doc/ext/list_plugins.py b/doc/ext/list_plugins.py new file mode 100644 index 00000000..96268804 --- /dev/null +++ b/doc/ext/list_plugins.py @@ -0,0 +1,93 @@ +# 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. + +import inspect + +from docutils import nodes +from docutils.parsers import rst +from docutils.parsers.rst import directives +from docutils.statemachine import ViewList +from sphinx.util.nodes import nested_parse_with_titles + +from stevedore import extension + + +class ListAuthPluginsDirective(rst.Directive): + """Present a simple list of the plugins in a namespace.""" + + option_spec = { + 'class': directives.class_option, + 'overline-style': directives.single_char_or_unicode, + 'underline-style': directives.single_char_or_unicode, + } + + has_content = True + + @property + def app(self): + return self.state.document.settings.env.app + + def report_load_failure(mgr, ep, err): + self.app.warn(u'Failed to load %s: %s' % (ep.module_name, err)) + + def display_plugin(self, ext): + overline_style = self.options.get('overline-style', '') + underline_style = self.options.get('underline-style', '=') + + if overline_style: + yield overline_style * len(ext.name) + + yield ext.name + + if underline_style: + yield underline_style * len(ext.name) + + yield "\n" + + doc = inspect.getdoc(ext.obj) + if doc: + yield doc + yield "\n" + yield "------" + + yield "\n" + + for opt in ext.obj.get_options(): + yield ":%s: %s" % (opt.name, opt.help) + + yield "\n" + + def run(self): + mgr = extension.ExtensionManager( + 'keystoneauth1.plugin', + on_load_failure_callback=self.report_load_failure, + invoke_on_load=True, + ) + + result = ViewList() + + for name in sorted(mgr.names()): + for line in self.display_plugin(mgr[name]): + for l in line.splitlines(): + result.append(l, mgr[name].entry_point.module_name) + + # Parse what we have into a new section. + node = nodes.section() + node.document = self.state.document + nested_parse_with_titles(self.state, result, node) + + return node.children + + +def setup(app): + app.info('loading keystoneauth1 plugins') + app.add_directive('list-auth-plugins', ListAuthPluginsDirective) diff --git a/doc/source/conf.py b/doc/source/conf.py index 9be29ee6..d6e4a195 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -24,6 +24,8 @@ import pbr.version sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), + '..'))) # 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 @@ -40,6 +42,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.intersphinx', 'oslosphinx', + 'ext.list_plugins', ] todo_include_todos = True diff --git a/doc/source/index.rst b/doc/source/index.rst index 47538725..8c433ecf 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -13,6 +13,7 @@ Contents: using-sessions authentication-plugins + plugin-options extras migrating diff --git a/doc/source/plugin-options.rst b/doc/source/plugin-options.rst new file mode 100644 index 00000000..4417f81b --- /dev/null +++ b/doc/source/plugin-options.rst @@ -0,0 +1,92 @@ +============== +Plugin Options +============== + +Using plugins via config file +----------------------------- + +When using the plugins via config file you define the plugin name as +``auth_type``. The options of the plugin are then specified while replacing +``-`` with ``_`` to be valid in configuration. + +For example to use the password_ plugin in a config file you would specify: + +.. code-block:: ini + + [section] + auth_url = http://keystone.example.com:5000/ + auth_type = password + username = myuser + password = mypassword + project_name = myproject + default_domain_name = mydomain + + +Using plugins via CLI +--------------------- + +When using auth plugins via CLI via ``os-client-config`` or ``shade`` you can +specify parameters via environment configuration by using the pattern ``OS_`` +followed by the uppercase parameter name replacing ``-`` with ``_``. + +For example to use the password_ plugin via environment variable you specify: + +.. code-block:: bash + + export OS_AUTH_TYPE=password + export OS_AUTH_URL=http://keystone.example.com:5000/ + export OS_USERNAME=myuser + export OS_PASSWORD=mypassword + export OS_PROJECT_NAME=myproject + export OS_DEFAULT_DOMAIN_NAME=mydomain + +Specifying operations via CLI parameter will override the environment +parameter. These are specified with the pattern ``--os-`` and the parameter +name. Using the password_ example again: + +.. code-block:: bash + + openstack --os-auth-type password \ + --os-auth-url http://keystone.example.com:5000/ \ + --os-username myuser \ + --os-password mypassword \ + --os-project-name myproject \ + --os-default-domain-name mydomain \ + operation + +Additional loaders +------------------ + +The configuration and CLI loaders are quite commonly used however similar +concepts are found in other situations such as ``os-client-config`` in which +you specify authentication and other cloud parameters in a ``clouds.yaml`` +file. + +Loaders such as these use the same plugin options listed below, but via their +own mechanism. In ``os-client-config`` the password_ plugin looks like: + +.. code-block:: yaml + + clouds: + mycloud: + auth_type: password + auth: + auth_url: http://keystone.example.com:5000/ + auth_type: password + username: myuser + password: mypassword + project_name: myproject + default_domain_name: mydomain + +However different services may implement loaders in their own way and you +should consult their relevant documentation. The same auth options will be +available. + + +Available Plugins +----------------- + +This is a listing of all included plugins and the options that they accept. +Plugins are listed alphabetically and not in any order of priority. + +.. list-auth-plugins:: diff --git a/keystoneauth1/loading/_plugins/admin_token.py b/keystoneauth1/loading/_plugins/admin_token.py index abffdc2c..3aba63d3 100644 --- a/keystoneauth1/loading/_plugins/admin_token.py +++ b/keystoneauth1/loading/_plugins/admin_token.py @@ -15,6 +15,17 @@ from keystoneauth1 import token_endpoint class AdminToken(loading.BaseLoader): + """Use an existing token and a known endpoint to perform requests. + + This plugin is primarily useful for development or for use with identity + service ADMIN tokens. Because this token is used directly there is no + fetching a service catalog or determining scope information and so it + cannot be used by clients that expect use this scope information. + + Because there is no service catalog the endpoint that is supplied with + initialization is used for all operations performed with this plugin so + must be the full base URL to an actual service. + """ @property def plugin_class(self): diff --git a/keystoneauth1/loading/_plugins/identity/generic.py b/keystoneauth1/loading/_plugins/identity/generic.py index ab9b547e..b6c139c7 100644 --- a/keystoneauth1/loading/_plugins/identity/generic.py +++ b/keystoneauth1/loading/_plugins/identity/generic.py @@ -15,6 +15,18 @@ from keystoneauth1 import loading class Token(loading.BaseGenericLoader): + """Given an existing token rescope it to another target. + + This plugin uses the Identity service's rescope mechanism to get a new + token based upon an existing token. Because an auth plugin requires a + service catalog and scope information it is often easier to fetch a new + token based on an existing one than validate and reuse the one you already + have. + + As a generic plugin this plugin is identity version independent and will + discover available versions before use. This means it expects to be + providen an unversioned URL to operate against. + """ @property def plugin_class(self): @@ -32,6 +44,15 @@ class Token(loading.BaseGenericLoader): class Password(loading.BaseGenericLoader): + """Authenticate via a username and password. + + Authenticate to the identity service using an inbuilt username and + password. This is the standard and most common form of authentication. + + As a generic plugin this plugin is identity version independent and will + discover available versions before use. This means it expects to be + providen an unversioned URL to operate against. + """ @property def plugin_class(self):