mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-13 03:42:35 -06:00
plugins/discovery: Replace environment variables after evaluation.
This allows simple setups -- those feeding the OPA discovery plugin with a static JSON file -- to still do env variable replacements. This should be possible already, by using a policy to construct the disco config, but it becomes easier now. Co-authored-by: Teemu Koponen <koponen@styra.com> Signed-off-by: Stephan Renatus <stephan@styra.com>
This commit is contained in:
committed by
Stephan Renatus
parent
e48e7f51c5
commit
2d014a89bb
@@ -120,8 +120,12 @@ func Load(configFile string, overrides []string, overrideFiles []string) ([]byte
|
||||
// regex looking for ${...} notation strings
|
||||
var envRegex = regexp.MustCompile(`(?U:\${.*})`)
|
||||
|
||||
// subEnvVars will look for any environment variables in the passed in string
|
||||
// SubEnvVars will look for any environment variables in the passed in string
|
||||
// with the syntax of ${VAR_NAME} and replace that string with ENV[VAR_NAME]
|
||||
func SubEnvVars(s string) string {
|
||||
return subEnvVars(s)
|
||||
}
|
||||
|
||||
func subEnvVars(s string) string {
|
||||
updatedConfig := envRegex.ReplaceAllStringFunc(s, func(s string) string {
|
||||
// Trim off the '${' and '}'
|
||||
|
||||
@@ -573,7 +573,8 @@ func evaluateBundle(ctx context.Context, id string, info *ast.Term, b *bundleApi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config.ParseConfig(bs, id)
|
||||
processedConf := cfg.SubEnvVars(string(bs))
|
||||
return config.ParseConfig([]byte(processedConf), id)
|
||||
}
|
||||
|
||||
type pluginSet struct {
|
||||
|
||||
@@ -189,6 +189,69 @@ func TestProcessBundle(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestEnvVarSubstitution(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
manager, err := plugins.New([]byte(`{
|
||||
"services": {
|
||||
"default": {
|
||||
"url": "http://localhost:8181"
|
||||
}
|
||||
},
|
||||
"discovery": {"name": "config"}
|
||||
}`), "test-id", inmem.New())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Setenv("ENV1", "test1")
|
||||
initialBundle := makeDataBundle(1, `
|
||||
{
|
||||
"config": {
|
||||
"bundle": {"name": "${ENV1}"},
|
||||
"status": {},
|
||||
"decision_logs": {}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
disco, err := New(manager)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ps, err := disco.processBundle(ctx, initialBundle)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(ps.Start) != 3 || len(ps.Reconfig) != 0 {
|
||||
t.Fatalf("Expected exactly three start events but got %v", ps)
|
||||
}
|
||||
|
||||
actualConfig, err := manager.Config.ActiveConfig()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertConfig(t, actualConfig, fmt.Sprintf(`{
|
||||
"bundle": {
|
||||
"name": "test1"
|
||||
},
|
||||
"decision_logs": {},
|
||||
"default_authorization_decision": "/system/authz/allow",
|
||||
"default_decision": "/system/main",
|
||||
"discovery": {
|
||||
"name": "config"
|
||||
},
|
||||
"labels": {
|
||||
"id": "test-id",
|
||||
"version": %v
|
||||
},
|
||||
"status": {}
|
||||
}`, version.Version))
|
||||
}
|
||||
|
||||
func TestProcessBundleV1Compatible(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
popts := ast.ParserOptions{RegoVersion: ast.RegoV1}
|
||||
|
||||
Reference in New Issue
Block a user