forked from microsoft/regorus
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bindings for C, C#, Golang (microsoft#124)
* FFI bindings Generate C FFI as well as C# FFI Signed-off-by: Anand Krishnamoorthi <[email protected]> * Regorus C binding Signed-off-by: Anand Krishnamoorthi <[email protected]> * C# binding Signed-off-by: Anand Krishnamoorthi <[email protected]> * Golang binding Signed-off-by: Anand Krishnamoorthi <[email protected]> --------- Signed-off-by: Anand Krishnamoorthi <[email protected]>
- Loading branch information
Showing
17 changed files
with
1,272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
[workspace] | ||
|
||
members = [ | ||
"bindings/ffi", | ||
"bindings/python", | ||
"bindings/wasm" | ||
] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Copyright (c) Microsoft | ||
# Licensed under the MIT License. | ||
|
||
cmake_minimum_required(VERSION 3.12 FATAL_ERROR) | ||
include(FetchContent) | ||
|
||
FetchContent_Declare( | ||
Corrosion | ||
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git | ||
GIT_TAG v0.4 # Optionally specify a commit hash, version tag or branch here | ||
) | ||
FetchContent_MakeAvailable(Corrosion) | ||
|
||
project("regorus-test-c") | ||
|
||
corrosion_import_crate( | ||
# Path to <regorus-source-folder>/bindings/ffi/Cargo.toml | ||
MANIFEST_PATH "../ffi/Cargo.toml" | ||
# Always build regorus in Release mode. | ||
PROFILE "release" | ||
# Only build the "regorusc" crate. | ||
CRATES "regorus-ffi") | ||
|
||
add_executable(regorus_test main.c) | ||
# Add path to <regorus-source-folder>/bindings/ffi | ||
target_include_directories(regorus_test PRIVATE "../ffi") | ||
target_link_libraries(regorus_test regorus-ffi) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <stdio.h> | ||
#include "regorus.h" | ||
|
||
int main() { | ||
// Create engine. | ||
RegorusEngine* engine = regorus_engine_new(); | ||
RegorusResult r; | ||
|
||
// Load policies. | ||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/framework.rego"); | ||
if (r.status != RegorusStatusOk) | ||
goto error; | ||
regorus_result_drop(r); | ||
|
||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/api.rego"); | ||
if (r.status != RegorusStatusOk) | ||
goto error; | ||
regorus_result_drop(r); | ||
|
||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/policy.rego"); | ||
if (r.status != RegorusStatusOk) | ||
goto error; | ||
regorus_result_drop(r); | ||
|
||
// Add data | ||
r = regorus_engine_add_data_from_json_file(engine, "../../../tests/aci/data.json"); | ||
if (r.status != RegorusStatusOk) | ||
goto error; | ||
regorus_result_drop(r); | ||
|
||
// Set input | ||
r = regorus_engine_set_input_from_json_file(engine, "../../../tests/aci/input.json"); | ||
if (r.status != RegorusStatusOk) | ||
goto error; | ||
regorus_result_drop(r); | ||
|
||
// Eval query | ||
r = regorus_engine_eval_query(engine, "data.framework.mount_overlay=x"); | ||
if (r.status != RegorusStatusOk) | ||
goto error; | ||
|
||
// Print output | ||
printf("%s", r.output); | ||
regorus_result_drop(r); | ||
|
||
|
||
// Free the engine. | ||
regorus_engine_drop(engine); | ||
|
||
return 0; | ||
error: | ||
printf("%s", r.error_message); | ||
|
||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using System.Diagnostics; | ||
|
||
long nanosecPerTick = (1000L*1000L*1000L) / Stopwatch.Frequency; | ||
var w = new Stopwatch(); | ||
|
||
|
||
// Force load of modules. | ||
{ | ||
var _e = new Regorus.Engine(); | ||
var _j = System.Text.Json.JsonDocument.Parse("{}"); | ||
} | ||
|
||
w.Restart(); | ||
|
||
var engine = new Regorus.Engine(); | ||
|
||
w.Stop(); | ||
var newEngineTicks = w.ElapsedTicks; | ||
|
||
|
||
w.Restart(); | ||
|
||
// Load policies and data. | ||
engine.AddPolicyFromFile("../../tests/aci/framework.rego"); | ||
engine.AddPolicyFromFile("../../tests/aci/api.rego"); | ||
engine.AddPolicyFromFile("../../tests/aci/policy.rego"); | ||
engine.AddDataFromJsonFile("../../tests/aci/data.json"); | ||
|
||
|
||
w.Stop(); | ||
var loadPoliciesTicks = w.ElapsedTicks; | ||
|
||
|
||
w.Restart(); | ||
|
||
// Set input and eval query. | ||
engine.SetInputFromJsonFile("../../tests/aci/input.json"); | ||
var results = engine.EvalQuery("data.framework.mount_overlay = x"); | ||
var resultsDoc = System.Text.Json.JsonDocument.Parse(results); | ||
|
||
w.Stop(); | ||
var evalTicks = w.ElapsedTicks; | ||
|
||
Console.WriteLine("{0}", results); | ||
|
||
|
||
Console.WriteLine("Engine creation took {0} msecs", (newEngineTicks*nanosecPerTick)/(1000.0*1000.0)); | ||
Console.WriteLine("Load policies and data took {0} msecs", (loadPoliciesTicks*nanosecPerTick)/(1000.0*1000.0)); | ||
Console.WriteLine("EvalQuery took {0} msecs", (evalTicks*nanosecPerTick)/(1000.0*1000.0)); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
using System.Text; | ||
|
||
namespace Regorus | ||
{ | ||
public class Exception : System.Exception | ||
{ | ||
public Exception(string? message) : base(message) {} | ||
} | ||
|
||
public class Engine : ICloneable | ||
{ | ||
unsafe private RegorusFFI.RegorusEngine* E; | ||
public Engine() | ||
{ | ||
unsafe | ||
{ | ||
E = RegorusFFI.API.regorus_engine_new(); | ||
} | ||
} | ||
|
||
public object Clone() | ||
{ | ||
var clone = (Engine)this.MemberwiseClone(); | ||
unsafe | ||
{ | ||
clone.E = RegorusFFI.API.regorus_engine_clone(E); | ||
} | ||
return clone; | ||
|
||
} | ||
|
||
public void AddPolicy(string path, string rego) | ||
{ | ||
var pathBytes = Encoding.UTF8.GetBytes(path); | ||
var regoBytes = Encoding.UTF8.GetBytes(rego); | ||
|
||
unsafe | ||
{ | ||
fixed (byte* pathPtr = pathBytes) | ||
{ | ||
fixed(byte* regoPtr = regoBytes) | ||
{ | ||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_policy(E, pathPtr, regoPtr)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void AddPolicyFromFile(string path) | ||
{ | ||
var pathBytes = Encoding.UTF8.GetBytes(path); | ||
|
||
unsafe | ||
{ | ||
fixed (byte* pathPtr = pathBytes) | ||
{ | ||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_policy_from_file(E, pathPtr)); | ||
} | ||
} | ||
} | ||
|
||
public void AddDataJson(string data) | ||
{ | ||
var dataBytes = Encoding.UTF8.GetBytes(data); | ||
|
||
unsafe | ||
{ | ||
fixed (byte* dataPtr = dataBytes) | ||
{ | ||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_data_json(E, dataPtr)); | ||
|
||
} | ||
} | ||
} | ||
|
||
public void AddDataFromJsonFile(string path) | ||
{ | ||
var pathBytes = Encoding.UTF8.GetBytes(path); | ||
|
||
unsafe | ||
{ | ||
fixed (byte* pathPtr = pathBytes) | ||
{ | ||
CheckAndDropResult(RegorusFFI.API.regorus_engine_add_data_from_json_file(E, pathPtr)); | ||
|
||
} | ||
} | ||
} | ||
|
||
public void SetInputJson(string input) | ||
{ | ||
var inputBytes = Encoding.UTF8.GetBytes(input); | ||
|
||
unsafe | ||
{ | ||
fixed (byte* inputPtr = inputBytes) | ||
{ | ||
CheckAndDropResult(RegorusFFI.API.regorus_engine_set_input_json(E, inputPtr)); | ||
|
||
} | ||
} | ||
} | ||
|
||
public void SetInputFromJsonFile(string path) | ||
{ | ||
var pathBytes = Encoding.UTF8.GetBytes(path); | ||
|
||
unsafe | ||
{ | ||
fixed (byte* pathPtr = pathBytes) | ||
{ | ||
CheckAndDropResult(RegorusFFI.API.regorus_engine_set_input_from_json_file(E, pathPtr)); | ||
|
||
} | ||
} | ||
} | ||
|
||
public string EvalQuery(string query) | ||
{ | ||
var queryBytes = Encoding.UTF8.GetBytes(query); | ||
|
||
var resultJson = ""; | ||
unsafe | ||
{ | ||
fixed (byte* queryPtr = queryBytes) | ||
{ | ||
var result = RegorusFFI.API.regorus_engine_eval_query(E, queryPtr); | ||
if (result.status == RegorusFFI.RegorusStatus.RegorusStatusOk) { | ||
if (result.output is not null) { | ||
resultJson = System.Runtime.InteropServices.Marshal.PtrToStringUTF8((IntPtr)result.output); | ||
} | ||
RegorusFFI.API.regorus_result_drop(result); | ||
} else { | ||
CheckAndDropResult(result); | ||
} | ||
|
||
} | ||
} | ||
if (resultJson is not null) { | ||
return resultJson; | ||
} else { | ||
return ""; | ||
} | ||
} | ||
|
||
~Engine() | ||
{ | ||
unsafe | ||
{ | ||
RegorusFFI.API.regorus_engine_drop(E); | ||
} | ||
} | ||
|
||
|
||
void CheckAndDropResult(RegorusFFI.RegorusResult result) | ||
{ | ||
if (result.status != RegorusFFI.RegorusStatus.RegorusStatusOk) { | ||
unsafe { | ||
var message = System.Runtime.InteropServices.Marshal.PtrToStringUTF8((IntPtr)result.error_message); | ||
var ex = new Exception(message); | ||
RegorusFFI.API.regorus_result_drop(result); | ||
throw ex; | ||
} | ||
} | ||
RegorusFFI.API.regorus_result_drop(result); | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<Target Name="BuildRegorusFFI"> | ||
<Exec Command="cargo build -r --manifest-path ../ffi/Cargo.toml" /> | ||
<Copy SourceFiles="../ffi/RegorusFFI.g.cs" DestinationFolder="." /> | ||
<ItemGroup> | ||
<RegorusDylib Include="..\..\target\release\*regorus_ffi*" /> | ||
</ItemGroup> | ||
<Copy SourceFiles="@(RegorusDylib)" DestinationFolder="." /> | ||
</Target> | ||
|
||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<RootNamespace>regorus_test</RootNamespace> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
|
||
|
||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "regorus-ffi" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
anyhow = "1.0.79" | ||
regorus = { path = "../.." } | ||
serde_json = "1.0.113" | ||
|
||
[build-dependencies] | ||
cbindgen = "0.26.0" | ||
csbindgen = "1.9.0" |
Oops, something went wrong.