rego

package
v0.12.2 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2019 License: Apache-2.0 Imports: 16 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 Dump added in v0.10.0

func Dump(w io.Writer) func(r *Rego)

Dump returns an argument that sets the writer to dump debugging information to.

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 Instrument added in v0.7.0

func Instrument(yes bool) func(r *Rego)

Instrument returns an argument that enables instrumentation for diagnosing performance issues.

func Metrics added in v0.4.9

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

Metrics returns an argument that sets the metrics collection.

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 ParsedImports added in v0.7.0

func ParsedImports(imp []*ast.Import) func(r *Rego)

ParsedImports returns an argument that adds Rego imports to the query's context.

func ParsedInput added in v0.7.0

func ParsedInput(x ast.Value) func(r *Rego)

ParsedInput returns an argument that sets the Rego input document.

func ParsedPackage added in v0.7.0

func ParsedPackage(pkg *ast.Package) func(r *Rego)

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

func ParsedQuery added in v0.7.0

func ParsedQuery(q ast.Body) func(r *Rego)

ParsedQuery returns an argument that sets the Rego query.

func ParsedUnknowns added in v0.9.0

func ParsedUnknowns(unknowns []*ast.Term) func(r *Rego)

ParsedUnknowns returns an argument that sets the values to treat as unknown during partial evaluation.

func PartialNamespace added in v0.7.0

func PartialNamespace(ns string) func(r *Rego)

PartialNamespace returns an argument that sets the namespace to use for partial evaluation results. The namespace must be a valid package path component.

func PrintTrace added in v0.10.2

func PrintTrace(w io.Writer, r *Rego)

PrintTrace is a helper function to write a human-readable version of the trace to the writer w.

func Query

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

Query returns an argument that sets the Rego query.

func Runtime added in v0.10.0

func Runtime(term *ast.Term) func(r *Rego)

Runtime returns an argument that sets the runtime data to provide to the evaluation engine.

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 Trace added in v0.10.2

func Trace(yes bool) func(r *Rego)

Trace returns an argument that enables tracing on r.

func Tracer added in v0.5.3

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

Tracer returns an argument that adds a query tracer to r.

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.

func Unknowns added in v0.7.0

func Unknowns(unknowns []string) func(r *Rego)

Unknowns returns an argument that sets the values to treat as unknown during partial evaluation.

Types

type CompileContext added in v0.11.0

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

CompileContext contains options for Compile calls.

type CompileOption added in v0.11.0

type CompileOption func(*CompileContext)

CompileOption defines a function to set options on Compile calls.

func CompilePartial added in v0.11.0

func CompilePartial(yes bool) CompileOption

CompilePartial defines an option to control whether partial evaluation is run before the query is planned and compiled.

type CompileResult added in v0.10.0

type CompileResult struct {
	Bytes []byte `json:"bytes"`
}

CompileResult represents the result of compiling a Rego query, zero or more Rego modules, and arbitrary contextual data into an executable.

type Errors

type Errors []error

Errors represents a collection of errors returned when evaluating Rego.

func (Errors) Error

func (errs Errors) Error() string

type EvalContext added in v0.11.0

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

EvalContext defines the set of options allowed to be set at evaluation time. Any other options will need to be set on a new Rego object.

type EvalOption added in v0.11.0

type EvalOption func(*EvalContext)

EvalOption defines a function to set an option on an EvalConfig

func EvalInput added in v0.11.0

func EvalInput(input interface{}) EvalOption

EvalInput configures the input for a Prepared Query's evaluation

func EvalInstrument added in v0.11.0

func EvalInstrument(instrument bool) EvalOption

EvalInstrument enables or disables instrumenting for a Prepared Query's evaluation

func EvalMetrics added in v0.11.0

func EvalMetrics(metric metrics.Metrics) EvalOption

EvalMetrics configures the metrics for a Prepared Query's evaluation

func EvalParsedInput added in v0.11.0

func EvalParsedInput(input ast.Value) EvalOption

EvalParsedInput configures the input for a Prepared Query's evaluation

func EvalParsedUnknowns added in v0.11.0

func EvalParsedUnknowns(unknowns []*ast.Term) EvalOption

EvalParsedUnknowns returns an argument that sets the values to treat as unknown during partial evaluation.

func EvalPartialNamespace added in v0.11.0

func EvalPartialNamespace(ns string) EvalOption

EvalPartialNamespace returns an argument that sets the namespace to use for partial evaluation results. The namespace must be a valid package path component.

func EvalTracer added in v0.11.0

func EvalTracer(tracer topdown.Tracer) EvalOption

EvalTracer configures a tracer for a Prepared Query's evaluation

func EvalTransaction added in v0.11.0

func EvalTransaction(txn storage.Transaction) EvalOption

EvalTransaction configures the Transaction for a Prepared Query's evaluation

func EvalUnknowns added in v0.11.0

func EvalUnknowns(unknowns []string) EvalOption

EvalUnknowns returns an argument that sets the values to treat as unknown during partial evaluation.

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.

func (*ExpressionValue) String added in v0.10.2

func (ev *ExpressionValue) String() string

type Location

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

Location defines a position in a Rego query or module.

type PartialQueries added in v0.9.0

type PartialQueries struct {
	Queries []ast.Body    `json:"queries,omitempty"`
	Support []*ast.Module `json:"modules,omitempty"`
}

PartialQueries contains the queries and support modules produced by partial evaluation.

type PartialResult added in v0.7.0

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

PartialResult represents the result of partial evaluation. The result can be used to generate a new query that can be run when inputs are known.

func (PartialResult) Rego added in v0.7.0

func (pr PartialResult) Rego(options ...func(*Rego)) *Rego

Rego returns an object that can be evaluated to produce a query result. If rego.Rego#Prepare was used to create the PartialResult this may lose the pre-parsed/compiled parts of the original Rego object. In those cases using rego.PartialResult#Eval is likely to be more performant.

type PrepareConfig added in v0.11.0

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

PrepareConfig holds settings to control the behavior of the Prepare call.

type PrepareOption added in v0.11.0

type PrepareOption func(*PrepareConfig)

PrepareOption defines a function to set an option to control the behavior of the Prepare call.

func WithPartialEval added in v0.11.0

func WithPartialEval() PrepareOption

WithPartialEval configures an option for PrepareForEval which will have it perform partial evaluation while preparing the query (similar to rego.Rego#PartialResult)

type PreparedEvalQuery added in v0.11.0

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

PreparedEvalQuery holds the prepared Rego state that has been pre-processed for subsequent evaluations.

func (PreparedEvalQuery) Eval added in v0.11.0

func (pq PreparedEvalQuery) Eval(ctx context.Context, options ...EvalOption) (ResultSet, error)

Eval evaluates this PartialResult's Rego object with additional eval options and returns a ResultSet. If options are provided they will override the original Rego options respective value. The original Rego object transaction will *not* be re-used. A new transaction will be opened if one is not provided with an EvalOption.

type PreparedPartialQuery added in v0.11.0

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

PreparedPartialQuery holds the prepared Rego state that has been pre-processed for partial evaluations.

func (PreparedPartialQuery) Partial added in v0.11.0

func (pq PreparedPartialQuery) Partial(ctx context.Context, options ...EvalOption) (*PartialQueries, error)

Partial runs partial evaluation on the prepared query and returns the result. The original Rego object transaction will *not* be re-used. A new transaction will be opened if one is not provided with an EvalOption.

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(r *Rego)) *Rego

New returns a new Rego object.

func (*Rego) Compile added in v0.10.0

func (r *Rego) Compile(ctx context.Context, opts ...CompileOption) (*CompileResult, error)

Compile returns a compiled policy query.

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"
		}
	`

	// Compile the module. The keys are used as identifiers in error messages.
	compiler, err := ast.CompileModules(map[string]string{
		"example.rego": module,
	})

	// 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)
	if err != nil {
		// Handle error.
	}

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

}
Output:


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

import (
	"context"
	"os"

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

func main() {

	ctx := context.Background()

	buf := topdown.NewBufferTracer()

	// Create very simple query that binds a single variable, and enables tracing.
	rego := rego.New(
		rego.Query("x = 1"),
		rego.Tracer(buf),
	)

	// Run evaluation.
	rego.Eval(ctx)

	// Inspect results.
	topdown.PrettyTrace(os.Stdout, *buf)

}
Output:


Enter x = 1
| Eval x = 1
| Exit x = 1
Redo x = 1
| Redo x = 1
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

func (*Rego) Partial added in v0.9.0

func (r *Rego) Partial(ctx context.Context) (*PartialQueries, error)

Partial runs partial evaluation on r and returns the result.

Example
package main

import (
	"context"
	"fmt"

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

func main() {

	ctx := context.Background()

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

	allow {
		input.method = read_methods[_]
		input.path = ["reviews", user]
		input.user = user
	}

	allow {
		input.method = read_methods[_]
		input.path = ["reviews", _]
		input.is_admin
	}

	read_methods = ["GET"]
	`

	r := rego.New(rego.Query("data.test.allow == true"), rego.Module("example.rego", module))
	pq, err := r.Partial(ctx)
	if err != nil {
		// Handle error.
	}

	// Inspect result.
	for i := range pq.Queries {
		fmt.Printf("Query #%d: %v\n", i+1, pq.Queries[i])
	}

}
Output:


Query #1: "GET" = input.method; input.path = ["reviews", _]; input.is_admin
Query #2: "GET" = input.method; input.path = ["reviews", user3]; user3 = input.user

func (*Rego) PartialEval added in v0.7.0

func (r *Rego) PartialEval(ctx context.Context) (PartialResult, error)

PartialEval has been deprecated and renamed to PartialResult.

func (*Rego) PartialResult added in v0.9.0

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

PartialResult partially evaluates this Rego object and returns a PartialResult.

Example
package main

import (
	"bytes"
	"context"
	"fmt"

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

func main() {

	ctx := context.Background()

	// Define a role-based access control (RBAC) policy that decides whether to
	// allow or deny requests. Requests are allowed if the user is bound to a
	// role that grants permission to perform the operation on the resource.
	module := `
		package example

		import data.bindings
		import data.roles

		default allow = false

		allow {
			user_has_role[role_name]
			role_has_permission[role_name]
		}

		user_has_role[role_name] {
			b = bindings[_]
			b.role = role_name
			b.user = input.subject.user
		}

		role_has_permission[role_name] {
			r = roles[_]
			r.name = role_name
			match_with_wildcard(r.operations, input.operation)
			match_with_wildcard(r.resources, input.resource)
		}

		match_with_wildcard(allowed, value) {
			allowed[_] = "*"
		}

		match_with_wildcard(allowed, value) {
			allowed[_] = value
		}
	`

	// Define dummy roles and role bindings for the example. In real-world
	// scenarios, this data would be pushed or pulled into the service
	// embedding OPA either from an external API or configuration file.
	store := inmem.NewFromReader(bytes.NewBufferString(`{
		"roles": [
			{
				"resources": ["documentA", "documentB"],
				"operations": ["read"],
				"name": "analyst"
			},
			{
				"resources": ["*"],
				"operations": ["*"],
				"name": "admin"
			}
		],
		"bindings": [
			{
				"user": "bob",
				"role": "admin"
			},
			{
				"user": "alice",
				"role": "analyst"
			}
		]
	}`))

	// Prepare and run partial evaluation on the query. The result of partial
	// evaluation can be cached for performance. When the data or policy
	// change, partial evaluation should be re-run.
	r := rego.New(
		rego.Query("data.example.allow"),
		rego.Module("example.rego", module),
		rego.Store(store),
	)

	pr, err := r.PartialEval(ctx)
	if err != nil {
		// Handle error.
	}

	// Define example inputs (representing requests) that will be used to test
	// the policy.
	examples := []map[string]interface{}{
		{
			"resource":  "documentA",
			"operation": "write",
			"subject": map[string]interface{}{
				"user": "bob",
			},
		},
		{
			"resource":  "documentB",
			"operation": "write",
			"subject": map[string]interface{}{
				"user": "alice",
			},
		},
		{
			"resource":  "documentB",
			"operation": "read",
			"subject": map[string]interface{}{
				"user": "alice",
			},
		},
	}

	for i := range examples {

		// Prepare and run normal evaluation from the result of partial
		// evaluation.
		r := pr.Rego(
			rego.Input(examples[i]),
		)

		rs, err := r.Eval(ctx)

		if err != nil || len(rs) != 1 || len(rs[0].Expressions) != 1 {
			// Handle erorr.
		} else {
			fmt.Printf("input %d allowed: %v\n", i+1, rs[0].Expressions[0].Value)
		}
	}

}
Output:


input 1 allowed: true
input 2 allowed: false
input 3 allowed: true

func (*Rego) PrepareForEval added in v0.11.0

func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (PreparedEvalQuery, error)

PrepareForEval will parse inputs, modules, and query arguments in preparation of evaluating them.

Example
package main

import (
	"context"
	"fmt"

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

func main() {
	ctx := context.Background()

	// Create a simple query
	r := rego.New(
		rego.Query("input.x == 1"),
	)

	// Prepare for evaluation
	pq, err := r.PrepareForEval(ctx)

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

	// Raw input data that will be used in the first evaluation
	input := map[string]interface{}{"x": 2}

	// Run the evaluation
	rs, err := pq.Eval(ctx, rego.EvalInput(input))

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

	// Inspect results.
	fmt.Println("initial result:", rs[0].Expressions[0])

	// Update input
	input["x"] = 1

	// Run the evaluation with new input
	rs, err = pq.Eval(ctx, rego.EvalInput(input))

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

	// Inspect results.
	fmt.Println("updated result:", rs[0].Expressions[0])

}
Output:


initial result: false
updated result: true

func (*Rego) PrepareForPartial added in v0.11.0

func (r *Rego) PrepareForPartial(ctx context.Context, opts ...PrepareOption) (PreparedPartialQuery, error)

PrepareForPartial will parse inputs, modules, and query arguments in preparation of partially evaluating them.

Example
package main

import (
	"context"
	"fmt"

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

func main() {

	ctx := context.Background()

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

	allow {
		input.method = read_methods[_]
		input.path = ["reviews", user]
		input.user = user
	}

	allow {
		input.method = read_methods[_]
		input.path = ["reviews", _]
		input.is_admin
	}

	read_methods = ["GET"]
	`

	r := rego.New(
		rego.Query("data.test.allow == true"),
		rego.Module("example.rego", module),
	)

	pq, err := r.PrepareForPartial(ctx)
	if err != nil {
		// Handle error.
	}

	pqs, err := pq.Partial(ctx)
	if err != nil {
		// Handle error.
	}

	// Inspect result
	fmt.Println("First evaluation")
	for i := range pqs.Queries {
		fmt.Printf("Query #%d: %v\n", i+1, pqs.Queries[i])
	}

	// Evaluate with specified input
	exampleInput := map[string]string{
		"method": "GET",
	}

	// Evaluate again with different input and unknowns
	pqs, err = pq.Partial(ctx,
		rego.EvalInput(exampleInput),
		rego.EvalUnknowns([]string{"input.user", "input.is_admin", "input.path"}),
	)
	if err != nil {
		// Handle error.
	}

	// Inspect result
	fmt.Println("Second evaluation")
	for i := range pqs.Queries {
		fmt.Printf("Query #%d: %v\n", i+1, pqs.Queries[i])
	}

}
Output:


First evaluation
Query #1: "GET" = input.method; input.path = ["reviews", _]; input.is_admin
Query #2: "GET" = input.method; input.path = ["reviews", user3]; user3 = input.user
Second evaluation
Query #1: input.path = ["reviews", _]; input.is_admin
Query #2: input.path = ["reviews", user3]; user3 = input.user

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