Skip to content

Commit

Permalink
sdk: expose manager options
Browse files Browse the repository at this point in the history
This commit adds the possibility to configure the plugin manager with
custom options.

It will allow SDK users to override the options already provided by the
SDK and to futher customize it with configurations that were not
previously available. This is an advanced feature as it requires
some knowledge about the inner workings of OPA.

One use case for this is to provide a prometheus registerer and have the
status plugin metrics available for the client to use it in a
/metrics endpoint, for example.

resolves open-policy-agent#6662

Signed-off-by: Francisco Rodrigues <ednofco@gmail.com>
  • Loading branch information
xico42 authored and ashutosh-narkar committed Apr 3, 2024
1 parent 27d6829 commit e0060ce
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
3 changes: 3 additions & 0 deletions sdk/opa.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type OPA struct {
hooks hooks.Hooks
config []byte
v1Compatible bool
managerOpts []func(*plugins.Manager)
}

type state struct {
Expand Down Expand Up @@ -88,6 +89,7 @@ func New(ctx context.Context, opts Options) (*OPA, error) {
opa.console = opts.ConsoleLogger
opa.plugins = opts.Plugins
opa.v1Compatible = opts.V1Compatible
opa.managerOpts = opts.ManagerOpts

return opa, opa.configure(ctx, opa.config, opts.Ready, opts.block)
}
Expand Down Expand Up @@ -141,6 +143,7 @@ func (opa *OPA) configure(ctx context.Context, bs []byte, ready chan struct{}, b
if opa.v1Compatible {
opts = append(opts, plugins.WithParserOptions(ast.ParserOptions{RegoVersion: ast.RegoV1}))
}
opts = append(opts, opa.managerOpts...)
manager, err := plugins.New(
bs,
opa.id,
Expand Down
72 changes: 72 additions & 0 deletions sdk/opa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import (
"testing"
"time"

"github.com/prometheus/client_golang/prometheus"
promdto "github.com/prometheus/client_model/go"

"github.com/fortytw2/leaktest"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
Expand Down Expand Up @@ -2772,3 +2775,72 @@ p { print("XXX") }
t.Fatal("expected print output but got:", e)
}
}

func TestConfigurableManagerOpts(t *testing.T) {
ctx := context.Background()

server := sdktest.MustNewServer(
sdktest.MockBundle("/bundles/bundle.tar.gz", map[string]string{
"main.rego": `
package system
main = true
str = "foo"
loopback = input
`,
}),
)

defer server.Stop()

config := fmt.Sprintf(`{
"services": {
"test": {
"url": %q
}
},
"bundles": {
"test": {
"resource": "/bundles/bundle.tar.gz"
}
},
"status": {
"prometheus": true
}
}`, server.URL())

opa, err := sdk.New(ctx, sdk.Options{
ID: "sdk-id-0",
Config: strings.NewReader(config),
ManagerOpts: []func(manager *plugins.Manager){
plugins.WithPrometheusRegister(prometheus.DefaultRegisterer),
},
})

defer opa.Stop(ctx)

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

m, err := prometheus.DefaultGatherer.Gather()
if err != nil {
t.Fatal(err)
}

registeredMetrics := toMetricMap(m)

if registeredMetrics["opa_info"] == false {
t.Errorf("expected metric 'opa_info' to be registered but it was not")
}
}

func toMetricMap(metrics []*promdto.MetricFamily) map[string]bool {
metricMap := make(map[string]bool, len(metrics))
for _, m := range metrics {
metricMap[m.GetName()] = true
}
return metricMap
}
5 changes: 5 additions & 0 deletions sdk/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ type Options struct {

V1Compatible bool

// ManagerOpts allows customization of the plugin manager.
// The given options get appended to the list of options already provided by the SDK and eventually
// overriding them.
ManagerOpts []func(manager *plugins.Manager)

config []byte
block bool
}
Expand Down

0 comments on commit e0060ce

Please sign in to comment.