Delegate _execute_method and access inventory in ActionModule

60 views
Skip to first unread message

Felix

unread,
Mar 6, 2023, 2:15:20 PM3/6/23
to Ansible Project
Hi all,

I am currently developing an Action-module which should do the following:

I have a playbook like this:
- hosts: target-host
  tasks:
     - my_module:
          src_host: source-host
          regex: some_regex

It should be checked if a file which meets the regex can be found on the source-host. If so, it should be copied to the target-host via the controller-node. I can't copy the file directly because of security-restrictions.

Currently I solved this by just using paramiko which works fine but isn't a clean solution.


Questions/What I want to do instead: 
1) I would like to access the inventory inside of my Action-Module to get ansible_user, ansible_password and ansible_port of the source-host and target-host. How can I achieve this? I tried to use the InventoryManager without success. Currently i provide all these values as parameters.

2) A far better solution would be, to use _execute_module and execute the find-module on the source-host and then copy the file via the copy-module to the controller-node and the target-host. But it seems there is no delegate-option for execute_module so (by looking at the play from above) it will always be executed on the target-host


Any help or pointing me into the right direction would be very much apricated. Couldn't find any suitable solution so far even after hours.

Thanks and best regads,
Felix

Atul Nasir

unread,
Aug 25, 2023, 1:55:00 AM8/25/23
to Ansible Project
# Import required modules
from ansible.plugins.action import ActionBase

class ActionModule(ActionBase):
    def run(self, tmp=None, task_vars=None):
        # Initialize variables
        result = super(ActionModule, self).run(tmp, task_vars)
        should_delegate = True  # Determine if delegation is needed

        # Access inventory variables
        source_host_vars = self._task_vars['hostvars'][self._task.args['src_host']]
        target_host_vars = self._task_vars['hostvars'][self._task.args['inventory_hostname']]

        # Prepare task_args for remote task execution
        task_args = {
            'module_name': 'find',
            'module_args': f"path={source_host_vars['source_path']} patterns={{ {self._task.args['regex']} }}",
            'inventory': self._task._inventory,
            'subset': [self._task.args['src_host']],
        }

        if should_delegate:
            # Remote execution
            result['remote_result'] = self._execute_module(task_args=task_args)
        else:
            # Local execution
            # Perform necessary local actions
            result['local_result'] = "Performed local actions"

        # Handle file transfers
        if should_delegate:
            # Execute remote copy task
            copy_task_args = {
                'module_name': 'copy',
                'module_args': f"src={result['remote_result']['files'][0]} dest=/destination/path",
                'inventory': self._task._inventory,
                'subset': [self._task.args['inventory_hostname']],
            }
            result['copy_result'] = self._execute_module(task_args=copy_task_args)

        return result
Reply all
Reply to author
Forward
0 new messages