Watcher Planner Selector

https://blueprints.launchpad.net/watcher/+spec/watcher-planner-selector

Watcher Planner takes the set of Actions generated by a Strategy and builds the design of a workflow which defines how-to schedule in time those different Actions and for each Action what are the prerequisite conditions. It is only possible to choose only one (default) Planner for all strategies now.

Custom Planners could be added to Watcher, thereby users can adapt Watcher workflow to their needs. As one of the ways for customization, the option could be added to set concrete Planner for specific Strategy that takes features of users’ workflow into account.

Problem description

Currently there is no opportunity to set unique Planner to specific Strategy. User can set default Planner in config file that would be used alongside every Audit.

If using different Planner is the case, user should change default value to desired one. By doing this we restrict ourselves to use this new Planner with all of the Strategies, what is not desired because some of Solutions generated by Strategies could be not compatible with the schedule made by this Planner.

Use Cases

  • As an Strategy developer, I want to choose what Planner would be applied to the Solution generated by my Strategy.

  • As an Strategy developer, I expect that if I provide no Planner to my Strategy, it will use default Planner that is set in base Strategy..

Proposed change

We propose to add property to base Strategy class, say ‘planner’, and set default value to this option in concrete Strategies where appropriate (for example, ‘workload_stabilization’ Planner as default for Strategy with the same name).

Planner should be load in AuditHandler. Currently it’s done with the help of PlannerManager, that loads sole planner for every Strategy which set by CONF.watcher_planner.planner value. Definitely, PlannerManager do only loading job, so it’s better to load Planner without this intermediate layer. Thus we propose to exchange AuditHandler._planner_manager with DefaultPlannerLoader. As a result, PlannerManager could be removed from Watcher.

Therefore, AuditHandler now should pass desired Planner name to Loader. We propose to get this name from property of the Strategy used in current Audit. In this case we ought to get Strategy object associated with current Audit.

For this propose, we need to be able to get Strategy prior to AuditHandler._planner_loader.load() method call. It could be be done with the help of StrategyContext class that loads Strategy based on names of Goal and Audit. The problem is that this loading is done during do_execute_strategy() what’s a bad design. We propose to move selecting of strategy to distinct method, say ‘select_strategy’:

def select_strategy(audit, request_context):
    osc = clients.OpenStackClients()
    goal = objects.Goal.get_by_id(request_context, audit.goal_id)

    strategy_name = None
    if audit.strategy_id:
        strategy = objects.Strategy.get_by_id(
            request_context, audit.strategy_id)
        strategy_name = strategy.name

    strategy_selector = default.DefaultStrategySelector(
        goal_name=goal.name,
        strategy_name=strategy_name,
        osc=osc)
    return strategy_selector.select()

Now we could call this method not only in do_execute_strategy() to pick strategy only for execution, but also call it in AuditHandler.

Another benefit to do it in this manner is that if Audit was created without specified Strategy, StrategyContext will take care to retrieve default Strategy for this Goal.

By design, whole AuditHandler class passes current Audit as an argument of many of its methods. It would be convenient to have current Audit as a field of AuditHandler class. Also, it is good design decision, because it’s true OOP paradigm. To sum up, we propose to remove all these arguments and replace them with class field.

As a result, we can get Planner for current Strategy without adding new argument to AuditHandler.planner() or storing name of Strategy in additional field.

Alternatives

Alternatively, we could pass Planner name as argument during creation of AuditTemplate.

As an alternative to changing signatures of AuditHandler methods we could add a new field only for Strategy name.

Data model impact

None

REST API impact

None

Security impact

None

Notifications impact

None

Other end user impact

None

Performance Impact

None

Other deployer impact

None

Developer impact

Signature of PlannerManager.load() method changes. AuditHandler methods change their signatures, ‘audit’ argument would be replaced with same class field.

Implementation

Assignee(s)

Primary assignee:

Egor Panfilov <erakli>

Work Items

  • Refactor DefaultStrategyContext.do_execute_strategy() and add select_strategy() method

  • Add ‘planner’ property to BaseStrategy

  • Replace PlannerManager with PlannerLoader in AuditHandler

  • Rewrite AuditHandler methods so that ‘audit’ argument would be replaced with class’ field

Dependencies

https://blueprints.launchpad.net/watcher/+spec/planner-storage-action-plan

Testing

Tests with different Planners assigned to different Strategies should be implemented.

Documentation Impact

Documentation should be updated to explain how to set ‘planner’ option.

References

None

History

None