preface

In the container realm, a common domain of the GO language, we often define various resource objects in the form of YAML files. For this reason, K8S engineers are nicknamed YAML engineers. However, in daily use, we usually read yamL files to obtain the configuration in yamL files. But what if we need to generate a YAML file from code? This article implements this functionality through the “github.com/spf13/viper” package

How do I read yamL files

Before we talk about how to generate, let’s talk about how to read yamL files, so if you have experience, you can skip to the next chapter, right

orgname: baas
channelname: publicchain
peer:
  - peer-0-baas
  - peer-1-baas
orderer:
  baas:
    - ServerHostName: orderer-0-baas:7050
      Address: 192.1689.159.: 30004
    - ServerHostName: orderer-1-baas:7050
      Address: 192.1689.159.: 30005
    - ServerHostName: orderer-2-baas:7050
      Address: 192.1689.159.: 30006
  baas2:
    - ServerHostName: orderer-0-baas2:7050
      Address: 192.1689.166.: 30012
Copy the code

Here is a simple YAML configuration file in a project. How do I use Golang to read this configuration information?

Full amount of reading

type ConfigStruct struct {
    OrgName       string                   `yaml:"orgname"`
    ChannelName   string                   `yaml:"channelname"`
    Peer          []string                 `yaml:"peer"`
    Orderer       map[string][]OrdererInfo `yaml:"ORDERER"`
}

type OrdererInfo struct {
    ServerHostName string `yaml:"ServerHostName"`
    Address        string `yaml:"Address"`
}
Copy the code

First we have to define a configuration appropriate structure, as shown above, yamL has four special tag tags

Tag name use
omitempty If the value is null, the field is ignored. The IsZero() interface can also be implemented for the structure for the field pair, and if the corresponding structure implements the interface, the return value of the interface is used to determine whether the field is ignored
flow This tag is used to indicate that you want to use stream mode instead of block mode
inline The built-in types
Always ignore this field

We then read the file via viper

var configViperConfig = viper.New()
configViperConfig.SetConfigName("config")
configViperConfig.SetConfigType("yaml")
// Read the contents of the configuration file
iferr = configViperConfig.ReadInConfig(); err ! =nil {
        panic(err)
}
var c ConfigStruct
iferr = configViperConfig.Unmarshal(&c); err ! =nil {
        panic(err)
}
Copy the code

In this way, we can get the configuration information in the code through the C variable

A single point of reading

If we only need a configuration in the configuration information, we can also read a single configuration

var configViperConfig = viper.New()
configViperConfig.SetConfigName("config")
configViperConfig.SetConfigType("yaml")
// Read the contents of the configuration file
iferr = configViperConfig.ReadInConfig(); err ! =nil {
        panic(err)
}
Copy the code

At this point, we provide the Get method through the Viper package

orgname := configViperConfig.Get("orgname")
Copy the code

Or use the GetString method

orgname := configViperConfig.GetString("orgname")
Copy the code

How do I write a configuration file

There are also two ways to generate a YAML file from code, corresponding to the reading above

The structure generates yamL files

Marshal by creating a corresponding structure and copying the corresponding fields

type Conf struct {
    Test []string `yaml:"array.test,flow"`
}

func main(a){
    data := `array.test: ["val1", "val2", "val3"]`
    var conf Conf
    yaml.Unmarshal([]byte(data), &conf)

    data2, _ := yaml.Marshal(conf)
    fmt.Printf("%s\n".string(data2))
}
Copy the code

Viper: Get (yamL) : Get (yamL) : Set (yamL

configViper := viper.New()
configViper.Set("version"."1.0.0")
/ /...
c := configViper.AllSettings()
bytes, err := yaml.Marshal(c)
iferr ! =nil {
        return nil, err
}
fmt.Println(string(bytes))
Copy the code

The first parameter of the Set method is the key of string type, and the second parameter is the value of interface type. Therefore, if the structure is complicated, the structure of the complex part can be written as a structure Set into the key, but the main fields of the structure must be exportable, otherwise it cannot be called by viper. Marshal would not have succeeded.