fix: validate platforms entries against MoleculePlatformModel - #4661
fix: validate platforms entries against MoleculePlatformModel#4661jeffcpullen wants to merge 1 commit into
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe platform schema now references ChangesPlatform schema validation
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
61602dd to
924f8a8
Compare
|
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. |
18e46f6 to
1e3e469
Compare
There was a problem hiding this comment.
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
📒 Files selected for processing (6)
src/molecule/data/molecule.jsontests/fixtures/resources/schema_instance_files/invalid/molecule_platforms.ymltests/fixtures/resources/schema_instance_files/valid/platforms.ymltests/unit/model/v2/conftest.pytests/unit/model/v2/test_platforms_section.pytests/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
1e3e469 to
5a9b8bf
Compare
b225e9d to
ded7c49
Compare
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>
ded7c49 to
94d019f
Compare
Summary
The
platforms:section ofmolecule.ymldefines 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 requirednameor a malformednetworksblock 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.itemsinsrc/molecule/data/molecule.jsonis typed as an open{"type": "object"}, so any object is accepted. The$defs/MoleculePlatformModeldefinition (typedchildren/networks, requiredname, and its dependenciesplatform-networkandContainerRegistryModel) 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:
Unknown, driver-specific keys are intentionally not affected.
MoleculePlatformModelkeepsadditionalProperties: 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 (requiredname,childrena list of strings, structurednetworks), not the open set of driver keys.Root cause
The schema was introduced with strict platform validation in #3668, where
platforms.itemswas{"$ref": "#/$defs/MoleculePlatformModel"}. #3765 ("Extend schema validation", commit5cd19b0) later replaced that$refwith{"type": "object"}and, in the same change, strippedMoleculeDriverModeldown tonamewithadditionalProperties: true, removing the last reference toMoleculeDriverOptionsModel. 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
MoleculePlatformModelwholesale also dropped the driver-agnostic platform shape (childrenis a list of strings,nameis required,networkshas structure), and left the definitions orphaned. The later nativeansible:configuration work inherited the already-openplatformsand is not the cause.There is a precedent for the driver-agnostic shape being validated: the sibling schema
src/molecule/data/driver.jsoncarries its own separate, minimalMoleculePlatformModeland already references it from its ownplatforms.items, so delegated-driver configs get a requirednameand a list-of-stringschildrenwhile the rootmolecule.jsondoes not. That confirms the shape is meant to apply toplatforms[]; inmolecule.jsonthe definition was simply left detached. This PR restores only the root$refinmolecule.json; it does not touchdriver.json.Because the schema is maintained by hand (the validator in
molecule/model/schema_v3.pyloadsmolecule.jsonand callsjsonschema.validate; there is no generation step), the fix is a direct edit to the JSON.Changes
platforms.itemsat#/$defs/MoleculePlatformModel. This revivesMoleculePlatformModeland its dependenciesplatform-networkandContainerRegistryModel.MoleculePlatformModelkeepsadditionalProperties: true, so unknown driver-specific keys remain permitted; only the typed, driver-agnostic fields are enforced.command:string->string | array, with the array'sitemstyped asstring.community.docker.docker_container.commandistype: raw(string or list of strings), and the podman driver defaults it to a list. Constrainingitemstostringkeeps argv-style commands validated instead of accepting any element (e.g.[1, {}, null]).cpus:integer->number. dockercpusis a float (for example1.5).memory:integer->string | integer. dockermemoryis a string such as"512M"/"1G".schema_instance_files(check-jsonschema) set and theschema_v3unit tests, so this cannot silently regress again.Verification
name->'name' is a required property;children: 2->2 is not of type 'array'; anetworksentry with noname->'name' is a required property.command: ["bash", "-c", "..."],cpus: 1.5,memory: "512m"; and the previous scalar forms (command: "...",memory: 512) still validate, so the change is backward compatible.commandis constrained to string elements:command: ["bash", "-c", "..."]validates, while a non-string element (command: ["bash", 42]) is now rejected — added as aschema_instance_filesnegative fixture and asserted intest_molecule_schema.molecule.ymlthat carries aplatforms:block still validates against the updated schema.tests/unit/model/v2passes, includingtest_molecule_schema(which runs check-jsonschema) and the new platform tests.molecule.json.Related
Complements ansible/ansible-lint#5119. That issue makes ansible-lint validate
molecule.ymlagainst this schema by default; this change ensures the schema it validates against actually catches malformedplatformsentries. The two together close the loop: linting validates molecule config, and the schema it validates against is correct.Summary by CodeRabbit
commandnow accepts either a string or an argv-style list.cpusnow supports decimal (numeric) values;memorynow accepts either a string (e.g.,512m) or an integer.platformsis validated more precisely using the platform model.platformsdefinitions (e.g.,childrennot being a list).children/commandcases.