mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
Update bindings to include newer APIs (#250)
- c, cpp - csharp - ffi - go - Java - Python - WASM `arc` feature is turned on for all bindings Use pretty string instead of colored string. Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
committed by
GitHub
parent
33fe9d5039
commit
d09c445add
@@ -46,21 +46,21 @@ int main() {
|
||||
free(buffer);
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
printf("Loaded policy %s\n", r.output);
|
||||
printf("Loaded package %s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_add_policy(engine, "api.rego", (buffer = file_to_string("../../../tests/aci/api.rego")));
|
||||
free(buffer);
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
printf("Loaded policy %s\n", r.output);
|
||||
printf("Loaded package %s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_add_policy(engine, "policy.rego", (buffer = file_to_string("../../../tests/aci/policy.rego")));
|
||||
free(buffer);
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
printf("Loaded policy %s\n", r.output);
|
||||
printf("Loaded package %s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Add data
|
||||
@@ -77,8 +77,8 @@ int main() {
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Eval query
|
||||
r = regorus_engine_eval_query(engine, "data.framework.mount_overlay=x");
|
||||
// Eval rule.
|
||||
r = regorus_engine_eval_rule(engine, "data.framework.mount_overlay");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ corrosion_import_crate(
|
||||
FEATURES "regorus/semver"
|
||||
|
||||
# Link statically
|
||||
CRATE_TYPES "staticlib"
|
||||
CRATE_TYPES "cdylib"
|
||||
)
|
||||
|
||||
add_executable(regorus_test main.c)
|
||||
|
||||
@@ -10,19 +10,19 @@ int main() {
|
||||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/framework.rego");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
printf("Loaded policy %s\n", r.output);
|
||||
printf("Loaded package %s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/api.rego");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
printf("Loaded policy %s\n", r.output);
|
||||
printf("Loaded package %s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_add_policy_from_file(engine, "../../../tests/aci/policy.rego");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
printf("Loaded policy %s\n", r.output);
|
||||
printf("Loaded package %s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Add data
|
||||
@@ -37,22 +37,61 @@ int main() {
|
||||
goto error;
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Eval query
|
||||
r = regorus_engine_eval_query(engine, "data.framework.mount_overlay=x");
|
||||
// Eval rule.
|
||||
r = regorus_engine_eval_query(engine, "data.framework.mount_overlay");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
|
||||
// Print output
|
||||
printf("%s", r.output);
|
||||
printf("%s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
|
||||
// Free the engine.
|
||||
regorus_engine_drop(engine);
|
||||
|
||||
// Create another engine.
|
||||
engine = regorus_engine_new();
|
||||
|
||||
r = regorus_engine_add_policy(
|
||||
engine,
|
||||
"test.rego",
|
||||
"package test\n"
|
||||
"x = 1\n"
|
||||
"message = `Hello`"
|
||||
);
|
||||
|
||||
// Evaluate rule.
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
|
||||
r = regorus_engine_set_enable_coverage(engine, true);
|
||||
regorus_result_drop(r);
|
||||
|
||||
r = regorus_engine_eval_query(engine, "data.test.message");
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
|
||||
// Print output
|
||||
printf("%s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Print pretty coverage report.
|
||||
r = regorus_engine_get_coverage_report_pretty(engine);
|
||||
if (r.status != RegorusStatusOk)
|
||||
goto error;
|
||||
|
||||
printf("%s\n", r.output);
|
||||
regorus_result_drop(r);
|
||||
|
||||
// Free the engine.
|
||||
regorus_engine_drop(engine);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
printf("%s", r.error_message);
|
||||
regorus_result_drop(r);
|
||||
regorus_engine_drop(engine);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ corrosion_import_crate(
|
||||
FEATURES "regorus/semver"
|
||||
|
||||
# Link statically
|
||||
CRATE_TYPES "staticlib")
|
||||
CRATE_TYPES "cdylib")
|
||||
|
||||
add_executable(regorus_test main.cpp)
|
||||
# Add path to <regorus-source-folder>/bindings/ffi
|
||||
|
||||
@@ -6,6 +6,8 @@ void example()
|
||||
// Create engine
|
||||
regorus::Engine engine;
|
||||
|
||||
engine.set_enable_coverage(true);
|
||||
|
||||
// Add policies.
|
||||
engine.add_policy("objects.rego",R"(package objects
|
||||
|
||||
@@ -67,6 +69,14 @@ f := e["dev"])");
|
||||
} else {
|
||||
std::cerr<<result.error()<<std::endl;
|
||||
}
|
||||
|
||||
// Print coverage report
|
||||
auto result1 = engine.get_coverage_report_pretty();
|
||||
if (result1) {
|
||||
std::cout<<result1.output()<<std::endl;
|
||||
} else {
|
||||
std::cerr<<result1.error()<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -89,7 +99,7 @@ int main() {
|
||||
std::cerr<<result.error()<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout<<"Loaded policy "<<result.output()<< std::endl;
|
||||
std::cout<<"Loaded package "<<result.output()<< std::endl;
|
||||
}
|
||||
{
|
||||
auto result = engine.add_data_from_json_file("../../../tests/aci/data.json");
|
||||
@@ -99,7 +109,7 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Set input and eval query.
|
||||
// Set input and eval rule.
|
||||
{
|
||||
auto result = engine.set_input_from_json_file("../../../tests/aci/input.json");
|
||||
if (!result) {
|
||||
@@ -107,13 +117,13 @@ int main() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
auto result = engine.eval_query("data.framework.mount_overlay = x");
|
||||
auto result = engine.eval_rule("data.framework.mount_overlay");
|
||||
if (!result) {
|
||||
std::cerr<<result.error()<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout<<result.output()<<std::endl;
|
||||
|
||||
|
||||
example();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,26 @@ namespace regorus {
|
||||
return Result(regorus_engine_eval_query(engine, query));
|
||||
}
|
||||
|
||||
Result eval_rule(const char* rule) {
|
||||
return Result(regorus_engine_eval_rule(engine, rule));
|
||||
}
|
||||
|
||||
Result set_enable_coverage(bool enable) {
|
||||
return Result(regorus_engine_set_enable_coverage(engine, enable));
|
||||
}
|
||||
|
||||
Result clear_coverage_data() {
|
||||
return Result(regorus_engine_clear_coverage_data(engine));
|
||||
}
|
||||
|
||||
Result get_coverage_report() {
|
||||
return Result(regorus_engine_get_coverage_report(engine));
|
||||
}
|
||||
|
||||
Result get_coverage_report_pretty() {
|
||||
return Result(regorus_engine_get_coverage_report_pretty(engine));
|
||||
}
|
||||
|
||||
~Engine() {
|
||||
regorus_engine_drop(engine);
|
||||
}
|
||||
|
||||
@@ -33,19 +33,26 @@ var loadPoliciesTicks = w.ElapsedTicks;
|
||||
|
||||
w.Restart();
|
||||
|
||||
// Set input and eval query.
|
||||
// Set input and eval rule.
|
||||
engine.SetInputFromJsonFile("../../tests/aci/input.json");
|
||||
var results = engine.EvalQuery("data.framework.mount_overlay = x");
|
||||
var resultsDoc = System.Text.Json.JsonDocument.Parse(results);
|
||||
var value = engine.EvalQuery("data.framework.mount_overlay");
|
||||
var valueDoc = System.Text.Json.JsonDocument.Parse(value);
|
||||
|
||||
w.Stop();
|
||||
var evalTicks = w.ElapsedTicks;
|
||||
|
||||
Console.WriteLine("{0}", results);
|
||||
Console.WriteLine("{0}", valueDoc);
|
||||
|
||||
|
||||
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));
|
||||
|
||||
engine = new Regorus.Engine();
|
||||
engine.AddPolicy(
|
||||
"test.rego",
|
||||
"package test\nx = 1\nmessage = `Hello`");
|
||||
|
||||
engine.SetEnableCoverage(true);
|
||||
Console.WriteLine("{0}", engine.EvalRule("data.test.message"));
|
||||
Console.WriteLine("{0}", engine.GetCoverageReportPretty());
|
||||
|
||||
@@ -29,117 +29,159 @@ namespace Regorus
|
||||
|
||||
}
|
||||
|
||||
public void AddPolicy(string path, string rego)
|
||||
public string 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));
|
||||
return CheckAndDropResult(RegorusFFI.API.regorus_engine_add_policy(E, pathPtr, regoPtr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddPolicyFromFile(string path)
|
||||
public string 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));
|
||||
}
|
||||
return 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);
|
||||
}
|
||||
|
||||
}
|
||||
return CheckAndDropResult(RegorusFFI.API.regorus_engine_eval_query(E, queryPtr));
|
||||
}
|
||||
}
|
||||
if (resultJson is not null) {
|
||||
return resultJson;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
public string EvalRule(string rule)
|
||||
{
|
||||
var ruleBytes = Encoding.UTF8.GetBytes(rule);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* rulePtr = ruleBytes)
|
||||
{
|
||||
return CheckAndDropResult(RegorusFFI.API.regorus_engine_eval_query(E, rulePtr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEnableCoverage(bool enable)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_set_enable_coverage(E, enable));
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCoverageData()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_clear_coverage_data(E));
|
||||
}
|
||||
}
|
||||
|
||||
public string GetCoverageReport()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return CheckAndDropResult(RegorusFFI.API.regorus_engine_get_coverage_report(E));
|
||||
}
|
||||
}
|
||||
|
||||
public string GetCoverageReportPretty()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return CheckAndDropResult(RegorusFFI.API.regorus_engine_get_coverage_report_pretty(E));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetGatherPrints(bool enable)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
CheckAndDropResult(RegorusFFI.API.regorus_engine_set_gather_prints(E, enable));
|
||||
}
|
||||
}
|
||||
|
||||
public string TakePrints()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return CheckAndDropResult(RegorusFFI.API.regorus_engine_take_prints(E));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,8 +193,8 @@ namespace Regorus
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CheckAndDropResult(RegorusFFI.RegorusResult result)
|
||||
|
||||
string CheckAndDropResult(RegorusFFI.RegorusResult result)
|
||||
{
|
||||
if (result.status != RegorusFFI.RegorusStatus.RegorusStatusOk) {
|
||||
unsafe {
|
||||
@@ -162,7 +204,16 @@ namespace Regorus
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
RegorusFFI.API.regorus_result_drop(result);
|
||||
|
||||
var resultString = "";
|
||||
unsafe
|
||||
{
|
||||
if (result.output is not null) {
|
||||
resultString = System.Runtime.InteropServices.Marshal.PtrToStringUTF8((IntPtr)result.output);
|
||||
}
|
||||
RegorusFFI.API.regorus_result_drop(result);
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,8 +13,9 @@ regorus = { path = "../..", default-features = false }
|
||||
serde_json = "1.0.113"
|
||||
|
||||
[features]
|
||||
default = ["std", "regorus/full-opa"]
|
||||
default = ["std", "coverage", "regorus/arc", "regorus/full-opa"]
|
||||
std = ["regorus/std"]
|
||||
coverage = ["regorus/coverage"]
|
||||
custom_allocator = []
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
// <auto-generated>
|
||||
// This code is generated by csbindgen.
|
||||
// DON'T CHANGE THIS DIRECTLY.
|
||||
// </auto-generated>
|
||||
#pragma warning disable CS8500
|
||||
#pragma warning disable CS8981
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace RegorusFFI
|
||||
{
|
||||
internal static unsafe partial class API
|
||||
{
|
||||
const string __DllName = "regorus_ffi";
|
||||
|
||||
|
||||
|
||||
/// <summary>Drop a `RegorusResult`. `output` and `error_message` strings are not valid after drop.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_result_drop", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void regorus_result_drop(RegorusResult r);
|
||||
|
||||
/// <summary>Construct a new Engine See https://docs.rs/regorus/latest/regorus/struct.Engine.html</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusEngine* regorus_engine_new();
|
||||
|
||||
/// <summary>Clone a [`RegorusEngine`] To avoid having to parse same policy again, the engine can be cloned after policies and data have been added.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusEngine* regorus_engine_clone(RegorusEngine* engine);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_drop", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern void regorus_engine_drop(RegorusEngine* engine);
|
||||
|
||||
/// <summary>Add a policy The policy is parsed into AST. See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy * `path`: A filename to be associated with the policy. * `rego`: Rego policy.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_policy", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_policy(RegorusEngine* engine, byte* path, byte* rego);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_policy_from_file", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_policy_from_file(RegorusEngine* engine, byte* path);
|
||||
|
||||
/// <summary>Add policy data. See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data * `data`: JSON encoded value to be used as policy data.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_data_json", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_data_json(RegorusEngine* engine, byte* data);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_add_data_from_json_file", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_add_data_from_json_file(RegorusEngine* engine, byte* path);
|
||||
|
||||
/// <summary>Clear policy data. See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_clear_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_clear_data(RegorusEngine* engine);
|
||||
|
||||
/// <summary>Set input. See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input * `input`: JSON encoded value to be used as input to query.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_set_input_json", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_set_input_json(RegorusEngine* engine, byte* input);
|
||||
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_set_input_from_json_file", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_set_input_from_json_file(RegorusEngine* engine, byte* path);
|
||||
|
||||
/// <summary>Evaluate query. See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query * `query`: Rego expression to be evaluate.</summary>
|
||||
[DllImport(__DllName, EntryPoint = "regorus_engine_eval_query", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
|
||||
public static extern RegorusResult regorus_engine_eval_query(RegorusEngine* engine, byte* query);
|
||||
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct RegorusResult
|
||||
{
|
||||
public RegorusStatus status;
|
||||
public byte* output;
|
||||
public byte* error_message;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe partial struct RegorusEngine
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
internal enum RegorusStatus : uint
|
||||
{
|
||||
RegorusStatusOk,
|
||||
RegorusStatusError,
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
#ifndef REGORUS_FFI_HPP
|
||||
#define REGORUS_FFI_HPP
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <new>
|
||||
|
||||
/// Status of a call on `RegorusEngine`.
|
||||
enum class RegorusStatus {
|
||||
/// The operation was successful.
|
||||
RegorusStatusOk,
|
||||
/// The operation was unsuccessful.
|
||||
RegorusStatusError,
|
||||
};
|
||||
|
||||
/// Wrapper for `regorus::Engine`.
|
||||
struct RegorusEngine;
|
||||
|
||||
/// Result of a call on `RegorusEngine`.
|
||||
///
|
||||
/// Must be freed using `regorus_result_drop`.
|
||||
struct RegorusResult {
|
||||
/// Status
|
||||
RegorusStatus status;
|
||||
/// Output produced by the call.
|
||||
/// Owned by Rust.
|
||||
char *output;
|
||||
/// Errors produced by the call.
|
||||
/// Owned by Rust.
|
||||
char *error_message;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
/// Drop a `RegorusResult`.
|
||||
///
|
||||
/// `output` and `error_message` strings are not valid after drop.
|
||||
void regorus_result_drop(RegorusResult r);
|
||||
|
||||
/// Construct a new Engine
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html
|
||||
RegorusEngine *regorus_engine_new();
|
||||
|
||||
/// Clone a [`RegorusEngine`]
|
||||
///
|
||||
/// To avoid having to parse same policy again, the engine can be cloned
|
||||
/// after policies and data have been added.
|
||||
RegorusEngine *regorus_engine_clone(RegorusEngine *engine);
|
||||
|
||||
void regorus_engine_drop(RegorusEngine *engine);
|
||||
|
||||
/// Add a policy
|
||||
///
|
||||
/// The policy is parsed into AST.
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy
|
||||
///
|
||||
/// * `path`: A filename to be associated with the policy.
|
||||
/// * `rego`: Rego policy.
|
||||
RegorusResult regorus_engine_add_policy(RegorusEngine *engine, const char *path, const char *rego);
|
||||
|
||||
RegorusResult regorus_engine_add_policy_from_file(RegorusEngine *engine, const char *path);
|
||||
|
||||
/// Add policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data
|
||||
/// * `data`: JSON encoded value to be used as policy data.
|
||||
RegorusResult regorus_engine_add_data_json(RegorusEngine *engine, const char *data);
|
||||
|
||||
RegorusResult regorus_engine_add_data_from_json_file(RegorusEngine *engine, const char *path);
|
||||
|
||||
/// Clear policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
RegorusResult regorus_engine_clear_data(RegorusEngine *engine);
|
||||
|
||||
/// Set input.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input
|
||||
/// * `input`: JSON encoded value to be used as input to query.
|
||||
RegorusResult regorus_engine_set_input_json(RegorusEngine *engine, const char *input);
|
||||
|
||||
RegorusResult regorus_engine_set_input_from_json_file(RegorusEngine *engine, const char *path);
|
||||
|
||||
/// Evaluate query.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query
|
||||
/// * `query`: Rego expression to be evaluate.
|
||||
RegorusResult regorus_engine_eval_query(RegorusEngine *engine, const char *query);
|
||||
|
||||
extern uint8_t *regorus_aligned_alloc(uintptr_t alignment, uintptr_t size);
|
||||
|
||||
extern void regorus_free(uint8_t *ptr);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // REGORUS_FFI_HPP
|
||||
@@ -1,131 +0,0 @@
|
||||
#ifndef REGORUS_H
|
||||
#define REGORUS_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Status of a call on `RegorusEngine`.
|
||||
*/
|
||||
typedef enum RegorusStatus {
|
||||
/**
|
||||
* The operation was successful.
|
||||
*/
|
||||
RegorusStatusOk,
|
||||
/**
|
||||
* The operation was unsuccessful.
|
||||
*/
|
||||
RegorusStatusError,
|
||||
} RegorusStatus;
|
||||
|
||||
/**
|
||||
* Wrapper for `regorus::Engine`.
|
||||
*/
|
||||
typedef struct RegorusEngine RegorusEngine;
|
||||
|
||||
/**
|
||||
* Result of a call on `RegorusEngine`.
|
||||
*
|
||||
* Must be freed using `regorus_result_drop`.
|
||||
*/
|
||||
typedef struct RegorusResult {
|
||||
/**
|
||||
* Status
|
||||
*/
|
||||
enum RegorusStatus status;
|
||||
/**
|
||||
* Output produced by the call.
|
||||
* Owned by Rust.
|
||||
*/
|
||||
char *output;
|
||||
/**
|
||||
* Errors produced by the call.
|
||||
* Owned by Rust.
|
||||
*/
|
||||
char *error_message;
|
||||
} RegorusResult;
|
||||
|
||||
/**
|
||||
* Drop a `RegorusResult`.
|
||||
*
|
||||
* `output` and `error_message` strings are not valid after drop.
|
||||
*/
|
||||
void regorus_result_drop(struct RegorusResult r);
|
||||
|
||||
/**
|
||||
* Construct a new Engine
|
||||
*
|
||||
* See https://docs.rs/regorus/latest/regorus/struct.Engine.html
|
||||
*/
|
||||
struct RegorusEngine *regorus_engine_new(void);
|
||||
|
||||
/**
|
||||
* Clone a [`RegorusEngine`]
|
||||
*
|
||||
* To avoid having to parse same policy again, the engine can be cloned
|
||||
* after policies and data have been added.
|
||||
*/
|
||||
struct RegorusEngine *regorus_engine_clone(struct RegorusEngine *engine);
|
||||
|
||||
void regorus_engine_drop(struct RegorusEngine *engine);
|
||||
|
||||
/**
|
||||
* Add a policy
|
||||
*
|
||||
* The policy is parsed into AST.
|
||||
* See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_policy
|
||||
*
|
||||
* * `path`: A filename to be associated with the policy.
|
||||
* * `rego`: Rego policy.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_add_policy(struct RegorusEngine *engine,
|
||||
const char *path,
|
||||
const char *rego);
|
||||
|
||||
struct RegorusResult regorus_engine_add_policy_from_file(struct RegorusEngine *engine,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Add policy data.
|
||||
*
|
||||
* See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data
|
||||
* * `data`: JSON encoded value to be used as policy data.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_add_data_json(struct RegorusEngine *engine, const char *data);
|
||||
|
||||
struct RegorusResult regorus_engine_add_data_from_json_file(struct RegorusEngine *engine,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Clear policy data.
|
||||
*
|
||||
* See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
*/
|
||||
struct RegorusResult regorus_engine_clear_data(struct RegorusEngine *engine);
|
||||
|
||||
/**
|
||||
* Set input.
|
||||
*
|
||||
* See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input
|
||||
* * `input`: JSON encoded value to be used as input to query.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_set_input_json(struct RegorusEngine *engine, const char *input);
|
||||
|
||||
struct RegorusResult regorus_engine_set_input_from_json_file(struct RegorusEngine *engine,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* Evaluate query.
|
||||
*
|
||||
* See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query
|
||||
* * `query`: Rego expression to be evaluate.
|
||||
*/
|
||||
struct RegorusResult regorus_engine_eval_query(struct RegorusEngine *engine, const char *query);
|
||||
|
||||
extern uint8_t *regorus_aligned_alloc(uintptr_t alignment, uintptr_t size);
|
||||
|
||||
extern void regorus_free(uint8_t *ptr);
|
||||
|
||||
#endif /* REGORUS_H */
|
||||
@@ -119,21 +119,20 @@ pub extern "C" fn regorus_engine_new() -> *mut RegorusEngine {
|
||||
///
|
||||
/// To avoid having to parse same policy again, the engine can be cloned
|
||||
/// after policies and data have been added.
|
||||
///
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_clone(engine: *mut RegorusEngine) -> *mut RegorusEngine {
|
||||
unsafe {
|
||||
if engine.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
Box::into_raw(Box::new((*engine).clone()))
|
||||
match to_ref(&engine) {
|
||||
Ok(e) => Box::into_raw(Box::new(e.clone())),
|
||||
_ => std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_drop(engine: *mut RegorusEngine) {
|
||||
if !engine.is_null() {
|
||||
if let Ok(e) = to_ref(&engine) {
|
||||
unsafe {
|
||||
let _ = Box::from_raw(engine);
|
||||
let _ = Box::from_raw(std::ptr::from_mut(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,6 +186,18 @@ pub extern "C" fn regorus_engine_add_data_json(
|
||||
}())
|
||||
}
|
||||
|
||||
/// Get list of loaded Rego packages as JSON.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.get_packages
|
||||
/// * `data`: JSON encoded value to be used as policy data.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_get_packages(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
to_regorus_string_result(|| -> Result<String> {
|
||||
serde_json::to_string_pretty(&to_ref(&engine)?.engine.get_packages()?)
|
||||
.map_err(anyhow::Error::msg)
|
||||
}())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_add_data_from_json_file(
|
||||
@@ -196,7 +207,7 @@ pub extern "C" fn regorus_engine_add_data_from_json_file(
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.add_data(regorus::Value::from_json_file(&from_c_str("path", path)?)?)
|
||||
.add_data(regorus::Value::from_json_file(from_c_str("path", path)?)?)
|
||||
}())
|
||||
}
|
||||
|
||||
@@ -237,7 +248,7 @@ pub extern "C" fn regorus_engine_set_input_from_json_file(
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.set_input(regorus::Value::from_json_file(&from_c_str("path", path)?)?);
|
||||
.set_input(regorus::Value::from_json_file(from_c_str("path", path)?)?);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
@@ -267,6 +278,139 @@ pub extern "C" fn regorus_engine_eval_query(
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluate specified rule.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_rule
|
||||
/// * `rule`: Path to the rule.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_eval_rule(
|
||||
engine: *mut RegorusEngine,
|
||||
rule: *const c_char,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.eval_rule(from_c_str("rule", rule)?)?
|
||||
.to_json_str()
|
||||
}();
|
||||
match output {
|
||||
Ok(out) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: to_c_str(out),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => to_regorus_result(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable/disable coverage.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_enable_coverage
|
||||
/// * `enable`: Whether to enable or disable coverage.
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_set_enable_coverage(
|
||||
engine: *mut RegorusEngine,
|
||||
enable: bool,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?.engine.set_enable_coverage(enable);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Get coverage report.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.get_coverage_report
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_get_coverage_report(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(
|
||||
&to_ref(&engine)?.engine.get_coverage_report()?,
|
||||
)?)
|
||||
}();
|
||||
match output {
|
||||
Ok(out) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: to_c_str(out),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => to_regorus_result(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get pretty printed coverage report.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/coverage/struct.Report.html#method.to_string_pretty
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_get_coverage_report_pretty(
|
||||
engine: *mut RegorusEngine,
|
||||
) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
to_ref(&engine)?
|
||||
.engine
|
||||
.get_coverage_report()?
|
||||
.to_string_pretty()
|
||||
}();
|
||||
match output {
|
||||
Ok(out) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: to_c_str(out),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => to_regorus_result(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear coverage data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_coverage_data
|
||||
#[no_mangle]
|
||||
#[cfg(feature = "coverage")]
|
||||
pub extern "C" fn regorus_engine_clear_coverage_data(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?.engine.clear_coverage_data();
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Whether to gather output of print statements.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_gather_prints
|
||||
/// * `enable`: Whether to enable or disable gathering print statements.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_set_gather_prints(
|
||||
engine: *mut RegorusEngine,
|
||||
enable: bool,
|
||||
) -> RegorusResult {
|
||||
to_regorus_result(|| -> Result<()> {
|
||||
to_ref(&engine)?.engine.set_gather_prints(enable);
|
||||
Ok(())
|
||||
}())
|
||||
}
|
||||
|
||||
/// Take all the gathered print statements.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.take_prints
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regorus_engine_take_prints(engine: *mut RegorusEngine) -> RegorusResult {
|
||||
let output = || -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(
|
||||
&to_ref(&engine)?.engine.take_prints()?,
|
||||
)?)
|
||||
}();
|
||||
match output {
|
||||
Ok(out) => RegorusResult {
|
||||
status: RegorusStatus::RegorusStatusOk,
|
||||
output: to_c_str(out),
|
||||
error_message: std::ptr::null_mut(),
|
||||
},
|
||||
Err(e) => to_regorus_result(Err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_allocator")]
|
||||
extern "C" {
|
||||
fn regorus_aligned_alloc(alignment: usize, size: usize) -> *mut u8;
|
||||
|
||||
@@ -12,7 +12,7 @@ func main() {
|
||||
var err error
|
||||
|
||||
t := time.Now();
|
||||
|
||||
|
||||
// Create new engine
|
||||
engine := regorus.NewEngine()
|
||||
defer engine.Close()
|
||||
@@ -26,10 +26,12 @@ func main() {
|
||||
"../../tests/aci/policy.rego",
|
||||
}
|
||||
for _, policy := range policies {
|
||||
if err := engine.AddPolicyFromFile(policy); err != nil {
|
||||
var pkg string
|
||||
if pkg, err = engine.AddPolicyFromFile(policy); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Loaded package %s\n", pkg);
|
||||
}
|
||||
if err = engine.AddDataFromJsonFile("../../tests/aci/data.json"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
@@ -38,21 +40,48 @@ func main() {
|
||||
elapsed2 := time.Since(t)
|
||||
|
||||
t = time.Now()
|
||||
// Set input and eval query.
|
||||
// Set input.
|
||||
if err = engine.SetInputFromJsonFile("../../tests/aci/input.json"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
if output, err = engine.EvalQuery("data.framework.mount_overlay = x"); err != nil {
|
||||
// Eval Rule
|
||||
if output, err = engine.EvalRule("data.framework.mount_overlay"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
elapsed3 := time.Since(t)
|
||||
|
||||
fmt.Println("{%s}", output)
|
||||
fmt.Printf("%s\n", output)
|
||||
fmt.Printf("NewEngine took %v\n", elapsed1)
|
||||
fmt.Printf("Add policies and data took %v\n", elapsed2)
|
||||
fmt.Printf("Set input and eval query took %v\n", elapsed3)
|
||||
|
||||
// Create new engine.
|
||||
engine1 := regorus.NewEngine()
|
||||
defer engine1.Close()
|
||||
|
||||
// Enable coverage
|
||||
engine1.SetEnableCoverage(true)
|
||||
|
||||
var pkg string
|
||||
pkg, err = engine1.AddPolicy("test.rego", "package test\nx = 1\nmessage = `Hello`")
|
||||
fmt.Printf("Loaded package %s\n", pkg)
|
||||
|
||||
// Eval Rule
|
||||
if output, err = engine1.EvalRule("data.test.message"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", output)
|
||||
|
||||
// Print pretty coverage report.
|
||||
if output, err = engine1.GetCoverageReportPretty(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", output)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func (e *Engine) Clone() *Engine {
|
||||
return c
|
||||
}
|
||||
|
||||
func (e *Engine) AddPolicy(path string, rego string) error {
|
||||
func (e *Engine) AddPolicy(path string, rego string) (string, error) {
|
||||
path_c := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(path_c))
|
||||
|
||||
@@ -38,21 +38,21 @@ func (e *Engine) AddPolicy(path string, rego string) error {
|
||||
result := C.regorus_engine_add_policy(e.e, path_c, rego_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
func (e *Engine) AddPolicyFromFile(path string) error {
|
||||
func (e *Engine) AddPolicyFromFile(path string) (string, error) {
|
||||
path_c := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(path_c))
|
||||
|
||||
result := C.regorus_engine_add_policy_from_file(e.e, path_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
func (e *Engine) AddDataJson(data string) error {
|
||||
@@ -115,3 +115,73 @@ func (e *Engine) EvalQuery(query string) (string, error) {
|
||||
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
func (e *Engine) EvalRule(rule string) (string, error) {
|
||||
rule_c := C.CString(rule)
|
||||
defer C.free(unsafe.Pointer(rule_c))
|
||||
|
||||
result := C.regorus_engine_eval_rule(e.e, rule_c)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
func (e *Engine) SetEnableCoverage(enable bool) error {
|
||||
result := C.regorus_engine_set_enable_coverage(e.e, C.bool(enable))
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) ClearCoverageData() error {
|
||||
result := C.regorus_engine_clear_coverage_data(e.e)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) GetCoverageReport() (string, error) {
|
||||
result := C.regorus_engine_get_coverage_report(e.e)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
func (e *Engine) GetCoverageReportPretty() (string, error) {
|
||||
result := C.regorus_engine_get_coverage_report_pretty(e.e)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
func (e *Engine) SetGatherPrints(b bool) error {
|
||||
result := C.regorus_engine_set_gather_prints(e.e, C.bool(b))
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Engine) TakePrints() (string, error) {
|
||||
result := C.regorus_engine_take_prints(e.e)
|
||||
defer C.regorus_result_drop(result)
|
||||
if result.status != C.RegorusStatusOk {
|
||||
return "", fmt.Errorf("%s", C.GoString(result.error_message))
|
||||
}
|
||||
|
||||
return C.GoString(result.output), nil
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@ keywords = ["interpreter", "opa", "policy-as-code", "rego"]
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["regorus/std", "regorus/full-opa"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
serde_json = "1.0.112"
|
||||
jni = "0.21.1"
|
||||
regorus = { path = "../.." }
|
||||
regorus = { path = "../..", default-features = false, features = ["arc"] }
|
||||
|
||||
@@ -6,15 +6,31 @@ import com.microsoft.regorus.Engine;
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
try (Engine engine = new Engine()) {
|
||||
engine.addPolicy(
|
||||
String pkg = engine.addPolicy(
|
||||
"hello.rego",
|
||||
"package test\nmessage = concat(\", \", [input.message, data.message])"
|
||||
"package test\nx=1\nmessage = concat(\", \", [input.message, data.message])"
|
||||
);
|
||||
System.out.println("Loaded package " + pkg);
|
||||
|
||||
|
||||
engine.addDataJson("{\"message\":\"World!\"}");
|
||||
engine.setInputJson("{\"message\":\"Hello\"}");
|
||||
String resJson = engine.evalQuery("data.test.message");
|
||||
|
||||
// Evaluate query.
|
||||
String resJson = engine.evalQuery("data.test.message");
|
||||
System.out.println(resJson);
|
||||
|
||||
// Enable coverage.
|
||||
engine.setEnableCoverage(true);
|
||||
|
||||
// Evaluate rule.
|
||||
String valueJson = engine.evalRule("data.test.message");
|
||||
System.out.println(valueJson);
|
||||
|
||||
String coverageJson = engine.getCoverageReport();
|
||||
System.out.println(coverageJson);
|
||||
|
||||
System.out.println(engine.getCoverageReportPretty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,18 +17,26 @@ JNIEXPORT jlong JNICALL Java_com_microsoft_regorus_Engine_nativeNewEngine
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeAddPolicy
|
||||
* Signature: (JLjava/lang/String;Ljava/lang/String;)V
|
||||
* Method: nativeClone
|
||||
* Signature: (J)J
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeAddPolicy
|
||||
JNIEXPORT jlong JNICALL Java_com_microsoft_regorus_Engine_nativeClone
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeAddPolicy
|
||||
* Signature: (JLjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeAddPolicy
|
||||
(JNIEnv *, jclass, jlong, jstring, jstring);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeAddPolicyFromFile
|
||||
* Signature: (JLjava/lang/String;)V
|
||||
* Signature: (JLjava/lang/String;)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeAddPolicyFromFile
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeAddPolicyFromFile
|
||||
(JNIEnv *, jclass, jlong, jstring);
|
||||
|
||||
/*
|
||||
@@ -79,6 +87,62 @@ JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeSetInputJsonFromF
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeEvalQuery
|
||||
(JNIEnv *, jclass, jlong, jstring);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeEvalRule
|
||||
* Signature: (JLjava/lang/String;)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeEvalRule
|
||||
(JNIEnv *, jclass, jlong, jstring);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeSetEnableCoverage
|
||||
* Signature: (JZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeSetEnableCoverage
|
||||
(JNIEnv *, jclass, jlong, jboolean);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeGetCoverageReport
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeGetCoverageReport
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeGetCoverageReportAsColoredString
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeGetCoverageReportAsColoredString
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeClearCoverageData
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeClearCoverageData
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeSetGatherPrints
|
||||
* Signature: (JZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeSetGatherPrints
|
||||
(JNIEnv *, jclass, jlong, jboolean);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeTakePrints
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeTakePrints
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_microsoft_regorus_Engine
|
||||
* Method: nativeDestroyEngine
|
||||
|
||||
@@ -17,6 +17,17 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeNewEngine(
|
||||
Box::into_raw(Box::new(engine)) as jlong
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeClone(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) -> jlong {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let c = engine.clone();
|
||||
Box::into_raw(Box::new(c)) as jlong
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddPolicy(
|
||||
env: JNIEnv,
|
||||
@@ -24,14 +35,19 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddPolicy(
|
||||
engine_ptr: jlong,
|
||||
path: JString,
|
||||
rego: JString,
|
||||
) {
|
||||
let _ = throw_err(env, |env| {
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let path: String = env.get_string(&path)?.into();
|
||||
let rego: String = env.get_string(®o)?.into();
|
||||
engine.add_policy(path, rego)?;
|
||||
Ok(())
|
||||
let pkg = env.new_string(engine.add_policy(path, rego)?)?;
|
||||
Ok(pkg.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -40,13 +56,37 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddPolicyFromFile
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
path: JString,
|
||||
) {
|
||||
let _ = throw_err(env, |env| {
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let path: String = env.get_string(&path)?.into();
|
||||
engine.add_policy_from_file(path)?;
|
||||
Ok(())
|
||||
let pkg = env.new_string(engine.add_policy_from_file(path)?)?;
|
||||
Ok(pkg.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeGetPackages(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let packages = engine.get_packages()?;
|
||||
let packages_json = env.new_string(serde_json::to_string_pretty(&packages)?)?;
|
||||
Ok(packages_json.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -117,7 +157,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeSetInputJsonFromF
|
||||
let _ = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let path: String = env.get_string(&path)?.into();
|
||||
engine.set_input(Value::from_json_file(&path)?);
|
||||
engine.set_input(Value::from_json_file(path)?);
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
@@ -144,12 +184,133 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeEvalQuery(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn Java_com_microsoft_regorus_Engine_nativeDestroyEngine(
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeEvalRule(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
rule: JString,
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let rule: String = env.get_string(&rule)?.into();
|
||||
let value = engine.eval_rule(rule)?;
|
||||
let output = env.new_string(value.to_json_str()?)?;
|
||||
Ok(output.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeSetEnableCoverage(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
enable: bool,
|
||||
) {
|
||||
let _ = throw_err(env, |_| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
engine.set_enable_coverage(enable);
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeGetCoverageReport(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let report = engine.get_coverage_report()?;
|
||||
let output = env.new_string(serde_json::to_string_pretty(&report)?)?;
|
||||
Ok(output.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeGetCoverageReportPretty(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let report = engine.get_coverage_report()?.to_string_pretty()?;
|
||||
let output = env.new_string(&report)?;
|
||||
Ok(output.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeClearCoverageData(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) {
|
||||
let _ = throw_err(env, |_| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
engine.clear_coverage_data();
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeSetGatherPrints(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
b: bool,
|
||||
) {
|
||||
let _ = throw_err(env, |_| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
engine.set_gather_prints(b);
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeTakePrints(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) -> jstring {
|
||||
let res = throw_err(env, |env| {
|
||||
let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
|
||||
let prints = engine.take_prints()?;
|
||||
let output = env.new_string(serde_json::to_string_pretty(&prints)?)?;
|
||||
Ok(output.into_raw())
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(_) => JObject::null().into_raw(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeDestroyEngine(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
engine_ptr: jlong,
|
||||
) {
|
||||
let _engine = Box::from_raw(engine_ptr as *mut Engine);
|
||||
unsafe {
|
||||
let _engine = Box::from_raw(engine_ptr as *mut Engine);
|
||||
}
|
||||
}
|
||||
|
||||
fn throw_err<T>(mut env: JNIEnv, mut f: impl FnMut(&mut JNIEnv) -> Result<T>) -> Result<T> {
|
||||
|
||||
@@ -16,20 +16,29 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
/**
|
||||
* Regorus Engine.
|
||||
*/
|
||||
public class Engine implements AutoCloseable {
|
||||
public class Engine implements AutoCloseable, Cloneable {
|
||||
// Methods exposed from Rust side, you can run
|
||||
// `javac -h . src/main/java/com/microsoft/regorus/Engine.java` to update
|
||||
// expected native header at `bindings/java/com_microsoft_regorus_Engine.h`
|
||||
// if you update the native API.
|
||||
private static native long nativeNewEngine();
|
||||
private static native void nativeAddPolicy(long enginePtr, String path, String rego);
|
||||
private static native void nativeAddPolicyFromFile(long enginePtr, String path);
|
||||
private static native long nativeClone(long enginePtr);
|
||||
private static native String nativeAddPolicy(long enginePtr, String path, String rego);
|
||||
private static native String nativeAddPolicyFromFile(long enginePtr, String path);
|
||||
private static native String nativeGetPackages(long enginePtr);
|
||||
private static native void nativeClearData(long enginePtr);
|
||||
private static native void nativeAddDataJson(long enginePtr, String data);
|
||||
private static native void nativeAddDataJsonFromFile(long enginePtr, String path);
|
||||
private static native void nativeSetInputJson(long enginePtr, String input);
|
||||
private static native void nativeSetInputJsonFromFile(long enginePtr, String path);
|
||||
private static native String nativeEvalQuery(long enginePtr, String query);
|
||||
private static native String nativeEvalRule(long enginePtr, String qrule);
|
||||
private static native void nativeSetEnableCoverage(long enginePtr, boolean enable);
|
||||
private static native String nativeGetCoverageReport(long enginePtr);
|
||||
private static native String nativeGetCoverageReportPretty(long enginePtr);
|
||||
private static native void nativeClearCoverageData(long enginePtr);
|
||||
private static native void nativeSetGatherPrints(long enginePtr, boolean b);
|
||||
private static native String nativeTakePrints(long enginePtr);
|
||||
private static native void nativeDestroyEngine(long enginePtr);
|
||||
|
||||
// Pointer to Engine allocated on Rust's heap, all native methods works on
|
||||
@@ -43,25 +52,50 @@ public class Engine implements AutoCloseable {
|
||||
enginePtr = nativeNewEngine();
|
||||
}
|
||||
|
||||
|
||||
Engine(long ptr) {
|
||||
enginePtr = ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficiently clones an Engine.
|
||||
*/
|
||||
public Engine Clone() {
|
||||
return new Engine(nativeClone(enginePtr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an inline Rego policy.
|
||||
*
|
||||
* @param filename Filename of this Rego policy.
|
||||
* @param rego Rego policy.
|
||||
*
|
||||
* @return Rego package defined in the policy.
|
||||
*/
|
||||
public void addPolicy(String filename, String rego) {
|
||||
nativeAddPolicy(enginePtr, filename, rego);
|
||||
public String addPolicy(String filename, String rego) {
|
||||
return nativeAddPolicy(enginePtr, filename, rego);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Rego policy from given path.
|
||||
*
|
||||
* @param path Path of the Rego policy.
|
||||
*
|
||||
* @return Rego package defined in the policy.
|
||||
*/
|
||||
public void addPolicyFromFile(String path) {
|
||||
nativeAddPolicyFromFile(enginePtr, path);
|
||||
public String addPolicyFromFile(String path) {
|
||||
return nativeAddPolicyFromFile(enginePtr, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of loaded Rego packages.
|
||||
*
|
||||
* @return List of Rego packages as a JSON array of strings.
|
||||
*/
|
||||
public String getPackages() {
|
||||
return nativeGetPackages(enginePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the data document.
|
||||
*/
|
||||
@@ -137,6 +171,70 @@ public class Engine implements AutoCloseable {
|
||||
return nativeEvalQuery(enginePtr, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates given Rego rule and returns a JSON string as a result.
|
||||
*
|
||||
* @param rule Path of the Rego rule.
|
||||
*
|
||||
* @return Value of the rule as a JSON string.
|
||||
*/
|
||||
public String evalRule(String rule) {
|
||||
return nativeEvalRule(enginePtr, rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable coverage.
|
||||
*
|
||||
* @param enable Whether to enable coverage or not.
|
||||
*
|
||||
*/
|
||||
public void setEnableCoverage(boolean enable) {
|
||||
nativeSetEnableCoverage(enginePtr, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear coverage data.
|
||||
*
|
||||
*/
|
||||
public void clearCoverageData() {
|
||||
nativeClearCoverageData(enginePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get coverage report as json string.
|
||||
*
|
||||
*/
|
||||
public String getCoverageReport() {
|
||||
return nativeGetCoverageReport(enginePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get coverage report as ANSI color coded string.
|
||||
*
|
||||
*/
|
||||
public String getCoverageReportPretty() {
|
||||
return nativeGetCoverageReportPretty(enginePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable gathering prints.
|
||||
*
|
||||
* @param b Whether to gather prints or not.
|
||||
*
|
||||
*/
|
||||
public void setGatherPrints(boolean b) {
|
||||
nativeSetGatherPrints(enginePtr, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take gathered prints.
|
||||
*
|
||||
*/
|
||||
public String takePrints() {
|
||||
return nativeTakePrints(enginePtr);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
nativeDestroyEngine(enginePtr);
|
||||
|
||||
@@ -11,10 +11,13 @@ keywords = ["interpreter", "opa", "policy-as-code", "rego"]
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["regorus/std", "regorus/full-opa"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
ordered-float = "4.2.0"
|
||||
pyo3 = {version = "0.21.0", features = ["anyhow", "extension-module"] }
|
||||
regorus = { path = "../.." }
|
||||
regorus = { path = "../..", default-features = false, features = ["arc"] }
|
||||
serde_json = "1.0.112"
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Regorus can be used in Python via `regorus` package. (It is not yet available in
|
||||
|
||||
See [Repository](https://github.com/microsoft/regorus).
|
||||
|
||||
To build this binding, see [building](https://github.com/microsoft/regorus/bindings/python/building.md)
|
||||
To build this binding, see [building](https://github.com/microsoft/regorus/blob/main/bindings/python/building.md)
|
||||
|
||||
## Usage
|
||||
```Python
|
||||
@@ -54,14 +54,11 @@ input = {
|
||||
}
|
||||
engine.set_input(input)
|
||||
|
||||
# Eval query
|
||||
results = engine.eval_query('data.framework.mount_overlay=x')
|
||||
# Eval rule
|
||||
value = engine.eval_rule('data.framework.mount_overlay')
|
||||
|
||||
# Print results
|
||||
print(results['result'][0])
|
||||
# Print value
|
||||
print(value)
|
||||
|
||||
# Eval query as json
|
||||
results_json = engine.eval_query_as_json('data.framework.mount_overlay=x')
|
||||
print(results_json)
|
||||
```
|
||||
|
||||
|
||||
@@ -21,19 +21,7 @@ impl Default for Engine {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Engine {
|
||||
/// Clone a [`Engine`]
|
||||
///
|
||||
/// To avoid having to parse same policy again, the engine can be cloned
|
||||
/// after policies and data have been added.
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
engine: self.engine.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from<'source>(ob: &Bound<'_, PyAny>) -> Result<Value, PyErr> {
|
||||
fn from(ob: &Bound<'_, PyAny>) -> Result<Value, PyErr> {
|
||||
// dicts
|
||||
Ok(if let Ok(dict) = ob.downcast::<PyDict>() {
|
||||
let mut map = BTreeMap::new();
|
||||
@@ -141,7 +129,7 @@ fn to(mut v: Value, py: Python<'_>) -> Result<PyObject> {
|
||||
|
||||
Value::Array(_) => {
|
||||
let list = PyList::empty_bound(py);
|
||||
for v in std::mem::replace(v.as_array_mut()?, Vec::new()) {
|
||||
for v in std::mem::take(v.as_array_mut()?) {
|
||||
list.append(to(v, py)?)?;
|
||||
}
|
||||
list.into()
|
||||
@@ -149,7 +137,7 @@ fn to(mut v: Value, py: Python<'_>) -> Result<PyObject> {
|
||||
|
||||
Value::Set(_) => {
|
||||
let set = PySet::empty_bound(py)?;
|
||||
for v in std::mem::replace(v.as_set_mut()?, BTreeSet::new()) {
|
||||
for v in std::mem::take(v.as_set_mut()?) {
|
||||
set.add(to(v, py)?)?;
|
||||
}
|
||||
set.into()
|
||||
@@ -157,7 +145,7 @@ fn to(mut v: Value, py: Python<'_>) -> Result<PyObject> {
|
||||
|
||||
Value::Object(_) => {
|
||||
let dict = PyDict::new_bound(py);
|
||||
for (k, v) in std::mem::replace(v.as_object_mut()?, BTreeMap::new()) {
|
||||
for (k, v) in std::mem::take(v.as_object_mut()?) {
|
||||
dict.set_item(to(k, py)?, to(v, py)?)?;
|
||||
}
|
||||
dict.into()
|
||||
@@ -221,7 +209,7 @@ impl Engine {
|
||||
///
|
||||
/// * `path`: Path to JSON policy data.
|
||||
pub fn add_data_from_json_file(&mut self, path: String) -> Result<()> {
|
||||
let data = Value::from_json_file(&path)?;
|
||||
let data = Value::from_json_file(path)?;
|
||||
self.engine.add_data(data)
|
||||
}
|
||||
|
||||
@@ -254,7 +242,7 @@ impl Engine {
|
||||
///
|
||||
/// * `path`: Path to JSON input data.
|
||||
pub fn set_input_from_json_file(&mut self, path: String) -> Result<()> {
|
||||
let input = Value::from_json_file(&path)?;
|
||||
let input = Value::from_json_file(path)?;
|
||||
self.engine.set_input(input);
|
||||
Ok(())
|
||||
}
|
||||
@@ -299,6 +287,69 @@ impl Engine {
|
||||
let results = self.engine.eval_query(query, false)?;
|
||||
serde_json::to_string_pretty(&results).map_err(|e| anyhow!("{e}"))
|
||||
}
|
||||
|
||||
/// Evaluate rule.
|
||||
///
|
||||
/// * `rule`: Full path to the rule.
|
||||
pub fn eval_rule(&mut self, rule: String, py: Python<'_>) -> Result<PyObject> {
|
||||
to(self.engine.eval_rule(rule)?, py)
|
||||
}
|
||||
|
||||
/// Evaluate rule and return value as json.
|
||||
///
|
||||
/// * `rule`: Full path to the rule.
|
||||
pub fn eval_rule_as_json(&mut self, rule: String) -> Result<String> {
|
||||
let v = self.engine.eval_rule(rule)?;
|
||||
v.to_json_str()
|
||||
}
|
||||
|
||||
/// Enable code coverage
|
||||
///
|
||||
/// * `enable`: Whether to enable coverage or not.
|
||||
pub fn set_enable_coverage(&mut self, enable: bool) {
|
||||
self.engine.set_enable_coverage(enable)
|
||||
}
|
||||
|
||||
/// Get coverage report as json.
|
||||
///
|
||||
pub fn get_coverage_report_as_json(&self) -> Result<String> {
|
||||
let report = self.engine.get_coverage_report()?;
|
||||
serde_json::to_string_pretty(&report).map_err(|e| anyhow!("{e}"))
|
||||
}
|
||||
|
||||
/// Get coverage report as pretty printable string.
|
||||
///
|
||||
pub fn get_coverage_report_pretty(&self) -> Result<String> {
|
||||
self.engine.get_coverage_report()?.to_string_pretty()
|
||||
}
|
||||
|
||||
/// Clear coverage data.
|
||||
///
|
||||
pub fn clear_coverage_data(&mut self) {
|
||||
self.engine.clear_coverage_data();
|
||||
}
|
||||
|
||||
/// Gather print statements instead of printing to stderr.
|
||||
///
|
||||
pub fn set_gather_prints(&mut self, b: bool) {
|
||||
self.engine.set_gather_prints(b)
|
||||
}
|
||||
|
||||
/// Take gathered prints.
|
||||
///
|
||||
pub fn take_prints(&mut self) -> Result<Vec<String>> {
|
||||
self.engine.take_prints()
|
||||
}
|
||||
|
||||
/// Clone a [`Engine`]
|
||||
///
|
||||
/// To avoid having to parse same policy again, the engine can be cloned
|
||||
/// after policies and data have been added.
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
engine: self.engine.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
|
||||
@@ -8,13 +8,13 @@ engine = regorus.Engine()
|
||||
|
||||
# Load policies
|
||||
pkg = engine.add_policy_from_file('../../tests/aci/framework.rego')
|
||||
print(' Loaded Policy %s' % pkg)
|
||||
print(' Loaded package %s' % pkg)
|
||||
|
||||
pkg = engine.add_policy_from_file('../../tests/aci/api.rego')
|
||||
print(' Loaded Policy %s' % pkg)
|
||||
print(' Loaded package %s' % pkg)
|
||||
|
||||
pkg = engine.add_policy_from_file('../../tests/aci/policy.rego')
|
||||
print(' Loaded Policy %s' % pkg)
|
||||
print(' Loaded package %s' % pkg)
|
||||
|
||||
# Add policy data
|
||||
data = {
|
||||
@@ -55,3 +55,40 @@ print(results['result'][0])
|
||||
# Eval query as json
|
||||
results_json = engine.eval_query_as_json('data.framework.mount_overlay=x')
|
||||
print(results_json)
|
||||
|
||||
# Eval rule
|
||||
v = engine.eval_rule('data.framework.mount_overlay')
|
||||
print(v)
|
||||
|
||||
# Eval rule as json
|
||||
v = engine.eval_rule_as_json('data.framework.mount_overlay')
|
||||
print(v)
|
||||
|
||||
# Enable coverage
|
||||
engine.set_enable_coverage(True)
|
||||
engine.eval_rule('data.framework.mount_overlay')
|
||||
|
||||
# Print coverage
|
||||
report_json = engine.get_coverage_report_as_json()
|
||||
print(report_json)
|
||||
|
||||
# Pretty coverage report
|
||||
report = engine.get_coverage_report_pretty()
|
||||
print(report)
|
||||
|
||||
# Clone engine
|
||||
engine1 = engine.clone()
|
||||
|
||||
|
||||
# Clear coverage data
|
||||
engine.clear_coverage_data();
|
||||
|
||||
print(engine1.get_coverage_report_pretty())
|
||||
|
||||
# Enable gathering prints
|
||||
engine1.set_gather_prints(True)
|
||||
|
||||
# Gather prints
|
||||
engine1.eval_query('print("Hello")')
|
||||
ps = engine1.take_prints()
|
||||
print(ps)
|
||||
|
||||
@@ -9,8 +9,11 @@ publish = false
|
||||
crate-type = ["cdylib"]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
default = ["regorus/std", "regorus/full-opa"]
|
||||
|
||||
[dependencies]
|
||||
magnus = { version = "0.6.4" }
|
||||
regorus = { git = "https://github.com/microsoft/regorus" }
|
||||
regorus = { git = "https://github.com/microsoft/regorus", default-features = false, features = ["arc"] }
|
||||
serde_json = "1.0.117"
|
||||
serde_magnus = "0.8.1"
|
||||
|
||||
@@ -72,7 +72,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
fn add_data_from_json_file(&self, path: String) -> Result<(), Error> {
|
||||
let json_data = regorus::Value::from_json_file(&path).map_err(|e| {
|
||||
let json_data = regorus::Value::from_json_file(path).map_err(|e| {
|
||||
Error::new(
|
||||
runtime_error(),
|
||||
format!("Failed to parse JSON data file: {}", e),
|
||||
@@ -112,7 +112,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
fn add_input_from_json_file(&self, path: String) -> Result<(), Error> {
|
||||
let json_data = regorus::Value::from_json_file(&path).map_err(|e| {
|
||||
let json_data = regorus::Value::from_json_file(path).map_err(|e| {
|
||||
Error::new(
|
||||
runtime_error(),
|
||||
format!("Failed to parse JSON input file: {}", e),
|
||||
@@ -193,7 +193,8 @@ impl Engine {
|
||||
}
|
||||
|
||||
fn set_enable_coverage(&self, enable: bool) -> Result<(), Error> {
|
||||
Ok(self.engine.borrow_mut().set_enable_coverage(enable))
|
||||
self.engine.borrow_mut().set_enable_coverage(enable);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_coverage_report_as_json(&self) -> Result<String, Error> {
|
||||
@@ -237,12 +238,14 @@ impl Engine {
|
||||
}
|
||||
|
||||
fn clear_coverage_data(&self) -> Result<(), Error> {
|
||||
Ok(self.engine.borrow_mut().clear_coverage_data())
|
||||
self.engine.borrow_mut().clear_coverage_data();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Print statements can be gathered async instead of printing to stderr
|
||||
fn set_gather_prints(&self, enable: bool) -> Result<(), Error> {
|
||||
Ok(self.engine.borrow_mut().set_gather_prints(enable))
|
||||
self.engine.borrow_mut().set_gather_prints(enable);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn take_prints(&self) -> Result<Vec<String>, Error> {
|
||||
|
||||
@@ -10,8 +10,11 @@ keywords = ["interpreter", "opa", "policy-as-code", "rego"]
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["regorus/std", "regorus/full-opa"]
|
||||
|
||||
[dependencies]
|
||||
regorus = { path = "../.." }
|
||||
regorus = { path = "../..", default-features = false, features = ["arc"] }
|
||||
serde_json = "1.0.111"
|
||||
wasm-bindgen = "0.2.90"
|
||||
|
||||
|
||||
@@ -10,72 +10,10 @@
|
||||
|
||||
See [Repository](https://github.com/microsoft/regorus).
|
||||
|
||||
To build this binding, see [building](https://github.com/microsoft/regorus/bindings/wasm/building.md)
|
||||
To build this binding, see [building.md](https://github.com/microsoft/regorus/blob/main/bindings/wasm/building.md)
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
|
||||
var regorus = require('regorusjs')
|
||||
|
||||
// Create an engine.
|
||||
var engine = new regorus.Engine();
|
||||
|
||||
// Add Rego policy.
|
||||
engine.add_policy(
|
||||
// Associate this file name with policy
|
||||
'hello.rego',
|
||||
|
||||
// Rego policy
|
||||
`
|
||||
package test
|
||||
|
||||
# Join messages
|
||||
message = concat(", ", [input.message, data.message])
|
||||
`)
|
||||
|
||||
// Set policy data
|
||||
engine.add_data_json(`
|
||||
{
|
||||
"message" : "World!"
|
||||
}
|
||||
`)
|
||||
|
||||
// Set policy input
|
||||
engine.set_input_json(`
|
||||
{
|
||||
"message" : "Hello"
|
||||
}
|
||||
`)
|
||||
|
||||
// Eval query
|
||||
results = engine.eval_query('data.test.message')
|
||||
|
||||
// Display
|
||||
console.log(results)
|
||||
// {
|
||||
// "result": [
|
||||
// {
|
||||
// "expressions": [
|
||||
// {
|
||||
// "value": "Hello, World!",
|
||||
// "text": "data.test.message",
|
||||
// "location": {
|
||||
// "row": 1,
|
||||
// "col": 1
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
// Convert results to object
|
||||
results = JSON.parse(results)
|
||||
|
||||
// Process result
|
||||
console.log(results.result[0].expressions[0].value)
|
||||
// Hello, World!
|
||||
```
|
||||
See [test.js](https://github.com/microsoft/regorus/blob/main/bindings/wasm/test.js) for example usage.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
@@ -50,7 +52,7 @@ impl Engine {
|
||||
///
|
||||
/// * `path`: A filename to be associated with the policy.
|
||||
/// * `rego`: Rego policy.
|
||||
pub fn add_policy(&mut self, path: String, rego: String) -> Result<String, JsValue> {
|
||||
pub fn addPolicy(&mut self, path: String, rego: String) -> Result<String, JsValue> {
|
||||
self.engine.add_policy(path, rego).map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
@@ -58,15 +60,22 @@ impl Engine {
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.add_data
|
||||
/// * `data`: JSON encoded value to be used as policy data.
|
||||
pub fn add_data_json(&mut self, data: String) -> Result<(), JsValue> {
|
||||
pub fn addDataJson(&mut self, data: String) -> Result<(), JsValue> {
|
||||
let data = regorus::Value::from_json_str(&data).map_err(error_to_jsvalue)?;
|
||||
self.engine.add_data(data).map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
/// Get the list of packages defined by loaded policies.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.get_packages
|
||||
pub fn getPackages(&self) -> Result<Vec<String>, JsValue> {
|
||||
self.engine.get_packages().map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
/// Clear policy data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.clear_data
|
||||
pub fn clear_data(&mut self) -> Result<(), JsValue> {
|
||||
pub fn clearData(&mut self) -> Result<(), JsValue> {
|
||||
self.engine.clear_data();
|
||||
Ok(())
|
||||
}
|
||||
@@ -75,7 +84,7 @@ impl Engine {
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.set_input
|
||||
/// * `input`: JSON encoded value to be used as input to query.
|
||||
pub fn set_input_json(&mut self, input: String) -> Result<(), JsValue> {
|
||||
pub fn setInputJson(&mut self, input: String) -> Result<(), JsValue> {
|
||||
let input = regorus::Value::from_json_str(&input).map_err(error_to_jsvalue)?;
|
||||
self.engine.set_input(input);
|
||||
Ok(())
|
||||
@@ -85,13 +94,75 @@ impl Engine {
|
||||
///
|
||||
/// See https://docs.rs/regorus/0.1.0-alpha.2/regorus/struct.Engine.html#method.eval_query
|
||||
/// * `query`: Rego expression to be evaluate.
|
||||
pub fn eval_query(&mut self, query: String) -> Result<String, JsValue> {
|
||||
pub fn evalQuery(&mut self, query: String) -> Result<String, JsValue> {
|
||||
let results = self
|
||||
.engine
|
||||
.eval_query(query, false)
|
||||
.map_err(error_to_jsvalue)?;
|
||||
serde_json::to_string_pretty(&results).map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
/// Evaluate rule(s) at given path.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.eval_rule
|
||||
///
|
||||
/// * `path`: The full path to the rule(s).
|
||||
pub fn evalRule(&mut self, path: String) -> Result<String, JsValue> {
|
||||
let v = self.engine.eval_rule(path).map_err(error_to_jsvalue)?;
|
||||
v.to_json_str().map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
/// Gather output from print statements instead of emiting to stderr.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.set_gather_prints
|
||||
/// * `b`: Whether to enable gathering prints or not.
|
||||
pub fn setGatherPrints(&mut self, b: bool) {
|
||||
self.engine.set_gather_prints(b)
|
||||
}
|
||||
|
||||
/// Take the gathered output of print statements.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.take_prints
|
||||
pub fn takePrints(&mut self) -> Result<Vec<String>, JsValue> {
|
||||
self.engine.take_prints().map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
/// Enable/disable policy coverage.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.set_enable_coverage
|
||||
/// * `b`: Whether to enable gathering coverage or not.
|
||||
pub fn setEnableCoverage(&mut self, enable: bool) {
|
||||
self.engine.set_enable_coverage(enable)
|
||||
}
|
||||
|
||||
/// Get the coverage report as json.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.get_coverage_report
|
||||
pub fn getCoverageReport(&self) -> Result<String, JsValue> {
|
||||
let report = self
|
||||
.engine
|
||||
.get_coverage_report()
|
||||
.map_err(error_to_jsvalue)?;
|
||||
serde_json::to_string_pretty(&report).map_err(error_to_jsvalue)
|
||||
}
|
||||
|
||||
/// Clear gathered coverage data.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/struct.Engine.html#method.clear_coverage_data
|
||||
pub fn clearCoverageData(&mut self) {
|
||||
self.engine.clear_coverage_data()
|
||||
}
|
||||
|
||||
/// Get ANSI color coded coverage report.
|
||||
///
|
||||
/// See https://docs.rs/regorus/latest/regorus/coverage/struct.Report.html#method.to_string_pretty
|
||||
pub fn getCoverageReportPretty(&self) -> Result<String, JsValue> {
|
||||
let report = self
|
||||
.engine
|
||||
.get_coverage_report()
|
||||
.map_err(error_to_jsvalue)?;
|
||||
report.to_string_pretty().map_err(error_to_jsvalue)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -102,9 +173,10 @@ mod tests {
|
||||
#[wasm_bindgen_test]
|
||||
pub fn basic() -> Result<(), JsValue> {
|
||||
let mut engine = crate::Engine::new();
|
||||
engine.setEnableCoverage(true);
|
||||
|
||||
// Exercise all APIs.
|
||||
engine.add_data_json(
|
||||
engine.addDataJson(
|
||||
r#"
|
||||
{
|
||||
"foo" : "bar"
|
||||
@@ -113,7 +185,7 @@ mod tests {
|
||||
.to_string(),
|
||||
)?;
|
||||
|
||||
engine.set_input_json(
|
||||
engine.setInputJson(
|
||||
r#"
|
||||
{
|
||||
"message" : "Hello"
|
||||
@@ -122,15 +194,16 @@ mod tests {
|
||||
.to_string(),
|
||||
)?;
|
||||
|
||||
engine.add_policy(
|
||||
let pkg = engine.addPolicy(
|
||||
"hello.rego".to_string(),
|
||||
r#"
|
||||
package test
|
||||
message = input.message"#
|
||||
.to_string(),
|
||||
)?;
|
||||
assert_eq!(pkg, "data.test");
|
||||
|
||||
let results = engine.eval_query("data".to_string())?;
|
||||
let results = engine.evalQuery("data".to_string())?;
|
||||
let r = regorus::Value::from_json_str(&results).map_err(crate::error_to_jsvalue)?;
|
||||
|
||||
let v = &r["result"][0]["expressions"][0]["value"];
|
||||
@@ -141,6 +214,38 @@ mod tests {
|
||||
// Test that data was set.
|
||||
assert_eq!(v["foo"], regorus::Value::from("bar"));
|
||||
|
||||
// Use eval_rule to perform same query.
|
||||
let v = engine.evalRule("data.test.message".to_owned())?;
|
||||
let v = regorus::Value::from_json_str(&v).map_err(crate::error_to_jsvalue)?;
|
||||
|
||||
// Ensure that input and policy were evaluated.
|
||||
assert_eq!(v, regorus::Value::from("Hello"));
|
||||
|
||||
let pkgs = engine.getPackages()?;
|
||||
assert_eq!(pkgs, vec!["data.test"]);
|
||||
|
||||
engine.setGatherPrints(true);
|
||||
let _ = engine.evalQuery("print(\"Hello\")".to_owned());
|
||||
let prints = engine.takePrints()?;
|
||||
assert_eq!(prints, vec!["<query.rego>:1: Hello"]);
|
||||
|
||||
// Test clone.
|
||||
let mut engine1 = engine.clone();
|
||||
|
||||
// Test code coverage.
|
||||
let report = engine1.getCoverageReport()?;
|
||||
let r = regorus::Value::from_json_str(&report).map_err(crate::error_to_jsvalue)?;
|
||||
|
||||
assert_eq!(
|
||||
r["files"][0]["covered"]
|
||||
.as_array()
|
||||
.map_err(crate::error_to_jsvalue)?,
|
||||
&vec![regorus::Value::from(3)]
|
||||
);
|
||||
|
||||
println!("{}", engine1.getCoverageReportPretty()?);
|
||||
|
||||
engine1.clearCoverageData();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +1,87 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
var regorus = require('./pkg/regorusjs')
|
||||
var regorus = require('./pkg/regorusjs');
|
||||
|
||||
// Create an engine.
|
||||
var engine = new regorus.Engine();
|
||||
|
||||
// Enable code coverage
|
||||
engine.setEnableCoverage(true);
|
||||
|
||||
// Add Rego policy.
|
||||
var pkg = engine.add_policy(
|
||||
var pkg = engine.addPolicy(
|
||||
// Associate this file name with policy
|
||||
'hello.rego',
|
||||
|
||||
// Rego policy
|
||||
`
|
||||
package test
|
||||
|
||||
|
||||
x = 10
|
||||
|
||||
# Join messages
|
||||
message = concat(", ", [input.message, data.message])
|
||||
`)
|
||||
console.log("Loaded policy " + pkg)
|
||||
`);
|
||||
|
||||
console.log(pkg);
|
||||
// data.test
|
||||
|
||||
// Set policy data
|
||||
engine.add_data_json(`
|
||||
engine.addDataJson(`
|
||||
{
|
||||
"message" : "World!"
|
||||
}
|
||||
`)
|
||||
`);
|
||||
|
||||
// Set policy input
|
||||
engine.set_input_json(`
|
||||
engine.setInputJson(`
|
||||
{
|
||||
"message" : "Hello"
|
||||
}
|
||||
`)
|
||||
`);
|
||||
|
||||
// Eval rule as json
|
||||
var value = engine.evalRule('data.test.message');
|
||||
value = JSON.parse(value);
|
||||
|
||||
// Display value
|
||||
console.log(value);
|
||||
// Hello, World!
|
||||
|
||||
// Eval query
|
||||
var results = engine.eval_query('data.test.message')
|
||||
results = engine.evalQuery('data.test.message');
|
||||
|
||||
// Display
|
||||
console.log(results)
|
||||
console.log(results);
|
||||
// {
|
||||
// "result": [
|
||||
// {
|
||||
// "expressions": [
|
||||
// {
|
||||
// "value": "Hello, World!",
|
||||
// "text": "data.test.message",
|
||||
// "location": {
|
||||
// "row": 1,
|
||||
// "col": 1
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
|
||||
// Convert results to object
|
||||
results = JSON.parse(results)
|
||||
results = JSON.parse(results);
|
||||
|
||||
// Process result
|
||||
console.log(results.result[0].expressions[0].value)
|
||||
console.log(results.result[0].expressions[0].value);
|
||||
// Hello, World!
|
||||
|
||||
// Print coverage report
|
||||
report = engine.getCoverageReport();
|
||||
console.log(report);
|
||||
|
||||
// Print pretty report.
|
||||
report = engine.getCoverageReportPretty();
|
||||
console.log(report);
|
||||
|
||||
Reference in New Issue
Block a user