regobrick

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 16, 2025 License: Apache-2.0 Imports: 8 Imported by: 0

README

RegoBrick

RegoBrick provides a straightforward way to parse and transform Rego modules without modifying the OPA engine. It applies certain transformations based on special import markers (for example, import data.regobrick.default_false) and also offers convenient helpers for custom builtins and Go↔Rego value conversion.


Overview

  • Default False: If your Rego module imports data.regobrick.default_false, RegoBrick will automatically insert a default rule that evaluates to false for any “if” or boolean rules.
  • Custom Builtins: Easily register builtins with typed arguments and return values. RegoBrick converts Rego AST terms to Go types and back, so you can write builtins in Go with minimal boilerplate.
  • Rego ↔ Go Conversion: The convert package allows you to map Rego types (e.g. strings, numbers, arrays, objects) to typed Go structs, decimals, time.Time, etc., and vice versa.
  • Parse & Transform: The ParseModule function reads a Rego module, looks for any RegoBrick import markers, and applies the corresponding AST transformations.

Installation

go get github.com/sky1core/regobrick

Make sure you also have OPA in your go.mod if you plan to work with the Rego engine.


Usage

1. Transforming Modules (e.g. default_false)
import (
    "context"
    "github.com/open-policy-agent/opa/v1/rego"
    "github.com/sky1core/regobrick"
)

func main() {
    ctx := context.Background()
    code := `
        package example

        import data.regobrick.default_false

        allow if {
            input.user == "admin"
        }
    `

    // RegoBrick parses and transforms the module (detecting 'default_false' import).
    // This injects a 'default allow = false' rule automatically.
    query, err := rego.New(
        regobrick.Module("example.rego", code),
        rego.Query("data.example.allow"),
    ).PrepareForEval(ctx)
    if err != nil {
        panic(err)
    }

    // Evaluate as normal
    rs, err := query.Eval(ctx)
    // ...
}
2. Writing Custom Builtins

You can register a custom function that OPA calls within your policies:

import (
    "context"
    "github.com/open-policy-agent/opa/v1/rego"
    "github.com/sky1core/regobrick"
)

// Example builtin that checks if a user is "admin"
func isAdmin(ctx rego.BuiltinContext, user string) (bool, error) {
    return user == "admin", nil
}

func main() {
    // Register the builtin with 1 string argument, returning bool
    regobrick.RegisterBuiltin1[string, bool]("is_admin", false, isAdmin)

    // Then in Rego, you can write:
//    is_admin(input.user)

    // ...
}

RegoBrick automatically converts the Rego argument to a Go string and converts the returned bool back to a Rego boolean.

3. Converting Rego Values ↔ Go

If you want to manually convert values, the convert package provides:

  • RegoToGoT any: Convert an AST value to a typed Go value.
  • GoToRego(interface{}): Convert a Go value to an AST term.

These functions support bool, string, numeric types, decimal.Decimal, time.Time, slices, maps, structs, and more.

import (
    "fmt"
    "github.com/open-policy-agent/opa/v1/ast"
    "github.com/sky1core/regobrick/convert"
)

func convertExample() {
    // Suppose we have a Rego AST number
    regoNumber := ast.Number("42")
    goVal, err := convert.RegoToGo[int](regoNumber)
    if err != nil {
        panic(err)
    }
    fmt.Println("Converted to Go int:", goVal) // 42

    // Convert back to a Rego term
    term, err := convert.GoToRego(goVal)
    fmt.Println("Converted back to Rego term:", term)
}

With these features, you can seamlessly integrate custom transformations, builtins, and value conversion into your OPA-based workflows without forking or modifying OPA’s core engine.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Module

func Module(filename, input string) func(r *rego.Rego)

Module returns a function conforming to `func(*rego.Rego)`. Internally, it tries to parse & transform the Rego code via ParseModule. If parsing fails, it falls back to providing the **original code** to OPA, so that OPA will raise a compile error at evaluation time.

TODO: If you prefer to detect errors earlier, call ParseModule(...) directly and handle them before using Module(...). This design just defers the error to OPA's compile phase instead of returning it immediately.

func ParseModule

func ParseModule(filename, input string) (*ast.Module, error)

ParseModule parses and transforms the given Rego source.

  • If parsing fails, returns an error.
  • If an import marker like "data.regobrick.default_false" exists, applies the corresponding AST transformation (e.g. addDefaultFalse).

func RegisterBuiltin0 added in v0.2.0

func RegisterBuiltin0[R any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext) (R, error))

RegisterBuiltin0 registers a function with no arguments, returning a value + error.

func RegisterBuiltin0_ added in v0.2.0

func RegisterBuiltin0_(name string, nondeterministic bool, fn func(ctx rego.BuiltinContext) error)

RegisterBuiltin0_ registers a function with no arguments and returns only error. On the Rego side, this builtin produces null.

func RegisterBuiltin1 added in v0.2.0

func RegisterBuiltin1[T1 any, R any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1) (R, error))

RegisterBuiltin1 registers a function with 1 argument, returning a value + error.

func RegisterBuiltin1_ added in v0.2.0

func RegisterBuiltin1_[T1 any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1) error)

RegisterBuiltin1_ registers a function with 1 argument and returns only error. On the Rego side, this builtin produces null.

func RegisterBuiltin2 added in v0.2.0

func RegisterBuiltin2[T1 any, T2 any, R any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2) (R, error))

RegisterBuiltin2 registers a function with 2 arguments, returning a value + error.

func RegisterBuiltin2_ added in v0.2.0

func RegisterBuiltin2_[T1 any, T2 any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2) error)

RegisterBuiltin2_ registers a function with 2 arguments and returns only error. On the Rego side, this builtin produces null.

func RegisterBuiltin3 added in v0.2.0

func RegisterBuiltin3[T1 any, T2 any, T3 any, R any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2, arg3 T3) (R, error))

RegisterBuiltin3 registers a function with 3 arguments, returning a value + error.

func RegisterBuiltin3_ added in v0.2.0

func RegisterBuiltin3_[T1 any, T2 any, T3 any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2, arg3 T3) error)

RegisterBuiltin3_ registers a function with 3 arguments and returns only error. On the Rego side, this builtin produces null.

func RegisterBuiltin4 added in v0.2.0

func RegisterBuiltin4[T1 any, T2 any, T3 any, T4 any, R any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2, arg3 T3, arg4 T4) (R, error))

RegisterBuiltin4 registers a function with 4 arguments, returning a value + error.

func RegisterBuiltin4_ added in v0.2.0

func RegisterBuiltin4_[T1 any, T2 any, T3 any, T4 any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2, arg3 T3, arg4 T4) error)

RegisterBuiltin4_ registers a function with 4 arguments and returns only error. On the Rego side, this builtin produces null.

func RegisterBuiltin5 added in v0.2.0

func RegisterBuiltin5[T1 any, T2 any, T3 any, T4 any, T5 any, R any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2, arg3 T3, arg4 T4, arg5 T5) (R, error))

RegisterBuiltin5 registers a function with 5 arguments, returning a value + error.

func RegisterBuiltin5_ added in v0.2.0

func RegisterBuiltin5_[T1 any, T2 any, T3 any, T4 any, T5 any](name string, nondeterministic bool, fn func(ctx rego.BuiltinContext, arg1 T1, arg2 T2, arg3 T3, arg4 T4, arg5 T5) error)

RegisterBuiltin5_ registers a function with 5 arguments and returns only error. On the Rego side, this builtin produces null.

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL