mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
fix(ffi): eliminate aliasing UB + add Azure Policy JSON compilation FFI (#727)
* fix(ffi): eliminate aliasing UB via to_shared_ref migration Add to_shared_ref() helper that creates &T (shared reference) from raw pointers instead of &mut T. This eliminates undefined behavior caused by violating Rust's aliasing invariant when C# SafeHandle permits concurrent FFI calls on the same handle. With &mut T, the compiler may assume exclusive (noalias) access and reorder or elide reads/writes — a miscompilation risk when another thread holds a reference to the same object. Switching to &T removes that assumption; actual mutation is mediated by the interior RwLock inside Handle<T>, which is the sole synchronization mechanism. Migrated sites: - rvm.rs: 20 non-drop call sites - engine.rs: 30 non-drop call sites + with_unwind_guard for timer fns - compiled_policy.rs: 2 call sites - Fix null-data UB in regorus_program_deserialize_binary Drop paths retain to_ref() where exclusive access is guaranteed by the caller contract (preventing use-after-free). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(ffi): add Azure Policy JSON compilation FFI and C# bindings - AliasRegistry builder pattern: RegorusAliasRegistryBuilder (mutable, single-threaded) + RegorusAliasRegistry (immutable, Arc-wrapped) - Azure Policy JSON compilation: regorus_compile_azure_policy_rule and regorus_compile_azure_policy_definition with alias registry support - regorus_rvm_set_context for host-supplied ambient data - C# AliasRegistryBuilder and AliasRegistry classes with convenience factories (FromJson, FromManifest, Empty) - C# AzurePolicyCompiler static class for policy rule/definition compilation - Compile functions take *const RegorusAliasRegistry (read-only via to_shared_ref for concurrent compilation safety) - Fix pre-existing clippy warnings across multiple crates Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
5467cd9e69
commit
86b4a279fa
@@ -8,51 +8,43 @@ using Regorus.Internal;
|
||||
namespace Regorus
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages Azure Policy alias definitions used for resource normalization
|
||||
/// Immutable Azure Policy alias registry used for resource normalization
|
||||
/// and policy compilation.
|
||||
/// </summary>
|
||||
public unsafe sealed class AliasRegistry : SafeHandleWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an empty alias registry.
|
||||
/// </summary>
|
||||
public AliasRegistry()
|
||||
: base(RegorusAliasRegistryHandle.Create(), nameof(AliasRegistry))
|
||||
internal AliasRegistry(RegorusAliasRegistryHandle handle)
|
||||
: base(handle, nameof(AliasRegistry))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load control-plane alias data (array of ProviderAliases) from a JSON string.
|
||||
/// Create an empty immutable alias registry.
|
||||
/// </summary>
|
||||
/// <param name="json">JSON array of ProviderAliases (e.g. from Get-AzPolicyAlias or ResourceTypesAndAliases.json)</param>
|
||||
public void LoadJson(string json)
|
||||
public static AliasRegistry Empty()
|
||||
{
|
||||
Utf8Marshaller.WithUtf8(json, jsonPtr =>
|
||||
{
|
||||
UseHandle(regPtr =>
|
||||
{
|
||||
CheckAndDropResult(API.regorus_alias_registry_load_json(
|
||||
(RegorusAliasRegistry*)regPtr, (byte*)jsonPtr));
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
using var builder = new AliasRegistryBuilder();
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a data-plane policy manifest from a JSON string.
|
||||
/// Create an immutable alias registry from control-plane alias JSON.
|
||||
/// </summary>
|
||||
/// <param name="json">JSON object containing a DataPolicyManifest</param>
|
||||
public void LoadManifest(string json)
|
||||
public static AliasRegistry FromJson(string json)
|
||||
{
|
||||
Utf8Marshaller.WithUtf8(json, jsonPtr =>
|
||||
{
|
||||
UseHandle(regPtr =>
|
||||
{
|
||||
CheckAndDropResult(API.regorus_alias_registry_load_manifest(
|
||||
(RegorusAliasRegistry*)regPtr, (byte*)jsonPtr));
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
using var builder = new AliasRegistryBuilder();
|
||||
builder.LoadJson(json);
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an immutable alias registry from a data-plane manifest JSON document.
|
||||
/// </summary>
|
||||
public static AliasRegistry FromManifest(string json)
|
||||
{
|
||||
using var builder = new AliasRegistryBuilder();
|
||||
builder.LoadManifest(json);
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,11 +66,6 @@ namespace Regorus
|
||||
/// Normalize an ARM resource JSON and wrap it into the standard input envelope
|
||||
/// expected by a compiled Azure Policy program.
|
||||
/// </summary>
|
||||
/// <param name="resourceJson">Raw ARM resource JSON</param>
|
||||
/// <param name="apiVersion">API version string (e.g. "2023-01-01"), or null to use default alias paths</param>
|
||||
/// <param name="contextJson">Additional context JSON object (pass "{}" if none)</param>
|
||||
/// <param name="parametersJson">Policy parameter values JSON (pass "{}" if none)</param>
|
||||
/// <returns>JSON string: { "resource": <normalized>, "context": <context>, "parameters": <params> }</returns>
|
||||
public string? NormalizeAndWrap(string resourceJson, string? apiVersion = null, string contextJson = "{}", string parametersJson = "{}")
|
||||
{
|
||||
return Utf8Marshaller.WithUtf8(resourceJson, resPtr =>
|
||||
@@ -96,27 +83,22 @@ namespace Regorus
|
||||
(byte*)ctxPtr, (byte*)paramsPtr));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return Utf8Marshaller.WithUtf8(apiVersion, apiPtr =>
|
||||
UseHandle(regPtr =>
|
||||
{
|
||||
return ResultHelpers.GetStringResult(
|
||||
API.regorus_alias_registry_normalize_and_wrap(
|
||||
(RegorusAliasRegistry*)regPtr,
|
||||
(byte*)resPtr, (byte*)apiPtr,
|
||||
(byte*)ctxPtr, (byte*)paramsPtr));
|
||||
}));
|
||||
}
|
||||
|
||||
return Utf8Marshaller.WithUtf8(apiVersion, apiPtr =>
|
||||
UseHandle(regPtr =>
|
||||
{
|
||||
return ResultHelpers.GetStringResult(
|
||||
API.regorus_alias_registry_normalize_and_wrap(
|
||||
(RegorusAliasRegistry*)regPtr,
|
||||
(byte*)resPtr, (byte*)apiPtr,
|
||||
(byte*)ctxPtr, (byte*)paramsPtr));
|
||||
}));
|
||||
})));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Denormalize a previously-normalized resource JSON back to ARM format.
|
||||
/// </summary>
|
||||
/// <param name="normalizedJson">The normalized resource JSON</param>
|
||||
/// <param name="apiVersion">API version string, or null to use default alias paths</param>
|
||||
/// <returns>Denormalized ARM JSON string</returns>
|
||||
public string? Denormalize(string normalizedJson, string? apiVersion = null)
|
||||
{
|
||||
return Utf8Marshaller.WithUtf8(normalizedJson, normPtr =>
|
||||
@@ -131,23 +113,16 @@ namespace Regorus
|
||||
(byte*)normPtr, null));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return Utf8Marshaller.WithUtf8(apiVersion, apiPtr =>
|
||||
UseHandle(regPtr =>
|
||||
{
|
||||
return ResultHelpers.GetStringResult(
|
||||
API.regorus_alias_registry_denormalize(
|
||||
(RegorusAliasRegistry*)regPtr,
|
||||
(byte*)normPtr, (byte*)apiPtr));
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static string? CheckAndDropResult(RegorusResult result)
|
||||
{
|
||||
return ResultHelpers.GetStringResult(result);
|
||||
return Utf8Marshaller.WithUtf8(apiVersion, apiPtr =>
|
||||
UseHandle(regPtr =>
|
||||
{
|
||||
return ResultHelpers.GetStringResult(
|
||||
API.regorus_alias_registry_denormalize(
|
||||
(RegorusAliasRegistry*)regPtr,
|
||||
(byte*)normPtr, (byte*)apiPtr));
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using Regorus.Internal;
|
||||
|
||||
#nullable enable
|
||||
namespace Regorus
|
||||
{
|
||||
/// <summary>
|
||||
/// Mutable, single-threaded builder for <see cref="AliasRegistry"/>.
|
||||
/// Load alias data, then call <see cref="Build"/> to freeze the registry.
|
||||
/// </summary>
|
||||
public unsafe sealed class AliasRegistryBuilder : SafeHandleWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an empty alias registry builder.
|
||||
/// </summary>
|
||||
public AliasRegistryBuilder()
|
||||
: base(RegorusAliasRegistryBuilderHandle.Create(), nameof(AliasRegistryBuilder))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load control-plane alias data (array of ProviderAliases) from a JSON string.
|
||||
/// </summary>
|
||||
public void LoadJson(string json)
|
||||
{
|
||||
Utf8Marshaller.WithUtf8(json, jsonPtr =>
|
||||
{
|
||||
UseHandle(builderPtr =>
|
||||
{
|
||||
ResultHelpers.GetStringResult(API.regorus_alias_registry_builder_load_json(
|
||||
(RegorusAliasRegistryBuilder*)builderPtr,
|
||||
(byte*)jsonPtr));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a data-plane policy manifest from a JSON string.
|
||||
/// </summary>
|
||||
public void LoadManifest(string json)
|
||||
{
|
||||
Utf8Marshaller.WithUtf8(json, jsonPtr =>
|
||||
{
|
||||
UseHandle(builderPtr =>
|
||||
{
|
||||
ResultHelpers.GetStringResult(API.regorus_alias_registry_builder_load_manifest(
|
||||
(RegorusAliasRegistryBuilder*)builderPtr,
|
||||
(byte*)jsonPtr));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Freeze the builder into an immutable, thread-safe alias registry.
|
||||
/// </summary>
|
||||
public AliasRegistry Build()
|
||||
{
|
||||
return UseHandle(builderPtr =>
|
||||
{
|
||||
var registryPtr = ResultHelpers.GetPointerResult(
|
||||
API.regorus_alias_registry_builder_build((RegorusAliasRegistryBuilder*)builderPtr));
|
||||
return new AliasRegistry(RegorusAliasRegistryHandle.FromPointer(registryPtr));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using Regorus.Internal;
|
||||
|
||||
#nullable enable
|
||||
namespace Regorus
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides static methods for compiling Azure Policy JSON definitions
|
||||
/// into RVM programs that can be executed by <see cref="Rvm"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This class bridges the gap between Azure Policy JSON (the native
|
||||
/// Azure policy language with <c>policyRule</c>, <c>field</c>,
|
||||
/// <c>equals</c>, etc.) and Regorus's RVM execution engine.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// <b>Typical workflow:</b>
|
||||
/// </para>
|
||||
/// <list type="number">
|
||||
/// <item>Load alias definitions with <see cref="AliasRegistryBuilder"/> and freeze them into an <see cref="AliasRegistry"/>.</item>
|
||||
/// <item>Normalize the ARM resource via <see cref="AliasRegistry.NormalizeAndWrap"/>.</item>
|
||||
/// <item>Compile the JSON policyRule with <see cref="CompilePolicyRule"/> or the
|
||||
/// full definition with <see cref="CompilePolicyDefinition"/>.</item>
|
||||
/// <item>Execute the resulting <see cref="Program"/> in an <see cref="Rvm"/>
|
||||
/// instance with the normalized input.</item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para>
|
||||
/// <b>Context-dependent policies:</b> Policies that use context functions
|
||||
/// such as <c>subscription()</c>, <c>resourceGroup()</c>, or
|
||||
/// <c>requestContext()</c> require the VM context to be set separately via
|
||||
/// <see cref="Rvm.SetContextJson"/> before execution. The context JSON
|
||||
/// returned by <see cref="AliasRegistry.NormalizeAndWrap"/> is passed as
|
||||
/// <c>input.context</c> but is <b>not</b> automatically wired into the VM's
|
||||
/// ambient context — the caller must do both:
|
||||
/// <c>vm.SetInputJson(envelope)</c> and <c>vm.SetContextJson(contextJson)</c>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static unsafe class AzurePolicyCompiler
|
||||
{
|
||||
/// <summary>
|
||||
/// Compile an Azure Policy JSON policy rule into an RVM <see cref="Program"/>.
|
||||
/// </summary>
|
||||
/// <param name="aliasRegistry">
|
||||
/// Alias registry for resolving fully-qualified alias names in field
|
||||
/// references. Pass <c>null</c> if no alias resolution is needed.
|
||||
/// <para>
|
||||
/// <b>Warning:</b> When <c>null</c>, alias field references compile as raw
|
||||
/// property paths and will silently produce incorrect evaluation results for
|
||||
/// policies that use aliases. Modify/Append effect policies will also skip
|
||||
/// the compile-time modifiability validation. Only pass <c>null</c> when the
|
||||
/// policy is known to contain no alias references (e.g. simple type/location
|
||||
/// checks or unit-test scenarios).
|
||||
/// </para>
|
||||
/// </param>
|
||||
/// <param name="policyRuleJson">
|
||||
/// JSON string containing the policyRule object, e.g.
|
||||
/// <c>{ "if": { "field": "type", "equals": "..." }, "then": { "effect": "deny" } }</c>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A compiled <see cref="Program"/> ready to be loaded into an
|
||||
/// <see cref="Rvm"/> instance.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when <paramref name="policyRuleJson"/> is <c>null</c>.
|
||||
/// </exception>
|
||||
/// <exception cref="Exception">
|
||||
/// Thrown when parsing or compilation fails.
|
||||
/// </exception>
|
||||
public static Program CompilePolicyRule(AliasRegistry? aliasRegistry, string policyRuleJson)
|
||||
{
|
||||
if (policyRuleJson is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(policyRuleJson));
|
||||
}
|
||||
|
||||
return Utf8Marshaller.WithUtf8(policyRuleJson, rulePtr =>
|
||||
{
|
||||
if (aliasRegistry is null)
|
||||
{
|
||||
var result = API.regorus_compile_azure_policy_rule(
|
||||
null, (byte*)rulePtr);
|
||||
return GetProgramResult(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
return aliasRegistry.UseHandleForInterop(regPtr =>
|
||||
{
|
||||
var result = API.regorus_compile_azure_policy_rule(
|
||||
(RegorusAliasRegistry*)regPtr, (byte*)rulePtr);
|
||||
return GetProgramResult(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compile a full Azure Policy definition JSON into an RVM <see cref="Program"/>.
|
||||
/// </summary>
|
||||
/// <param name="aliasRegistry">
|
||||
/// Alias registry for resolving fully-qualified alias names in field
|
||||
/// references. Pass <c>null</c> if no alias resolution is needed.
|
||||
/// <para>
|
||||
/// <b>Warning:</b> When <c>null</c>, alias field references compile as raw
|
||||
/// property paths and will silently produce incorrect evaluation results for
|
||||
/// policies that use aliases. Modify/Append effect policies will also skip
|
||||
/// the compile-time modifiability validation. Only pass <c>null</c> when the
|
||||
/// policy is known to contain no alias references (e.g. simple type/location
|
||||
/// checks or unit-test scenarios).
|
||||
/// </para>
|
||||
/// </param>
|
||||
/// <param name="policyDefinitionJson">
|
||||
/// JSON string containing the full policy definition, which includes
|
||||
/// <c>policyRule</c>, <c>parameters</c>, <c>displayName</c>, etc.
|
||||
/// Accepted in both wrapped and unwrapped forms.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A compiled <see cref="Program"/> ready to be loaded into an
|
||||
/// <see cref="Rvm"/> instance.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Thrown when <paramref name="policyDefinitionJson"/> is <c>null</c>.
|
||||
/// </exception>
|
||||
/// <exception cref="Exception">
|
||||
/// Thrown when parsing or compilation fails.
|
||||
/// </exception>
|
||||
public static Program CompilePolicyDefinition(AliasRegistry? aliasRegistry, string policyDefinitionJson)
|
||||
{
|
||||
if (policyDefinitionJson is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(policyDefinitionJson));
|
||||
}
|
||||
|
||||
return Utf8Marshaller.WithUtf8(policyDefinitionJson, defnPtr =>
|
||||
{
|
||||
if (aliasRegistry is null)
|
||||
{
|
||||
var result = API.regorus_compile_azure_policy_definition(
|
||||
null, (byte*)defnPtr);
|
||||
return GetProgramResult(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
return aliasRegistry.UseHandleForInterop(regPtr =>
|
||||
{
|
||||
var result = API.regorus_compile_azure_policy_definition(
|
||||
(RegorusAliasRegistry*)regPtr, (byte*)defnPtr);
|
||||
return GetProgramResult(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Program GetProgramResult(RegorusResult result)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (result.status != RegorusStatus.Ok)
|
||||
{
|
||||
var message = Utf8Marshaller.FromUtf8(result.error_message);
|
||||
throw result.status.CreateException(message);
|
||||
}
|
||||
|
||||
if (result.data_type != RegorusDataType.Pointer || result.pointer_value == null)
|
||||
{
|
||||
throw new Exception("Expected program pointer but got different data type");
|
||||
}
|
||||
|
||||
var handle = RegorusProgramHandle.FromPointer((IntPtr)result.pointer_value);
|
||||
return new Program(handle);
|
||||
}
|
||||
finally
|
||||
{
|
||||
API.regorus_result_drop(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,6 +178,14 @@ namespace Regorus.Internal
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_rvm_set_input", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_rvm_set_input(RegorusRvm* vm, byte* input_json);
|
||||
|
||||
/// <summary>
|
||||
/// Set the context document for the RVM.
|
||||
/// The context provides host-supplied ambient data (e.g. resourceGroup(), subscription())
|
||||
/// that Azure Policy functions can access.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_rvm_set_context", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_rvm_set_context(RegorusRvm* vm, byte* context_json);
|
||||
|
||||
/// <summary>
|
||||
/// Execute the program.
|
||||
/// </summary>
|
||||
@@ -490,6 +498,20 @@ namespace Regorus.Internal
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_compile_policy_for_target", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_compile_policy_for_target(byte* data_json, RegorusPolicyModule* modules, UIntPtr modules_len);
|
||||
|
||||
/// <summary>
|
||||
/// Compile an Azure Policy JSON policy rule into an RVM program.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_compile_azure_policy_rule", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_compile_azure_policy_rule(
|
||||
RegorusAliasRegistry* registry, byte* policy_rule_json);
|
||||
|
||||
/// <summary>
|
||||
/// Compile a full Azure Policy definition JSON into an RVM program.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_compile_azure_policy_definition", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_compile_azure_policy_definition(
|
||||
RegorusAliasRegistry* registry, byte* policy_definition_json);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Compiled Policy Methods
|
||||
@@ -673,10 +695,34 @@ namespace Regorus.Internal
|
||||
#region Alias Registry Methods
|
||||
|
||||
/// <summary>
|
||||
/// Create a new, empty AliasRegistry.
|
||||
/// Create a new alias registry builder.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusAliasRegistry* regorus_alias_registry_new();
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_builder_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusAliasRegistryBuilder* regorus_alias_registry_builder_new();
|
||||
|
||||
/// <summary>
|
||||
/// Drop an alias registry builder.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_builder_drop", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern void regorus_alias_registry_builder_drop(RegorusAliasRegistryBuilder* builder);
|
||||
|
||||
/// <summary>
|
||||
/// Load control-plane alias data into the builder.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_builder_load_json", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_alias_registry_builder_load_json(RegorusAliasRegistryBuilder* builder, byte* json);
|
||||
|
||||
/// <summary>
|
||||
/// Load a data-plane policy manifest into the builder.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_builder_load_manifest", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_alias_registry_builder_load_manifest(RegorusAliasRegistryBuilder* builder, byte* json);
|
||||
|
||||
/// <summary>
|
||||
/// Freeze a builder into an immutable alias registry.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_builder_build", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_alias_registry_builder_build(RegorusAliasRegistryBuilder* builder);
|
||||
|
||||
/// <summary>
|
||||
/// Drop an AliasRegistry.
|
||||
@@ -684,18 +730,6 @@ namespace Regorus.Internal
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_drop", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern void regorus_alias_registry_drop(RegorusAliasRegistry* registry);
|
||||
|
||||
/// <summary>
|
||||
/// Load control-plane alias data (array of ProviderAliases) into the registry.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_load_json", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_alias_registry_load_json(RegorusAliasRegistry* registry, byte* json);
|
||||
|
||||
/// <summary>
|
||||
/// Load a data-plane policy manifest into the registry.
|
||||
/// </summary>
|
||||
[DllImport(LibraryName, EntryPoint = "regorus_alias_registry_load_manifest", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
internal static extern RegorusResult regorus_alias_registry_load_manifest(RegorusAliasRegistry* registry, byte* json);
|
||||
|
||||
/// <summary>
|
||||
/// Return the number of resource types loaded in the alias registry.
|
||||
/// </summary>
|
||||
@@ -923,6 +957,14 @@ namespace Regorus.Internal
|
||||
public byte* content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper for AliasRegistryBuilder.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct RegorusAliasRegistryBuilder
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper for AliasRegistry.
|
||||
/// </summary>
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Regorus
|
||||
/// </summary>
|
||||
public unsafe sealed class Program : SafeHandleWrapper
|
||||
{
|
||||
private Program(RegorusProgramHandle handle)
|
||||
internal Program(RegorusProgramHandle handle)
|
||||
: base(handle, nameof(Program))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,5 +69,29 @@ namespace Regorus.Internal
|
||||
API.regorus_result_drop(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal static IntPtr GetPointerResult(RegorusResult result)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (result.status != RegorusStatus.Ok)
|
||||
{
|
||||
var message = Utf8Marshaller.FromUtf8(result.error_message);
|
||||
throw result.status.CreateException(message);
|
||||
}
|
||||
|
||||
if (result.data_type != RegorusDataType.Pointer || result.pointer_value == null)
|
||||
{
|
||||
throw new InvalidOperationException("Expected pointer result.");
|
||||
}
|
||||
|
||||
return (IntPtr)result.pointer_value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
API.regorus_result_drop(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,24 @@ namespace Regorus
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the context document for the VM.
|
||||
/// The context provides host-supplied ambient data (e.g. resourceGroup(),
|
||||
/// subscription()) that Azure Policy functions can access via LoadContext
|
||||
/// instructions.
|
||||
/// </summary>
|
||||
public void SetContextJson(string contextJson)
|
||||
{
|
||||
Utf8Marshaller.WithUtf8(contextJson, contextPtr =>
|
||||
{
|
||||
UseHandle(vmPtr =>
|
||||
{
|
||||
CheckAndDropResult(API.regorus_rvm_set_context((RegorusRvm*)vmPtr, (byte*)contextPtr));
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the execution mode (0 = run-to-completion, 1 = suspendable).
|
||||
/// </summary>
|
||||
|
||||
@@ -184,28 +184,48 @@ namespace Regorus
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RegorusAliasRegistryBuilderHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private RegorusAliasRegistryBuilderHandle() : base(ownsHandle: true)
|
||||
{
|
||||
}
|
||||
|
||||
internal static RegorusAliasRegistryBuilderHandle Create()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var raw = Internal.API.regorus_alias_registry_builder_new();
|
||||
if (raw is null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to create Regorus alias registry builder.");
|
||||
}
|
||||
|
||||
var handle = new RegorusAliasRegistryBuilderHandle();
|
||||
handle.SetHandle((IntPtr)raw);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
if (!IsInvalid)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Internal.API.regorus_alias_registry_builder_drop((Internal.RegorusAliasRegistryBuilder*)handle);
|
||||
}
|
||||
SetHandle(IntPtr.Zero);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RegorusAliasRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private RegorusAliasRegistryHandle() : base(ownsHandle: true)
|
||||
{
|
||||
}
|
||||
|
||||
internal static RegorusAliasRegistryHandle Create()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var raw = Internal.API.regorus_alias_registry_new();
|
||||
if (raw is null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to create Regorus alias registry.");
|
||||
}
|
||||
|
||||
var handle = new RegorusAliasRegistryHandle();
|
||||
handle.SetHandle((IntPtr)raw);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
internal static RegorusAliasRegistryHandle FromPointer(IntPtr pointer)
|
||||
{
|
||||
if (pointer == IntPtr.Zero)
|
||||
|
||||
Reference in New Issue
Block a user