Files
regorus/src/compile.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

92 lines
2.9 KiB
Rust

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use crate::compiled_policy::CompiledPolicy;
use crate::engine::Engine;
use crate::value::Value;
use crate::*;
use anyhow::Result;
/// Represents a Rego policy module with an identifier and content.
#[derive(Debug, Clone)]
pub struct PolicyModule {
pub id: Rc<str>,
pub content: Rc<str>,
}
/// Compiles a target-aware policy from data and modules.
///
/// This is a convenience function that sets up an [`Engine`] and calls
/// [`Engine::compile_for_target`]. For more control over the compilation process
/// or to reuse an engine, use the engine method directly.
///
/// # Arguments
///
/// * `data` - Static data to be available during policy evaluation
/// * `modules` - Array of Rego policy modules to compile together
///
/// # Returns
///
/// Returns a [`CompiledPolicy`] for target-aware evaluation.
///
/// # Note
///
/// This function is only available when the `azure_policy` feature is enabled.
///
/// # See Also
///
/// - [`Engine::compile_for_target`] for detailed documentation and examples
/// - [`compile_policy_with_entrypoint`] for explicit rule-based compilation
#[cfg(feature = "azure_policy")]
#[cfg_attr(docsrs, doc(cfg(feature = "azure_policy")))]
pub fn compile_policy_for_target(data: Value, modules: &[PolicyModule]) -> Result<CompiledPolicy> {
let mut engine = setup_engine_with_modules(data, modules)?;
engine.compile_for_target()
}
/// Compiles a policy from data and modules with a specific entry point rule.
///
/// This is a convenience function that sets up an [`Engine`] and calls
/// [`Engine::compile_with_entrypoint`]. For more control over the compilation process
/// or to reuse an engine, use the engine method directly.
///
/// # Arguments
///
/// * `data` - Static data to be available during policy evaluation
/// * `modules` - Array of Rego policy modules to compile together
/// * `entry_point_rule` - The specific rule path to evaluate (e.g., "data.policy.allow")
///
/// # Returns
///
/// Returns a [`CompiledPolicy`] focused on the specified entry point rule.
///
/// # See Also
///
/// - [`Engine::compile_with_entrypoint`] for detailed documentation and examples
/// - [`compile_policy_for_target`] for target-aware compilation
pub fn compile_policy_with_entrypoint(
data: Value,
modules: &[PolicyModule],
entry_point_rule: Rc<str>,
) -> Result<CompiledPolicy> {
let mut engine = setup_engine_with_modules(data, modules)?;
engine.compile_with_entrypoint(&entry_point_rule)
}
/// Helper function to set up an engine with data and modules.
fn setup_engine_with_modules(data: Value, modules: &[PolicyModule]) -> Result<Engine> {
let mut engine = Engine::new();
// Add data to the engine
engine.add_data(data)?;
engine.set_gather_prints(true);
// Add all modules to the engine
for module in modules {
engine.add_policy(module.id.to_string(), module.content.to_string())?;
}
Ok(engine)
}