From 8d93e7348c9c3b9ff3bb9ef56c139bc48f0fff18 Mon Sep 17 00:00:00 2001 From: edwinlab Date: Fri, 17 Apr 2020 11:19:47 +0700 Subject: [PATCH 01/10] add slice string --- config.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config.go b/config.go index 504841d..799d09b 100644 --- a/config.go +++ b/config.go @@ -151,3 +151,7 @@ func GetInt(k string) int { func GetFloat64(k string) float64 { return c.GetFloat64(k) } + +func GetStringSlice(k string) []string { + return c.GetStringSlice(k) +} \ No newline at end of file From c5b61ce36eb56cd684cc1e33177a0e31b8877b42 Mon Sep 17 00:00:00 2001 From: Purwandi Date: Tue, 22 Sep 2020 16:43:21 +0700 Subject: [PATCH 02/10] Implement feature reconnecting to remote config --- config.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/config.go b/config.go index 799d09b..6ff83e0 100644 --- a/config.go +++ b/config.go @@ -1,14 +1,14 @@ package goconf import ( - "fmt" + "log" "os" + "time" "github.com/joho/godotenv" "github.com/pkg/errors" "github.com/spf13/viper" _ "github.com/spf13/viper/remote" - "log" ) type Source string @@ -78,11 +78,25 @@ func Configure() { // next we load from consul; only if consul host defined if ch := os.Getenv(EnvConsulHostKey); ch != "" { - if err := c.AddRemoteProvider("consul", ch, fmt.Sprintf("/%s", fname)); err != nil { + if err := c.AddRemoteProvider("consul", ch, fname); err != nil { errConsul = errors.Cause(err) } else { - if err := c.ReadRemoteConfig(); err != nil { - errConsul = errors.Cause(err) + attempt := 0 + maxAttempt := 10 + + for { + if err := c.ReadRemoteConfig(); err != nil { + if attempt == maxAttempt { + log.Printf("[goconf] giving up connecting to remote config after %d attempt", attempt) + errConsul = errors.Cause(err) + break + } + attempt++ + log.Printf("[goconf] attempt %d connecting to remote config", attempt) + time.Sleep(10 * time.Second) + continue + } + break } } } else { @@ -154,4 +168,4 @@ func GetFloat64(k string) float64 { func GetStringSlice(k string) []string { return c.GetStringSlice(k) -} \ No newline at end of file +} From 63859609c58df2733812c690ad9f4f8de0d4b91f Mon Sep 17 00:00:00 2001 From: Purwandi Date: Wed, 23 Sep 2020 13:29:53 +0700 Subject: [PATCH 03/10] Swap to use exponential backoff --- config.go | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/config.go b/config.go index 6ff83e0..4c99590 100644 --- a/config.go +++ b/config.go @@ -5,6 +5,7 @@ import ( "os" "time" + "github.com/cenkalti/backoff/v4" "github.com/joho/godotenv" "github.com/pkg/errors" "github.com/spf13/viper" @@ -81,22 +82,15 @@ func Configure() { if err := c.AddRemoteProvider("consul", ch, fname); err != nil { errConsul = errors.Cause(err) } else { - attempt := 0 - maxAttempt := 10 - - for { - if err := c.ReadRemoteConfig(); err != nil { - if attempt == maxAttempt { - log.Printf("[goconf] giving up connecting to remote config after %d attempt", attempt) - errConsul = errors.Cause(err) - break - } - attempt++ - log.Printf("[goconf] attempt %d connecting to remote config", attempt) - time.Sleep(10 * time.Second) - continue - } - break + connect := func() error { return c.ReadRemoteConfig() } + notify := func(err error, t time.Duration) { log.Println("[goconf]", err.Error(), t) } + b := backoff.NewExponentialBackOff() + b.MaxElapsedTime = 2 * time.Minute + + err := backoff.RetryNotify(connect, b, notify) + if err != nil { + log.Printf("[goconf] giving up connecting to remote config ") + errConsul = errors.Cause(err) } } } else { From b3213daafc55f4c8d253c1e48f34adb608434377 Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Thu, 15 Dec 2022 10:04:34 +0700 Subject: [PATCH 04/10] add const for token consul --- config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.go b/config.go index 4c99590..f648c24 100644 --- a/config.go +++ b/config.go @@ -24,6 +24,8 @@ const ( EnvTypeKey = "GOCONF_TYPE" EnvFileNameKey = "GOCONF_FILENAME" EnvPrefixKey = "GOCONF_ENV_PREFIX" + EnvHttpToken = "GOCONF_HTTP_TOKEN" + EnvHttpTokenFile = "GOCONF_HTTP_TOKEN_FILE" //configuration sources SourceEnv Source = "env" From 6a27e27301a1ef90d1c374c54cf73b25c3053fa0 Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Tue, 27 Dec 2022 09:14:11 +0700 Subject: [PATCH 05/10] change method remote secure --- config.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/config.go b/config.go index f648c24..a67e448 100644 --- a/config.go +++ b/config.go @@ -34,9 +34,9 @@ const ( ) var ( - typ = DefaultType - fname = DefaultFilename - prefix string + typ = DefaultType + fname = DefaultFilename + prefix, token string c *viper.Viper dirs = []string{ @@ -69,6 +69,12 @@ func Configure() { if v := os.Getenv(EnvPrefixKey); len(v) > 0 { prefix = v } + if v := os.Getenv(EnvHttpToken); len(v) > 0 { + token = v + } + if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { + token = v + } // setup and configure viper instance c = viper.New() @@ -77,11 +83,12 @@ func Configure() { if len(prefix) > 0 { c.SetEnvPrefix(prefix) } + c.AutomaticEnv() // next we load from consul; only if consul host defined if ch := os.Getenv(EnvConsulHostKey); ch != "" { - if err := c.AddRemoteProvider("consul", ch, fname); err != nil { + if err := c.AddSecureRemoteProvider("consul", ch, fname, token); err != nil { errConsul = errors.Cause(err) } else { connect := func() error { return c.ReadRemoteConfig() } From 5dcbe3d6d0c739037e749043a6a43943c9338a96 Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Wed, 28 Dec 2022 13:20:44 +0700 Subject: [PATCH 06/10] add new config for goconf with token --- config.go | 78 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/config.go b/config.go index a67e448..a8f77eb 100644 --- a/config.go +++ b/config.go @@ -6,6 +6,7 @@ import ( "time" "github.com/cenkalti/backoff/v4" + capi "github.com/hashicorp/consul/api" "github.com/joho/godotenv" "github.com/pkg/errors" "github.com/spf13/viper" @@ -39,6 +40,7 @@ var ( prefix, token string c *viper.Viper + kv *capi.Client dirs = []string{ ".", "$HOME", @@ -69,12 +71,6 @@ func Configure() { if v := os.Getenv(EnvPrefixKey); len(v) > 0 { prefix = v } - if v := os.Getenv(EnvHttpToken); len(v) > 0 { - token = v - } - if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { - token = v - } // setup and configure viper instance c = viper.New() @@ -88,31 +84,73 @@ func Configure() { // next we load from consul; only if consul host defined if ch := os.Getenv(EnvConsulHostKey); ch != "" { - if err := c.AddSecureRemoteProvider("consul", ch, fname, token); err != nil { + if err := c.AddRemoteProvider("consul", ch, fname); err != nil { errConsul = errors.Cause(err) } else { - connect := func() error { return c.ReadRemoteConfig() } - notify := func(err error, t time.Duration) { log.Println("[goconf]", err.Error(), t) } - b := backoff.NewExponentialBackOff() - b.MaxElapsedTime = 2 * time.Minute - - err := backoff.RetryNotify(connect, b, notify) + err = c.ReadRemoteConfig() if err != nil { - log.Printf("[goconf] giving up connecting to remote config ") - errConsul = errors.Cause(err) + NewConfigure() + } else { + connect := func() error { return c.ReadRemoteConfig() } + notify := func(err error, t time.Duration) { log.Println("[goconf]", err.Error(), t) } + b := backoff.NewExponentialBackOff() + b.MaxElapsedTime = 2 * time.Minute + + err := backoff.RetryNotify(connect, b, notify) + if err != nil { + log.Printf("[goconf] giving up connecting to remote config ") + errConsul = errors.Cause(err) + } + + // last, we attempt to load from file in configured dir + for _, d := range dirs { + c.AddConfigPath(d) + } + if err := c.ReadInConfig(); err != nil { + errFile = errors.Cause(err) + } } } } else { errConsul = errors.New("failed loading remote source; ENV not defined") } +} - // last, we attempt to load from file in configured dir - for _, d := range dirs { - c.AddConfigPath(d) +func NewConfigure() { + // first lets load .env file + if err := godotenv.Load(); err != nil { + errEnv = errors.Cause(err) } - if err := c.ReadInConfig(); err != nil { - errFile = errors.Cause(err) + + if v := os.Getenv(EnvFileNameKey); len(v) > 0 { + fname = v } + if v := os.Getenv(EnvHttpToken); len(v) > 0 { + token = v + } + if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { + token = v + } + + client, err := capi.NewClient(&capi.Config{ + Address: os.Getenv(EnvConsulHostKey), + Token: token, + }) + if err != nil { + panic(err) + } + + // Get a handle to the KV API + kv := client.KV() + + // Lookup the pair + pair, _, err := kv.Get(fname, nil) + if err != nil { + panic(err) + } + + c = viper.New() + c.Unmarshal(pair.Value) } func MustSource(s ...Source) { From e6254af58306bc3da53e5bf9ad486b25f68ab689 Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Wed, 28 Dec 2022 14:54:06 +0700 Subject: [PATCH 07/10] add parameter token to switch --- config.go | 110 +++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 60 deletions(-) diff --git a/config.go b/config.go index a8f77eb..9f618d8 100644 --- a/config.go +++ b/config.go @@ -1,6 +1,7 @@ package goconf import ( + "bytes" "log" "os" "time" @@ -40,7 +41,7 @@ var ( prefix, token string c *viper.Viper - kv *capi.Client + pair *capi.KVPair dirs = []string{ ".", "$HOME", @@ -71,6 +72,15 @@ func Configure() { if v := os.Getenv(EnvPrefixKey); len(v) > 0 { prefix = v } + if v := os.Getenv(EnvPrefixKey); len(v) > 0 { + prefix = v + } + if v := os.Getenv(EnvHttpToken); len(v) > 0 { + token = v + } + if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { + token = v + } // setup and configure viper instance c = viper.New() @@ -84,73 +94,53 @@ func Configure() { // next we load from consul; only if consul host defined if ch := os.Getenv(EnvConsulHostKey); ch != "" { - if err := c.AddRemoteProvider("consul", ch, fname); err != nil { - errConsul = errors.Cause(err) + if token == "" { + if err := c.AddRemoteProvider("consul", ch, fname); err != nil { + errConsul = errors.Cause(err) + } } else { - err = c.ReadRemoteConfig() + client, err := capi.NewClient(&capi.Config{ + Address: ch, + Token: token, + }) if err != nil { - NewConfigure() - } else { - connect := func() error { return c.ReadRemoteConfig() } - notify := func(err error, t time.Duration) { log.Println("[goconf]", err.Error(), t) } - b := backoff.NewExponentialBackOff() - b.MaxElapsedTime = 2 * time.Minute - - err := backoff.RetryNotify(connect, b, notify) - if err != nil { - log.Printf("[goconf] giving up connecting to remote config ") - errConsul = errors.Cause(err) - } - - // last, we attempt to load from file in configured dir - for _, d := range dirs { - c.AddConfigPath(d) - } - if err := c.ReadInConfig(); err != nil { - errFile = errors.Cause(err) - } + errConsul = errors.Cause(err) } - } - } else { - errConsul = errors.New("failed loading remote source; ENV not defined") - } -} -func NewConfigure() { - // first lets load .env file - if err := godotenv.Load(); err != nil { - errEnv = errors.Cause(err) - } - - if v := os.Getenv(EnvFileNameKey); len(v) > 0 { - fname = v - } - if v := os.Getenv(EnvHttpToken); len(v) > 0 { - token = v - } - if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { - token = v - } + // Lookup the pair + pair, _, err = client.KV().Get(fname, nil) + if err != nil { + errConsul = errors.Cause(err) + } + } - client, err := capi.NewClient(&capi.Config{ - Address: os.Getenv(EnvConsulHostKey), - Token: token, - }) - if err != nil { - panic(err) - } + connect := func() error { + if token != "" { + return c.ReadConfig(bytes.NewBuffer(pair.Value)) + } else { + return c.ReadRemoteConfig() + } + } + notify := func(err error, t time.Duration) { log.Println("[goconf]", err.Error(), t) } + b := backoff.NewExponentialBackOff() + b.MaxElapsedTime = 2 * time.Minute - // Get a handle to the KV API - kv := client.KV() + err := backoff.RetryNotify(connect, b, notify) + if err != nil { + log.Printf("[goconf] giving up connecting to remote config ") + errConsul = errors.Cause(err) + } - // Lookup the pair - pair, _, err := kv.Get(fname, nil) - if err != nil { - panic(err) + // last, we attempt to load from file in configured dir + for _, d := range dirs { + c.AddConfigPath(d) + } + if err := c.ReadInConfig(); err != nil { + errFile = errors.Cause(err) + } + } else { + errConsul = errors.New("failed loading remote source; ENV not defined") } - - c = viper.New() - c.Unmarshal(pair.Value) } func MustSource(s ...Source) { From 674b988ef82db727ff73276c4f45573cbeb7b474 Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Thu, 29 Dec 2022 15:44:20 +0700 Subject: [PATCH 08/10] change variabel name --- config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index 9f618d8..f0b1e4b 100644 --- a/config.go +++ b/config.go @@ -22,12 +22,12 @@ const ( DefaultFilename = "config" // environment variable key names - EnvConsulHostKey = "GOCONF_CONSUL" + EnvConsulHostKey = "CONSUL_HTTP_ADDR" EnvTypeKey = "GOCONF_TYPE" EnvFileNameKey = "GOCONF_FILENAME" EnvPrefixKey = "GOCONF_ENV_PREFIX" - EnvHttpToken = "GOCONF_HTTP_TOKEN" - EnvHttpTokenFile = "GOCONF_HTTP_TOKEN_FILE" + EnvHttpToken = "CONSUL_HTTP_TOKEN" + EnvHttpTokenFile = "CONSUL_HTTP_TOKEN_FILE" //configuration sources SourceEnv Source = "env" From d4b9c1aedbb7ca435c413248b19569535e5610e4 Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Thu, 29 Dec 2022 16:52:52 +0700 Subject: [PATCH 09/10] handle new variabel name addr --- config.go | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/config.go b/config.go index f0b1e4b..e1a0401 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,7 @@ package goconf import ( "bytes" + "io/ioutil" "log" "os" "time" @@ -22,10 +23,12 @@ const ( DefaultFilename = "config" // environment variable key names - EnvConsulHostKey = "CONSUL_HTTP_ADDR" + EnvConsulHostKey = "GOCONF_CONSUL" EnvTypeKey = "GOCONF_TYPE" EnvFileNameKey = "GOCONF_FILENAME" EnvPrefixKey = "GOCONF_ENV_PREFIX" + + EnvHttpAddr = "CONSUL_HTTP_ADDR" EnvHttpToken = "CONSUL_HTTP_TOKEN" EnvHttpTokenFile = "CONSUL_HTTP_TOKEN_FILE" @@ -36,9 +39,9 @@ const ( ) var ( - typ = DefaultType - fname = DefaultFilename - prefix, token string + typ = DefaultType + fname = DefaultFilename + prefix, token, addr string c *viper.Viper pair *capi.KVPair @@ -77,9 +80,18 @@ func Configure() { } if v := os.Getenv(EnvHttpToken); len(v) > 0 { token = v + } else if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { + fileContent, err := ioutil.ReadFile(v) + if err != nil { + log.Fatal(err) + } + token = string(fileContent) } - if v := os.Getenv(EnvHttpTokenFile); len(v) > 0 { - token = v + + if v := os.Getenv(EnvConsulHostKey); len(v) > 0 { + addr = v + } else if v := os.Getenv(EnvHttpAddr); len(v) > 0 { + addr = v } // setup and configure viper instance @@ -93,14 +105,14 @@ func Configure() { c.AutomaticEnv() // next we load from consul; only if consul host defined - if ch := os.Getenv(EnvConsulHostKey); ch != "" { + if addr != "" { if token == "" { - if err := c.AddRemoteProvider("consul", ch, fname); err != nil { + if err := c.AddRemoteProvider("consul", addr, fname); err != nil { errConsul = errors.Cause(err) } } else { client, err := capi.NewClient(&capi.Config{ - Address: ch, + Address: addr, Token: token, }) if err != nil { From f96c29441070f103b0df45f9252e75950d02e1af Mon Sep 17 00:00:00 2001 From: Ari Gusti Date: Fri, 30 Dec 2022 10:58:50 +0700 Subject: [PATCH 10/10] add path file config --- config.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/config.go b/config.go index e1a0401..34bd932 100644 --- a/config.go +++ b/config.go @@ -27,6 +27,7 @@ const ( EnvTypeKey = "GOCONF_TYPE" EnvFileNameKey = "GOCONF_FILENAME" EnvPrefixKey = "GOCONF_ENV_PREFIX" + EnvPath = "GOCONF_PATH" EnvHttpAddr = "CONSUL_HTTP_ADDR" EnvHttpToken = "CONSUL_HTTP_TOKEN" @@ -39,9 +40,9 @@ const ( ) var ( - typ = DefaultType - fname = DefaultFilename - prefix, token, addr string + typ = DefaultType + fname = DefaultFilename + prefix, token, addr, path string c *viper.Viper pair *capi.KVPair @@ -69,8 +70,11 @@ func Configure() { if v := os.Getenv(EnvTypeKey); len(v) > 0 { typ = v } + if v := os.Getenv(EnvPath); len(v) > 0 { + path = v + } if v := os.Getenv(EnvFileNameKey); len(v) > 0 { - fname = v + fname = path + v } if v := os.Getenv(EnvPrefixKey); len(v) > 0 { prefix = v @@ -87,7 +91,6 @@ func Configure() { } token = string(fileContent) } - if v := os.Getenv(EnvConsulHostKey); len(v) > 0 { addr = v } else if v := os.Getenv(EnvHttpAddr); len(v) > 0 {