Skip to content

fix: validate platforms entries against MoleculePlatformModel - #4661

Open
jeffcpullen wants to merge 1 commit into
ansible:mainfrom
jeffcpullen:fix/platforms-schema-validation
Open

fix: validate platforms entries against MoleculePlatformModel#4661
jeffcpullen wants to merge 1 commit into
ansible:mainfrom
jeffcpullen:fix/platforms-schema-validation

Conversation

@jeffcpullen

@jeffcpullen jeffcpullen commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

The platforms: section of molecule.yml defines the instances a scenario creates and tests, and it is the part of the config users are most likely to hand-edit and get wrong. Today the schema does not validate it: a platform with a missing required name or a malformed networks block passes validation clean, and the mistake only surfaces later as confusing runtime behavior. Every tool that trusts this schema inherits the blind spot, including editors and ansible-lint (see ansible/ansible-lint#5119). This PR restores that validation so those mistakes are caught when the file is written or linted, not when the scenario runs.

The cause is a one-line gap: platforms.items in src/molecule/data/molecule.json is typed as an open {"type": "object"}, so any object is accepted. The $defs/MoleculePlatformModel definition (typed children/networks, required name, and its dependencies platform-network and ContainerRegistryModel) still exists in the file but is orphaned: nothing references it. This PR restores the reference and relaxes three field types that had drifted from the docker/podman drivers.

Current behavior

Malformed platform entries pass validation today. All of these are accepted:

platforms:
  - children: 2          # should be a list of group names
  - image: example       # missing the required `name`
  - name: x
    networks:
      - ipv4_address: 10.0.0.5   # a network entry with no `name`

Unknown, driver-specific keys are intentionally not affected. MoleculePlatformModel keeps additionalProperties: true, so an entry with a typo'd or unrecognized key still validates by design — each driver owns its own key set, and molecule cannot know them all. What this PR enforces is the typed, driver-agnostic shape (required name, children a list of strings, structured networks), not the open set of driver keys.

Root cause

The schema was introduced with strict platform validation in #3668, where platforms.items was {"$ref": "#/$defs/MoleculePlatformModel"}. #3765 ("Extend schema validation", commit 5cd19b0) later replaced that $ref with {"type": "object"} and, in the same change, stripped MoleculeDriverModel down to name with additionalProperties: true, removing the last reference to MoleculeDriverOptionsModel. The definition bodies were left in place, now unreachable.

The intent of #3765 (see #3689, "Move Driver JSONSchema Validation to Drivers") was to let each driver own its driver-specific schema rather than centralize every driver key in molecule. That is reasonable for driver-specific keys, but detaching MoleculePlatformModel wholesale also dropped the driver-agnostic platform shape (children is a list of strings, name is required, networks has structure), and left the definitions orphaned. The later native ansible: configuration work inherited the already-open platforms and is not the cause.

There is a precedent for the driver-agnostic shape being validated: the sibling schema src/molecule/data/driver.json carries its own separate, minimal MoleculePlatformModel and already references it from its own platforms.items, so delegated-driver configs get a required name and a list-of-strings children while the root molecule.json does not. That confirms the shape is meant to apply to platforms[]; in molecule.json the definition was simply left detached. This PR restores only the root $ref in molecule.json; it does not touch driver.json.

Because the schema is maintained by hand (the validator in molecule/model/schema_v3.py loads molecule.json and calls jsonschema.validate; there is no generation step), the fix is a direct edit to the JSON.

Changes

  • Point platforms.items at #/$defs/MoleculePlatformModel. This revives MoleculePlatformModel and its dependencies platform-network and ContainerRegistryModel. MoleculePlatformModel keeps additionalProperties: true, so unknown driver-specific keys remain permitted; only the typed, driver-agnostic fields are enforced.
  • Relax three types that had drifted from the docker/podman drivers, so the restored model does not raise false positives:
    • command: string -> string | array, with the array's items typed as string. community.docker.docker_container.command is type: raw (string or list of strings), and the podman driver defaults it to a list. Constraining items to string keeps argv-style commands validated instead of accepting any element (e.g. [1, {}, null]).
    • cpus: integer -> number. docker cpus is a float (for example 1.5).
    • memory: integer -> string | integer. docker memory is a string such as "512M" / "1G".
  • Add positive and negative platform fixtures in both the schema_instance_files (check-jsonschema) set and the schema_v3 unit tests, so this cannot silently regress again.

Verification

  • Reproduced first, then fixed. Against the unmodified schema, the malformed entries above validate (exit 0). After the change they are rejected: missing name -> 'name' is a required property; children: 2 -> 2 is not of type 'array'; a networks entry with no name -> 'name' is a required property.
  • The relaxed types accept real driver values: command: ["bash", "-c", "..."], cpus: 1.5, memory: "512m"; and the previous scalar forms (command: "...", memory: 512) still validate, so the change is backward compatible.
  • The array-form command is constrained to string elements: command: ["bash", "-c", "..."] validates, while a non-string element (command: ["bash", 42]) is now rejected — added as a schema_instance_files negative fixture and asserted in test_molecule_schema.
  • No regression across the repo: every existing in-repo molecule.yml that carries a platforms: block still validates against the updated schema.
  • tests/unit/model/v2 passes, including test_molecule_schema (which runs check-jsonschema) and the new platform tests.
  • The JSON formatting hook (biome) passes on the edited molecule.json.

Related

Complements ansible/ansible-lint#5119. That issue makes ansible-lint validate molecule.yml against this schema by default; this change ensures the schema it validates against actually catches malformed platforms entries. The two together close the loop: linting validates molecule config, and the schema it validates against is correct.

Summary by CodeRabbit

  • Enhancements
    • Expanded Molecule platform configuration schema validation: command now accepts either a string or an argv-style list.
    • cpus now supports decimal (numeric) values; memory now accepts either a string (e.g., 512m) or an integer.
    • platforms is validated more precisely using the platform model.
  • Bug Fixes
    • Stricter schema checks now correctly reject malformed platforms definitions (e.g., children not being a list).
  • Tests
    • Added/expanded fixtures and unit tests covering valid relaxed configurations and invalid children/command cases.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The platform schema now references MoleculePlatformModel, supports array commands and relaxed CPU/memory types, and includes valid and invalid platform fixtures with unit and CLI validation coverage.

Changes

Platform schema validation

Layer / File(s) Summary
Platform model schema updates
src/molecule/data/molecule.json
MoleculePlatformModel accepts array commands, numeric CPUs, and string or integer memory values; top-level platform items now use its $ref.
Platform validation coverage
tests/fixtures/resources/schema_instance_files/..., tests/unit/model/v2/...
Valid and invalid platform fixtures and tests cover expanded field types, required fields, and invalid children and command values.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% 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
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main change: validating platforms entries against MoleculePlatformModel.
✨ 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.

@jeffcpullen
jeffcpullen force-pushed the fix/platforms-schema-validation branch 2 times, most recently from 61602dd to 924f8a8 Compare July 20, 2026 00:29
@jeffcpullen

Copy link
Copy Markdown
Contributor Author

My original PR wasn't signed, so I followed the directions in the Ansible forum to fix the issue. Pipeline continues to fail with a 503 error to the Github validation endpoint even though I've rebased and have a signed commit. So I'm guessing this is a pipeline issue. If the issue is on my end please let me know and I'll keep digging.

@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 `@src/molecule/data/molecule.json`:
- Around line 212-214: Update the command schema’s array branch under the
command property to define an items schema of type string, while preserving
support for scalar strings and arrays. Ensure array-form commands reject
non-string elements such as numbers, objects, and nulls.
🪄 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: Pro Plus

Run ID: 9b83030d-f477-4460-a1cc-f068451e3e12

📥 Commits

Reviewing files that changed from the base of the PR and between 18e46f6 and 1e3e469.

📒 Files selected for processing (6)
  • src/molecule/data/molecule.json
  • tests/fixtures/resources/schema_instance_files/invalid/molecule_platforms.yml
  • tests/fixtures/resources/schema_instance_files/valid/platforms.yml
  • tests/unit/model/v2/conftest.py
  • tests/unit/model/v2/test_platforms_section.py
  • tests/unit/model/v2/test_schema.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/fixtures/resources/schema_instance_files/invalid/molecule_platforms.yml
  • tests/unit/model/v2/conftest.py
  • tests/fixtures/resources/schema_instance_files/valid/platforms.yml
  • tests/unit/model/v2/test_platforms_section.py
  • tests/unit/model/v2/test_schema.py

Comment thread src/molecule/data/molecule.json
@jeffcpullen
jeffcpullen force-pushed the fix/platforms-schema-validation branch from 1e3e469 to 5a9b8bf Compare July 24, 2026 04:57
@jeffcpullen
jeffcpullen force-pushed the fix/platforms-schema-validation branch 2 times, most recently from b225e9d to ded7c49 Compare July 31, 2026 20:22
The root molecule.json schema typed `platforms.items` as an open
`{"type": "object"}`, so every entry under `platforms:` was silently
unvalidated. Its `$defs/MoleculePlatformModel` definition (typed
children/networks, required name) was left orphaned once `platforms.items`
went open; nothing in molecule.json referenced it. (driver.json keeps its
own separate model of that name and is not touched here.)

Point `platforms.items` at `#/$defs/MoleculePlatformModel` and relax
three types that had drifted from the docker/podman drivers so the
restored model does not raise false positives:

- command: string -> string|array with array items typed as string
  (docker command is `raw`; the podman driver defaults it to a list of
  strings), so argv-style commands stay validated rather than accepting
  any element
- cpus: integer -> number (docker cpus is a float, e.g. 1.5)
- memory: integer -> string|integer (docker memory is a str, e.g. "512m")

Add positive/negative platform fixtures in both the schema_instance_files
(check-jsonschema) convention and the schema_v3 unit tests so the drift
cannot silently return, including a negative fixture rejecting a
non-string element in an array-form command.

Assisted-by: Claude (Anthropic)
Signed-off-by: Jeff Pullen <9343691+jeffcpullen@users.noreply.github.com>
@jeffcpullen
jeffcpullen force-pushed the fix/platforms-schema-validation branch from ded7c49 to 94d019f Compare July 31, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant