diff options
author | Valery Piashchynski <[email protected]> | 2021-02-17 09:24:30 +0300 |
---|---|---|
committer | GitHub <[email protected]> | 2021-02-17 09:24:30 +0300 |
commit | 0b6bc3a6043a769cd4aeb4cb9f88caf226ad4f29 (patch) | |
tree | 65465cd0596046de0304dc2968fccaf329b18bba | |
parent | bb9dd8d3f46da089217e61efc3f058cfbba5ede3 (diff) | |
parent | 98dcf79ea7cabea3f45a55f69d425434bccdd72b (diff) |
Merge pull request #547 from spiral/parse_env_variables
feat(config): Parse env variables in the config
-rwxr-xr-x | .rr.yaml | 21 | ||||
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rwxr-xr-x | pkg/pool/supervisor_pool.go | 3 | ||||
-rwxr-xr-x | pkg/worker_watcher/worker_watcher.go | 4 | ||||
-rwxr-xr-x | plugins/config/plugin.go | 24 | ||||
-rw-r--r-- | tests/docker-compose-full.yaml | 3 | ||||
-rwxr-xr-x | tests/plugins/config/config_test.go | 85 | ||||
-rwxr-xr-x | tests/plugins/config/configs/.rr-env.yaml | 24 | ||||
-rwxr-xr-x | tests/plugins/config/configs/.rr.yaml (renamed from tests/plugins/config/.rr.yaml) | 0 |
9 files changed, 154 insertions, 14 deletions
@@ -17,12 +17,25 @@ server: relay: "pipes" relay_timeout: 20s + # optional for development logs: - # default - development - mode: development - # default - debug - level: error + # default + mode: debug + encoding: json + output: stderr + err_output: stderr + channels: + http: + mode: development + level: panic + encoding: console + output: stdout + server: + mode: production + level: info + encoding: json + output: stderr # Workflow and activity mesh service temporal: diff --git a/CHANGELOG.md b/CHANGELOG.md index ff21738b..df060492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,15 @@ CHANGELOG vNext ------------------- + - Add support for the overwriting `.rr.yaml` keys with values (ref: https://roadrunner.dev/docs/intro-config) - Make logger plugin optional to define in the config. Default values: level -> `debug`, mode -> `development` +- Add the ability to read env variables from the `.rr.yaml` in the form of: `rpc.listen: {RPC_ADDR}`. Reference: + ref: https://roadrunner.dev/docs/intro-config (Environment Variables paragraph) v2.0.0-RC.2 (11.02.2021) ------------------- + - Update RR-Core to version v2.0.0-RC.2 - Update Temporal plugin to version v2.0.0-RC.1 - Update goridge to version v3.0.1 diff --git a/pkg/pool/supervisor_pool.go b/pkg/pool/supervisor_pool.go index 3618786d..bfb997d8 100755 --- a/pkg/pool/supervisor_pool.go +++ b/pkg/pool/supervisor_pool.go @@ -139,7 +139,8 @@ func (sp *supervised) control() { now := time.Now() const op = errors.Op("supervised_pool_control_tick") - // THIS IS A COPY OF WORKERS + // MIGHT BE OUTDATED + // It's a copy of the Workers pointers workers := sp.pool.Workers() for i := 0; i < len(workers); i++ { diff --git a/pkg/worker_watcher/worker_watcher.go b/pkg/worker_watcher/worker_watcher.go index 804e4658..cc8cc2b6 100755 --- a/pkg/worker_watcher/worker_watcher.go +++ b/pkg/worker_watcher/worker_watcher.go @@ -216,8 +216,8 @@ func (ww *workerWatcher) Destroy(ctx context.Context) { // Warning, this is O(n) operation, and it will return copy of the actual workers func (ww *workerWatcher) List() []worker.BaseProcess { - ww.Lock() - defer ww.Unlock() + ww.RLock() + defer ww.RUnlock() base := make([]worker.BaseProcess, 0, len(ww.workers)) for i := 0; i < len(ww.workers); i++ { diff --git a/plugins/config/plugin.go b/plugins/config/plugin.go index ddb7fe88..a01a32b3 100755 --- a/plugins/config/plugin.go +++ b/plugins/config/plugin.go @@ -3,6 +3,7 @@ package config import ( "bytes" "fmt" + "os" "strings" "github.com/spf13/viper" @@ -49,6 +50,12 @@ func (v *Viper) Init() error { return errors.E(op, err) } + // automatically inject ENV variables using ${ENV} pattern + for _, key := range v.viper.AllKeys() { + val := v.viper.Get(key) + v.viper.Set(key, parseEnv(val)) + } + // override config Flags if len(v.Flags) > 0 { for _, f := range v.Flags { @@ -61,7 +68,7 @@ func (v *Viper) Init() error { } } - return v.viper.ReadInConfig() + return nil } // Overwrite overwrites existing config with provided values @@ -125,3 +132,18 @@ func parseValue(value string) string { return value } + +func parseEnv(value interface{}) interface{} { + str, ok := value.(string) + if !ok || len(str) <= 3 { + return value + } + + if str[0:2] == "${" && str[len(str)-1:] == "}" { + if v, ok := os.LookupEnv(str[2 : len(str)-1]); ok { + return v + } + } + + return str +} diff --git a/tests/docker-compose-full.yaml b/tests/docker-compose-full.yaml index 1ccc34f6..889f7898 100644 --- a/tests/docker-compose-full.yaml +++ b/tests/docker-compose-full.yaml @@ -21,11 +21,8 @@ services: - POSTGRES_USER=temporal - POSTGRES_PWD=temporal - POSTGRES_SEEDS=postgresql - - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development.yaml ports: - 7233:7233 - volumes: - - ./dynamicconfig:/etc/temporal/config/dynamicconfig temporal-admin-tools: container_name: temporal-admin-tools diff --git a/tests/plugins/config/config_test.go b/tests/plugins/config/config_test.go index dc387086..a0c2932b 100755 --- a/tests/plugins/config/config_test.go +++ b/tests/plugins/config/config_test.go @@ -19,7 +19,7 @@ func TestViperProvider_Init(t *testing.T) { t.Fatal(err) } vp := &config.Viper{} - vp.Path = ".rr.yaml" + vp.Path = "configs/.rr.yaml" vp.Prefix = "rr" vp.Flags = nil @@ -73,7 +73,7 @@ func TestConfigOverwriteFail(t *testing.T) { t.Fatal(err) } vp := &config.Viper{} - vp.Path = ".rr.yaml" + vp.Path = "configs/.rr.yaml" vp.Prefix = "rr" vp.Flags = []string{"rpc.listen=tcp//not_exist"} @@ -95,7 +95,7 @@ func TestConfigOverwriteValid(t *testing.T) { t.Fatal(err) } vp := &config.Viper{} - vp.Path = ".rr.yaml" + vp.Path = "configs/.rr.yaml" vp.Prefix = "rr" vp.Flags = []string{"rpc.listen=tcp://localhost:6061"} @@ -136,3 +136,82 @@ func TestConfigOverwriteValid(t *testing.T) { } } } + +func TestConfigEnvVariables(t *testing.T) { + container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) + if err != nil { + t.Fatal(err) + } + + err = os.Setenv("SUPER_RPC_ENV", "tcp://localhost:6061") + assert.NoError(t, err) + + vp := &config.Viper{} + vp.Path = "configs/.rr-env.yaml" + vp.Prefix = "rr" + + err = container.RegisterAll( + &logger.ZapLogger{}, + &rpc.Plugin{}, + vp, + &Foo2{}, + ) + assert.NoError(t, err) + + err = container.Init() + assert.NoError(t, err) + + errCh, err := container.Serve() + assert.NoError(t, err) + + // stop by CTRL+C + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + + tt := time.NewTicker(time.Second * 3) + defer tt.Stop() + + for { + select { + case e := <-errCh: + assert.NoError(t, e.Error) + assert.NoError(t, container.Stop()) + return + case <-c: + er := container.Stop() + assert.NoError(t, er) + return + case <-tt.C: + assert.NoError(t, container.Stop()) + return + } + } +} + +func TestConfigEnvVariablesFail(t *testing.T) { + container, err := endure.NewContainer(nil, endure.RetryOnFail(false), endure.SetLogLevel(endure.ErrorLevel)) + if err != nil { + t.Fatal(err) + } + + err = os.Setenv("SUPER_RPC_ENV", "tcp://localhost:6065") + assert.NoError(t, err) + + vp := &config.Viper{} + vp.Path = "configs/.rr-env.yaml" + vp.Prefix = "rr" + + err = container.RegisterAll( + &logger.ZapLogger{}, + &rpc.Plugin{}, + vp, + &Foo2{}, + ) + assert.NoError(t, err) + + err = container.Init() + assert.NoError(t, err) + + _, err = container.Serve() + assert.Error(t, err) +} diff --git a/tests/plugins/config/configs/.rr-env.yaml b/tests/plugins/config/configs/.rr-env.yaml new file mode 100755 index 00000000..3cacb5d0 --- /dev/null +++ b/tests/plugins/config/configs/.rr-env.yaml @@ -0,0 +1,24 @@ +rpc: + listen: ${SUPER_RPC_ENV} + +logs: + mode: development + level: error + +reload: + interval: 1s + patterns: [ ".php" ] + services: + http: + recursive: true + ignore: [ "vendor" ] + patterns: [ ".php", ".go",".md", ] + dirs: [ "." ] + jobs: + recursive: false + ignore: [ "service/metrics" ] + dirs: [ "./jobs" ] + rpc: + recursive: true + patterns: [ ".json" ] + dirs: [ "" ] diff --git a/tests/plugins/config/.rr.yaml b/tests/plugins/config/configs/.rr.yaml index f449dcf3..f449dcf3 100755 --- a/tests/plugins/config/.rr.yaml +++ b/tests/plugins/config/configs/.rr.yaml |