diff options
6 files changed, 35 insertions, 14 deletions
diff --git a/changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml b/changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml new file mode 100644 index 0000000000..ea77b48dde --- /dev/null +++ b/changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml @@ -0,0 +1,2 @@ +bugfixes: + - ssh - connection options were incorrectly templated during ``reset_connection`` tasks (https://github.com/ansible/ansible/pull/84238). diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index ff1c33871f..77fae99af3 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1073,18 +1073,6 @@ class TaskExecutor: option_vars = C.config.get_plugin_vars('connection', self._connection._load_name) varnames.extend(option_vars) - # create dict of 'templated vars' - options = {'_extras': {}} - for k in option_vars: - if k in variables: - options[k] = templar.template(variables[k]) - - # add extras if plugin supports them - if getattr(self._connection, 'allow_extras', False): - for k in variables: - if k.startswith('ansible_%s_' % self._connection.extras_prefix) and k not in options: - options['_extras'][k] = templar.template(variables[k]) - task_keys = self._task.dump_attrs() # The task_keys 'timeout' attr is the task's timeout, not the connection timeout. @@ -1102,7 +1090,8 @@ class TaskExecutor: del task_keys['retries'] # set options with 'templated vars' specific to this plugin and dependent ones - self._connection.set_options(task_keys=task_keys, var_options=options) + var_options = self._connection._resolve_option_variables(variables, templar) + self._connection.set_options(task_keys=task_keys, var_options=var_options) varnames.extend(self._set_plugin_options('shell', variables, templar, task_keys)) if self._connection.become is not None: diff --git a/lib/ansible/plugins/connection/__init__.py b/lib/ansible/plugins/connection/__init__.py index de4a79e981..3743d3601e 100644 --- a/lib/ansible/plugins/connection/__init__.py +++ b/lib/ansible/plugins/connection/__init__.py @@ -285,6 +285,27 @@ class ConnectionBase(AnsiblePlugin): display.debug('Set connection var {0} to {1}'.format(varname, value)) variables[varname] = value + def _resolve_option_variables(self, variables, templar): + """ + Return a dict of variable -> templated value, for any variables that + that match options registered by this plugin. + """ + # create dict of 'templated vars' + var_options = { + '_extras': {}, + } + for var_name in C.config.get_plugin_vars('connection', self._load_name): + if var_name in variables: + var_options[var_name] = templar.template(variables[var_name]) + + # add extras if plugin supports them + if getattr(self, 'allow_extras', False): + for var_name in variables: + if var_name.startswith(f'ansible_{self.extras_prefix}_') and var_name not in var_options: + var_options['_extras'][var_name] = templar.template(variables[var_name]) + + return var_options + class NetworkConnectionBase(ConnectionBase): """ diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index 3eb5538b96..c9fdfeeb22 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -1068,7 +1068,8 @@ class StrategyBase: del self._active_connections[target_host] else: connection = plugin_loader.connection_loader.get(play_context.connection, play_context, os.devnull) - connection.set_options(task_keys=task.dump_attrs(), var_options=all_vars) + var_options = connection._resolve_option_variables(all_vars, templar) + connection.set_options(task_keys=task.dump_attrs(), var_options=var_options) play_context.set_attributes_from_plugin(connection) if connection: diff --git a/test/integration/targets/connection/test.sh b/test/integration/targets/connection/test.sh index 6e16a87ea7..c376e28a0a 100755 --- a/test/integration/targets/connection/test.sh +++ b/test/integration/targets/connection/test.sh @@ -20,3 +20,4 @@ else fi ansible-playbook test_reset_connection.yml -i "${INVENTORY}" "$@" +ansible-playbook test_reset_connection_templated.yml -i "${INVENTORY}" "$@" diff --git a/test/integration/targets/connection/test_reset_connection_templated.yml b/test/integration/targets/connection/test_reset_connection_templated.yml new file mode 100644 index 0000000000..de36ca17ae --- /dev/null +++ b/test/integration/targets/connection/test_reset_connection_templated.yml @@ -0,0 +1,7 @@ +- hosts: "{{ target_hosts }}" + gather_facts: false + vars: + ansible_ssh_executable: "{{ 'ssh' | trim }}" + tasks: + # https://github.com/ansible/ansible/issues/84238 + - meta: reset_connection |