Skip to content

insolar/insconfig

Repository files navigation

Insolar configurations

test

Insolar configurations unify configuring for all Insolar applications: Assured Ledger, Insolar Observer, Insolar MainNet, Insolar Explorer and more.

Configurations are consolidated into a single configuration library that is a wrapper for Viper.

Configurations are used by Insolar applications as a dependency.

Insolar is extensively documented. If you need more information on what is Insolar, visit Insolar Docs.

Key features

  • .yaml format of configuration files.
  • No default configuration paths. A path should be explicitly set by the "--config/-c" flag. Optionally, you can override this by implementing ConfigPathGetter (look at configurator_test.go for details).
  • Environment values override file values.
  • Option to use only ENV, without a configuration file at all.
  • Option to write the config file content to the log file at an app launch.
  • Hiding sensitive data via the insconfigsecret tag.
  • No default values in a configuration file. All values should be set explicitly, otherwise the library returns an error.
  • No unnecessary field or parameters both in a configuration file and ENV, otherwise the library returns an error. Consider as unecessary: fields in a config struct unused in a configuration file, old or obsolete parameters in a configuration file that are not currently used, unused parameters in ENV.
  • Support of custom flags, go flags and pflags.
  • No overriding configutation files by flags.
  • Option to generate an empty .yaml file with field descriptions.
  • Automatic adding of the --config flag.
  • [work in progress] Automatic of the --gen-config flag.
  • No overriding app configuration on the fly.
  • Support of custom Viper decode hooks.

Usage

Consider the example in ./example/example.go.

Run the example:

run ./example/example.go --config="./example/example_config.yaml"

In addition:

  • Test the code snippets below by replacing the contents of func main() in example.go with them.

  • Modify the snippets appropriately to include them directly into your code. Pay attention to variable and configuration field contents.

Tip: Don't forget to add github.com/insolar/insconfig to the import section.

Note: EnvPrefix value shouldn't have any delimiters: EnvPrefix: "incorrect example" has incorrect syntax, while EnvPrefix: "correctexample" has correct syntax.

No flags

If you don't use any flags and DefaultPathGetter, which adds the --config flag so you can start right away, consider this example for func main():

mconf := &Config{}	
	params := insconfig.Params{
		EnvPrefix:        "example",
		ConfigPathGetter: &insconfig.DefaultPathGetter{},
	}
	insConfigurator := insconfig.New(params)
	if err := insConfigurator.Load(mconf); err != nil {
		panic(err)
	}
	insConfigurator.ToYaml(mconf)
	fmt.Println(insConfigurator.ToYaml(mconf))

Custom flags

Custom Go flags (from example.go)

    var flag_example_1 = flag.String("flag_example_1", "example_value", "flag_example_1_desc")
    mconf := Config{}
    params := insconfig.Params{
	EnvPrefix:    "example",
	ConfigPathGetter: &insconfig.FlagPathGetter{
		GoFlags: flag.CommandLine,
	},
    }
    insConfigurator := insconfig.New(params)
    _ = insConfigurator.Load(&mconf)
    fmt.Println(*flag_example_1)
    fmt.Println(insConfigurator.ToYaml(mconf))
    var flag_example_1 = pflag.String("flag_example_1", "", "flag_example_1_desc")
    mconf := Config{}
    params := insconfig.Params{
        EnvPrefix:    "example",
        ConfigPathGetter: &insconfig.PFlagPathGetter{
            PFlags: pflag.CommandLine,
        },
    }
    insConfigurator := insconfig.New(params)
    _ = insConfigurator.Load(&mconf)
    fmt.Println(flag_example_1)
    fmt.Println(insConfigurator.ToYaml(mconf))

Note: Cobra doesn't provide tools that manage flags parsing, so you need to add the --config flag yourself.

// To set your path from flag to insconfig you need to implement simple ConfigPathGetter interface and return path
type stringPathGetter struct {
	Path string
}
func (g *stringPathGetter) GetConfigPath() string {
	return g.Path
}
func main() {
	var configPath string
	rootCmd := &cobra.Command{
		Use: "your_command_name",
	}
	rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "path to config file")
	_ = rootCmd.MarkPersistentFlagRequired("config")
	err := rootCmd.Execute()
	if err != nil {
		panic(err)
	}
	cfg := Config{}
	params := insconfig.Params{
		EnvPrefix:        "example",
		ConfigPathGetter: &stringPathGetter{Path: configPath},
		FileNotRequired:     true,
	}
	insConfigurator := insconfig.New(params)
	err = insConfigurator.Load(&cfg)
	if err != nil {
		panic(err)
	}
	println(insConfigurator.ToYaml(cfg))
}

Generating a configuration template

Tip: You can use tags to enrich a field with a comment, and it will end up in your template.

If you want to create a config file example and you have a ready config structure, consider this example:

    type Config struct {
    ... 
        Field Type `insonfig:"Commentary for this field"`
    }
    ...
    cfg := Config{
        ...
        Field: "default_value",
    }
    insconfig.NewYamlTemplaterStruct(cfg).TemplateTo(os.StdOut)

As you see, default value for a field can be provided via instance of config structure.

Generating a configuration template with hidden fields

If you have some sensitive data, you may want to hide it in a config. You can use the insconfigsecret tag to hide such data.

    type Config struct {
    ...
	    Pass string `insconfigsecret:""`
    }
    ...
    insconfig.NewYamlDumper(Config).DumpTo(os.StdOut)

Using maps in a configuration file

You can use maps in a configuration file, althought with some limitations:

  • Only String type keys are allowed
  • A map cannot be nested and has to be used on the first level
  • Nested maps (directly or in a struct) are not allowed

Contribute!

Feel free to submit issues, fork the repository and send pull requests!

To make the process smooth for both reviewers and contributors, familiarize yourself with the following guidelines:

  1. Open source contributor guide.
  2. Style guide: Effective Go.
  3. List of shorthands for Go code review comments.

When submitting an issue, include a complete test function that reproduces it.

Thank you for your intention to contribute to the Insolar Mainnet project. As a company developing open-source code, we highly appreciate external contributions to our project.

Contacts

If you have any additional questions, join our developers chat on Telegram.

Our social media:

License

This project is licensed under the terms of the MIT License.

Releases

No releases published

Packages

No packages published

Languages