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:
Teemu Koponen
2024-08-07 13:13:57 -07:00
committed by Stephan Renatus
parent e48e7f51c5
commit 2d014a89bb
3 changed files with 70 additions and 2 deletions
+5 -1
View File
@@ -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 '}'
+2 -1
View File
@@ -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 {
+63
View File
@@ -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}