Merge "cleaned up extension development docs"

This commit is contained in:
Jenkins
2014-02-07 22:12:29 +00:00
committed by Gerrit Code Review

View File

@@ -1,19 +1,30 @@
..
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 Extensions Development Guide Keystone Extensions Development Guide
===================================== =====================================
General General
------- =======
This Extension Development Guide provides some mocked code to use as an This Extension Development Guide provides some mocked code to use as an
Extension code base in the `keystone/contrib/example` folder. Extension code base in the ``keystone/contrib/example`` folder.
- All Extensions must be created in the ``keystone/contrib`` folder.
- All Extensions must be created in the `keystone/contrib` folder. - The new Extension code must be contained in a new folder under ``contrib``.
- The new Extension code must be contained in a new folder under `contrib`.
- Whenever possible an Extension should follow the following structure - Whenever possible an Extension should follow the following structure
convention: convention::
keystone keystone
\\\ contrib \\\ contrib
@@ -32,37 +43,38 @@ Extension code base in the `keystone/contrib/example` folder.
\\\ routers.py (mandatory for API Extension) \\\ routers.py (mandatory for API Extension)
- If the Extension implements an API Extension the ``controllers.py`` and
- If the Extension implements an API Extension the `controllers.py` and ``routers.py`` must be present and correctly handle the API Extension
`routers.py` must be present and correctly handle the API Extension requests requests and responses.
and responses. - If the Extension implements backends a ``backends`` folder should exist.
- If the Extension implements backends a `backends` folder should exist.
Backends are defined to store data persistently and can use a variety of Backends are defined to store data persistently and can use a variety of
technologies. Please see the Backends section in this document for more info. technologies. Please see the Backends section in this document for more info.
- If the Extension adds data structures a `migrate_repo` folder should exist. - If the Extension adds data structures, then a ``migrate_repo`` folder should
- If configuration changes are required/introduced in the `keystone.conf.sample` exist.
file, these should be kept disabled as default and have their own element. - If configuration changes are required/introduced in the
- If configuration changes are required/introduced in the `keystone-paste.ini`, ``keystone.conf.sample`` file, these should be kept disabled as default and
the new filter must be declared. have their own section.
- If configuration changes are required/introduced in the
``keystone-paste.ini``, the new filter must be declared.
- The module may register to listen to events by declaring the corresponding - The module may register to listen to events by declaring the corresponding
callbacks in the ``core.py`` file. callbacks in the ``core.py`` file.
- The new extension should be disabled by default (it should not affect the
default application pipelines).
`keystone.conf.sample` File Modifying the `keystone.conf.sample` File
--------------------------- =========================================
In the case an Extension needs to change the `keystone.conf.sample` file, it In the case an Extension needs to change the ``keystone.conf.sample`` file, it
must follow the config file conventions and introduce a dedicated entry. must follow the config file conventions and introduce a dedicated section.
Example:: Example::
[example] [example]
driver = keystone.contrib.example.backends.sql.mySQLClass driver = keystone.contrib.example.backends.sql.mySQLClass
[my_other_extension]
[myOtherExtension]
extension_flag = False extension_flag = False
The Extension parameters expressed should be commented out since, by default, The Extension parameters expressed should be commented out since, by default,
extensions are disabled. extensions are disabled.
@@ -71,23 +83,21 @@ Example::
[example] [example]
#driver = keystone.contrib.example.backends.sql.mySQLClass #driver = keystone.contrib.example.backends.sql.mySQLClass
[my_other_extension]
[myOtherExtension]
#extension_flag = False #extension_flag = False
In case the Extension is overriding or re-implementing an existing portion of In case the Extension is overriding or re-implementing an existing portion of
Keystone the required change should be commented in the `configuration.rst` but Keystone, the required change should be commented in the ``configuration.rst``
not placed in the `keystone.conf.sample` file to avoid unnecessary confusion. but not placed in the `keystone.conf.sample` file to avoid unnecessary
confusion.
Modifying the ``keystone-paste.ini`` File
=========================================
`keystone-paste.ini` File In the case an Extension is augmenting a pipeline introducing a new ``filter``
-------------------------- and/or APIs in the ``OS`` namespace, a corresponding ``filter:`` section is
necessary to be introduced in the ``keystone-paste.ini`` file. The Extension
In the case an Extension is augmenting a pipeline introducing a new `filter` should declare the filter factory constructor in the ``ini`` file.
and/or APIs in the `OS` namespace, a corresponding `filter:` section is
necessary to be introduced in the `keystone-paste.ini` file.
The Extension should declare the filter factory constructor in the `ini` file.
Example:: Example::
@@ -95,16 +105,15 @@ Example::
paste.filter_factory = keystone.contrib.example.routers:ExampleRouter. paste.filter_factory = keystone.contrib.example.routers:ExampleRouter.
factory factory
The `filter` must not be placed in the `pipeline` and treated as optional. The ``filter`` must not be placed in the ``pipeline`` and treated as optional.
How to add the extension in the pipeline should be specified in detail in the How to add the extension in the pipeline should be specified in detail in the
`configuration.rst` file. ``configuration.rst`` file.
Package Constructor File Package Constructor File
------------------------ ========================
The `__init__.py` file represents the package constructor. Extension needs to The ``__init__.py`` file represents the package constructor. Extension needs to
import what is necessary from the `core.py` module. import what is necessary from the ``core.py`` module.
Example: Example:
@@ -112,18 +121,18 @@ Example:
from keystone.contrib.example.core import * from keystone.contrib.example.core import *
Core Core
---- ====
The `core.py` file represents the main module defining the data structure and The ``core.py`` file represents the main module defining the data structure and
interface. In the `Model View Control` (MVC) model it represents the `Model` interface. In the ``Model View Control`` (MVC) model it represents the
part and it delegates to the `Backends` the data layer implementation. ``Model`` part and it delegates to the ``Backends`` the data layer
implementation.
In case the `core.py` file contains a `Manager` and a `Driver` it must provide
the dependency injections for the `Controllers` and/or other modules using the
`Manager`. A good practice is to call the dependency `extension_name_api`.
In case the ``core.py`` file contains a ``Manager`` and a ``Driver`` it must
provide the dependency injections for the ``Controllers`` and/or other modules
using the ``Manager``. A good practice is to call the dependency
``extension_name_api``.
Example: Example:
@@ -132,14 +141,12 @@ Example:
@dependency.provider('example_api') @dependency.provider('example_api')
class Manager(manager.Manager): class Manager(manager.Manager):
Routers Routers
------- =======
`routers.py` have the objective of routing the HTTP requests and direct them to
the right method within the `Controllers`. Extension routers are extending the
`wsgi.ExtensionRouter`.
``routers.py`` have the objective of routing the HTTP requests and direct them to
the correct method within the ``Controllers``. Extension routers are extending
the ``wsgi.ExtensionRouter``.
Example: Example:
@@ -159,18 +166,14 @@ Example:
controller=example_controller, controller=example_controller,
action='do_something', action='do_something',
conditions=dict(method=['GET'])) conditions=dict(method=['GET']))
...
Controllers Controllers
----------- ===========
`controllers.py` have the objective of handing requests and implement the ``controllers.py`` have the objective of handing requests and implement the
Extension logic. Controllers are consumers of 'Managers' API and must have all Extension logic. Controllers are consumers of 'Managers' API and must have all
the dependency injections required. `Controllers` are extending the the dependency injections required. ``Controllers`` are extending the
`V3Controller` class. ``V3Controller`` class.
Example: Example:
@@ -178,16 +181,14 @@ Example:
@dependency.requires('identity_api', 'example_api') @dependency.requires('identity_api', 'example_api')
class ExampleV3Controller(controller.V3Controller): class ExampleV3Controller(controller.V3Controller):
... pass
Backends Backends
-------- ========
The `backends` folder provides the model implementations for the different
backends supported by the Extension.
The folder structure must be the following:
The ``backends`` folder provides the model implementations for the different
backends supported by the Extension. The folder structure must be the
following::
keystone keystone
\\\ contrib \\\ contrib
@@ -199,16 +200,13 @@ The folder structure must be the following:
\\\ kvs.py (optional) \\\ kvs.py (optional)
If a SQL backend is provided, in the ``sql.py`` backend implementation it is
If a SQL backend is provided, in the `sql.py` backend implementation it is
mandatory to define the new table(s) that the Extension introduces and the mandatory to define the new table(s) that the Extension introduces and the
attributes they are composed of. attributes they are composed of.
For more information on backends, refer to the `Keystone Architecture
For more information on Backends please consult the Keystone Architecture <http://docs.openstack.org/developer/keystone/architecture.html>`_
documentation: documentation.
(http://docs.openstack.org/developer/keystone/architecture.html)
Example: Example:
@@ -224,38 +222,33 @@ Example:
nullable=False) nullable=False)
... ...
SQL Migration Repository
========================
In case the Extension is adding SQL data structures, these must be stored in
Migrate Repository separate tables and must not be included in the ``migrate_repo`` of the core
------------------ Keystone. Please refer to the ``migrate.cfg`` file to configure the Extension
In case the Extension is adding data structures, these must be stored in
separate tables and must not be included in the `migrate_repo` of the core
Keystone. Please refere to the 'migrate.cfg' file to configure the Extension
repository. repository.
In order to create the Extension tables and their attributes, a ``db_sync``
In order to create the Extension tables and its attributes, a db_sync command command must be executed.
must be executed.
Example:: Example::
./bin/keystone-manage db_sync --extension example ./bin/keystone-manage db_sync --extension example
Event Callbacks Event Callbacks
----------- ---------------
Extensions may provide callbacks to Keystone (Identity) events. Extensions may provide callbacks to Keystone (Identity) events.
Extensions must provide the list of events of interest and the corresponding Extensions must provide the list of events of interest and the corresponding
callbacks. Events are issued upon successful creation, modification, and callbacks. Events are issued upon successful creation, modification, and
deletion of the following Keystone resources: deletion of the following Keystone resources:
* ``group`` - ``group``
* ``project`` - ``project``
* ``role`` - ``role``
* ``user`` - ``user``
The extension's ``Manager`` class must contain the The extension's ``Manager`` class must contain the
``event_callbacks`` attribute. It is a dictionary listing as keys ``event_callbacks`` attribute. It is a dictionary listing as keys
@@ -299,20 +292,20 @@ Example:
A callback must accept the following parameters: A callback must accept the following parameters:
* ``service`` - the service information (e.g. identity) - ``service`` - the service information (e.g. identity)
* ``resource_type`` - the resource type (e.g. project) - ``resource_type`` - the resource type (e.g. project)
* ``operation`` - the operation (updated, created, deleted) - ``operation`` - the operation (updated, created, deleted)
* ``payload`` - the actual payload info of the resource that was acted on - ``payload`` - the actual payload info of the resource that was acted on
Current callback operations: Current callback operations:
* ``created`` - ``created``
* ``deleted`` - ``deleted``
* ``updated`` - ``updated``
Example: Example:
.. code:: python .. code:: python
def project_deleted_callback(self, service, resource_type, operation, def project_deleted_callback(self, service, resource_type, operation,
payload): payload):