Closed rcarrillocruz closed 3 years ago
@sivel I would say this is close to yours but with an explicit implementation, I only see one way to do this (with many variations) and that is having a persistent mapping between module and action.
Currently we map on name (or prefix in case of network modules), this just prioritizes another module property. The most different alternative I see would be keeping a centralized mapping in core with all the info, but I think we all can agree that is not a better way.
The only things we might want to debate are precedence and location of the property.
I'm not opposed, I'm just linking for visibility
@bcoca @sivel @rcarrillocruz I would like to revive this proposal (and/or #55) for inclusion into Ansible 2.5 The current mechanism is insufficient and there is a need for more / better flexibility in determining which action plugin to use. Can we come to consensus on this proposal such that it can get committed to the 2.5 roadmap?
closing as mostly dupe of #55
Proposal: Module metadata driven action handler
Author: Ricardo Carrillo Cruz <@rcarrillocruz>
Date: 2017/May/30
Motivation
The task executor will run action plugin with same name as module, otherwise run 'normal' action handler.
Problems
We have modules that manage vendor specific resources, e.g. 'apt' for Debian based operating system packages and 'yum' for RedHat based operating system packages. This has the advantage that those modules can expose options that are specific to each vendor, and are not common to the generic package management. There is also the 'package' module, which abstracts package management and exposes features that are common to different vendor mechanisms. Checking the 'package' implementation we can see it is not a standalone module, but rather an action plugin that detects which OS is the target server via facts and based upon that invokes either 'apt' or 'yum' module. This pattern is very nice, because users can use 'package' for basic operations that are common on apt/yum, but they can also use 'apt' or 'yum' modules for vendor specific options.
However, it becomes unwieldy in other Ansible realms, like networking. For every networking vendor, there are (and will be) modules for all sorts of networking devices resources: system attributes, banners, l2 interfaces, l3 interfaces, vrfs, vlans, etc. If we wanted to create vendor agnostic modules for those, we would have an action plugin for each one of them, with a lot of duplicated code. Ideally, we could have just one action plugin that would check network device OS and kind of resource and invoke the relevant vendor specific module. This also has the bonus that a module developer can alter the action plugin to use on their modules, avoiding name clashing when their module has the same name as an already existing action plugin and better action plugin code re-use as explained in the networking example.
Solution proposal
Add a new field to metadata, called 'action_handler'. This will need a bump of the metadata version:
_taskexecutor checks the module metadata and, if applicable, uses the module defined action handler. The logic would look like:
Add a field to ActionBase called 'module_selectable', which defaults to False. The intent for this field is that action plugins that are meant to be selectable by modules metadata should have this field explicitly set to True, to avoid potential security implications of new modules selecting currently available action plugins.
Testing (optional)
Test new Ansible metadata version schema, along with task executor tests in the case a module specifies the action handler to use.
Documentation (optional)
Documentation on plugin and modules development for new options depicted on proposal.