rego

package
v0.5.13 Latest Latest
Warning

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

Go to latest
Published: Dec 8, 2017 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package rego exposes high level APIs for evaluating Rego policies.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Compiler

func Compiler(c *ast.Compiler) func(r *Rego)

Compiler returns an argument that sets the Rego compiler.

func Imports

func Imports(p []string) func(r *Rego)

Imports returns an argument that adds a Rego import to the query's context.

func Input

func Input(x interface{}) func(r *Rego)

Input returns an argument that sets the Rego input document. Input should be a native Go value representing the input document.

func Metrics added in v0.4.9

func Metrics(m metrics.Metrics) func(r *Rego)

Metrics returns an argument that sets the metrics collection and enables instrumentation.

func Module

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

Module returns an argument that adds a Rego module.

func Package

func Package(p string) func(r *Rego)

Package returns an argument that sets the Rego package on the query's context.

func Query

func Query(q string) func(r *Rego)

Query returns an argument that sets the Rego query.

func Store added in v0.5.0

func Store(s storage.Store) func(r *Rego)

Store returns an argument that sets the policy engine's data storage layer.

func Tracer added in v0.5.3

func Tracer(t topdown.Tracer) func(r *Rego)

Tracer returns an argument that sets the topdown Tracer.

func Transaction added in v0.5.2

func Transaction(txn storage.Transaction) func(r *Rego)

Transaction returns an argument that sets the transaction to use for storage layer operations.

Types

type Errors

type Errors []error

Errors represents a collection of errors returned when evaluating Rego.

func (Errors) Error

func (errs Errors) Error() string

type ExpressionValue

type ExpressionValue struct {
	Value    interface{} `json:"value"`
	Text     string      `json:"text"`
	Location *Location   `json:"location"`
}

ExpressionValue defines the value of an expression in a Rego query.

type Location

type Location struct {
	Row int `json:"row"`
	Col int `json:"col"`
}

Location defines a position in a Rego query or module.

type Rego

type Rego struct {
	// contains filtered or unexported fields
}

Rego constructs a query and can be evaluated to obtain results.

func New

func New(options ...func(*Rego)) *Rego

New returns a new Rego object.

func (*Rego) Eval

func (r *Rego) Eval(ctx context.Context) (ResultSet, error)

Eval evaluates this Rego object and returns a ResultSet.

Example (Compiler)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/ast"
	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Define a simple policy.
	module := `
		package example

		default allow = false

		allow {
			input.identity = "admin"
		}

		allow {
			input.method = "GET"
		}
	`

	// Parse the module. The first argument is used as an identifier in error messages.
	parsed, err := ast.ParseModule("example.rego", module)
	if err != nil {
		// Handle error.
	}

	// Create a new compiler and compile the module. The keys are used as
	// identifiers in error messages.
	compiler := ast.NewCompiler()
	compiler.Compile(map[string]*ast.Module{
		"example.rego": parsed,
	})

	if compiler.Failed() {
		// Handle error. Compilation errors are stored on the compiler.
		panic(compiler.Errors)
	}

	// Create a new query that uses the compiled policy from above.
	rego := rego.New(
		rego.Query("data.example.allow"),
		rego.Compiler(compiler),
		rego.Input(
			map[string]interface{}{
				"identity": "bob",
				"method":   "GET",
			},
		),
	)

	// Run evaluation.
	rs, err := rego.Eval(ctx)

	if err != nil {
		// Handle error.
	}

	// Inspect results.
	fmt.Println("len:", len(rs))
	fmt.Println("value:", rs[0].Expressions[0].Value)

}
Output:


len: 1
value: true
Example (Errors)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/ast"
	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	r := rego.New(
		rego.Query("data.example.p"),
		rego.Module("example_error.rego",
			`package example

p = true { not q[x] }
q = {1, 2, 3} { true }`,
		))

	_, err := r.Eval(ctx)

	switch err := err.(type) {
	case rego.Errors:
		for i := range err {
			switch e := err[i].(type) {
			case *ast.Error:
				fmt.Println("code:", e.Code)
				fmt.Println("row:", e.Location.Row)
				fmt.Println("filename:", e.Location.File)
			}
		}
	default:
		// Some other error occurred.
	}

}
Output:


code: rego_unsafe_var_error
row: 3
filename: example_error.rego
Example (Input)
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Raw input data that will be used in evaluation.
	raw := `{"users": [{"id": "bob"}, {"id": "alice"}]}`
	d := json.NewDecoder(bytes.NewBufferString(raw))

	// Numeric values must be represented using json.Number.
	d.UseNumber()

	var input interface{}

	if err := d.Decode(&input); err != nil {
		panic(err)
	}

	// Create a simple query over the input.
	rego := rego.New(
		rego.Query("input.users[idx].id = user_id"),
		rego.Input(input))

	//Run evaluation.
	rs, err := rego.Eval(ctx)

	if err != nil {
		// Handle error.
	}

	// Inspect results.
	fmt.Println("len:", len(rs))
	fmt.Println("bindings.idx:", rs[1].Bindings["idx"])
	fmt.Println("bindings.user_id:", rs[1].Bindings["user_id"])

}
Output:


len: 2
bindings.idx: 1
bindings.user_id: alice
Example (MultipleBindings)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Create query that produces multiple bindings for variable.
	rego := rego.New(
		rego.Query(`a = ["ex", "am", "ple"]; x = a[_]; not p[x]`),
		rego.Package(`example`),
		rego.Module("example.rego", `package example

		p["am"] { true }
		`),
	)

	// Run evaluation.
	rs, err := rego.Eval(ctx)

	// Inspect results.
	fmt.Println("len:", len(rs))
	fmt.Println("err:", err)
	for i := range rs {
		fmt.Printf("bindings[\"x\"]: %v (i=%d)\n", rs[i].Bindings["x"], i)
	}

}
Output:


len: 2
err: <nil>
bindings["x"]: ex (i=0)
bindings["x"]: ple (i=1)
Example (MultipleDocuments)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Create query that produces multiple documents.
	rego := rego.New(
		rego.Query("data.example.p[x]"),
		rego.Module("example.rego",
			`package example

p = {"hello": "alice", "goodbye": "bob"} { true }`,
		))

	// Run evaluation.
	rs, err := rego.Eval(ctx)

	// Inspect results.
	fmt.Println("len:", len(rs))
	fmt.Println("err:", err)
	for i := range rs {
		fmt.Printf("bindings[\"x\"]: %v (i=%d)\n", rs[i].Bindings["x"], i)
		fmt.Printf("value: %v (i=%d)\n", rs[i].Expressions[0].Value, i)
	}

}
Output:


len: 2
err: <nil>
bindings["x"]: hello (i=0)
value: alice (i=0)
bindings["x"]: goodbye (i=1)
value: bob (i=1)
Example (Simple)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Create very simple query that binds a single variable.
	rego := rego.New(rego.Query("x = 1"))

	// Run evaluation.
	rs, err := rego.Eval(ctx)

	// Inspect results.
	fmt.Println("len:", len(rs))
	fmt.Println("bindings:", rs[0].Bindings)
	fmt.Println("err:", err)

}
Output:


len: 1
bindings: map[x:1]
err: <nil>
Example (SingleDocument)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Create query that produces a single document.
	rego := rego.New(
		rego.Query("data.example.p"),
		rego.Module("example.rego",
			`package example

p = ["hello", "world"] { true }`,
		))

	// Run evaluation.
	rs, err := rego.Eval(ctx)

	// Inspect result.
	fmt.Println("value:", rs[0].Expressions[0].Value)
	fmt.Println("err:", err)

}
Output:


value: [hello world]
err: <nil>
Example (Storage)
package main

import (
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
	"github.com/open-policy-agent/opa/storage/inmem"
	"github.com/open-policy-agent/opa/util"
)

func main() {

	ctx := context.Background()

	data := `{
        "example": {
            "users": [
                {
                    "name": "alice",
                    "likes": ["dogs", "clouds"]
                },
                {
                    "name": "bob",
                    "likes": ["pizza", "cats"]
                }
            ]
        }
    }`

	var json map[string]interface{}

	err := util.UnmarshalJSON([]byte(data), &json)
	if err != nil {
		// Handle error.
	}

	// Manually create the storage layer. inmem.NewFromObject returns an
	// in-memory store containing the supplied data.
	store := inmem.NewFromObject(json)

	// Create new query that returns the value
	rego := rego.New(
		rego.Query("data.example.users[0].likes"),
		rego.Store(store))

	// Run evaluation.
	rs, err := rego.Eval(ctx)

	// Inspect the result.
	fmt.Println("value:", rs[0].Expressions[0].Value)

}
Output:


value: [dogs clouds]
Example (Transactions)
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/open-policy-agent/opa/rego"
	"github.com/open-policy-agent/opa/storage"
	"github.com/open-policy-agent/opa/storage/inmem"
)

func main() {

	ctx := context.Background()

	// Create storage layer and load dummy data.
	store := inmem.NewFromReader(bytes.NewBufferString(`{
		"favourites": {
			"pizza": "cheese",
			"colour": "violet"
		}
	}`))

	// Open a write transaction on the store that will perform write operations.
	txn, err := store.NewTransaction(ctx, storage.WriteParams)
	if err != nil {
		// Handle error.
	}

	// Create rego query that uses the transaction created above.
	inside := rego.New(
		rego.Query("data.favourites.pizza"),
		rego.Store(store),
		rego.Transaction(txn),
	)

	// Create rego query that DOES NOT use the transaction created above. Under
	// the hood, the rego package will create it's own read-only transaction to
	// ensure it evaluates over a consistent snapshot of the storage layer.
	outside := rego.New(
		rego.Query("data.favourites.pizza"),
		rego.Store(store),
	)

	// Write change to storage layer inside the transaction.
	err = store.Write(ctx, txn, storage.AddOp, storage.MustParsePath("/favourites/pizza"), "pepperoni")
	if err != nil {
		// Handle error.
	}

	// Run evaluation INSIDE the transction.
	rs, err := inside.Eval(ctx)
	if err != nil {
		// Handle error.
	}

	fmt.Println("value (inside txn):", rs[0].Expressions[0].Value)

	// Run evaluation OUTSIDE the transaction.
	rs, err = outside.Eval(ctx)
	if err != nil {
		// Handle error.
	}

	fmt.Println("value (outside txn):", rs[0].Expressions[0].Value)

	if err := store.Commit(ctx, txn); err != nil {
		// Handle error.
	}

	// Run evaluation AFTER the transaction commits.
	rs, err = outside.Eval(ctx)
	if err != nil {
		// Handle error.
	}

	fmt.Println("value (after txn):", rs[0].Expressions[0].Value)

}
Output:


value (inside txn): pepperoni
value (outside txn): cheese
value (after txn): pepperoni

type Result

type Result struct {
	Expressions []*ExpressionValue `json:"expressions"`
	Bindings    Vars               `json:"bindings,omitempty"`
}

Result defines the output of Rego evaluation.

type ResultSet

type ResultSet []Result

ResultSet represents a collection of output from Rego evaluation. An empty result set represents an undefined query.

type Vars

type Vars map[string]interface{}

Vars represents a collection of variable bindings. The keys are the variable names and the values are the binding values.

func (Vars) WithoutWildcards added in v0.5.3

func (v Vars) WithoutWildcards() Vars

WithoutWildcards returns a copy of v with wildcard variables removed.

Jump to

Keyboard shortcuts

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