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

Fix add_hosts when ansible_host_key_checking is passed to the new host #1067

Merged
merged 3 commits into from
May 11, 2024
Merged
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
2 changes: 1 addition & 1 deletion .ci/localhost_ansible_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,5 @@
with ci_lib.Fold('ansible'):
os.chdir(TESTS_DIR)
playbook = os.environ.get('PLAYBOOK', 'all.yml')
ci_lib.run('./run_ansible_playbook.py %s -l target %s',
ci_lib.run('./run_ansible_playbook.py %s %s',
playbook, ' '.join(sys.argv[1:]))
2 changes: 1 addition & 1 deletion ansible_mitogen/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def _connect_ssh(spec):
"""
Return ContextService arguments for an SSH connection.
"""
if C.HOST_KEY_CHECKING:
if spec.host_key_checking():
check_host_keys = 'enforce'
else:
check_host_keys = 'ignore'
Expand Down
23 changes: 23 additions & 0 deletions ansible_mitogen/transport_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import ansible.constants as C

from ansible.module_utils.six import with_metaclass
from ansible.module_utils.parsing.convert_bool import boolean

# this was added in Ansible >= 2.8.0; fallback to the default interpreter if necessary
try:
Expand Down Expand Up @@ -245,6 +246,12 @@ def python_path(self):
Path to the Python interpreter on the target machine.
"""

@abc.abstractmethod
def host_key_checking(self):
"""
Whether or not to check the keys of the target machine
"""

@abc.abstractmethod
def private_key_file(self):
"""
Expand Down Expand Up @@ -466,6 +473,14 @@ def python_path(self, rediscover_python=False):
action=self._action,
rediscover_python=rediscover_python)

def host_key_checking(self):
def candidates():
yield self._connection.get_task_var('ansible_ssh_host_key_checking')
yield self._connection.get_task_var('ansible_host_key_checking')
yield C.HOST_KEY_CHECKING
val = next((v for v in candidates() if v is not None), True)
return boolean(val)

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

Expand Down Expand Up @@ -692,6 +707,14 @@ def python_path(self, rediscover_python=False):
action=self._action,
rediscover_python=rediscover_python)

def host_key_checking(self):
def candidates():
yield self._host_vars.get('ansible_ssh_host_key_checking')
yield self._host_vars.get('ansible_host_key_checking')
yield C.HOST_KEY_CHECKING
val = next((v for v in candidates() if v is not None), True)
return boolean(val)

def private_key_file(self):
# TODO: must come from PlayContext too.
return (
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Unreleased
* :gh:issue:`952` Fix Ansible `--ask-become-pass`, add test coverage
* :gh:issue:`957` Fix Ansible exception when executing against 10s of hosts
"ValueError: filedescriptor out of range in select()"
* :gh:issue:`1066` Support Ansible `ansible_host_key_checking` & `ansible_ssh_host_key_checking`

moreati marked this conversation as resolved.
Show resolved Hide resolved

v0.3.7 (2024-04-08)
Expand Down
11 changes: 8 additions & 3 deletions tests/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
[defaults]
any_errors_fatal = true
# callback_whitelist naming will be deprecated in ansible-core >= 2.15.
# callbacks_enabled naming was added in ansible-core 2.11
# callbacks_enabled was added in Ansible 4 (ansible-core 2.11).
# profile_tasks: Displays timing for each task and summary table of top N tasks
# timer: Displays "Playbook run took 0 days, 0 hours, ..."
callbacks_enabled =
profile_tasks,
timer
# callback_whitelist was deprecated in Ansible >= 8 (ansible-core >= 2.15).
callback_whitelist =
profile_tasks,
timer
Expand Down Expand Up @@ -37,7 +40,9 @@ no_target_syslog = True
# Required by integration/ssh/timeouts.yml
timeout = 30

# On Travis, paramiko check fails due to host key checking enabled.
# Ideally this would be true here and and overridden for hosts/groups. However
# ansible_host_key_checking don't work on Vanilla Ansible 2.10, even for
# static inventory hosts (ansible/ansible#49254, ansible/ansible#73708)
host_key_checking = False

[inventory]
Expand Down
6 changes: 6 additions & 0 deletions tests/ansible/hosts/transport_config.hosts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tc_become
tc_become_method
tc_become_pass
tc_become_user
tc_host_key_checking
tc_password
tc_port
tc_remote_addr
Expand Down Expand Up @@ -74,6 +75,11 @@ tc-become-pass-password ansible_become_password=apassword
tc-become-pass-pass ansible_become_pass=apass
tc-become-pass-both ansible_become_pass=bpass ansible_become_password=bpassword

[tc_host_key_checking]
tc-hkc-unset
tc-hkc-host-key-checking ansible_host_key_checking=true
tc-hkc-ssh-host-key-checking ansible_ssh_host_key_checking=true

[tc_port]
tc-port-unset
tc-port-explicit-port ansible_port=1234
Expand Down
1 change: 1 addition & 0 deletions tests/ansible/integration/transport_config/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- import_playbook: become_pass.yml
- import_playbook: become_user.yml
- import_playbook: become.yml
- import_playbook: host_key_checking.yml
- import_playbook: password.yml
- import_playbook: port.yml
- import_playbook: python_path.yml
Expand Down
94 changes: 94 additions & 0 deletions tests/ansible/integration/transport_config/host_key_checking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Each case is followed by mitogen_via= case to test hostvars method.

- name: integration/transport_config/host_key_checking.yml
hosts: tc-hkc-unset
tasks:
- include_tasks: ../_mitogen_only.yml
- {mitogen_get_stack: {}, register: out}
- assert:
that:
- out.result | length == 1
- out.result[0].method == "ssh"
- out.result[0].kwargs.check_host_keys == "ignore"
fail_msg: out={{ out }}
tags:
- mitogen_only

- hosts: tc-hkc-unset
vars:
mitogen_via: tc-hkc-host-key-checking
tasks:
- include_tasks: ../_mitogen_only.yml
- {mitogen_get_stack: {}, register: out}
- assert:
that:
- out.result | length == 2
- out.result[0].method == "ssh"
- out.result[0].kwargs.check_host_keys == "enforce"
- out.result[1].method == "ssh"
- out.result[1].kwargs.check_host_keys == "ignore"
fail_msg: out={{ out }}
tags:
- mitogen_only


- hosts: tc-hkc-host-key-checking
tasks:
- include_tasks: ../_mitogen_only.yml
- {mitogen_get_stack: {}, register: out}
- assert:
that:
- out.result | length == 1
- out.result[0].method == "ssh"
- out.result[0].kwargs.check_host_keys == "enforce"
fail_msg: out={{ out }}
tags:
- mitogen_only

- hosts: tc-hkc-host-key-checking
vars:
mitogen_via: tc-hkc-unset
tasks:
- include_tasks: ../_mitogen_only.yml
- {mitogen_get_stack: {}, register: out}
- assert:
that:
- out.result | length == 2
- out.result[0].method == "ssh"
- out.result[0].kwargs.check_host_keys == "ignore"
- out.result[1].method == "ssh"
- out.result[1].kwargs.check_host_keys == "enforce"
fail_msg: out={{ out }}
tags:
- mitogen_only


- hosts: tc-hkc-ssh-host-key-checking
tasks:
- include_tasks: ../_mitogen_only.yml
- {mitogen_get_stack: {}, register: out}
- assert:
that:
- out.result | length == 1
- out.result[0].method == "ssh"
- out.result[0].kwargs.check_host_keys == "enforce"
fail_msg: out={{ out }}
tags:
- mitogen_only

- hosts: tc-hkc-ssh-host-key-checking
vars:
mitogen_via: tc-hkc-unset
tasks:
- include_tasks: ../_mitogen_only.yml
- {mitogen_get_stack: {}, register: out}
- assert:
that:
- out.result | length == 2
- out.result[0].method == "ssh"
- out.result[0].kwargs.check_host_keys == "ignore"
- out.result[1].method == "ssh"
- out.result[1].kwargs.check_host_keys == "enforce"
fail_msg: out={{ out }}
tags:
- mitogen_only
1 change: 1 addition & 0 deletions tests/ansible/regression/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
- import_playbook: issue_655__wait_for_connection_error.yml
- import_playbook: issue_776__load_plugins_called_twice.yml
- import_playbook: issue_952__ask_become_pass.yml
- import_playbook: issue_1066__add_host__host_key_checking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
- name: regression/issue_1066__add_host__host_key_checking.yml
hosts: test-targets[0]
gather_facts: false
become: false
tasks:
- name: Add hosts dynamically
add_host:
name: "{{ item.name }}"
ansible_host_key_checking: "{{ item.host_key_checking | default(omit) }}"
ansible_ssh_host_key_checking: "{{ item.host_ssh_key_checking | default(omit) }}"
ansible_host: "{{ hostvars[inventory_hostname].ansible_host | default(omit) }}"
ansible_password: "{{ hostvars[inventory_hostname].ansible_password | default(omit) }}"
ansible_port: "{{ hostvars[inventory_hostname].ansible_port | default(omit) }}"
ansible_python_interpreter: "{{ hostvars[inventory_hostname].ansible_python_interpreter | default(omit) }}"
ansible_user: "{{ hostvars[inventory_hostname].ansible_user | default(omit) }}"
loop:
- {name: issue-1066-host-hkc-false, host_key_checking: false}
- {name: issue-1066-host-hkc-true, host_key_checking: true}
- {name: issue-1066-host-hskc-false, host_ssh_key_checking: false}
- {name: issue-1066-host-hskc-true, host_ssh_key_checking: true}
delegate_to: localhost
tags:
- issue_1066

- name: regression/issue_1066__add_host__host_key_checking.yml
hosts: issue-1066-host-*
gather_facts: false
become: false
serial: 1
tasks:
- meta: reset_connection

# The host key might be in ~/.ssh/known_hosts. If it's removed then no
# problem - test-targets hosts have host_key_checking=false.
- name: Remove existing host keys
known_hosts:
name: "{{ ansible_host }}"
state: absent
delegate_to: localhost

- name: Ping dynamically added hosts
ping:
ignore_errors: true
ignore_unreachable: true
register: issue_1066_ping

- debug:
var: issue_1066_ping

- name: Confirm dynamically added hosts are/are not reachable
vars:
expected:
issue-1066-host-hkc-false: {}
issue-1066-host-hkc-true: {unreachable: true}
issue-1066-host-hskc-false: {}
issue-1066-host-hskc-true: {unreachable: true}
assert:
that:
- issue_1066_ping.unreachable is defined == expected[inventory_hostname].unreachable is defined
- issue_1066_ping.unreachable | default(42) == expected[inventory_hostname].unreachable | default(42)
# ansible_host_key_checking don't work on Vanilla Ansible 2.10, even for
# static inventory hosts (ansible/ansible#49254, ansible/ansible#73708).
when:
- ansible_version.full is version('2.11', '>=', strict=True)
or is_mitogen
tags:
- issue_1066
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
# since things are ran on localhost; Azure DevOps loses connection and fails
# TODO: do we want to install docker a different way to be able to do this for other tests too
---
- name: regression/issue_655_wait_for_connection_error.yml
- name: regression/issue_655__wait_for_connection_error.yml
hosts: localhost
gather_facts: yes
become: no
tasks:
- meta: end_play
when:
# TODO CI currently runs on macOS 11 images in Azure DevOps. MacOS 11
# is no longer supported by homebrew, so the following install
# task fails.
- ansible_facts.system == 'Darwin'
- ansible_facts.distribution_major_version == '11'

- name: set up test container and run tests inside it
block:
- name: install deps
Expand Down
4 changes: 3 additions & 1 deletion tests/ansible/setup/report_controller.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- name: Report controller parameters
hosts: localhost
hosts: test-targets[0]
gather_facts: false
tasks:
- debug:
Expand All @@ -9,9 +9,11 @@
- $(groups): "{{ lookup('pipe', 'groups') }}"
- $(pwd): "{{ lookup('pipe', 'pwd') }}"
- $(whoami): "{{ lookup('pipe', 'whoami') }}"
- ansible_inventory_sources: "{{ ansible_inventory_sources | default('<unset>') }}"
- ansible_run_tags: "{{ ansible_run_tags | default('<unset>') }}"
- ansible_playbook_python: "{{ ansible_playbook_python | default('<unset>') }}"
- ansible_skip_tags: "{{ ansible_skip_tags | default('<unset>') }}"
- ansible_version.full: "{{ ansible_version.full | default('<unset>') }}"
- is_mitogen: "{{ is_mitogen | default('<unset>') }}"
- playbook_dir: "{{ playbook_dir | default('<unset>') }}"
delegate_to: localhost
Loading