From c2e15cfed9cf18c95c2e1156cd2b2fb76e4f95a0 Mon Sep 17 00:00:00 2001 From: Tak Wai Wong <64229756+tak-hntlabs@users.noreply.github.com> Date: Fri, 30 Sep 2022 13:41:29 -0700 Subject: [PATCH] Support environment variables for selected config fields (#40) * deployment time config using env variables * check if ethereum is enabled before replacing the config value with env variable --- setup/config/config.go | 56 ++++++++++++++++++++++++++++++++ setup/config/config_publickey.go | 9 ++--- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/setup/config/config.go b/setup/config/config.go index 150053fd2..65c97704f 100644 --- a/setup/config/config.go +++ b/setup/config/config.go @@ -23,6 +23,7 @@ import ( "os" "path/filepath" "regexp" + "strconv" "strings" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" @@ -291,6 +292,9 @@ func LoadMatrixKey(privateKeyPath string, readFile func(string) ([]byte, error)) // Derive generates data that is derived from various values provided in // the config file. func (config *Dendrite) Derive() error { + // Replace selected config with env variables. + config.replaceWithEnvVariables() + // Determine registrations flows based off config values config.Derived.Registration.Params = make(map[string]interface{}) @@ -576,6 +580,58 @@ func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err ) } +/* +* +Replace selected config with environment variables +*/ + +func (config *Dendrite) replaceWithEnvVariables() { + // Replace selected fields with env variables + + config.Global.ServerName = gomatrixserverlib.ServerName( + replaceWithEnvVariables(string(config.Global.ServerName)), + ) + logrus.Infof("Matrix ServerName=%s\n", config.Global.ServerName) + + config.Global.DatabaseOptions.ConnectionString = DataSource( + replaceWithEnvVariables( + string(config.Global.DatabaseOptions.ConnectionString), + ), + ) + + // If env variable is set, convert the deployment chain IDs from the env + // variable into []int and replace the ChainIDs field. + if config.ClientAPI.PublicKeyAuthentication.Ethereum.Enabled { + deploymentChainIDs := replaceWithEnvVariables(config.ClientAPI.PublicKeyAuthentication.Ethereum.DeploymentChainIDs) + chainIds := strings.Split(deploymentChainIDs, ",") + if len(chainIds) > 0 && chainIds[0] != "" { + var ids []int + for _, id := range chainIds { + id, err := strconv.Atoi(strings.TrimSpace(id)) + if err == nil { + ids = append(ids, id) + } + } + config.ClientAPI.PublicKeyAuthentication.Ethereum.ChainIDs = ids + } + logrus.Infof("Supported Ethereum chain IDs=%d\n", config.ClientAPI.PublicKeyAuthentication.Ethereum.ChainIDs) + } +} + +var regexpEnvVariables = regexp.MustCompile(`\$\{(?P\w+)\}`) +var varIndex = regexpEnvVariables.SubexpIndex("Var") + +func replaceWithEnvVariables(value string) string { + matches := regexpEnvVariables.FindAllStringSubmatch(value, -1) + for _, m := range matches { + if varIndex < len(m) { + envValue := os.Getenv(m[varIndex]) + value = strings.ReplaceAll(value, fmt.Sprintf("${%s}", m[varIndex]), envValue) + } + } + return value +} + // logrusLogger is a small wrapper that implements jaeger.Logger using logrus. type logrusLogger struct { l *logrus.Logger diff --git a/setup/config/config_publickey.go b/setup/config/config_publickey.go index d834cfefc..b0d3e4c2a 100644 --- a/setup/config/config_publickey.go +++ b/setup/config/config_publickey.go @@ -21,10 +21,11 @@ func (p EthereumAuthParams) GetParams() interface{} { } type EthereumAuthConfig struct { - Enabled bool `yaml:"enabled"` - Version uint `yaml:"version"` - ChainIDs []int `yaml:"chain_ids"` - EnableAuthz bool `yaml:"enable_authz"` // Flag to enable / disable authorization during development + Enabled bool `yaml:"enabled"` + Version uint `yaml:"version"` + ChainIDs []int `yaml:"chain_ids"` + DeploymentChainIDs string `yaml:"deployment_chain_ids"` // For deployment: use env variable strings to override the chain IDs. + EnableAuthz bool `yaml:"enable_authz"` // Flag to enable / disable authorization during development } type PublicKeyAuthentication struct {