Skip to content

Support molecule login/molecule list for ansible-native scenarios - #4663

Open
jirib wants to merge 5 commits into
ansible:mainfrom
jirib:fix-login-ansible-native
Open

Support molecule login/molecule list for ansible-native scenarios#4663
jirib wants to merge 5 commits into
ansible:mainfrom
jirib:fix-login-ansible-native

Conversation

@jirib

@jirib jirib commented Jul 21, 2026

Copy link
Copy Markdown

Summary

Ansible-native scenarios (no platforms: declared, instance lifecycle managed entirely by custom create.yml/destroy.yml) left molecule login and molecule list non-functional — both relied solely on the static platforms: list, which these scenarios don't have.

This adds a fallback: when no platforms are configured, both commands query the real inventory via ansible-inventory, reusing the exact same --inventory sources ansible-playbook itself is invoked with. No new molecule-specific config file is required — connection details already present in your inventory (e.g. written by create.yml) are used directly.

Changes

  • driver/delegated.py — resolve the same --inventory sources as ansible-playbook; add ansible-inventory-backed host discovery (get_ansible_native_hosts) and login-option resolution (_get_inventory_login_options), used as a fallback when instance_config.yml has no entry for the instance.
  • driver/base.pystatus() reports real host names from the inventory instead of a single blank placeholder when no platforms are configured.
  • command/login.pyexecute()/_get_hostname() use the same inventory fallback; clearer error messages when no hosts can be found by either mechanism.
  • Tests — unit coverage for all of the above, including ansible-inventory subprocess success/failure handling.
  • Docs — new "Logging Into / Listing Instances" section in docs/ansible-native.md, plus notes on the existing container/cloud examples flagging that dynamically-assigned connection details must be persisted to a host_vars file (not just registered as in-play facts) to be discoverable by login/list.

Backward compatibility

instance_config.yml is still checked first if a create playbook populates it — the inventory query only kicks in as a fallback, so existing non-native scenarios are unaffected.

Testing

Verified end-to-end against a real ansible-native scenario (custom libvirt-based instance lifecycle): confirmed molecule list/molecule login correctly resolve the real instance name and connect over SSH, both with and without instance_config.yml present. Full unit suite passes (53 new/updated tests).

Summary by CodeRabbit

  • New Features
    • Added inventory-based host discovery for ansible-native flows when no static platform instances are configured, so molecule login/molecule list can use runtime-resolved connection details.
  • Bug Fixes
    • Improved molecule login behavior when no hosts are available, including clearer messaging when --host is missing and safer handling when --host is provided.
    • Provide more actionable failures when required SSH connection details can’t be derived.
  • Documentation
    • Updated ansible-native docs to describe persisting runtime-resolved connection details and how inventory lookups are performed.
  • Tests
    • Expanded unit tests for host discovery, inventory parsing/mapping, and error-handling paths.

@github-actions

Copy link
Copy Markdown

Label error. Requires at least 1 of: breaking, chore, feat, fix. Found: . Follow https://www.conventionalcommits.org to get auto-labeling to work correctly.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Molecule now discovers ansible-native hosts and connection details from persisted Ansible inventory data. Login handles empty host lists and missing connection fields explicitly, while delegated-driver inventory fallbacks and related documentation and tests are added.

Changes

Ansible-native inventory discovery

Layer / File(s) Summary
Inventory resolution and driver hooks
src/molecule/driver/base.py, src/molecule/driver/delegated.py, tests/unit/driver/test_delegated.py, docs/ansible-native.md
Drivers expose ansible-native host discovery, reconstruct configured inventory arguments, query ansible-inventory, map host variables to login options, and document persisted runtime connection data.
Login host selection and errors
src/molecule/command/login.py, tests/unit/command/test_login.py
Login discovers hosts when configured instances are absent, accepts explicit hosts when none are discovered, and reports missing connection fields during command formatting.
Fallback validation
tests/unit/driver/test_delegated.py, tests/unit/command/test_login.py
Tests cover inventory parsing, native host discovery, fallback behavior, and login errors.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MoleculeLogin
  participant DelegatedDriver
  participant AnsibleInventory
  MoleculeLogin->>DelegatedDriver: discover hosts when instances are empty
  DelegatedDriver->>AnsibleInventory: query configured inventory sources
  AnsibleInventory-->>DelegatedDriver: return JSON host data
  DelegatedDriver-->>MoleculeLogin: return hosts and connection options
  MoleculeLogin-->>MoleculeLogin: build login command
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: enabling login/list support for ansible-native scenarios.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/ansible-native.md`:
- Line 373: Update both links in docs/ansible-native.md at lines 373-373 and
423-423 to use the fragment `#logging-into--listing-instances`, matching the
generated anchor for the “Logging Into / Listing Instances” heading.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 02a8d52c-8efa-4eb7-af94-06b4db2574a5

📥 Commits

Reviewing files that changed from the base of the PR and between ab625b4 and 9653fdb.

📒 Files selected for processing (6)
  • docs/ansible-native.md
  • src/molecule/command/login.py
  • src/molecule/driver/base.py
  • src/molecule/driver/delegated.py
  • tests/unit/command/test_login.py
  • tests/unit/driver/test_delegated.py

Comment thread docs/ansible-native.md Outdated
jirib added 3 commits July 21, 2026 21:51
Ansible-native scenarios (no `platforms:` declared) left `molecule login`
and `molecule list` with no way to discover instance names or connection
details, since both previously relied solely on the static platform list.

Both commands now fall back to querying the real inventory - the same
`--inventory` sources `ansible-playbook` itself is invoked with - via
`ansible-inventory --list`/`--host <name>`, reusing whatever the create
playbook already wrote there instead of requiring a separate,
molecule-specific config file to stay in sync.

- driver/delegated.py: add inventory-backed host discovery and
  login-option resolution, used as a fallback when instance_config.yml
  has no entry.
- driver/base.py: status() reports real inventory host names instead of
  a blank placeholder when no platforms are configured.
- command/login.py: execute()/_get_hostname() use the same fallback;
  clearer error messages when no hosts can be found either way.
Add unit test coverage for the inventory-based fallback paths added for
ansible-native scenarios: inventory source resolution, ansible-inventory
subprocess success/failure handling (including the new debug logging),
inventory-based login-option resolution, host discovery, and the
corresponding fallback behavior in status()/execute()/_get_hostname().
Explain how molecule login/list resolve instance names and connection
details for ansible-native scenarios by querying the real inventory.
Also flag a gap in the existing container/cloud examples: dynamically
assigned connection details (IP, published port) only exist as in-play
facts unless explicitly persisted to a host_vars file, and login/list
can't see anything that wasn't written to disk.
@jirib
jirib force-pushed the fix-login-ansible-native branch from 9653fdb to dc70a07 Compare July 21, 2026 19:52
Renamed the heading to drop the "/" (previously "Logging Into / Listing
Instances") since GitHub's own anchor slugifier and mkdocs' default
python-markdown slugifier disagree on how a removed "/" between two
spaces collapses - GitHub yields a double hyphen, mkdocs collapses to a
single hyphen. Neither in-page link worked for both renderers at once.
Renaming to "Logging Into and Listing Instances" produces the same
anchor under both, so the links now work regardless of where the page
is viewed.

Reported by CodeRabbit on PR ansible#4663 (markdownlint-cli2 MD051).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/molecule/driver/delegated.py`:
- Around line 181-213: Add a finite timeout to the subprocess.run call in
_run_ansible_inventory, using the project’s established timeout configuration or
constant if available, and catch subprocess.TimeoutExpired alongside
CalledProcessError. Log the timeout through the existing debug path and return
None, preserving current behavior for other failures.
- Around line 154-179: Update _ansible_inventory_args to preserve split
inventory option/value pairs from provisioner.ansible_args and ansible_args,
including both -i path and --inventory path forms. Keep inline forms intact,
ensure the associated value is included with its flag, and continue prepending
provisioner.inventory_directory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 5133898f-24b3-401f-a1bf-052fa8031f20

📥 Commits

Reviewing files that changed from the base of the PR and between 9653fdb and dc70a07.

📒 Files selected for processing (6)
  • docs/ansible-native.md
  • src/molecule/command/login.py
  • src/molecule/driver/base.py
  • src/molecule/driver/delegated.py
  • tests/unit/command/test_login.py
  • tests/unit/driver/test_delegated.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/molecule/command/login.py
  • src/molecule/driver/base.py
  • tests/unit/command/test_login.py

Comment thread src/molecule/driver/delegated.py
Comment thread src/molecule/driver/delegated.py
Two issues flagged by CodeRabbit on PR ansible#4663:

- _ansible_inventory_args() only kept extra --inventory/-i args when
  written in the single-token "--inventory=path" form. Space-separated
  form ("-i", "path" as two list items) had its value silently dropped,
  producing a broken ansible-inventory invocation. Now both forms are
  handled explicitly.
- _run_ansible_inventory() had no timeout, so a hanging dynamic
  inventory source (network calls, cloud plugins) would hang molecule
  login/molecule list indefinitely. Add a 30s timeout and handle
  subprocess.TimeoutExpired the same way as other failure modes.

Add test coverage for both.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/molecule/driver/delegated.py (1)

245-252: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Read both Ansible key-file variable names
_get_inventory_login_options() only reads ansible_ssh_private_key_file; inventories that expose ansible_private_key_file will miss identity_file, breaking key-based login fallback. Check ansible_private_key_file first and keep ansible_ssh_private_key_file as a fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/molecule/driver/delegated.py` around lines 245 - 252, Update
_get_inventory_login_options() to read ansible_private_key_file first when
setting identity_file, then fall back to ansible_ssh_private_key_file when the
primary variable is absent. Preserve the existing address, user, and port
handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/molecule/driver/delegated.py`:
- Around line 245-252: Update _get_inventory_login_options() to read
ansible_private_key_file first when setting identity_file, then fall back to
ansible_ssh_private_key_file when the primary variable is absent. Preserve the
existing address, user, and port handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 398df079-d0d1-4cfc-b89f-e91c6d33f3ca

📥 Commits

Reviewing files that changed from the base of the PR and between 45d1075 and 7fc3428.

📒 Files selected for processing (2)
  • src/molecule/driver/delegated.py
  • tests/unit/driver/test_delegated.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/driver/test_delegated.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant