cfginterpolator

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2022 License: MIT Imports: 12 Imported by: 0

README

cfginterpolator

example workflow Go Report Card Go Reference

cfginterpolator is an interpolate library in golang allowing to include data from external sources in your configuration

It will also allow you to keep your configuration up to date when a value change in one of any external data source. See section configuration reload of this README.

cfginterpolator can ingest several types of data:

  • a yaml file
---
key1: "{{env::ENV_VAR1}}"
key2:
  subkey1: "{{env::ENV_VAR2}}"
  subkey2: "{{env::wrongly_formatted::value}}"
key3: value
key4:
  - listkey1: listvalue1
  - listkey2: "{{env::ENV_VAR3}}"
  - listkey3:
      listsubkey1: listsubvalue1
      listsubkey2: "{{env::ENV_VAR4}}"
  • a map[string]interface{} with as many nested map[string]interface{} as you want

Example

package main

import (
    "github.com/bbayszczak/cfginterpolator"
)

type Config struct {
	Key1 string
	Key2 map[string]string
	Key3 []map[string]string
}
os.Setenv("ENV_VAR_1", "secret_value_1_kv_V1")
os.Setenv("ENV_VAR_2", "secret_value_2_kv_V1")
os.Setenv("ENV_VAR_3", "secret_value_3_kv_V1")
var conf Config
if err := cfginterpolator.InterpolateFromYAMLFile("cfginterpolator/example_files/config.yml", &conf); err != nil {
	panic(err)
}

Other examples can be found in the go doc Go Reference

Available external datasources

environment variables

{{env::ENV_VAR1}} will be replaced by the value of the environment variable ENV_VAR1

Hashicorp Vault
Prequisites
  • Environment variable VAULT_ADDR should contains the Vault address (e.g.: https://vault.mydomain.com:8200)

  • A Vault token should exists in environment variable VAULT_TOKEN on in file $HOME/.vault-token. The enviroment variable takes predence over the file if both are set.

K/V v1

{{hashivault:kvv1::secret/path/to/secret:key}} will be replaced by the value of the key key of secret secret/path/to/secret

K/V v1 is the the default value, the two following expressions act identical: {{hashivault::secret/path/to/secret:key}} & {{hashivault:kvv1::secret/path/to/secret:key}}

K/V v1 JSON

{{hashivault:kvv1_json::secret/path/to/secret}} will be replaced by secret secret/path/to/secret JSON value

K/V v2

{{hashivault:kvv2::secret/data/path/to/secret:key}} will be replaced by the value of the key key of secret secret/path/to/secret

With K/V v2 you need to add data after the secret engine name. apps/my/secret will become apps/data/my/secret

Hashicorp Consul
Prequisites
  • Environment variable CONSUL_HTTP_ADDR should contains the Consul address (e.g.: consul.mydomain.com:8500)

  • If a Consul token is needed to access the K/V, it needs to be in the environment variable CONSUL_HTTP_TOKEN

K/V

{{consul:kv::path/to/key}} will be replaced by the vlue in the key path/to/key

Reload

Consul data source handle reload as soon as the key is modified. It does not needs to wait the reload interval

Configuration reload

Using the method InterpolateAndWatchYAMLFile will not return any value except if an error occured

While this function runs, the object provided for configuration storage will be kept up to date with external data sources specified.

See function example in go doc

External datasources to be implemented

  • environment variables

  • file

  • Hashicorp Vault

  • Hashicorp Consul

Improvements

  • interpolate directly from YAML file

  • interpolate directly from JSON file

  • allow to interpolate several times in the same value

  • not panic when interpolator name does not exists

  • add error returns

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	LeftSeparator                      = "{{"
	RightSeparator                     = "}}"
	InterpolatorSeparator              = "::"
	InterpolatorConfigurationSeparator = ":"
	// When using watch, specify interval between reloads
	ReloadInterval = 30 * time.Second
)

Functions

func Interpolate

func Interpolate(conf map[string]interface{}, reloadChan chan string) error

Interpolate interpolate values in a map[string]interface{}

func InterpolateAndWatchYAMLFile added in v0.4.0

func InterpolateAndWatchYAMLFile(yamlFileName string, out interface{}) error

InterpolateFromYAMLFile interpolate YAML file content and write interpolated content to out interface{}. If the data is updated in any external sources, it will be updated int he out interface InterpolateFromYAMLFile does not end unless an error occured which will be returned

Example
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/bbayszczak/cfginterpolator"
)

func main() {
	type Config struct {
		Key1 string
		Key2 map[string]string
		Key3 []map[string]string
	}
	os.Setenv("ENV_VAR_1", "var1_0")
	os.Setenv("ENV_VAR_2", "var2")
	os.Setenv("ENV_VAR_3", "var3")
	var conf Config

	cfginterpolator.ReloadInterval = time.Second
	go func() {
		time.Sleep(500 * time.Millisecond)
		if err := cfginterpolator.InterpolateAndWatchYAMLFile("example_files/config.yml", &conf); err != nil {
			fmt.Println(err)
		}
	}()
	for i := 1; i <= 3; i++ {
		time.Sleep(time.Second)
		os.Setenv("ENV_VAR_1", fmt.Sprintf("var1_%d", i))
		fmt.Printf("%d: %s\n", i, conf)
	}

}
Output:

1: {var1_0 map[subkey1:var2] [map[listkey1:var3]]}
2: {var1_1 map[subkey1:var2] [map[listkey1:var3]]}
3: {var1_2 map[subkey1:var2] [map[listkey1:var3]]}

func InterpolateFromYAMLFile added in v0.1.0

func InterpolateFromYAMLFile(yamlFileName string, out interface{}) error

InterpolateFromYAMLFile interpolate YAML file content and write interpolated content to out interface{}

Example
package main

import (
	"fmt"
	"os"

	"github.com/bbayszczak/cfginterpolator"
)

func main() {
	type Config struct {
		Key1 string
		Key2 map[string]string
		Key3 []map[string]string
	}
	os.Setenv("ENV_VAR_1", "secret_value_1_kv_V1")
	os.Setenv("ENV_VAR_2", "secret_value_2_kv_V1")
	os.Setenv("ENV_VAR_3", "secret_value_3_kv_V1")
	var conf Config
	if err := cfginterpolator.InterpolateFromYAMLFile("example_files/config.yml", &conf); err != nil {
		panic(err)
	}
	fmt.Println(conf)
}
Output:

{secret_value_1_kv_V1 map[subkey1:secret_value_2_kv_V1] [map[listkey1:secret_value_3_kv_V1]]}

Types

type Interpolators

type Interpolators struct{}

func (*Interpolators) ConsulInterpolator added in v0.3.0

func (i *Interpolators) ConsulInterpolator(interpolatorConf string, value string, reloadChan chan string) string

func (*Interpolators) EnvInterpolator

func (i *Interpolators) EnvInterpolator(interpolatorConf string, value string, reloadChan chan string) string

func (*Interpolators) HashivaultInterpolator added in v0.0.2

func (i *Interpolators) HashivaultInterpolator(interpolatorConf string, value string, reloadChan chan string) string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL