From fe9696be525d4ef3177decda6919206492977582 Mon Sep 17 00:00:00 2001 From: Rick Elrod Date: Fri, 22 May 2020 08:34:26 -0500 Subject: [PATCH] Fix `ansible -K` become_pass regression (#69629) * Fix `ansible -K` become_pass regression Change: - This fixes a breaking change introduced in 2165f9ac40cf212891b11a75bd9b9b2f4f0b8dc3 Test Plan: - Local VM for now, with plans to add an integration test for -K going forward. Tickets: Refs #69244 --- lib/ansible/executor/task_executor.py | 11 ++++-- test/integration/targets/cli/aliases | 3 ++ test/integration/targets/cli/setup.yml | 40 +++++++++++++++++++- test/integration/targets/cli/test_k_and_K.py | 27 +++++++++++++ 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 test/integration/targets/cli/test_k_and_K.py diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 589b1a5964d..3a5c98dd582 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1010,16 +1010,19 @@ class TaskExecutor: task_keys = self._task.dump_attrs() - # set options with 'templated vars' specific to this plugin and dependant ones + # set options with 'templated vars' specific to this plugin and dependent ones self._connection.set_options(task_keys=task_keys, var_options=options) varnames.extend(self._set_plugin_options('shell', variables, templar, task_keys)) if self._connection.become is not None: + if self._play_context.become_pass: + # FIXME: eventually remove from task and play_context, here for backwards compat + # keep out of play objects to avoid accidental disclosure, only become plugin should have + # The become pass is already in the play_context if given on + # the CLI (-K). Make the plugin aware of it in this case. + task_keys['become_pass'] = self._play_context.become_pass varnames.extend(self._set_plugin_options('become', variables, templar, task_keys)) - # FIXME: eventually remove from task and play_context, here for backwards compat - # keep out of play objects to avoid accidental disclosure, only become plugin should have - task_keys['become_pass'] = self._connection.become.get_option('become_pass') # FOR BACKWARDS COMPAT: for option in ('become_user', 'become_flags', 'become_exe', 'become_pass'): diff --git a/test/integration/targets/cli/aliases b/test/integration/targets/cli/aliases index 6b71e884a14..a8816e110de 100644 --- a/test/integration/targets/cli/aliases +++ b/test/integration/targets/cli/aliases @@ -1,2 +1,5 @@ +destructive +needs/root +needs/ssh needs/target/setup_pexpect shippable/posix/group3 diff --git a/test/integration/targets/cli/setup.yml b/test/integration/targets/cli/setup.yml index 9f6ab117412..901cfd14c06 100644 --- a/test/integration/targets/cli/setup.yml +++ b/test/integration/targets/cli/setup.yml @@ -1,4 +1,42 @@ - hosts: localhost - gather_facts: no + gather_facts: yes roles: - setup_pexpect + + tasks: + - name: Test ansible-playbook and ansible with -K + block: + - name: Create user to connect as + user: + name: cliuser1 + shell: /bin/bash + groups: wheel + append: yes + password: "{{ 'secretpassword' | password_hash('sha512', 'mysecretsalt') }}" + - name: Create user to become + user: + name: cliuser2 + shell: /bin/bash + password: "{{ 'secretpassword' | password_hash('sha512', 'mysecretsalt') }}" + # Sometimes this file doesn't get removed, and we need it gone to ssh + - name: Remove /run/nologin + file: + path: /run/nologin + state: absent + # Make Ansible run Python to run Ansible + - name: Run the test + shell: python test_k_and_K.py {{ ansible_python_interpreter }} + always: + - name: Remove users + user: + name: "{{ item }}" + state: absent + with_items: + - cliuser1 + - cliuser2 + # For now, we don't test this everywhere, because `user` works differently + # on some platforms, as does sudo/sudoers. On Fedora, we can just add + # the user to 'wheel' and things magically work. + # TODO: In theory, we should test this with all the different 'become' + # plugins in base. + when: ansible_distribution == 'Fedora' diff --git a/test/integration/targets/cli/test_k_and_K.py b/test/integration/targets/cli/test_k_and_K.py new file mode 100644 index 00000000000..f7077fba0ab --- /dev/null +++ b/test/integration/targets/cli/test_k_and_K.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import sys + +import pexpect + +os.environ['ANSIBLE_NOCOLOR'] = '1' + +out = pexpect.run( + 'ansible -c ssh -i localhost, -u cliuser1 -e ansible_python_interpreter={0} ' + '-m command -a whoami -Kkb --become-user cliuser2 localhost'.format(sys.argv[1]), + events={ + 'SSH password:': 'secretpassword\n', + 'BECOME password': 'secretpassword\n', + }, + timeout=10 +) + +print(out) + +assert b'cliuser2' in out