Files
regorus/src/target.rs
Anand Krishnamoorthi cc917ea75d feat: Complete target system with C# bindings and resource inference (#458)
* feat: Add Schema Registry and Validation Framework

This commit introduces a comprehensive schema registry and validation framework, providing schema-based validation of resources and policy effects.

- Thread-safe, in-memory registry for schema storage and management
- Global registry patterns for effects and resources
- Concurrent access with proper error handling
- Unicode schema names support

- JSON Schema-compliant validation for all primitive types
- Advanced constraint validation (patterns, ranges, length limits)
- Discriminated union support with anyOf schemas
- Detailed error reporting with nested validation paths
- Discriminated subobject validation for polymorphic schemas

- **Registry Tests**: All registry operations
- **Effect Tests**: Policy effect validation
- **Resource Tests**: Resource validation
- **Validation Tests**: Core validation engine
- Thread-safety, error handling, integration scenarios, edge cases

- **Dependencies**: dashmap, once_cell, regex
- **Thread Safety**: Minimal locking with Rc<Schema> sharing
- **Error Types**: TypeMismatch, OutOfRange, PatternMismatch, etc.

- Complete schema registry and validation subsystem
- Comprehensive test coverage
- Foundation for policy validation in Regorus

Benchmarks:

- Criterion benchmarks for basic types, effects and Azure resources
- Performance range: 3.22ns (string) to 34.74µs (Azure VM resource schema validation)
- String withs patterns validation: 30.2µs. Need to explore whether regex caching helps
  bring this down.
- Azure policy effects: 188ns-1.4µs

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

* feat: Complete target system with C# bindings and resource inference

- Add comprehensive target system with TargetRegistry and target-aware compilation
- Implement resource type inference from policy equality expressions
- Create modular C# bindings with separate wrapper classes for each concept
- Add thread-safe CompiledPolicy with reference counting for safe disposal
- Enhance FFI with detailed error propagation and target functionality
- Create TargetExampleApp demonstrating Azure Policy integration
- Add CI/CD pipeline testing for all C# applications
- Support target definitions with schema validation and resource selectors
- Implement PolicyModule struct and target-aware compilation methods
- Add comprehensive test coverage for target functionality

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

---------

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
2025-08-19 20:23:43 -05:00

80 lines
2.5 KiB
Rust

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#![allow(dead_code)]
use crate::{Rc, Schema, Value, Vec};
use alloc::collections::BTreeMap;
use serde::Deserialize;
mod deserialize;
mod error;
mod resource_schema_selector;
type String = Rc<str>;
use deserialize::{deserialize_effects, deserialize_resource_schemas};
pub use error::TargetError;
/// A target defines the domain for which a set of policies are written.
/// It specifies the types of input resources, possible policy effects,
/// and configuration for policy evaluation.
#[derive(Debug, Clone, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Target {
/// Name of the target domain
/// A Rego module can specify a target by defining a rule named `__target__`:
/// __target__ = "my_target"
pub name: String,
/// Description of what this target is for
pub description: Option<String>,
/// Version of the target
pub version: String,
/// Types of input resources that policies can evaluate
#[serde(deserialize_with = "deserialize_resource_schemas")]
pub resource_schemas: Vec<Rc<Schema>>,
/// The discriminator property that can be used to select
/// a specific resource schema
pub resource_schema_selector: String,
/// Set of effects that policies can produce
#[serde(deserialize_with = "deserialize_effects")]
pub effects: BTreeMap<String, Rc<Schema>>,
/// Lookup table for resource schemas by discrimiator values.
#[serde(skip)]
pub resource_schema_lookup: BTreeMap<Value, Rc<Schema>>,
/// Resource chemas that cannot be distinguished by the discriminator
#[serde(skip)]
pub default_resource_schema: Option<Rc<Schema>>,
}
impl Target {
pub fn from_json_str(json: &str) -> Result<Self, TargetError> {
let mut target: Target = serde_json::from_str(json).map_err(TargetError::from)?;
// Validate that resource schemas is not empty
if target.resource_schemas.is_empty() {
return Err(TargetError::EmptyResourceSchemas(
"Target must have at least one resource schema defined".into(),
));
}
if target.effects.is_empty() {
return Err(TargetError::EmptyEffectSchemas(
"Target must have at least one effect defined".into(),
));
}
resource_schema_selector::populate_target_lookup_fields(&mut target)?;
Ok(target)
}
}
#[cfg(test)]
mod tests {
mod deserialize;
}