ansible / proposals

Repository for sharing and tracking progress on enhancement proposals for Ansible.
Creative Commons Zero v1.0 Universal
93 stars 19 forks source link

Module metadata driven action handler #64

Closed rcarrillocruz closed 3 years ago

rcarrillocruz commented 7 years ago

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:

ANSIBLE_METADATA = {'metadata_version': '1.2',
                    'status': ['preview'],
                    'supported_by': 'core',
                    'action_handler': 'new_handler'}

_taskexecutor checks the module metadata and, if applicable, uses the module defined action handler. The logic would look like:

  1. If module metadata has 'action_handler' defined, use it
  2. If there's action plugin with same name as module, use it
  3. If module prefix is in network modules groups list, use prefix action plugin
  4. If none the above, use normal action handler

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.

sivel commented 7 years ago

See also: https://github.com/ansible/proposals/issues/55

bcoca commented 7 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.

sivel commented 7 years ago

I'm not opposed, I'm just linking for visibility

privateip commented 6 years ago

@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?

bcoca commented 3 years ago

closing as mostly dupe of #55