Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruby bindings for existing FFI methods, plus eval_rule() #188

Merged
merged 5 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"bindings/python",
"bindings/wasm",
"bindings/java",
"bindings/ruby/ext/regorusrb",
]

[package]
Expand Down
14 changes: 14 additions & 0 deletions bindings/ruby/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/.bundle/
/.yardoc
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
target/
29 changes: 29 additions & 0 deletions bindings/ruby/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require:
- rubocop-minitest
- rubocop-rake

AllCops:
TargetRubyVersion: 3.0
NewCops: enable

Layout/LineLength:
Max: 180

Lint/EmptyClass:
Enabled: false

Metrics/ClassLength:
Exclude:
- 'test/**/*.rb'

Metrics/MethodLength:
Enabled: false

Style/StringLiterals:
EnforcedStyle: double_quotes

Style/StringLiteralsInInterpolation:
EnforcedStyle: double_quotes

Style/WordArray:
Enabled: false
1 change: 1 addition & 0 deletions bindings/ruby/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby 3.3.0
5 changes: 5 additions & 0 deletions bindings/ruby/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## [Unreleased]

## [0.1.0] - 2024-03-29

- Initial release
16 changes: 16 additions & 0 deletions bindings/ruby/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Specify your gem's dependencies in regorusrb.gemspec
gemspec

# These gems are required for local development and testing,
# but won't be included in the published gem
gem "minitest", "~> 5.16"
gem "rake", "~> 13.0"
gem "rake-compiler"
gem "rb_sys", "~> 0.9.63"
gem "rubocop", "~> 1.62", require: false
gem "rubocop-minitest", require: false
gem "rubocop-rake", require: false
61 changes: 61 additions & 0 deletions bindings/ruby/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
PATH
remote: .
specs:
regorusrb (0.1.0)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
json (2.7.1)
language_server-protocol (3.17.0.3)
minitest (5.22.3)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
racc (1.7.3)
rainbow (3.1.1)
rake (13.1.0)
rake-compiler (1.2.7)
rake
rb_sys (0.9.90)
regexp_parser (2.9.0)
rexml (3.2.6)
rubocop (1.62.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.2)
parser (>= 3.3.0.4)
rubocop-minitest (0.35.0)
rubocop (>= 1.61, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rake (0.6.0)
rubocop (~> 1.0)
ruby-progressbar (1.13.0)
unicode-display_width (2.5.0)

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
minitest (~> 5.16)
rake (~> 13.0)
rake-compiler
rb_sys (~> 0.9.63)
regorusrb!
rubocop (~> 1.62)
rubocop-minitest
rubocop-rake

BUNDLED WITH
2.5.7
1 change: 1 addition & 0 deletions bindings/ruby/LICENSE.txt
95 changes: 95 additions & 0 deletions bindings/ruby/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Regorusrb

**Regorus** is

- *Rego*-*Rus(t)* - A fast, light-weight [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/)
interpreter written in Rust.
- *Rigorous* - A rigorous enforcer of well-defined Rego semantics.

## Installation

Regorus can be used in Ruby by configuring bundler to build from the remote git source.

Use the bundler CLI to add the gem from remote git source:
`
bundle add regorus --git 'https://github.com/microsoft/regorus/tree/main/bindings/ruby'
`

or manually edit your gemfile to include the following
`
gem "regorus", git: "https://github.com/microsoft/regorus/tree/main/bindings/ruby"
`

It is not yet available in rubygems.

See [Repository](https://github.com/microsoft/regorus).

To build this gem locally without bundler,

`rake build`

then to install the gem and build the native extensions

`gem install --local ./pkg/regorusrb-0.1.0.gem`

## Usage

```ruby
require "regorus"

engine = Regorus::Engine.new

engine.add_policy_from_file('../../tests/aci/framework.rego')
engine.add_policy_from_file('../../tests/aci/api.rego')
engine.add_policy_from_file('../../tests/aci/policy.rego')


# can be strings or symbols
data = {
metadata: {
devices: {
"/run/layers/p0-layer0": "1b80f120dbd88e4355d6241b519c3e25290215c469516b49dece9cf07175a766",
"/run/layers/p0-layer1": "e769d7487cc314d3ee748a4440805317c19262c7acd2fdbdb0d47d2e4613a15c",
"/run/layers/p0-layer2": "eb36921e1f82af46dfe248ef8f1b3afb6a5230a64181d960d10237a08cd73c79",
"/run/layers/p0-layer3": "41d64cdeb347bf236b4c13b7403b633ff11f1cf94dbc7cf881a44d6da88c5156",
"/run/layers/p0-layer4": "4dedae42847c704da891a28c25d32201a1ae440bce2aecccfa8e6f03b97a6a6c",
"/run/layers/p0-layer5": "fe84c9d5bfddd07a2624d00333cf13c1a9c941f3a261f13ead44fc6a93bc0e7a"
}
}
}

engine.add_data(data)
input = {
"containerID": "container0",
"layerPaths": [
"/run/layers/p0-layer0",
"/run/layers/p0-layer1",
"/run/layers/p0-layer2",
"/run/layers/p0-layer3",
"/run/layers/p0-layer4",
"/run/layers/p0-layer5"
],
"target": "/run/gcs/c/container0/rootfs"
}

engine.set_input(input)

# Evaluate a specife rule
rule_results = engine.eval_rule('data.framework.mount_overlay')
puts rule_results # { "allowed" => true, "metadata" => [...]}

# Or evalute a full policy document
query_results = engine.eval_query('data.framework')
puts query_results[:result][0]

# Query results can can also be returned as JSON strings instead of Ruby Hash structure
results_json = engine.eval_query_as_json('data.framework.mount_overlay=x')
puts results_json
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).

23 changes: 23 additions & 0 deletions bindings/ruby/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require "minitest/test_task"

Minitest::TestTask.create

require "rubocop/rake_task"

RuboCop::RakeTask.new

require "rb_sys/extensiontask"

desc "build the .gem file, including native extensions, according to the .gemspec"
task build: :compile

GEMSPEC = Gem::Specification.load("regorusrb.gemspec")

RbSys::ExtensionTask.new("regorusrb", GEMSPEC) do |ext|
ext.lib_dir = "lib/regorusrb"
end

task default: %i[compile test rubocop]
11 changes: 11 additions & 0 deletions bindings/ruby/bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/setup"
require "regorus"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

require "irb"
IRB.start(__FILE__)
8 changes: 8 additions & 0 deletions bindings/ruby/bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
16 changes: 16 additions & 0 deletions bindings/ruby/ext/regorusrb/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "regorusrb"
version = "0.1.0"
edition = "2021"
description = "Ruby bindings for Regorus - a fast, lightweight Rego interpreter written in Rust"
publish = false

[lib]
crate-type = ["cdylib"]
path = "src/lib.rs"

[dependencies]
magnus = { version = "0.6.2" }
regorus = { path = "../../../.." }
serde_json = "1.0.115"
serde_magnus = "0.8.1"
6 changes: 6 additions & 0 deletions bindings/ruby/ext/regorusrb/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

require "mkmf"
require "rb_sys/mkmf"

create_rust_makefile("regorusrb/regorusrb")
Loading
Loading