diff --git a/ansible_mitogen/connection.py b/ansible_mitogen/connection.py index 3e02b971..03856f4d 100644 --- a/ansible_mitogen/connection.py +++ b/ansible_mitogen/connection.py @@ -147,7 +147,7 @@ def _connect_ssh(spec): 'ssh_path': spec.ssh_executable(), 'connect_timeout': spec.timeout(), 'ssh_args': spec.ssh_args(), - 'ssh_debug_level': spec.mitogen_ssh_debug_level(), + 'ssh_debug_level': spec.verbosity(), 'remote_name': get_remote_name(spec), 'keepalive_count': ( spec.mitogen_ssh_keepalive_count() or 10 diff --git a/ansible_mitogen/transport_config.py b/ansible_mitogen/transport_config.py index 22afd197..3d5fac3c 100644 --- a/ansible_mitogen/transport_config.py +++ b/ansible_mitogen/transport_config.py @@ -406,6 +406,12 @@ class Spec(with_metaclass(abc.ABCMeta, object)): Value of "ansible_doas_exe" variable. """ + @abc.abstractmethod + def verbosity(self): + """ + How verbose to make logging or diagnostics output. + """ + class PlayContextSpec(Spec): """ @@ -601,6 +607,17 @@ class PlayContextSpec(Spec): os.environ.get('ANSIBLE_DOAS_EXE') ) + def verbosity(self): + try: + verbosity = self._connection.get_option('verbosity', hostvars=self._task_vars) + except KeyError: + verbosity = self.mitogen_ssh_debug_level() + + if verbosity: + return int(verbosity) + + return 0 + class MitogenViaSpec(Spec): """ @@ -836,3 +853,13 @@ class MitogenViaSpec(Spec): self._host_vars.get('ansible_doas_exe') or os.environ.get('ANSIBLE_DOAS_EXE') ) + + def verbosity(self): + verbosity = self._host_vars.get('ansible_ssh_verbosity') + if verbosity is None: + verbosity = self.mitogen_ssh_debug_level() + + if verbosity: + return int(verbosity) + + return 0 diff --git a/docs/changelog.rst b/docs/changelog.rst index c7b7ae49..f2de5561 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -38,6 +38,8 @@ to strategy plugins under :gh:issue:`1278`. release candidate is under test * :gh:issue:`1275` CI: Test ``ansible_ssh_password`` behaviour without ``sshpass`` installed +* :gh:issue:`1282` :mod:`ansible_mitogen`: Support ``ANSIBLE_SSH_VERBOSITY`` + with Ansible 12 v0.3.25a2 (2025-06-21) diff --git a/tests/ansible/integration/connection_delegation/delegate_to_template.yml b/tests/ansible/integration/connection_delegation/delegate_to_template.yml index 4cff57e1..8cd50f98 100644 --- a/tests/ansible/integration/connection_delegation/delegate_to_template.yml +++ b/tests/ansible/integration/connection_delegation/delegate_to_template.yml @@ -50,7 +50,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -78,7 +78,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'ansible-cfg-remote-user', }, diff --git a/tests/ansible/integration/connection_delegation/stack_construction.yml b/tests/ansible/integration/connection_delegation/stack_construction.yml index 1cfd34ef..58abac7b 100644 --- a/tests/ansible/integration/connection_delegation/stack_construction.yml +++ b/tests/ansible/integration/connection_delegation/stack_construction.yml @@ -87,7 +87,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -131,7 +131,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -186,7 +186,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'ansible-cfg-remote-user', }, @@ -230,7 +230,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -258,7 +258,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'ansible-cfg-remote-user', }, @@ -312,7 +312,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'newuser-normal-normal-user', }, @@ -357,7 +357,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, diff --git a/tests/ansible/integration/ssh/all.yml b/tests/ansible/integration/ssh/all.yml index 20031704..6dbf945f 100644 --- a/tests/ansible/integration/ssh/all.yml +++ b/tests/ansible/integration/ssh/all.yml @@ -8,3 +8,4 @@ - import_playbook: templated_by_play_taskvar.yml - import_playbook: templated_by_task_keyword.yml - import_playbook: variables.yml +- import_playbook: verbosity.yml diff --git a/tests/ansible/integration/ssh/verbosity.yml b/tests/ansible/integration/ssh/verbosity.yml new file mode 100644 index 00000000..2bf1ed10 --- /dev/null +++ b/tests/ansible/integration/ssh/verbosity.yml @@ -0,0 +1,41 @@ +# Ansible >= 12 (ansible-core >= 2.19) adds SSH connection `verbosity` property. +# Ansible <= 11 (ansible-core <= 2.18) applies ANSIBLE_VERBOSITY -> ssh. + +- name: integration/ssh/verbosity.yml + hosts: test-targets + gather_facts: false + tasks: + - meta: end_play + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) + + - name: Exercise ssh verbosity + connection: local + environment: + ANSIBLE_CALLBACK_RESULT_FORMAT: json + ANSIBLE_LOAD_CALLBACK_PLUGINS: "false" + ANSIBLE_SSH_VERBOSITY: 3 + ANSIBLE_STRATEGY: "{{ lookup('env', 'ANSIBLE_STRATEGY') | mandatory }}" + ANSIBLE_VERBOSITY: 3 + vars: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + command: + cmd: + ansible + {% for inv in ansible_inventory_sources %} + -i "{{ inv }}" + {% endfor %} + "{{ inventory_hostname }}" + -m ping + chdir: ../.. + register: out + changed_when: false + check_mode: false + + - name: Verify ssh -vvv output is included + assert: + that: + - >- + out.stdout is search('debug1: Reading configuration data') + fail_msg: | + out={{ out }}