From bdcc01a7ff4774bdc0cc57c02236d5aca176b574 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Thu, 21 Nov 2024 15:51:19 +0100 Subject: fix: properly parse includes outside the Configuration plugin Signed-off-by: Valery Piashchynski --- internal/rpc/client.go | 17 ++++++-- internal/rpc/client_test.go | 14 +++++++ internal/rpc/includes.go | 62 +++++++++++++++++++++++++++++ internal/rpc/test/include1/.rr-include.yaml | 5 +++ internal/rpc/test/include1/.rr.yaml | 11 +++++ 5 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 internal/rpc/includes.go create mode 100644 internal/rpc/test/include1/.rr-include.yaml create mode 100644 internal/rpc/test/include1/.rr.yaml diff --git a/internal/rpc/client.go b/internal/rpc/client.go index 26d60d24..ba739d87 100644 --- a/internal/rpc/client.go +++ b/internal/rpc/client.go @@ -33,9 +33,6 @@ func NewClient(cfg string, flags []string) (*rpc.Client, error) { return nil, err } - // automatically inject ENV variables using ${ENV} pattern - expandEnvViper(v) - // override config Flags if len(flags) > 0 { for _, f := range flags { @@ -48,6 +45,20 @@ func NewClient(cfg string, flags []string) (*rpc.Client, error) { } } + ver := v.Get(versionKey) + if ver == nil { + return nil, fmt.Errorf("rr configuration file should contain a version e.g: version: 3") + } + + if _, ok := ver.(string); !ok { + return nil, fmt.Errorf("version should be a string: `version: \"3\"`, actual type is: %T", ver) + } + + err = handleInclude(ver.(string), v) + if err != nil { + return nil, fmt.Errorf("failed to handle includes: %w", err) + } + // rpc.listen might be set by the -o flags or env variable if !v.IsSet(rpcPlugin.PluginName) { return nil, errors.New("rpc service not specified in the configuration. Tip: add\n rpc:\n\r listen: rr_rpc_address") diff --git a/internal/rpc/client_test.go b/internal/rpc/client_test.go index 453491ff..60dd754b 100644 --- a/internal/rpc/client_test.go +++ b/internal/rpc/client_test.go @@ -52,6 +52,20 @@ func TestNewClient_SuccessfullyConnected(t *testing.T) { defer func() { assert.NoError(t, c.Close()) }() } +func TestNewClient_WithIncludes(t *testing.T) { + l, err := net.Listen("tcp", "127.0.0.1:6010") + assert.NoError(t, err) + + defer func() { assert.NoError(t, l.Close()) }() + + c, err := rpc.NewClient("test/include1/.rr.yaml", nil) + + assert.NotNil(t, c) + assert.NoError(t, err) + + defer func() { assert.NoError(t, c.Close()) }() +} + func TestNewClient_SuccessfullyConnectedOverride(t *testing.T) { l, err := net.Listen("tcp", "127.0.0.1:55554") assert.NoError(t, err) diff --git a/internal/rpc/includes.go b/internal/rpc/includes.go new file mode 100644 index 00000000..834cf034 --- /dev/null +++ b/internal/rpc/includes.go @@ -0,0 +1,62 @@ +package rpc + +import ( + "github.com/roadrunner-server/errors" + "github.com/spf13/viper" +) + +const ( + versionKey string = "version" + includeKey string = "include" + defaultConfigVersion string = "3" + prevConfigVersion string = "2.7" +) + +func getConfiguration(path string) (map[string]any, string, error) { + v := viper.New() + v.SetConfigFile(path) + err := v.ReadInConfig() + if err != nil { + return nil, "", err + } + + // get configuration version + ver := v.Get(versionKey) + if ver == nil { + return nil, "", errors.Str("rr configuration file should contain a version e.g: version: 2.7") + } + + if _, ok := ver.(string); !ok { + return nil, "", errors.Errorf("type of version should be string, actual: %T", ver) + } + + // automatically inject ENV variables using ${ENV} pattern + expandEnvViper(v) + + return v.AllSettings(), ver.(string), nil +} + +func handleInclude(rootVersion string, v *viper.Viper) error { + ifiles := v.GetStringSlice(includeKey) + if ifiles == nil { + return nil + } + + for _, file := range ifiles { + config, version, err := getConfiguration(file) + if err != nil { + return err + } + + if version != rootVersion { + return errors.Str("version in included file must be the same as in root") + } + + // overriding configuration + for key, val := range config { + v.Set(key, val) + } + } + + return nil +} diff --git a/internal/rpc/test/include1/.rr-include.yaml b/internal/rpc/test/include1/.rr-include.yaml new file mode 100644 index 00000000..a145a947 --- /dev/null +++ b/internal/rpc/test/include1/.rr-include.yaml @@ -0,0 +1,5 @@ +version: "3" + +rpc: + listen: tcp://127.0.0.1:6010 + diff --git a/internal/rpc/test/include1/.rr.yaml b/internal/rpc/test/include1/.rr.yaml new file mode 100644 index 00000000..66de370b --- /dev/null +++ b/internal/rpc/test/include1/.rr.yaml @@ -0,0 +1,11 @@ +version: "3" + +server: + command: "php app-with-domain-specific-routes.php" + +logs: + level: debug + mode: development + +include: + - test/include1/.rr-include.yaml -- cgit v1.2.3 From 8c9aed54caa5efd8e2e292086302e1db14d11213 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Thu, 21 Nov 2024 15:53:53 +0100 Subject: chore: remove defer Signed-off-by: Valery Piashchynski --- internal/rpc/client_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/rpc/client_test.go b/internal/rpc/client_test.go index 60dd754b..79335c0c 100644 --- a/internal/rpc/client_test.go +++ b/internal/rpc/client_test.go @@ -62,8 +62,6 @@ func TestNewClient_WithIncludes(t *testing.T) { assert.NotNil(t, c) assert.NoError(t, err) - - defer func() { assert.NoError(t, c.Close()) }() } func TestNewClient_SuccessfullyConnectedOverride(t *testing.T) { -- cgit v1.2.3 From 642e83ef2771ef6b99571626ecc188c9e41aeeb7 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Thu, 21 Nov 2024 16:05:43 +0100 Subject: fix: expand envs for the root and included files Signed-off-by: Valery Piashchynski --- internal/rpc/client_test.go | 2 ++ internal/rpc/includes.go | 4 ++++ internal/rpc/test/config_rpc_conn_err.yaml | 2 ++ internal/rpc/test/config_rpc_empty.yaml | 1 + internal/rpc/test/config_rpc_ok.yaml | 2 ++ internal/rpc/test/config_rpc_ok_env.yaml | 2 ++ internal/rpc/test/config_rpc_wrong.yaml | 2 ++ 7 files changed, 15 insertions(+) diff --git a/internal/rpc/client_test.go b/internal/rpc/client_test.go index 79335c0c..4a060f33 100644 --- a/internal/rpc/client_test.go +++ b/internal/rpc/client_test.go @@ -62,6 +62,8 @@ func TestNewClient_WithIncludes(t *testing.T) { assert.NotNil(t, c) assert.NoError(t, err) + + assert.NoError(t, c.Close()) } func TestNewClient_SuccessfullyConnectedOverride(t *testing.T) { diff --git a/internal/rpc/includes.go b/internal/rpc/includes.go index 834cf034..87b00001 100644 --- a/internal/rpc/includes.go +++ b/internal/rpc/includes.go @@ -37,6 +37,10 @@ func getConfiguration(path string) (map[string]any, string, error) { } func handleInclude(rootVersion string, v *viper.Viper) error { + // automatically inject ENV variables using ${ENV} pattern + // root config + expandEnvViper(v) + ifiles := v.GetStringSlice(includeKey) if ifiles == nil { return nil diff --git a/internal/rpc/test/config_rpc_conn_err.yaml b/internal/rpc/test/config_rpc_conn_err.yaml index c7d31056..5438198f 100644 --- a/internal/rpc/test/config_rpc_conn_err.yaml +++ b/internal/rpc/test/config_rpc_conn_err.yaml @@ -1,2 +1,4 @@ +version: "3" + rpc: listen: tcp://127.0.0.1:55554 diff --git a/internal/rpc/test/config_rpc_empty.yaml b/internal/rpc/test/config_rpc_empty.yaml index e69de29b..5db6fe96 100644 --- a/internal/rpc/test/config_rpc_empty.yaml +++ b/internal/rpc/test/config_rpc_empty.yaml @@ -0,0 +1 @@ +version: "3" diff --git a/internal/rpc/test/config_rpc_ok.yaml b/internal/rpc/test/config_rpc_ok.yaml index c7d31056..5438198f 100644 --- a/internal/rpc/test/config_rpc_ok.yaml +++ b/internal/rpc/test/config_rpc_ok.yaml @@ -1,2 +1,4 @@ +version: "3" + rpc: listen: tcp://127.0.0.1:55554 diff --git a/internal/rpc/test/config_rpc_ok_env.yaml b/internal/rpc/test/config_rpc_ok_env.yaml index fd0d3f11..f5ae461e 100644 --- a/internal/rpc/test/config_rpc_ok_env.yaml +++ b/internal/rpc/test/config_rpc_ok_env.yaml @@ -1,2 +1,4 @@ +version: "3" + rpc: listen: ${RPC} diff --git a/internal/rpc/test/config_rpc_wrong.yaml b/internal/rpc/test/config_rpc_wrong.yaml index 8282ee1f..c4ff9c46 100644 --- a/internal/rpc/test/config_rpc_wrong.yaml +++ b/internal/rpc/test/config_rpc_wrong.yaml @@ -1,2 +1,4 @@ +version: "3" + rpc: $foo bar -- cgit v1.2.3