Repository navigation
fix: write only recorded connection vars for managed instances - #4702
Conversation
The managed path of the default driver wrote ansible_connection: smart whenever the create playbook recorded no connection, and wrote ansible_user, ansible_host and ansible_port as null when those keys were not recorded. A host var shadows the same variable set at group or all level, so a user's own ansible_connection, ansible_user or ansible_port in the inventory was silently discarded. Write each of those host vars only when the instance config records it. With no ansible_connection written, Ansible resolves the transport itself, from the inventory, ansible.cfg or the environment, otherwise its own default. That default is ssh since ansible-core 2.16 and smart on 2.15, so a scenario that sets no transport anywhere connects as it did before. The unconditional smart write is a regression. It was removed in 4efdb48 (ansible#2811) and 11d09c8 (ansible#2988). 5b750ff (ansible#3932) reintroduced an unconditional write, as null, and 99a95f8 (ansible#3957) made it smart because ansible_connection: null crashed meta: reset_connection. This change leaves the key absent rather than null, so that crash does not return. The null user, host and port vars have been written since the keys were first mapped, so dropping them is new behavior. Also document that these four host vars are written only when recorded. Fixes: ansible#4696 Assisted-by: Claude (Anthropic) Signed-off-by: Jeff Pullen <9343691+jeffcpullen@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe delegated driver no longer defaults ChangesDelegated connection option handling
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Fixed issue severity: <fixed_issue_severity>Medium</fixed_issue_severity> Merge Risk: ⚪ Minimal · up to The generated inventory now omits unrecorded managed connection values, allowing configured inventory values and Ansible defaults to apply. No current merge-blocking risk is identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Fixes #4696.
Problem
On the default driver with Molecule managing the instances, every host with an instance-config entry gets
ansible_connection: smartin the generated inventory unless the create playbook recorded aconnection. If the create playbook recorded nouserorport, the host also getsansible_user: nullandansible_port: null.A host variable beats the same variable set at group or all level, so a user's own
ansible_connection,ansible_useroransible_portin the scenario's inventory is silently discarded.Scenario, with a create playbook that records only
instanceandaddress:On
main(20b71bda), the host entry Molecule generates and the effective host vars:What changes
ansible_connection,ansible_user,ansible_hostandansible_portonly when the create playbook recorded the matching value. Nosmartfallback, nonull.The same scenario on this branch (
fb42ac7d). Theansible_connection: smart,ansible_port: nullandansible_user: nulllines are gone from the host entry, and the group values apply:The reporter's scenario records no
connection, so it now gets noansible_connectionand connects oversshwithout theconnection: sshworkaround.driver.options.ansible_connection_optionsstill applies only withmanaged: False, andprovisioner.connection_optionsis the override for the generated host vars. Both are unchanged.ansible_ssh_common_argsis still written for every managed host.Risk / Impact
A managed scenario that set
ansible_connection,ansible_useroransible_portin its own inventory and depended on Molecule's host-levelsmartornullwinning now gets its own value.Root cause
Delegated.ansible_connection_options()insrc/molecule/driver/delegated.pybuilds the managed host vars frominstance_config.yml. Theinstance_paramstable's last entry is("connection", "smart")under a truthy guard, so the fallback is emitted on every host unless the instance config carries its ownconnection. Below the table,ansible_user,ansible_hostandansible_portare assigned unconditionally fromd.get(...), so an unrecorded key lands asNoneand is dumped asnull.The
smartfallback is a regression. #1674 (0e07804b, 2019) introduced it. #2811 (4efdb48a, 2020-09) and #2988 (11d09c81, 2020-11) put it behind a guard, soansible_connectionwas written only when recorded. #3932 (5b750ff4, 2023-06) folded the keys into theinstance_paramstable and reintroduced an unconditional write, asnull. #3957 (99a95f87, 2023-07) made itsmartbecauseansible_connection: nullcrashedmeta: reset_connection. This PR leaves the key absent rather thannull, so that crash does not return. Thenullwrites for user, host and port also date from #1674, so dropping them is new behavior.Ansible's own default transport has been
sshsince ansible-core 2.16, andsmartresolved tosshon any controller with a ControlPersist-capable OpenSSH, so removing the host var does not change the plugin for a scenario that sets nothing.The fix changes the table entry to
("connection", None)and dropsNonevalues from the result in one comprehension at the return.Changes
docs/configuration.md, one paragraph after the instance-config API block: the four host vars are written only when recorded, where a managed scenario sets its own values, and thatdriver.options.ansible_connection_optionssupplies host vars only withmanaged: False.Tests
tests/unit/driver/test_delegated.py:test_ansible_connection_options_when_managed, ssh case: the"ansible_connection": "smart"expectation is removed andassert "ansible_connection" not in ssh_resultis added. The winrm case, which recordsconnection: winrm, is unchanged and still expects it.test_ansible_connection_options_omits_unrecorded_keys_when_managed: the instance config recordsinstance,addressanduser: null. Assertsansible_hostis present, the other three are absent, and no value isNone, which is the shape Fix connection plugin name setting #3957 fixed.Test plan
tox -e lintpassestox -e pkgpassestox -e pypasses, 910 passed, 7 skipped, same skips asmaindelegated.py93%main(2 failed, 44 passed), passes on this branch (46 passed)mainand this branch,ansible_inventory.ymlandansible-inventory --hostcaptured, outputs are the blocks in this bodyaddress,user,portand noconnection, only theansible_connection: smartline differsinstance_config.yml, host entry{}on both sidesSummary by CodeRabbit
Bug Fixes
smartconnection type when no connection is recorded.Documentation