Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Become options exploration #1160

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ansible_mitogen/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ def _connect_stack(self, stack):

self.context = dct['context']
self.chain = CallChain(self, self.context, pipelined=True)
if self._play_context.become:
if self.become:
self.login_context = dct['via']
else:
self.login_context = self.context
Expand Down Expand Up @@ -926,7 +926,7 @@ def reset(self):
self.close()

inventory_name, stack = self._build_stack()
if self._play_context.become:
if self.become:
stack = stack[:-1]

worker_model = ansible_mitogen.process.get_worker_model()
Expand Down
2 changes: 1 addition & 1 deletion ansible_mitogen/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def _remote_expand_user(self, path, sudoable=True):
if not path.startswith('~'):
# /home/foo -> /home/foo
return path
if sudoable or not self._play_context.become:
if sudoable or not self._connection.become:
if path == '~':
# ~ -> /home/dmw
return self._connection.homedir
Expand Down
37 changes: 34 additions & 3 deletions ansible_mitogen/transport_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,42 @@ def __init__(self, connection, play_context, transport, inventory_name):
# used to run interpreter discovery
self._action = connection._action

def _become_option(self, name):
plugin = self._connection.become
return plugin.get_option(name, self._task_vars, self._play_context)
try:
if name not in plugin._options:
value, _ = plugin.get_option_and_origin(
name, hostvars=self._task_vars,
#playcontext=self._play_context,
)
plugin.set_option(name, value)
return plugin._options.get(name)
except AttributeError as exc:
raise
LOG.error('become plugin=%r: %s', plugin, exc)
except KeyError:
raise
if name not in {'become_user', 'become_pass', 'become_flags', 'become_exe'}:
raise
LOG.error(
'Used PlayContext fallback for become plugin=%r, option=%r, connection=%r, transport=%r, action=%r',
plugin, name, self._connection, self._transport, self._action,
)
try:
return getattr(self._play_context, name)
except AttributeError:
LOG.error('PlayContext did not have attribute %r', name)
return None

def _connection_option(self, name):
try:
return self._connection.get_option(name, hostvars=self._task_vars)
except KeyError:
LOG.debug('Used PlayContext fallback for option=%r', name)
LOG.error(
'Used PlayContext fallback for connection plugin=%r, option=%r',
self._connection, name,
)
return getattr(self._play_context, name)

def transport(self):
Expand All @@ -437,13 +468,13 @@ def remote_user(self):
return self._connection_option('remote_user')

def become(self):
return self._play_context.become
return self._connection.become

def become_method(self):
return self._play_context.become_method

def become_user(self):
return self._play_context.become_user
return self._become_option('become_user')

def become_pass(self):
# become_pass is owned/provided by the active become plugin. However
Expand Down
14 changes: 14 additions & 0 deletions tests/ansible/hosts/default.hosts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ tt-bare
[tt_targets_bare:vars]
ansible_host=localhost

[tt_become_bare]
tt-become-bare

[tt_become_bare:vars]
ansible_host=localhost
ansible_user="{{ lookup('pipe', 'whoami') }}"

[tt_become_by_inv]
tt-become-user ansible_become=true ansible_become_user="{{ 'root' | trim }}"

[tt_become_by_inv:vars]
ansible_host=localhost
ansible_user="{{ lookup('pipe', 'whoami') }}"

[tt_targets_inventory]
tt-password ansible_password="{{ 'has_sudo_nopw_password' | trim }}" ansible_user=mitogen__has_sudo_nopw
tt-port ansible_password=has_sudo_nopw_password ansible_port="{{ 22 | int }}" ansible_user=mitogen__has_sudo_nopw
Expand Down
4 changes: 4 additions & 0 deletions tests/ansible/integration/become/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
- import_playbook: sudo_nopassword.yml
- import_playbook: sudo_password.yml
- import_playbook: sudo_requiretty.yml
- import_playbook: templated_by_inv.yml
- import_playbook: templated_by_play_keywords.yml
- import_playbook: templated_by_play_vars.yml
- import_playbook: templated_by_task_keywords.yml
14 changes: 14 additions & 0 deletions tests/ansible/integration/become/templated_by_inv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- name: integration/become/templated_by_inv.yml
hosts: tt_become_by_inv
gather_facts: false
tasks:
- meta: reset_connection
- name: Templated become in inventory
command:
cmd: whoami
changed_when: false
check_mode: false
register: become_templated_by_inv_whoami
failed_when:
- become_templated_by_inv_whoami is failed
or become_templated_by_inv_whoami.stdout != 'root'
16 changes: 16 additions & 0 deletions tests/ansible/integration/become/templated_by_play_keywords.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- name: integration/become/templated_by_play_keywords.yml
hosts: tt_become_bare
gather_facts: false
become: true
become_user: "{{ 'root' | trim }}"
tasks:
- meta: reset_connection
- name: Templated become by play keywords
command:
cmd: whoami
changed_when: false
check_mode: false
register: become_templated_by_play_keywords_whoami
failed_when:
- become_templated_by_play_keywords_whoami is failed
or become_templated_by_play_keywords_whoami.stdout != 'root'
16 changes: 16 additions & 0 deletions tests/ansible/integration/become/templated_by_play_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- name: integration/become/templated_by_play_vars.yml
hosts: tt_become_bare
gather_facts: false
vars:
ansible_become: true
ansible_become_user: "{{ 'root' | trim }}"
tasks:
- name: Templated become by play vars
command:
cmd: whoami
changed_when: false
check_mode: false
register: become_templated_by_play_vars_whoami
failed_when:
- become_templated_by_play_vars_whoami is failed
or become_templated_by_play_vars_whoami.stdout != 'root'
27 changes: 27 additions & 0 deletions tests/ansible/integration/become/templated_by_task_keywords.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
- name: integration/become/templated_by_task_keywords.yml
hosts: tt_become_bare
gather_facts: false
# FIXME Resetting the connection shouldn't require credentials
# https://github.com/mitogen-hq/mitogen/issues/1132
become: true
become_user: "{{ 'root' | trim }}"
tasks:
- name: Reset connection to target that will be delegate_to
meta: reset_connection

- name: Test connection template by task keywords, with delegate_to
hosts: test-targets[0]
gather_facts: false
tasks:
- name: Templated become by task keywords, with delegate_to
become: true
become_user: "{{ 'root' | trim }}"
delegate_to: "{{ groups.tt_become_bare[0] }}"
command:
cmd: whoami
changed_when: false
check_mode: false
register: become_templated_by_task_with_delegate_to_whoami
failed_when:
- become_templated_by_task_with_delegate_to_whoami is failed
or become_templated_by_task_with_delegate_to_whoami.stdout != 'root'
20 changes: 20 additions & 0 deletions tests/ansible/templates/test-targets.j2
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ ansible_host={{ tt.hostname }}
ansible_port={{ tt.port }}
ansible_python_interpreter={{ tt.python_path }}

[tt_become_bare]
tt-become-bare

[tt_become_bare:vars]
ansible_host={{ tt.hostname }}
ansible_password=has_sudo_nopw_password
ansible_port={{ tt.port }}
ansible_python_interpreter={{ tt.python_path }}
ansible_user=mitogen__has_sudo_nopw

[tt_become_by_inv]
tt-become-user ansible_become=true ansible_become_user="{{ '{{' }} 'root' | trim {{ '}}' }}"

[tt_become_by_inv:vars]
ansible_host={{ tt.hostname }}
ansible_password=has_sudo_nopw_password
ansible_port={{ tt.port }}
ansible_python_interpreter={{ tt.python_path }}
ansible_user=mitogen__has_sudo_nopw

[tt_targets_inventory]
tt-password ansible_password="{{ '{{' }} 'has_sudo_nopw_password' | trim {{ '}}' }}" ansible_port={{ tt.port }} ansible_user=mitogen__has_sudo_nopw
tt-port ansible_password=has_sudo_nopw_password ansible_port="{{ '{{' }} {{ tt.port }} | int {{ '}}' }}" ansible_user=mitogen__has_sudo_nopw
Expand Down
Loading