Ignore write-only properties in schema-aware diffs - #1674
Ignore write-only properties in schema-aware diffs#1674Steve Lee (SteveL-MSFT) wants to merge 4 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR reduces false-positive schema-aware differences when resources intentionally do not return “instruction-only” properties by making get_diff_with_schema() ignore schema properties marked writeOnly: true. It also updates the Windows Firewall resource schema and tests to reflect that unspecifiedRulesAction is write-only and should not affect desired-state comparisons.
Changes:
- Update
get_diff_with_schema()to skip properties whose JSON Schema setswriteOnly: true, and add unit tests for write-only behavior. - Mark
unspecifiedRulesActionaswriteOnlyin the Windows Firewall resource schema. - Adjust Windows Firewall resource tests to assert non-default
unspecifiedRulesActionvalues do not cause diffs.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| resources/windows_firewall/windows_firewall.dsc.resource.json | Marks unspecifiedRulesAction as writeOnly so it’s excluded from schema-aware diffing. |
| resources/windows_firewall/tests/windows_firewall_schema_default.tests.ps1 | Updates resource tests to assert unspecifiedRulesAction does not affect inDesiredState/diff output. |
| lib/dsc-lib/src/dscresources/dscresource.rs | Implements write-only skipping in schema-aware diffs and adds unit tests for the behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
😁 Code Coverage ReportChanged Code Coverage94% (90%+ coverage)
🔵 Full Codebase Coverage82% (good)
|
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
|
||
| /// Returns whether a property's JSON Schema sets `writeOnly` to `true`, directly or | ||
| /// through a local JSON Pointer reference. | ||
| fn is_schema_write_only(schema: Option<&Value>, property_name: &str) -> bool { |
There was a problem hiding this comment.
Initially, I was going to recommend implementing this would be easier in the dsc-lib-jsonschema crate, but thinking about this a bit more, I think the ergonomics and simplicity will mostly improve when we implement the in-memory schema registry and retriever, when we can call deference() to get the full property definition for verification.
| let Some(pointer) = reference.strip_prefix('#') else { | ||
| return false; | ||
| }; |
There was a problem hiding this comment.
This works for pointer references like #/$defs/foo but not URI references (site-relative or absolute), like https://schemas.contoso.com/foo or /foo.
The formalized bundling format for JSON Schema 2020-12 (known more correctly as a compound schema document) is to ensure that you include any external schemas in the $defs keyword with their $id keyword.
For example, the following non-bundled schema:
{
"$id": "https://jsonschema.dev/schemas/examples/non-negative-integer",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Must be a non-negative integer",
"$ref": "#/$defs/nonNegativeInteger"
"$defs": {
"nonNegativeInteger": {
"allOf": [
{ "$ref": "/schemas/mixins/integer" },
{ "$ref": "/schemas/mixins/non-negative" }
]
}
},
}Bundles to the following compound schema document:
{
"$id": "https://jsonschema.dev/schemas/examples/non-negative-integer-bundle",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Must be a non-negative integer",
"$ref": "#/$defs/nonNegativeInteger"
"$defs": {
"nonNegativeInteger": {
"allOf": [
{ "$ref": "/schemas/mixins/integer" },
{ "$ref": "/schemas/mixins/non-negative" }
]
},
"https://jsonschema.dev/schemas/mixins/integer": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://jsonschema.dev/schemas/mixins/integer",
"description": "Must be an integer",
"type": "integer"
},
"https://jsonschema.dev/schemas/mixins/non-negative": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://jsonschema.dev/schemas/mixins/non-negative",
"description": "Not allowed to be negative",
"minimum": 0
}
},
}When a validator resolves a relative URI like /schemas/mixins/integer, it does so _relative to the schemas $id URI.
The key in the $defs for bundled schema resources doesn't matter, using the absolute URI is a convention that ensures unique keys for each resource. What the resolver does is look for a subschema in $defs that defines an $id that matches the reference.
We have an extension method on the schemars::Schema type for checking whether a reference is to a bundled schema resource that handles both pointers and absolute/relative URI references:
DSC/lib/dsc-lib-jsonschema/src/schema_utility_extensions.rs
Lines 1619 to 1666 in 88ca706
There was a problem hiding this comment.
One of the limitations we have is we CAN'T do a HTTP call to retrieve URLs due to compliance restrictions
|
Copilot resolve the merge conflicts in this pull request |
Co-authored-by: SteveL-MSFT <11859881+SteveL-MSFT@users.noreply.github.com>
Co-authored-by: SteveL-MSFT <11859881+SteveL-MSFT@users.noreply.github.com>
Resolved the conflicts by merging |
Properties used only as resource instructions may not be returned by a resource, which caused schema-aware comparisons to report false differences.
This change makes
get_diff_with_schema()skip properties markedwriteOnly: truein the resource schema. The Windows Firewall resource now marksunspecifiedRulesActionas write-only, and unit and resource tests cover differing, omitted, and explicitly non-write-only properties.Fix #1668