issue #340: use expanded delegate_to hostname, not template.

PlayContext.delegate_to is the unexpanded template, Ansible doesn't keep
a copy of it around anywhere convenient. We either need to re-expand it
or take the expanded version that was stored on the Task, which is what
is done here.
pull/350/head
David Wilson 7 years ago
parent 154dc2e119
commit 3d588323ff

@ -448,7 +448,9 @@ class Connection(ansible.plugins.connection.ConnectionBase):
#: Set to 'hostvars' by on_action_run() #: Set to 'hostvars' by on_action_run()
host_vars = None host_vars = None
#: Set to '_loader.get_basedir()' by on_action_run(). #: Set to '_loader.get_basedir()' by on_action_run(). Used by mitogen_local
#: to change the working directory to that of the current playbook,
#: matching vanilla Ansible behaviour.
loader_basedir = None loader_basedir = None
#: Set after connection to the target context's home directory. #: Set after connection to the target context's home directory.
@ -470,11 +472,20 @@ class Connection(ansible.plugins.connection.ConnectionBase):
# https://github.com/dw/mitogen/issues/140 # https://github.com/dw/mitogen/issues/140
self.close() self.close()
def on_action_run(self, task_vars, loader_basedir): def on_action_run(self, task_vars, delegate_to_hostname, loader_basedir):
""" """
Invoked by ActionModuleMixin to indicate a new task is about to start Invoked by ActionModuleMixin to indicate a new task is about to start
executing. We use the opportunity to grab relevant bits from the executing. We use the opportunity to grab relevant bits from the
task-specific data. task-specific data.
:param dict task_vars:
Task variable dictionary.
:param str delegate_to_hostname:
:data:`None`, or the template-expanded inventory hostname this task
is being delegated to. A similar variable exists on PlayContext
when ``delegate_to:`` is active, however it is unexpanded.
:param str loader_basedir:
Loader base directory; see :attr:`loader_basedir`.
""" """
self.ansible_ssh_timeout = task_vars.get('ansible_ssh_timeout', self.ansible_ssh_timeout = task_vars.get('ansible_ssh_timeout',
C.DEFAULT_TIMEOUT) C.DEFAULT_TIMEOUT)
@ -488,6 +499,7 @@ class Connection(ansible.plugins.connection.ConnectionBase):
self.mitogen_ssh_debug_level = task_vars.get('mitogen_ssh_debug_level') self.mitogen_ssh_debug_level = task_vars.get('mitogen_ssh_debug_level')
self.inventory_hostname = task_vars['inventory_hostname'] self.inventory_hostname = task_vars['inventory_hostname']
self.host_vars = task_vars['hostvars'] self.host_vars = task_vars['hostvars']
self.delegate_to_hostname = delegate_to_hostname
self.loader_basedir = loader_basedir self.loader_basedir = loader_basedir
self.close(new_task=True) self.close(new_task=True)
@ -563,29 +575,38 @@ class Connection(ansible.plugins.connection.ConnectionBase):
broker=self.broker, broker=self.broker,
) )
def _build_stack(self): def _config_from_direct_connection(self):
""" """
Construct a list of dictionaries representing the connection
configuration between the controller and the target. This is
additionally used by the integration tests "mitogen_get_stack" action
to fetch the would-be connection configuration.
""" """
if hasattr(self._play_context, 'delegate_to'): return config_from_play_context(
target_config = config_from_hostvars( transport=self.transport,
inventory_name=self.inventory_hostname,
connection=self
)
def _config_from_delegate_to(self):
return config_from_hostvars(
transport=self._play_context.connection, transport=self._play_context.connection,
inventory_name=self._play_context.delegate_to, inventory_name=self.delegate_to_hostname,
connection=self, connection=self,
hostvars=self.host_vars[self._play_context.delegate_to], hostvars=self.host_vars[self._play_context.delegate_to],
become_user=(self._play_context.become_user become_user=(self._play_context.become_user
if self._play_context.become if self._play_context.become
else None), else None),
) )
def _build_stack(self):
"""
Construct a list of dictionaries representing the connection
configuration between the controller and the target. This is
additionally used by the integration tests "mitogen_get_stack" action
to fetch the would-be connection configuration.
"""
if self.delegate_to_hostname is not None:
target_config = self._config_from_delegate_to()
else: else:
target_config = config_from_play_context( target_config = self._config_from_direct_connection()
transport=self.transport,
inventory_name=self.inventory_hostname,
connection=self
)
stack, _ = self._stack_from_config(target_config) stack, _ = self._stack_from_config(target_config)
return stack return stack

@ -110,6 +110,7 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
""" """
self._connection.on_action_run( self._connection.on_action_run(
task_vars=task_vars, task_vars=task_vars,
delegate_to_hostname=self._task.delegate_to,
loader_basedir=self._loader.get_basedir(), loader_basedir=self._loader.get_basedir(),
) )
return super(ActionModuleMixin, self).run(tmp, task_vars) return super(ActionModuleMixin, self).run(tmp, task_vars)

@ -1,2 +1,2 @@
- import_playbook: delegate_to_template.yml
- import_playbook: stack_construction.yml - import_playbook: stack_construction.yml

@ -0,0 +1,41 @@
# Ensure templated delegate_to field works.
- name: integration/delegation/delegate_to_template.yml
vars:
physical_host: "cd-normal-alias"
physical_hosts: ["cd-normal-alias", "cd-normal-normal"]
hosts: test-targets
gather_facts: no
any_errors_fatal: true
tasks:
- mitogen_get_stack:
delegate_to: "{{ physical_host }}"
register: out
- assert:
that: |
out.result == [
{
'kwargs': {
'check_host_keys': 'ignore',
'connect_timeout': 10,
'hostname': 'cd-normal-alias',
'identity_file': None,
'password': None,
'port': None,
'python_path': None,
'ssh_args': [
'-o',
'ForwardAgent=yes',
'-o',
'ControlMaster=auto',
'-o',
'ControlPersist=60s',
],
'ssh_debug_level': None,
'ssh_path': 'ssh',
'username': None,
},
'method': 'ssh',
},
]
Loading…
Cancel
Save