Categorygithub.com/spgyip/olayc
modulepackage
0.6.4
Repository: https://github.com/spgyip/olayc.git
Documentation: pkg.go.dev

# README

Overlay configuration

Configurations are very common scenerios controlling program behaviors at runtime. There are different ways of configuration, e.g. from configure files, commandline arguments, environment variables. Overlay configuration is composition of multiple configure sources, and provides a unified interface to load from different configure sources.

                                [### Configure sources ###]

                                -------------------------
                       --------- | commandline arguments |
                       |         -------------------------
    ---------------    |         --------------
    |    olayc    | <----------- | Yaml files |
    ---------------    |         --------------
                       |         --------------
                       --------- |    ENVs    |
                                 --------------

Currently supported:

  • Commandline arguments
  • Yaml file
  • Json file
  • Environments
  • Etcd KV

Overlay

Every configure sources are overlayed from bottom to top, the upper layer has more priority than the lower ones, which means if there are keys conflited the value in the upper layer will be got.

layers

Examples

See examples/. Build with make all, binaries are built in bin/.

Load yaml files

Use -of.f.y=... to add yaml file.

./bin/simple -oc.f.y=./testdata/test1.yaml \
             -oc.f.y=./testdata/test2.yaml

The left yaml file is prior to right file, thus, if there are same keys in test1.yaml and test2.yaml, the value in test1.yaml will be got.

Load json files

Use -of.f.j=... to add json file.

./bin/simple -oc.f.y=./testdata/test1.yaml \
             -oc.f.y=./testdata/test2.yaml
             -oc.f.j=./testdata/test1.json

Load from commandline arguments

Use commandline argument seperated by ..

./bin/simple -oc.f.y=./testdata/test1.yaml \
             -oc.f.y=./testdata/test2.yaml \
             -oc.f.j=./testdata/test1.json
             -foo.redis.host=redis.othercluster \
             -foo.redis.port=999

Load from environment variables

Environment variables are not loaded on default, can be turned on with -oc.env | -oc.e. The environment format "FOO_NAME" is converted to "foo.name".

FOO_NAME=foo-env ./bin/simple -oc.e \
                              -oc.f.y=./testdata/test1.yaml \
                              -oc.f.y=./testdata/test2.yaml \
                              -oc.f.j=./testdata/test1.json
                              -foo.redis.host=redis.othercluster \
                              -foo.redis.port=999

Verbose mode

Turn verbose mode with -oc.v, more debug messages are printed out.

./bin/simple -oc.v \
             -oc.e \
             -oc.f.y=./testdata/test1.yaml \
             -oc.f.y=./testdata/test2.yaml \
             -oc.f.j=./testdata/test1.json \
             -foo.redis.host=redis.othercluster \
             -foo.redis.port=999

Dry run mode

Use -oc.dr to turn on dry run mode, olayc loads and prints out the merged configurations with yaml format then exits the program. It's convenient for pre-checking what configurations are loaded.

./bin/simple -oc.dr \
             -oc.s \
             -oc.e \
             -oc.f.y=./testdata/test1.yaml \
             -oc.f.y=./testdata/test2.yaml \
             -oc.f.j=./testdata/test1.json \
             -foo.redis.host=redis.othercluster \
             -foo.redis.port=999

[OlayConfig] Dry run mode is on, program will exit after yaml printed.
foo:
  id: 123
  labels:
    app: foo
    zone: sz
  name: foo1
  redis:
    host: redis.othercluster
    port: 999
  url: http://www.example.com

Usage

Load

It's easy to initialize the default olayc with Load().

olayc.Load()

It's very common there are configure files must be loaded before program startup. Use WithFileRequire(), program will exits if the required file is not loaded.

olayc.Load(
    olayc.WithFileRequire("test1.yaml"),
)

Add application usage with WithUsage(), usage message will be printed out with commandline argument -h|--help.

olayc.Load(
	olayc.WithUsage("foo.id", reflect.Int, 99, "Set foo ID"),
)

Get scalar value

olayc.Load()
id := olayc.Int("foo.id", 99))
name: = olayc.String("foo.name", "foo")
url := olayc.String("foo.url", "http://www.default.com"))

Unmarshal to struct

Unmarshal is using yaml field tags.

var cfg struct {
	Foo struct {
		Id   int    `yaml:'id'`
		Name string `yaml: 'name'`
		Url  string `yaml: 'url'`
	} `yaml: 'foo'`
}

olayc.Load()
olayc.Unmarshal(olayc.Root, &cfg)

Priority

The default olayc has default priority when multiple configure sources are loaded, which are:

  • Commandline arguments
  • Environment variables
  • Yaml/Json Files

Help message

Use -oc.h|--oc.help to see OlayConfig help message.

./bin/simple -oc.h
Usage of olayc:
  -oc.help | -oc.h
         Print this help message.
  -oc.verbose|-oc.v bool
         Set verbose mode, more messages are printed.
  -oc.file.yaml | -oc.f.y
         Load yaml file.
  -oc.file.json | -oc.f.j
         Load json file.
  -oc.env | -oc.e
         Load from environments.
  -oc.dryrun | -oc.dr
         Dry run, load and print Yaml then exit.

Notice that commandline arguments which are prefixed with -oc.|--oc. is preserved by OlayConfig.

Use -h|--help to see application help message.

./bin/simple -h
Usage of app:
  -h|--help bool
       Print this help message.
  -foo.id int
       Set foo ID (default 99)

Overlap keys

When use commandline arguments or environment variables, keys may be overlap, for examples

-foo.redis=cluster1
-foo.redis.name=cluster2
FOO_REDIS=cluster1
FOO_REDIS_NAME=cluster2

There is only one value can be got with key 'foo.redis'. This depends on the order of loading. The previously loaded key is prior to the latter ones, the latter ones will be ignored.

If -foo.redis=cluster1 is loaded previously, the -foo.redis.name=cluster2 will be ignored. This is resulting to:

Get("foo.redis")         => "cluster1"
Get("foo.redis.name")    => nil(NOT EXIST)

If the -foo.redis.name=cluster2 is loaded previously, the -foo.redis=cluster1 will be ignored. This is resulting to:

Get("foo.redis")         => {"name": "cluster2"}
Get("foo.redis.name")    => "cluster2"

Should notice that in case 2, Get("foo.redis") returns the subnode, not nil(NOT EXIST).

Tests

Make sure passing all tests with make test if you try to add some features.

# Packages

No description provided by the author

# Functions

Get bool with default OlayConfig.
Get float64 with default OlayConfig.
Get value with default OlaycConfig.
Get int with default OlayConfig.
Get int64 with default OlayConfig.
Load the default OlayConfig from configure sources: - Commandline arguments, e.g.
New allocates and returns a new OlayConfig.
Get string with default OlayConfig.
ToYaml with default OlayConfig.
Get uint with default OlayConfig.
Get uint64 with default OlayConfig.
Unmarshal with default OlayConfig.
WithFileRequire returns a loadOptionFunc appends a required file.
WithUsage appends a usage message, when there are parsing errors or '-h|--help' arguments, usage message will be printed.

# Constants

Root key.

# Structs

KV is composition of key and value.
OlayConfig is composition of multiple configure sources, each source is overlayed from bottom to top.
Value represents a configure value, it can be scalar node or sub-tree node.