Skip to content

Commit

Permalink
Move golang-opa-wasm into opa
Browse files Browse the repository at this point in the history
This moves the package from:

github.com/open-policy-agent/golang-opa-wasm/opa

to:

github.com/open-policy-agent/opa/wasm/sdk/opa

This avoids callers from having to do much in the way of changes
besides adjusting the import path.

Signed-off-by: Patrick East <[email protected]>
  • Loading branch information
patrick-east authored and tsandall committed Nov 6, 2020
1 parent f84f467 commit ba54066
Show file tree
Hide file tree
Showing 24 changed files with 2,388 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ opa_*
_release
wasm/_obj
_test
!*_test.go
site.tar.gz
policy.wasm
.npm
Expand Down
7 changes: 7 additions & 0 deletions internal/wasm/sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
**Work in Progress -- Contributions welcome!**

# Open Policy Agent WebAssemby Go SDK
This is the source for the Open Policy Agent WebAssembly Go SDK which
is a small go library for using WebAssembly (wasm) compiled [Open
Policy Agent](https://www.openpolicyagent.org/) Rego policies.

3 changes: 3 additions & 0 deletions internal/wasm/sdk/examples/basic/example-1.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package example

allow = input.foo
Binary file added internal/wasm/sdk/examples/basic/example-1.wasm
Binary file not shown.
3 changes: 3 additions & 0 deletions internal/wasm/sdk/examples/basic/example-2.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package example

allow = input.bar
Binary file added internal/wasm/sdk/examples/basic/example-2.wasm
Binary file not shown.
97 changes: 97 additions & 0 deletions internal/wasm/sdk/examples/basic/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2020 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.
package main

import (
"context"
"fmt"
"io/ioutil"
"os"
"path"

"github.com/open-policy-agent/opa/internal/wasm/sdk/opa"
)

// main demonstrates the loading and executnig of OPA produced wasm
// policy binary. To execute run 'go run main.go .' in the directory
// of the main.go.
func main() {
if len(os.Args) < 2 {
fmt.Printf("%s: first argument must a path to a directory with example-1.wasm and example-2.wasm.\n", os.Args[0])
return
}

directory := os.Args[1]

// Setup the SDK

policy, err := ioutil.ReadFile(path.Join(directory, "example-1.wasm"))
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

rego, err := opa.New().WithPolicyBytes(policy).Init()
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

defer rego.Close()

// Evaluate the policy once.

var input interface{} = map[string]interface{}{
"foo": true,
"bar": false,
}

ctx := context.Background()
result, err := rego.Eval(ctx, &input)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

fmt.Printf("Policy 1 result: %v\n", result)

resultBool, err := opa.EvalBool(ctx, rego, &input)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

fmt.Printf("Policy 1 boolean result: %v\n", resultBool)

// Update the policy on the fly.

policy, err = ioutil.ReadFile(path.Join(directory, "example-2.wasm"))
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

// Evaluate the new policy.

if err := rego.SetPolicy(policy); err != nil {
fmt.Printf("error: %v\n", err)
return
}

result, err = rego.Eval(ctx, &input)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

fmt.Printf("Policy 2 result: %v\n", result)

resultBool, err = opa.EvalBool(ctx, rego, &input)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

fmt.Printf("Policy 2 boolean result: %v\n", resultBool)
}
Binary file added internal/wasm/sdk/examples/loaders/bundle.tgz
Binary file not shown.
114 changes: 114 additions & 0 deletions internal/wasm/sdk/examples/loaders/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2020 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.
package main

import (
"context"
"fmt"
gohttp "net/http"
"net/url"
"os"
"time"

"github.com/open-policy-agent/opa/internal/wasm/sdk/opa"
"github.com/open-policy-agent/opa/internal/wasm/sdk/opa/file"
"github.com/open-policy-agent/opa/internal/wasm/sdk/opa/http"
)

var (
loader opa.Loader
rego *opa.OPA
)

// main loads a bundle either from a file or HTTP server.
//
// In the directory of the main.go, execute 'go run main.go
// bundle.tgz' to load the accompanied bundle file. Similarly, execute
// 'go run main.go http://url/to/bundle.tgz' to test the HTTP
// downloading from a HTTP server.
func main() {
if len(os.Args) < 2 {
fmt.Printf("provide URL or file\n")
return
}

url := os.Args[1]
token := ""
if len(os.Args) >= 3 {
token = os.Args[2]
}

// Setup the SDK, either with HTTP bundle loader or file bundle loader.

if err := setup(url, token); err != nil {
fmt.Printf("error: %v\n", err)
return
}

defer cleanup()

// Evaluate the policy.

var input interface{} = map[string]interface{}{
"foo": true,
}

ctx := context.Background()
result, err := rego.Eval(ctx, &input)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}

fmt.Printf("Policy result: %v\n", result)
}

func setup(u string, token string) error {
r, err := opa.New().Init()
if err != nil {
return err
}

url, err := url.Parse(u)
if err != nil {
return err
}

var l opa.Loader

switch url.Scheme {
case "http", "https":
l, err = http.New(r).
WithURL(url.String()).
WithPrepareRequest(func(req *gohttp.Request) error {
if token != "" {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
}
return nil
}).
WithInterval(30*time.Second, 60*time.Second).
Init()
case "file", "":
l, err = file.New(r).
WithFile(url.String()).
WithInterval(10 * time.Second).
Init()
}

if err != nil {
return err
}

if err := l.Start(context.Background()); err != nil {
return err
}

rego, loader = r, l
return nil
}

func cleanup() {
loader.Close()
rego.Close()
}
85 changes: 85 additions & 0 deletions internal/wasm/sdk/opa/bindings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2020 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.

package opa

// #include <stdlib.h>
//
// extern void opa_abort(void *context, int32_t addr);
// extern int32_t opa_builtin0(void *context, int32_t builtin_id, int32_t ctx);
// extern int32_t opa_builtin1(void *context, int32_t builtin_id, int32_t ctx, int32_t arg0);
// extern int32_t opa_builtin2(void *context, int32_t builtin_id, int32_t ctx, int32_t arg0, int32_t arg1);
// extern int32_t opa_builtin3(void *context, int32_t builtin_id, int32_t ctx, int32_t arg0, int32_t arg1, int32_t arg2);
// extern int32_t opa_builtin4(void *context, int32_t builtin_id, int32_t ctx, int32_t arg0, int32_t arg1, int32_t arg2, int32_t arg3);
import "C"

import (
"unsafe"

wasm "github.com/wasmerio/go-ext-wasm/wasmer"
)

func opaFunctions(imports *wasm.Imports) (*wasm.Imports, error) {
imports, err := imports.AppendFunction("opa_abort", opa_abort, C.opa_abort)
if err != nil {
return nil, err
}

imports, err = imports.AppendFunction("opa_builtin0", opa_builtin0, C.opa_builtin0)
if err != nil {
return nil, err
}

imports, err = imports.AppendFunction("opa_builtin1", opa_builtin1, C.opa_builtin1)
if err != nil {
return nil, err
}

imports, err = imports.AppendFunction("opa_builtin2", opa_builtin2, C.opa_builtin2)
if err != nil {
return nil, err
}

imports, err = imports.AppendFunction("opa_builtin3", opa_builtin3, C.opa_builtin3)
if err != nil {
return nil, err
}

return imports.AppendFunction("opa_builtin4", opa_builtin4, C.opa_builtin4)
}

//export opa_abort
func opa_abort(ctx unsafe.Pointer, addr int32) {
getVM(ctx).Abort(addr)
}

//export opa_builtin0
func opa_builtin0(ctx unsafe.Pointer, builtinID, context int32) int32 {
return getVM(ctx).Builtin(builtinID, context)
}

//export opa_builtin1
func opa_builtin1(ctx unsafe.Pointer, builtinID, context, arg0 int32) int32 {
return getVM(ctx).Builtin(builtinID, context, arg0)
}

//export opa_builtin2
func opa_builtin2(ctx unsafe.Pointer, builtinID, context, arg0, arg1 int32) int32 {
return getVM(ctx).Builtin(builtinID, context, arg0, arg1)
}

//export opa_builtin3
func opa_builtin3(ctx unsafe.Pointer, builtinID, context, arg0, arg1, arg2 int32) int32 {
return getVM(ctx).Builtin(builtinID, context, arg0, arg1, arg2)
}

//export opa_builtin4
func opa_builtin4(ctx unsafe.Pointer, builtinID, context, arg0, arg1, arg2, arg3 int32) int32 {
return getVM(ctx).Builtin(builtinID, context, arg0, arg1, arg2, arg3)
}

func getVM(ctx unsafe.Pointer) *vm {
ictx := wasm.IntoInstanceContext(ctx)
return ictx.Data().(*vm)
}
Loading

0 comments on commit ba54066

Please sign in to comment.