diff --git a/doc/source/dev/plugin/cdmc-plugin.rst b/doc/source/dev/plugin/cdmc-plugin.rst index 2a5e4e505..e04286ecb 100644 --- a/doc/source/dev/plugin/cdmc-plugin.rst +++ b/doc/source/dev/plugin/cdmc-plugin.rst @@ -10,10 +10,10 @@ Build a new cluster data model collector ======================================== -Watcher Decision Engine has an external cluster data model plugin interface -which gives anyone the ability to integrate an external cluster data model -collector in order to extend the initial set of cluster data model collectors -Watcher provides. +Watcher Decision Engine has an external cluster data model (CDM) plugin +interface which gives anyone the ability to integrate an external cluster data +model collector (CDMC) in order to extend the initial set of cluster data model +collectors Watcher provides. This section gives some guidelines on how to implement and integrate custom cluster data model collectors within Watcher. @@ -22,6 +22,17 @@ cluster data model collectors within Watcher. Creating a new plugin ===================== +In order to create a new model, you have to: + +- Extend the :py:class:`~.base.BaseClusterDataModelCollector` class. +- Implement its :py:meth:`~.BaseClusterDataModelCollector.execute` abstract + method to return your entire cluster data model that this method should + build. +- Implement its :py:meth:`~.Goal.notification_endpoints` abstract property to + return the list of all the :py:class:`~.base.NotificationEndpoint` instances + that will be responsible for handling incoming notifications in order to + incrementally update your cluster data model. + First of all, you have to extend the :class:`~.BaseClusterDataModelCollector` base class which defines the :py:meth:`~.BaseClusterDataModelCollector.execute` abstract method you will have to implement. This method is responsible for @@ -46,6 +57,10 @@ Here is an example showing how you can write a plugin called # Do something here... return model + @property + def notification_endpoints(self): + return [] + This implementation is the most basic one. So in order to get a better understanding on how to implement a more advanced cluster data model collector, have a look at the :py:class:`~.NovaClusterDataModelCollector` class. @@ -54,12 +69,12 @@ Define configuration parameters =============================== At this point, you have a fully functional cluster data model collector. -By default, cluster data model collectors define an ``period`` option (see +By default, cluster data model collectors define a ``period`` option (see :py:meth:`~.BaseClusterDataModelCollector.get_config_opts`) that corresponds to the interval of time between each synchronization of the in-memory model. However, in more complex implementation, you may want to define some -configuration options so one can tune the cluster data model collector to its +configuration options so one can tune the cluster data model collector to your needs. To do so, you can implement the :py:meth:`~.Loadable.get_config_opts` class method as followed: @@ -77,6 +92,10 @@ class method as followed: # Do something here... return model + @property + def notification_endpoints(self): + return [] + @classmethod def get_config_opts(cls): return super( @@ -87,7 +106,9 @@ class method as followed: The configuration options defined within this class method will be included within the global ``watcher.conf`` configuration file under a section named by -convention: ``{namespace}.{plugin_name}``. In our case, the ``watcher.conf`` +convention: ``{namespace}.{plugin_name}`` (see section :ref:`Register a new +entry point `). The namespace for CDMC plugins is +``watcher_cluster_data_model_collectors``, so in our case, the ``watcher.conf`` configuration would have to be modified as followed: .. code-block:: ini @@ -113,14 +134,16 @@ single cluster data model collector should implement: :noindex: +.. _register_new_cdmc_entrypoint: + Register a new entry point ========================== -In order for the Watcher Applier to load your new cluster data model collector, -the cluster data model collector must be registered as a named entry point -under the ``decision_engine.model.collector`` entry point of your ``setup.py`` -file. If you are using pbr_, this entry point should be placed in your -``setup.cfg`` file. +In order for the Watcher Decision Engine to load your new cluster data model +collector, the latter must be registered as a named entry point under the +``watcher_cluster_data_model_collectors`` entry point namespace of your +``setup.py`` file. If you are using pbr_, this entry point should be placed in +your ``setup.cfg`` file. The name you give to your entry point has to be unique. @@ -135,6 +158,56 @@ Here below is how to register ``DummyClusterDataModelCollector`` using pbr_: .. _pbr: http://docs.openstack.org/developer/pbr/ +Add new notification endpoints +============================== + +At this point, you have a fully functional cluster data model collector. +However, this CDMC is only refreshed periodically via a background scheduler. +As you may sometimes execute a strategy with a stale CDM due to a high activity +on your infrastructure, you can define some notification endpoints that will be +responsible for incrementally updating the CDM based on notifications emitted +by other services such as Nova. To do so, you can implement and register a new +``DummyEndpoint`` notification endpoint regarding a ``dummy`` event as shown +below: + +.. code-block:: python + + from watcher.decision_engine.model import model_root + from watcher.decision_engine.model.collector import base + + + class DummyNotification(base.NotificationEndpoint): + + @property + def filter_rule(self): + return filtering.NotificationFilter( + publisher_id=r'.*', + event_type=r'^dummy$', + ) + + def info(self, ctxt, publisher_id, event_type, payload, metadata): + # Do some CDM modifications here... + pass + + + class DummyClusterDataModelCollector(base.BaseClusterDataModelCollector): + + def execute(self): + model = model_root.ModelRoot() + # Do something here... + return model + + @property + def notification_endpoints(self): + return [DummyNotification(self)] + + +Note that if the event you are trying to listen to is published by a new +service, you may have to also add a new topic Watcher will have to subscribe to +in the ``notification_topics`` option of the ``[watcher_decision_engine]`` +section. + + Using cluster data model collector plugins ==========================================