Skip to content

Commit

Permalink
sdk: Allow map of plugins to be passed to SDK
Browse files Browse the repository at this point in the history
This adds a Plugins field to the SDK Options struct that accepts a
map[string]plugins.Factory similarly to the map created by
runtime.RegisterPlugin this map is passed to the discovery.Factories
plugin similarly, again, to how it works within the Runtime module. This
allows an OPA SDK instance to initialize plugins.

Fixes open-policy-agent#3826

Signed-off-by: Edward Paget <edward.paget@chime.com>

Fixed changes requested by @tsandall (squash before merge)

Signed-off-by: Edward Paget <edward.paget@chime.com>
  • Loading branch information
edpaget committed Oct 1, 2021
1 parent dff1dca commit f6fa2af
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
4 changes: 3 additions & 1 deletion sdk/opa.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type OPA struct {
mtx sync.Mutex
logger logging.Logger
console logging.Logger
plugins map[string]plugins.Factory
config []byte
}

Expand Down Expand Up @@ -69,6 +70,7 @@ func New(ctx context.Context, opts Options) (*OPA, error) {
opa.config = opts.config
opa.logger = opts.Logger
opa.console = opts.ConsoleLogger
opa.plugins = opts.Plugins

return opa, opa.configure(ctx, opa.config, opts.Ready, opts.block)
}
Expand Down Expand Up @@ -138,7 +140,7 @@ func (opa *OPA) configure(ctx context.Context, bs []byte, ready chan struct{}, b
close(ready)
})

d, err := discovery.New(manager)
d, err := discovery.New(manager, discovery.Factories(opa.plugins))
if err != nil {
return err
}
Expand Down
53 changes: 53 additions & 0 deletions sdk/opa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,63 @@ import (

"github.com/fortytw2/leaktest"
loggingtest "github.com/open-policy-agent/opa/logging/test"
"github.com/open-policy-agent/opa/plugins"
"github.com/open-policy-agent/opa/sdk"
sdktest "github.com/open-policy-agent/opa/sdk/test"
)

// Plugin creates an empty plugin to test plugin initialization
type plugin struct {
manager *plugins.Manager
}

type factory struct{}

func (p *plugin) Start(ctx context.Context) error {
p.manager.UpdatePluginStatus("test_plugin", &plugins.Status{State: plugins.StateOK})
return nil
}

func (p *plugin) Stop(ctx context.Context) {
}

func (p *plugin) Reconfigure(ctx context.Context, config interface{}) {
}

func (factory) New(manager *plugins.Manager, config interface{}) plugins.Plugin {
return &plugin{
manager: manager,
}
}

func (factory) Validate(manager *plugins.Manager, config []byte) (interface{}, error) {
return nil, nil
}

func TestPlugins(t *testing.T) {

ctx := context.Background()

config := []byte(`{
"plugins": {
"test_plugin": {}
}
}`)

opa, err := sdk.New(ctx, sdk.Options{
Config: bytes.NewReader(config),
Plugins: map[string]plugins.Factory{
"test_plugin": factory{},
},
})

if err != nil {
t.Fatal(err)
}

defer opa.Stop(ctx)
}

func TestDecision(t *testing.T) {

ctx := context.Background()
Expand Down
5 changes: 5 additions & 0 deletions sdk/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/sirupsen/logrus"

"github.com/open-policy-agent/opa/logging"
"github.com/open-policy-agent/opa/plugins"
)

// Options contains parameters to setup and configure OPA.
Expand All @@ -35,6 +36,10 @@ type Options struct {
// is closed to signal readiness.
Ready chan struct{}

// Plugins provides a set of plugins.Factory instances that will be
// registered with the OPA SDK instance.
Plugins map[string]plugins.Factory

config []byte
block bool
}
Expand Down

0 comments on commit f6fa2af

Please sign in to comment.