feat(rvm): implement Azure Policy condition evaluation (#661)

Add VM support for Azure Policy's condition operators and allOf/anyOf
short-circuit logic, gated behind cfg(feature = "azure_policy").

Policy conditions (equals, contains, like, match, exists, and their
negations — 21 total) are encoded as a single PolicyCondition
instruction with a PolicyOp sub-opcode rather than bloating the
Instruction enum with 21 variants. The dispatch handles Azure Policy's
quirky comparison semantics: case-insensitive string comparison,
string↔number coercion, null vs undefined distinction, and element-wise
collection membership.

allOf/anyOf blocks use four instructions — LogicalBlockStart,
AllOfNext/AnyOfNext, and LogicalBlockEnd — that wire up a result
register and short-circuit on the first failing (allOf) or passing
(anyOf) child.

Helper functions for case-folded comparison, wildcard/glob matching, and
type coercion live in builtins::azure_policy::helpers.

Two YAML test suites (~2200 lines) exercise the full operator matrix and
the allOf/anyOf control flow.
This commit is contained in:
Anand Krishnamoorthi
2026-04-07 19:04:24 -05:00
committed by GitHub
parent 83ce8c3580
commit 4d35744c4f
10 changed files with 3165 additions and 3 deletions
+62 -1
View File
@@ -10,7 +10,9 @@ pub use params::{
FunctionCallParams, InstructionData, LoopStartParams, ObjectCreateParams, SetCreateParams,
VirtualDataDocumentLookupParams,
};
pub use types::{ComprehensionMode, GuardMode, LiteralOrRegister, LoopMode};
pub use types::{
ComprehensionMode, GuardMode, LiteralOrRegister, LogicalBlockMode, LoopMode, PolicyOp,
};
use serde::{Deserialize, Serialize};
@@ -355,6 +357,65 @@ pub enum Instruction {
/// End a comprehension block
ComprehensionEnd {},
// ── Azure Policy condition operators (consolidated) ────────────────
/// Consolidated Azure Policy condition instruction.
///
/// Replaces 21 separate Policy* variants. The `op` discriminant selects
/// the specific Azure Policy condition semantics.
///
/// For most ops: `dest = op(left, right)`.
/// For `PolicyOp::Not`: `dest = !is_true(left)`, `right` is unused (0).
/// For `PolicyOp::ValueConditionGuard`: `left` = value register,
/// `right` = condition register.
PolicyCondition {
dest: u8,
left: u8,
right: u8,
op: PolicyOp,
},
// ── AllOf / AnyOf structured short-circuit instructions ───────────
/// Initialize allOf/anyOf: set result register to false.
LogicalBlockStart {
mode: LogicalBlockMode,
/// Register that accumulates the result.
result: u8,
/// PC of the corresponding End instruction.
end_pc: u16,
},
/// Check one allOf child: if not true, short-circuit (result stays false),
/// jump to end_pc.
AllOfNext {
/// Register holding the child condition result.
check: u8,
/// Register that accumulates the allOf result.
result: u8,
/// PC of the AllOfEnd instruction (jump target on short-circuit).
end_pc: u16,
},
/// Check one anyOf child: if true, short-circuit (set result to true),
/// jump to end_pc.
AnyOfNext {
/// Register holding the child condition result.
check: u8,
/// Register that accumulates the anyOf result.
result: u8,
/// PC of the AnyOfEnd instruction.
end_pc: u16,
},
/// Finalize allOf/anyOf block.
///
/// For AllOf: all children passed → set result to true.
/// For AnyOf: no child matched → result stays false (no-op).
LogicalBlockEnd {
mode: LogicalBlockMode,
/// Register that accumulates the result.
result: u8,
},
}
impl Instruction {