From 1fa7ac2b673ce5950b36e9f7fb19acee313df8c1 Mon Sep 17 00:00:00 2001 From: gw0 Date: Wed, 30 Sep 2020 15:59:39 +0200 Subject: [PATCH] helper/schema: Add helper function JsonEnvDefaultFunc --- helper/schema/schema.go | 18 +++++++++++++++++ helper/schema/schema_test.go | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 24befc9d7fa..1e257c9c0d2 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -13,6 +13,7 @@ package schema import ( "context" + "encoding/json" "fmt" "log" "os" @@ -296,6 +297,23 @@ func MultiEnvDefaultFunc(ks []string, dv interface{}) SchemaDefaultFunc { } } +// JsonEnvDefaultFunc is a helper function that parses the given environment +// variable as a JSON object, or returns the default value otherwise. +func JsonEnvDefaultFunc(k string, dv interface{}) SchemaDefaultFunc { + return func() (interface{}, error) { + if valStr := os.Getenv(k); valStr != "" { + var valObj map[string]interface{} + err := json.Unmarshal([]byte(valStr), &valObj) + if err != nil { + return nil, err + } + return valObj, nil + } + + return dv, nil + } +} + // SchemaSetFunc is a function that must return a unique ID for the given // element. This unique ID is used to store the element in a hash. type SchemaSetFunc func(interface{}) int diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 389d98559aa..9c329671d90 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -107,6 +107,45 @@ func TestMultiEnvDefaultFunc(t *testing.T) { } } +func TestJsonEnvDefaultFunc(t *testing.T) { + key := "TF_TEST_JSON_ENV_DEFAULT_FUNC" + defer os.Unsetenv(key) + + def := map[string]interface{} {"foo": "default"} + f := JsonEnvDefaultFunc(key, def) + if err := os.Setenv(key, "{\"foo\":\"bar\"}"); err != nil { + t.Fatalf("err: %s", err) + } + + actualAbs, err := f() + if err != nil { + t.Fatalf("err: %s", err) + } + actual, ok := actualAbs.(map[string]interface{}) + if !ok { + t.Fatalf("bad: %#v", actualAbs) + } + if actual["foo"] != "bar" { + t.Fatalf("bad: %#v", actual) + } + + if err := os.Unsetenv(key); err != nil { + t.Fatalf("err: %s", err) + } + + actualAbs, err = f() + if err != nil { + t.Fatalf("err: %s", err) + } + actual, ok = actualAbs.(map[string]interface{}) + if !ok { + t.Fatalf("bad: %#v", actualAbs) + } + if actual["foo"] != "default" { + t.Fatalf("bad: %#v", actual) + } +} + func TestValueType_Zero(t *testing.T) { cases := []struct { Type ValueType