This patch is proposed according to the Direction 10 of doc migration(https://etherpad.openstack.org/p/doc-migration-tracking). Change-Id: I4eb594115e350e28f9136f7003692a1ec0abfcf6
6.0 KiB
Build a new planner
Watcher Decision Engine <watcher_decision_engine_definition>
has an external planner <watcher_planner_definition> plugin
interface which gives anyone the ability to integrate an external planner
<watcher_planner_definition> in order to extend the initial
set of planners Watcher provides.
This section gives some guidelines on how to implement and integrate custom planners with Watcher.
Creating a new plugin
First of all you have to extend the base :py~.BasePlanner class which
defines an abstract method that you will have to implement. The :py~.BasePlanner.schedule is
the method being called by the Decision Engine to schedule a given
solution (:py~.BaseSolution) into an action plan <action_plan_definition> by
ordering/sequencing an unordered set of actions contained in the
proposed solution (for more details, see definition of a solution <solution_definition>).
Here is an example showing how you can write a planner plugin called
DummyPlanner:
# Filepath = third-party/third_party/dummy.py
# Import path = third_party.dummy
from oslo_utils import uuidutils
from watcher.decision_engine.planner import base
class DummyPlanner(base.BasePlanner):
def _create_action_plan(self, context, audit_id):
action_plan_dict = {
'uuid': uuidutils.generate_uuid(),
'audit_id': audit_id,
'first_action_id': None,
'state': objects.action_plan.State.RECOMMENDED
}
new_action_plan = objects.ActionPlan(context, **action_plan_dict)
new_action_plan.create(context)
new_action_plan.save()
return new_action_plan
def schedule(self, context, audit_id, solution):
# Empty action plan
action_plan = self._create_action_plan(context, audit_id)
# todo: You need to create the workflow of actions here
# and attach it to the action plan
return action_planThis implementation is the most basic one. So if you want to have
more advanced examples, have a look at the implementation of planners
already provided by Watcher like :py~.DefaultPlanner. A list with all available planner
plugins can be found here <watcher_planners>.
Define configuration parameters
At this point, you have a fully functional planner. However, in more
complex implementation, you may want to define some configuration
options so one can tune the planner to its needs. To do so, you can
implement the :py~.Loadable.get_config_opts class method as
followed:
from oslo_config import cfg
class DummyPlanner(base.BasePlanner):
# [...]
def schedule(self, context, audit_uuid, solution):
assert self.config.test_opt == 0
# [...]
@classmethod
def get_config_opts(cls):
return super(
DummyPlanner, cls).get_config_opts() + [
cfg.StrOpt('test_opt', help="Demo Option.", default=0),
# Some more options ...
]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 configuration would have to be modified as
followed:
[watcher_planners.dummy]
# Option used for testing.
test_opt = test_valueThen, the configuration options you define within this method will
then be injected in each instantiated object via the config
parameter of the :py~.BasePlanner.__init__ method.
Abstract Plugin Class
Here below is the abstract BasePlanner class that every
single planner should implement:
watcher.decision_engine.planner.base.BasePlanner
Register a new entry point
In order for the Watcher Decision Engine to load your new planner,
the latter must be registered as a new entry point under the
watcher_planners 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.
Here below is how you would proceed to register
DummyPlanner using pbr:
[entry_points]
watcher_planners =
dummy = third_party.dummy:DummyPlannerUsing planner plugins
The Watcher Decision Engine <watcher_decision_engine_definition>
service will automatically discover any installed plugins when it is
started. This means that if Watcher is already running when you install
your plugin, you will have to restart the related Watcher services. If a
Python package containing a custom plugin is installed within the same
environment as Watcher, Watcher will automatically make that plugin
available for use.
At this point, Watcher will use your new planner if you referenced it
in the planner option under the
[watcher_planner] section of your watcher.conf
configuration file when you started it. For example, if you want to use
the dummy planner you just installed, you would have to
select it as followed:
[watcher_planner]
planner = dummyAs you may have noticed, only a single planner implementation can be activated at a time, so make sure it is generic enough to support all your strategies and actions.