Skip to content

Commit

Permalink
Allow templating when loading configs. (stripe#1004)
Browse files Browse the repository at this point in the history
  • Loading branch information
arnavdugar-stripe authored Nov 8, 2022
1 parent 1851efb commit 48ec7e4
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 5 deletions.
2 changes: 1 addition & 1 deletion cmd/veneur-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func main() {
}

config, err :=
utilConfig.ReadConfig[proxy.Config](*configFile, "veneur_proxy")
utilConfig.ReadConfig[proxy.Config](*configFile, nil, "veneur_proxy")
if err != nil {
logger.WithError(err).Fatal("failed to load config file")
}
Expand Down
30 changes: 26 additions & 4 deletions util/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,56 @@ package config
import (
"encoding/json"
"fmt"
"io/ioutil"
"io"
"net/http"
"os"
"text/template"

"github.com/kelseyhightower/envconfig"
"gopkg.in/yaml.v2"
)

func ReadConfig[Config interface{}](
path string, envBase string,
path string, templateData interface{}, envBase string,
) (*Config, error) {
file, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("failed to open config file: %v", err)
}
defer file.Close()

fileData, err := ioutil.ReadAll(file)
fileData, err := io.ReadAll(file)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %v", err)
}

configTemplate, err := template.New("config").Parse(string(fileData))
if err != nil {
return nil, err
}

configReader, configWriter := io.Pipe()
templateErr := make(chan error)
go func() {
err := configTemplate.Execute(configWriter, templateData)
configWriter.Close()
templateErr <- err
}()

decoder := yaml.NewDecoder(configReader)
decoder.SetStrict(true)

config := new(Config)
err = yaml.UnmarshalStrict(fileData, config)
err = decoder.Decode(config)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal config file: %v", err)
}

err = <-templateErr
if err != nil {
return nil, err
}

err = envconfig.Process(envBase, config)
if err != nil {
return nil, fmt.Errorf("failed to process environment variables: %v", err)
Expand Down
49 changes: 49 additions & 0 deletions util/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package config_test

import (
"io/ioutil"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stripe/veneur/v14/util/config"
)

type Config struct {
Key1 string
}

func TestReadConfigWithoutTemplate(t *testing.T) {
file, err := ioutil.TempFile("", "config.yaml")
require.NoError(t, err)
defer os.Remove(file.Name())

file.Write([]byte("key1: value1"))

parsedConfig, err :=
config.ReadConfig[Config](file.Name(), nil, "")
require.NoError(t, err)

assert.Equal(t, "value1", parsedConfig.Key1)
}

type ConfigParams struct {
ConfigValue string
}

func TestReadConfigWithTemplate(t *testing.T) {
file, err := ioutil.TempFile("", "config.yaml")
require.NoError(t, err)
defer os.Remove(file.Name())

file.Write([]byte("key1: {{.ConfigValue}}"))

parsedConfig, err :=
config.ReadConfig[Config](file.Name(), ConfigParams{
ConfigValue: "value1",
}, "")
require.NoError(t, err)

assert.Equal(t, "value1", parsedConfig.Key1)
}

0 comments on commit 48ec7e4

Please sign in to comment.