mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
* feat: add Azure Policy alias normalization/denormalization Add normalizer and denormalizer for ARM JSON resources, enabling Azure Policy alias short names to become direct paths into a flat structure. - Normalizer: flattens properties wrappers, lowercases keys, resolves per-alias versioned ARM paths, handles sub-resource array flattening, element-level field remaps, and array base renames - Denormalizer: reverses all transformations with casing restoration - AliasRegistry: loads production alias catalogs and data policy manifests - Types: serde deserialization for ARM provider alias formats - YAML test suite: 13 test files covering normalize, denormalize, round-trip, data-plane, edge cases, malformed input, sub-resources, and registry API - Benchmark suite for normalization performance * feat: add FFI and C# bindings for alias normalization - FFI: alias_registry.rs with C-compatible API for loading catalogs, normalizing resources, and denormalizing back to ARM JSON - C#: AliasRegistry wrapper class with NativeMethods P/Invoke bindings and integration tests - Updated Cargo.lock files for new serde_json dependency
202 lines
5.7 KiB
YAML
202 lines
5.7 KiB
YAML
# Tests pinning behavior for ambiguous or malformed inputs that could
|
|
# be produced by external callers rather than the normalizer itself.
|
|
#
|
|
# The normalizer / denormalizer make assumptions about their input shape
|
|
# (e.g., keys are fully lowercased after normalization). These tests
|
|
# document what happens when those assumptions are violated, without
|
|
# asserting the behavior is "correct" per se — rather, they pin it so
|
|
# regressions are detected.
|
|
|
|
aliases_json: |
|
|
[
|
|
{
|
|
"namespace": "Microsoft.Storage",
|
|
"resourceTypes": [
|
|
{
|
|
"resourceType": "storageAccounts",
|
|
"aliases": [
|
|
{
|
|
"name": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
|
|
"defaultPath": "properties.supportsHttpsTrafficOnly",
|
|
"paths": []
|
|
},
|
|
{
|
|
"name": "Microsoft.Storage/storageAccounts/accessTier",
|
|
"defaultPath": "properties.accessTier",
|
|
"paths": []
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"namespace": "Microsoft.Network",
|
|
"resourceTypes": [
|
|
{
|
|
"resourceType": "networkSecurityGroups",
|
|
"aliases": [
|
|
{
|
|
"name": "Microsoft.Network/networkSecurityGroups/securityRules[*].protocol",
|
|
"defaultPath": "properties.securityRules[*].properties.protocol",
|
|
"paths": []
|
|
},
|
|
{
|
|
"name": "Microsoft.Network/networkSecurityGroups/securityRules[*].access",
|
|
"defaultPath": "properties.securityRules[*].properties.access",
|
|
"paths": []
|
|
},
|
|
{
|
|
"name": "Microsoft.Network/networkSecurityGroups/securityRules[*].name",
|
|
"defaultPath": "properties.securityRules[*].name",
|
|
"paths": []
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"namespace": "Microsoft.Web",
|
|
"resourceTypes": [
|
|
{
|
|
"resourceType": "sites",
|
|
"aliases": [
|
|
{
|
|
"name": "Microsoft.Web/sites/isEnabled",
|
|
"defaultPath": "properties.isEnabled",
|
|
"paths": [
|
|
{
|
|
"path": "properties.enabled",
|
|
"apiVersions": ["2020-01-01"]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
|
|
cases:
|
|
# ── Normalize: ARM input with both root and properties having same field ──
|
|
|
|
- note: "normalize: both root 'name' and properties.name (root wins)"
|
|
input:
|
|
name: root-name
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
properties:
|
|
name: props-name
|
|
accessTier: Hot
|
|
expected_normalized:
|
|
name: root-name
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
accesstier: Hot
|
|
|
|
# ── Normalize: extra fields not in alias catalog or ROOT_FIELDS ──
|
|
|
|
- note: "normalize: extra non-aliased properties are kept (lowercased)"
|
|
input:
|
|
name: test
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
properties:
|
|
supportsHttpsTrafficOnly: true
|
|
customUnknownField: 42
|
|
expected_normalized:
|
|
name: test
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
supportshttpstrafficonly: true
|
|
customunknownfield: 42
|
|
|
|
# ── Denormalize: input has mixed casing (externally constructed) ──
|
|
|
|
- note: "denormalize: mixed-case keys still resolve via aliases"
|
|
input:
|
|
name: test
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
SupportsHttpsTrafficOnly: true
|
|
expected_denormalized:
|
|
name: test
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
properties:
|
|
supportsHttpsTrafficOnly: true
|
|
|
|
# ── Denormalize: input has extra fields not in alias catalog ──
|
|
|
|
- note: "denormalize: unknown fields go under properties (control-plane)"
|
|
input:
|
|
name: test
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
unknownfield: 123
|
|
accesstier: Hot
|
|
expected_denormalized:
|
|
name: test
|
|
type: "Microsoft.Storage/storageAccounts"
|
|
properties:
|
|
unknownfield: 123
|
|
accessTier: Hot
|
|
|
|
# ── Denormalize with versioned path: both alias-named and ARM-named present ──
|
|
|
|
- note: "denormalize: both isenabled and enabled present, alias wins"
|
|
input:
|
|
type: "Microsoft.Web/sites"
|
|
isenabled: true
|
|
enabled: false
|
|
api_version: "2020-01-01"
|
|
expected_denormalized:
|
|
type: "Microsoft.Web/sites"
|
|
properties:
|
|
enabled: true
|
|
|
|
- note: "denormalize: both isenabled and enabled present, default path"
|
|
input:
|
|
type: "Microsoft.Web/sites"
|
|
isenabled: true
|
|
enabled: false
|
|
expected_denormalized:
|
|
type: "Microsoft.Web/sites"
|
|
properties:
|
|
isEnabled: true
|
|
enabled: false
|
|
|
|
# ── Normalize: ARM resource with empty type ──
|
|
|
|
- note: "normalize: empty type field, no alias match"
|
|
input:
|
|
name: test
|
|
type: ""
|
|
properties:
|
|
foo: bar
|
|
expected_normalized:
|
|
name: test
|
|
type: ""
|
|
foo: bar
|
|
|
|
# ── Normalize: ARM resource with null properties ──
|
|
|
|
- note: "normalize: null properties value"
|
|
input:
|
|
name: test
|
|
properties: null
|
|
expected_normalized:
|
|
name: test
|
|
|
|
# ── Denormalize: sub-resource array with elements already containing properties ──
|
|
|
|
- note: "denormalize: elements already have properties wrapper (double-wrap)"
|
|
input:
|
|
name: myNsg
|
|
type: "Microsoft.Network/networkSecurityGroups"
|
|
securityrules:
|
|
- name: rule1
|
|
properties:
|
|
protocol: Tcp
|
|
expected_denormalized:
|
|
name: myNsg
|
|
type: "Microsoft.Network/networkSecurityGroups"
|
|
properties:
|
|
securityRules:
|
|
- name: rule1
|
|
properties:
|
|
properties:
|
|
protocol: Tcp
|