summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2024-11-21 15:51:19 +0100
committerValery Piashchynski <[email protected]>2024-11-21 15:51:19 +0100
commitbdcc01a7ff4774bdc0cc57c02236d5aca176b574 (patch)
tree9b8e0b5163262863fd48fdbed622f5b3618e0f3e
parentbd93d5c005b48a086646145827e302e2fd5d5872 (diff)
fix: properly parse includes outside the Configuration plugin
Signed-off-by: Valery Piashchynski <[email protected]>
-rw-r--r--internal/rpc/client.go17
-rw-r--r--internal/rpc/client_test.go14
-rw-r--r--internal/rpc/includes.go62
-rw-r--r--internal/rpc/test/include1/.rr-include.yaml5
-rw-r--r--internal/rpc/test/include1/.rr.yaml11
5 files changed, 106 insertions, 3 deletions
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