Skip to content

feat(azure-policy): add policy rule and policy definition parsers#660

Draft
anakrish wants to merge 1 commit intomicrosoft:mainfrom
anakrish:azure-policy-parser
Draft

feat(azure-policy): add policy rule and policy definition parsers#660
anakrish wants to merge 1 commit intomicrosoft:mainfrom
anakrish:azure-policy-parser

Conversation

@anakrish
Copy link
Copy Markdown
Collaborator

@anakrish anakrish commented Apr 4, 2026

Extend the Azure Policy parser to handle complete policyRule and
policyDefinition JSON structures, not just standalone constraints.

Policy rule parser (policy_rule.rs):

  • Parse top-level { "if": ..., "then": ... } objects
  • Extract effect kind (deny, audit, append, modify, etc.) into typed AST
  • Parse "details" structurally when it's an object to pull out
    existenceCondition as a first-class Constraint; fall back to opaque
    JSON for non-object details (e.g. append's array form)
  • Detect duplicate/missing keys for "if", "then", "effect", "details"

Policy definition parser (policy_definition.rs):

  • Handle both wrapped ARM envelope ({ "properties": { ... } }) and
    unwrapped (properties-level keys at top level) forms
  • Type-extract displayName, description, mode, metadata, parameters,
    and policyRule; everything else goes into extra
  • Parse parameter definitions with type, defaultValue, allowedValues,
    and metadata; detect duplicate parameter names
  • Duplicate key detection throughout

Grammar documentation (docs/azure-policy/azurepolicy.ebnf):

  • Add formal EBNF grammar covering policy-rule, then-block,
    constraints, conditions, all 20 operators, count expressions,
    JSON values, and ARM template expressions

Test harness changes:

  • Add parse_level field to YAML test cases: "constraint" (default),
    "policy_rule", or "policy_definition"
  • Un-skip three parse_errors cases that needed policy_rule-level parsing
  • Add policy_rule.yaml with 12 cases covering all 9 effect kinds,
    existenceCondition, parameterized effects, complex conditions, and
    extra key handling
  • Add policy_definition.yaml with wrapped, unwrapped, parameterized,
    and missing-policyRule error cases

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds new Azure Policy parsing entry points for full policyRule and full policy definition envelopes, extending the existing constraint-only parser and broadening the YAML-driven test harness to run at different parse “levels”.

Changes:

  • Introduce parse_policy_rule() (top-level "if" + "then", effect handling, existenceCondition extraction).
  • Introduce parse_policy_definition() (wrapped/unwrapped envelope handling, parameter definitions, policyRule parsing).
  • Extend YAML test harness with parse_level and add new test suites for policy rules/definitions.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/azure_policy/parser_tests/mod.rs Adds parse_level switching to run tests against constraint/policy_rule/policy_definition parsers.
tests/azure_policy/parser_tests/cases/policy_rule.yaml New YAML cases exercising full policyRule parsing.
tests/azure_policy/parser_tests/cases/policy_definition.yaml New YAML cases exercising full policy definition envelope parsing.
tests/azure_policy/parser_tests/cases/parse_errors.yaml Un-skips policy_rule-level error cases by switching them to parse_level: policy_rule.
src/languages/azure_policy/parser/policy_rule.rs New policy rule + then-block parser and existenceCondition extraction.
src/languages/azure_policy/parser/policy_definition.rs New policy definition parser plus JSON re-serialization helpers for reparsing policyRule.
src/languages/azure_policy/parser/mod.rs Exposes new public APIs and updates module docs.
src/languages/azure_policy/ast/mod.rs Updates EffectKind::Other to carry a string payload; updates parameter doc comment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@anakrish anakrish force-pushed the azure-policy-parser branch 2 times, most recently from a20db77 to 270f8b6 Compare April 4, 2026 18:42
@anakrish anakrish requested a review from Copilot April 4, 2026 19:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@anakrish anakrish force-pushed the azure-policy-parser branch 2 times, most recently from 4b4118e to 949ca8a Compare April 5, 2026 02:47
@anakrish anakrish requested a review from Copilot April 5, 2026 02:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@anakrish anakrish force-pushed the azure-policy-parser branch from 949ca8a to f36aab3 Compare April 5, 2026 03:15
@anakrish anakrish requested a review from Copilot April 5, 2026 03:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +133 to +134
let constraint_json =
extract_if_json(&policy_rule_json).unwrap_or_else(|| policy_rule_json.clone());
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

In the constraint parse_level branch, unwrap_or_else(|| policy_rule_json.clone()) clones the entire JSON string on the fallback path. This can be avoided by restructuring to move policy_rule_json into constraint_json when extraction fails (e.g., using a match on extract_if_json(...)) so the error-path tests don’t pay an extra allocation for large inputs.

Suggested change
let constraint_json =
extract_if_json(&policy_rule_json).unwrap_or_else(|| policy_rule_json.clone());
let constraint_json = match extract_if_json(&policy_rule_json) {
Some(constraint_json) => constraint_json,
None => policy_rule_json,
};

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +183 to +186
self.expect_symbol("{")?;

let mut seen_keys: Vec<String> = Vec::new();

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

parse_properties_fields creates a fresh seen_keys list, so duplicate detection for recognized properties (e.g., displayName, mode, policyRule, parameters) does not apply across the outer object and the inner properties object. If a wrapped ARM envelope contains a recognized key before properties (or inside extra) and the same key appears inside properties, the later parse will overwrite the earlier typed field without producing ParseError::DuplicateKey, contradicting “duplicate key detection throughout”. Consider sharing a single case-insensitive seen_keys set between the outer loop and parse_properties_fields (or explicitly rejecting/extra-ifying recognized keys once properties is detected) so cross-scope duplicates can’t silently overwrite.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Extend the Azure Policy parser to handle complete policyRule and
policyDefinition JSON structures, not just standalone constraints.

Policy rule parser (policy_rule.rs):
- Parse top-level { "if": ..., "then": ... } objects
- Extract effect kind (deny, audit, append, modify, etc.) into typed AST
- Parse "details" structurally when it is an object to pull out
  existenceCondition as a first-class Constraint; fall back to opaque
  JSON for non-object details (e.g. append array form)
- Detect duplicate/missing keys for "if", "then", "effect", "details"

Policy definition parser (policy_definition.rs):
- Handle both wrapped ARM envelope ({ "properties": { ... } }) and
  unwrapped (properties-level keys at top level) forms
- Type-extract displayName, description, mode, metadata, parameters,
  and policyRule; everything else goes into extra
- Parse parameter definitions with type, defaultValue, allowedValues,
  and metadata; detect duplicate parameter names
- Duplicate key detection throughout

Grammar documentation (docs/azure-policy/azurepolicy.ebnf):
- Add formal EBNF grammar covering policy-rule, then-block,
  constraints, conditions, all 19 operators, count expressions,
  JSON values, and ARM template expressions

Test harness changes:
- Add parse_level field to YAML test cases: "constraint" (default),
  "policy_rule", or "policy_definition"
- Un-skip three parse_errors cases that needed policy_rule-level parsing
- Add policy_rule.yaml with 12 cases covering all 9 effect kinds,
  existenceCondition, parameterized effects, complex conditions, and
  extra key handling
- Add policy_definition.yaml with wrapped, unwrapped, parameterized,
  missing-policyRule, and duplicate-key error cases
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants