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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user