Skip to content

Commit

Permalink
Merge pull request #1114 from moreati/ansible_ssh_password
Browse files Browse the repository at this point in the history
`ansible_ssh_password` support
  • Loading branch information
moreati authored Oct 6, 2024
2 parents ab2a921 + 551690e commit 17d3f39
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 27 deletions.
27 changes: 6 additions & 21 deletions ansible_mitogen/plugins/connection/mitogen_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,20 @@
import os.path
import sys

from ansible.plugins.connection.ssh import (
DOCUMENTATION as _ansible_ssh_DOCUMENTATION,
)

DOCUMENTATION = """
name: mitogen_ssh
author: David Wilson <[email protected]>
connection: mitogen_ssh
short_description: Connect over SSH via Mitogen
description:
- This connects using an OpenSSH client controlled by the Mitogen for
Ansible extension. It accepts every option the vanilla ssh plugin
accepts.
version_added: "2.5"
options:
ssh_args:
type: str
vars:
- name: ssh_args
- name: ansible_ssh_args
- name: ansible_mitogen_ssh_args
ssh_common_args:
type: str
vars:
- name: ssh_args
- name: ansible_ssh_common_args
- name: ansible_mitogen_ssh_common_args
ssh_extra_args:
type: str
vars:
- name: ssh_args
- name: ansible_ssh_extra_args
- name: ansible_mitogen_ssh_extra_args
"""
""" + _ansible_ssh_DOCUMENTATION.partition('options:\n')[2]

try:
import ansible_mitogen
Expand Down
14 changes: 13 additions & 1 deletion ansible_mitogen/transport_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
__metaclass__ = type

import abc
import logging
import os
import ansible.utils.shlex
import ansible.constants as C
Expand All @@ -74,6 +75,9 @@
import mitogen.core


LOG = logging.getLogger(__name__)


def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_python):
"""
Triggers ansible python interpreter discovery if requested.
Expand Down Expand Up @@ -412,6 +416,13 @@ def __init__(self, connection, play_context, transport, inventory_name):
# used to run interpreter discovery
self._action = connection._action

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)
return getattr(self._play_context, name)

def transport(self):
return self._transport

Expand Down Expand Up @@ -449,7 +460,7 @@ def become_pass(self):
return optional_secret(become_pass)

def password(self):
return optional_secret(self._play_context.password)
return optional_secret(self._connection_option('password'))

def port(self):
return self._play_context.port
Expand Down Expand Up @@ -678,6 +689,7 @@ def become_pass(self):

def password(self):
return optional_secret(
self._host_vars.get('ansible_ssh_password') or
self._host_vars.get('ansible_ssh_pass') or
self._host_vars.get('ansible_password')
)
Expand Down
6 changes: 4 additions & 2 deletions docs/ansible_detailed.rst
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ container.
* Intermediary machines cannot use login and become passwords that were
supplied to Ansible interactively. If an intermediary requires a
password, it must be supplied via ``ansible_ssh_pass``,
``ansible_password``, or ``ansible_become_pass`` inventory variables.
``ansible_ssh_password``, ``ansible_password``, or
``ansible_become_pass`` inventory variables.

* Automatic tunnelling of SSH-dependent actions, such as the
``synchronize`` module, is not yet supported. This will be addressed in a
Expand Down Expand Up @@ -1011,7 +1012,8 @@ Like the :ans:conn:`ssh` except connection delegation is supported.
* ``ansible_port``, ``ssh_port``
* ``ansible_ssh_executable``, ``ssh_executable``
* ``ansible_ssh_private_key_file``
* ``ansible_ssh_pass``, ``ansible_password`` (default: assume passwordless)
* ``ansible_ssh_pass``, ``ansible_ssh_password``, ``ansible_password``
(default: assume passwordless)
* ``ssh_args``, ``ssh_common_args``, ``ssh_extra_args``
* ``mitogen_mask_remote_name``: if :data:`True`, mask the identity of the
Ansible controller process on remote machines. To simplify diagnostics,
Expand Down
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ To avail of fixes in an unreleased version, please download a ZIP file
Unreleased
----------

* :gh:issue:`1106` :mod:`ansible_mitogen`: Support for `ansible_ssh_password`
connection variable, and templated SSH connection password.


v0.3.11 (2024-10-30)
Expand Down
1 change: 1 addition & 0 deletions docs/contributors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ sponsorship and outstanding future-thinking of its early adopters.
<li>Lewis Bellwood &mdash; <em>Happy to be apart of a great project.</em></li>
<li>luto</li>
<li><a href="https://mayeu.me/">Mayeu a.k.a Matthieu Maury</a></li>
<li><a href="https://github.com/madsi1m">Michael D'Silva</a></li>
<li><a href="https://twitter.com/nathanhruby">@nathanhruby</a></li>
<li><a href="https://github.com/opoplawski">Orion Poplawski</a></li>
<li><a href="https://github.com/philfry">Philippe Kueck</a></li>
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 @@ -19,3 +19,17 @@ ssh-common-args ansible_host=localhost ansible_user="{{ lookup('pipe', 'whoami')
[issue905:vars]
ansible_ssh_common_args=-o PermitLocalCommand=yes -o LocalCommand="touch {{ ssh_args_canary_file }}"
ssh_args_canary_file=/tmp/ssh_args_{{ inventory_hostname }}

[tt_targets_bare]
tt-bare

[tt_targets_bare:vars]
ansible_host=localhost
ansible_user=mitogen__has_sudo_nopw

[tt_targets_inventory]
tt-password ansible_password="{{ 'has_sudo_nopw_password' | trim }}"

[tt_targets_inventory:vars]
ansible_host=localhost
ansible_user=mitogen__has_sudo_nopw
2 changes: 2 additions & 0 deletions tests/ansible/integration/ssh/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
- import_playbook: config.yml
- import_playbook: password.yml
- import_playbook: timeouts.yml
- import_playbook: templated_by_inv.yml
- import_playbook: templated_by_play_taskvar.yml
- import_playbook: variables.yml
21 changes: 18 additions & 3 deletions tests/ansible/integration/ssh/password.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
ansible_ssh_pass: user1_password
ping:

- meta: reset_connection
- name: ansible_ssh_password
vars:
ansible_ssh_password: user1_password
ping:

- meta: reset_connection
- name: absent password should fail
ping:
Expand All @@ -34,13 +40,22 @@
ansible_password: wrong
ansible_ssh_pass: user1_password

# Tests that ansible_ssh_pass has priority over ansible_password
- meta: reset_connection
- name: Highest priority password variable should override all others
vars:
ansible_password: wrong
ansible_ssh_pass: wrong
ansible_ssh_password: user1_password
ping:

# Tests that ansible_ssh_password has priority over others
# and that a wrong password causes a target to be marked unreachable.
- meta: reset_connection
- name: ansible_password should not override
- name: Lower priority password variables should not override
vars:
ansible_password: user1_password
ansible_ssh_pass: wrong
ansible_ssh_pass: user1_password
ansible_ssh_password: wrong
ping:
ignore_errors: true
ignore_unreachable: true
Expand Down
7 changes: 7 additions & 0 deletions tests/ansible/integration/ssh/templated_by_inv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
- name: integration/ssh/templated_by_inv.yml
hosts: tt_targets_inventory
gather_facts: false
tasks:
- meta: reset_connection
- name: Templated variables in inventory
ping:
10 changes: 10 additions & 0 deletions tests/ansible/integration/ssh/templated_by_play_taskvar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- name: integration/ssh/templated_by_play_taskvar.yml
hosts: tt_targets_bare
gather_facts: false
vars:
ansible_password: "{{ 'has_sudo_nopw_password' | trim }}"

tasks:
- meta: reset_connection
- name: Templated variables in play
ping:
19 changes: 19 additions & 0 deletions tests/ansible/templates/test-targets.j2
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,22 @@ ansible_user=mitogen__has_sudo_nopw
ansible_password=has_sudo_nopw_password
ansible_ssh_common_args=-o PermitLocalCommand=yes -o LocalCommand="touch {{ '{{' }} ssh_args_canary_file {{ '}}' }}"
ssh_args_canary_file=/tmp/ssh_args_{{ '{{' }} inventory_hostname {{ '}}' }}

{% set tt = containers[0] %}

[tt_targets_bare]
tt-bare

[tt_targets_bare:vars]
ansible_host={{ tt.hostname }}
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 }}

[tt_targets_inventory:vars]
ansible_host={{ tt.hostname }}
ansible_python_interpreter={{ tt.python_path }}
ansible_user=mitogen__has_sudo_nopw

0 comments on commit 17d3f39

Please sign in to comment.