From 5830729fbe81019520572e680d475cea39a3d8ab Mon Sep 17 00:00:00 2001 From: Jeremy Chang Date: Tue, 8 Feb 2022 02:52:36 +0000 Subject: [PATCH] feat: Implemented Go SDK env var handling Also added unit tests for it that will leave existing environment variables undisturbed. (Will store env vars before test and restore env vars after test) --- go/rtl/constants.go | 7 ++- go/rtl/settings.go | 44 +++++++++++++++-- go/rtl/settings_test.go | 104 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 5 deletions(-) diff --git a/go/rtl/constants.go b/go/rtl/constants.go index 377b5575f..d6ec3dc75 100644 --- a/go/rtl/constants.go +++ b/go/rtl/constants.go @@ -1,5 +1,10 @@ package rtl const ( - DefaultApiVersion = "4.0" + baseUrlEnvKey = "LOOKERSDK_BASE_URL" + apiVersionEnvKey = "LOOKERSDK_API_VERSION" + verifySslEnvKey = "LOOKERSDK_VERIFY_SSL" + timeoutEnvKey = "LOOKERSDK_TIMEOUT" + clientIdEnvKey = "LOOKERSDK_CLIENT_ID" + clientSecretEnvKey = "LOOKERSDK_CLIENT_SECRET" ) diff --git a/go/rtl/settings.go b/go/rtl/settings.go index fc8279241..d476616e2 100644 --- a/go/rtl/settings.go +++ b/go/rtl/settings.go @@ -3,6 +3,9 @@ package rtl import ( "fmt" "gopkg.in/ini.v1" + "os" + "strconv" + "strings" ) var defaultSectionName string = "Looker" @@ -18,15 +21,19 @@ type ApiSettings struct { ApiVersion string `ini:"api_version"` } +var defaultSettings ApiSettings = ApiSettings{ + VerifySsl: true, + ApiVersion: "4.0", + Timeout: 120, +} + func NewSettingsFromFile(file string, section *string) (ApiSettings, error) { if section == nil { section = &defaultSectionName } - s := ApiSettings{ - VerifySsl: true, - ApiVersion: DefaultApiVersion, - } + // Default values + s := defaultSettings cfg, err := ini.Load(file) if err != nil { @@ -37,3 +44,32 @@ func NewSettingsFromFile(file string, section *string) (ApiSettings, error) { return s, err } + +func NewSettingsFromEnv() (ApiSettings, error) { + settings := defaultSettings + + if v, present := os.LookupEnv(baseUrlEnvKey); present { + settings.BaseUrl = v + } + if v, present := os.LookupEnv(apiVersionEnvKey); present { + settings.ApiVersion = v + } + if v, present := os.LookupEnv(verifySslEnvKey); present { + s := strings.ToLower(v) + settings.VerifySsl = s == "true" || s == "t" || s == "1" || s == "y" || s == "yes" + } + if v, present := os.LookupEnv(timeoutEnvKey); present { + timeout, err := strconv.ParseInt(v,10,32) + if err == nil { + settings.Timeout = int32(timeout) + } + } + if v, present := os.LookupEnv(clientIdEnvKey); present { + settings.ClientId = v + } + if v, present := os.LookupEnv(clientSecretEnvKey); present { + settings.ClientSecret = v + } + + return settings, nil +} diff --git a/go/rtl/settings_test.go b/go/rtl/settings_test.go index 5bd8b040a..51d83d53d 100644 --- a/go/rtl/settings_test.go +++ b/go/rtl/settings_test.go @@ -1,6 +1,7 @@ package rtl import ( + "os" "reflect" "testing" ) @@ -48,3 +49,106 @@ func TestNewSettingsFromFile(t *testing.T) { }) } } + +type pair struct { + k string + v string +} + +func TestNewSettingsFromEnv(t *testing.T) { + getEnv := func() []pair { + var pairs []pair + + if v,present := os.LookupEnv(baseUrlEnvKey); present { + pairs = append(pairs, pair{ k: baseUrlEnvKey, v: v }) + } + if v,present := os.LookupEnv(apiVersionEnvKey); present { + pairs = append(pairs, pair{ k: apiVersionEnvKey, v: v }) + } + if v,present := os.LookupEnv(verifySslEnvKey); present { + pairs = append(pairs, pair{ k: verifySslEnvKey, v: v }) + } + if v,present := os.LookupEnv(timeoutEnvKey); present { + pairs = append(pairs, pair{ k: timeoutEnvKey, v: v }) + } + if v,present := os.LookupEnv(clientIdEnvKey); present { + pairs = append(pairs, pair{ k: clientIdEnvKey, v: v }) + } + if v,present := os.LookupEnv(clientSecretEnvKey); present { + pairs = append(pairs, pair{ k: clientSecretEnvKey, v: v }) + } + + return pairs + } + + clearEnv := func() { + os.Unsetenv(baseUrlEnvKey) + os.Unsetenv(apiVersionEnvKey) + os.Unsetenv(verifySslEnvKey) + os.Unsetenv(timeoutEnvKey) + os.Unsetenv(clientIdEnvKey) + os.Unsetenv(clientSecretEnvKey) + } + + setEnv := func(pairs []pair ) { + clearEnv() + for _, pair := range pairs { + os.Setenv(pair.k, pair.v) + } + } + + tests := []struct { + name string + env []pair + want ApiSettings + }{ + { + name: "NewSettingsFromEnv() returns settings when all environment variables set", + env: []pair { + {baseUrlEnvKey, "url"}, + {apiVersionEnvKey, "5.0"}, + {verifySslEnvKey, "false"}, + {timeoutEnvKey, "360"}, + {clientIdEnvKey, "id"}, + {clientSecretEnvKey, "secret"}, + }, + want: ApiSettings{ + BaseUrl: "url", + ApiVersion: "5.0", + VerifySsl: false, + Timeout: 360, + ClientId: "id", + ClientSecret: "secret", + }, + }, + { + name: "NewSettingsFromEnv() sets defaults correctly if env vars not set for them", + env: []pair { + {baseUrlEnvKey, "url"}, + {clientIdEnvKey, "id"}, + {clientSecretEnvKey, "secret"}, + }, + want: ApiSettings{ + BaseUrl: "url", + ApiVersion: "4.0", + VerifySsl: true, + Timeout: 120, + ClientId: "id", + ClientSecret: "secret", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + origEnv := getEnv() + defer setEnv(origEnv) + + setEnv(tt.env) + + got, _ := NewSettingsFromEnv() + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewSettingsFromEnv() got = %v, want %v", got, tt.want) + } + }) + } +}