Go parse yaml file

go, struct, yaml

Solution

If you're working with google cloud or kubernetes more specifically and want to parse a service.yaml like this:

apiVersion: v1
kind: Service
metadata:
  name: myName
  namespace: default
  labels:
    router.deis.io/routable: "true"
  annotations:
    router.deis.io/domains: ""
spec:
  type: NodePort
  selector:
    app: myName
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443

Supplying a real world example so you get the hang of how nesting can be written.

type Service struct {
    APIVersion string `yaml:"apiVersion"`
    Kind       string `yaml:"kind"`
    Metadata   struct {
        Name      string `yaml:"name"`
        Namespace string `yaml:"namespace"`
        Labels    struct {
            RouterDeisIoRoutable string `yaml:"router.deis.io/routable"`
        } `yaml:"labels"`
        Annotations struct {
            RouterDeisIoDomains string `yaml:"router.deis.io/domains"`
        } `yaml:"annotations"`
    } `yaml:"metadata"`
    Spec struct {
        Type     string `yaml:"type"`
        Selector struct {
            App string `yaml:"app"`
        } `yaml:"selector"`
        Ports []struct {
            Name       string `yaml:"name"`
            Port       int    `yaml:"port"`
            TargetPort int    `yaml:"targetPort"`
            NodePort   int    `yaml:"nodePort,omitempty"`
        } `yaml:"ports"`
    } `yaml:"spec"`
}

There's a convenient service called yaml-to-go https://zhwt.github.io/yaml-to-go/ which converts YAML to go structs, just input your YAML into that service and you get an autogenerated struct.

A JSON equivalent exists aswell: https://mholt.github.io/json-to-go/

And last unmarshal as a previous poster wrote:

var service Service

err = yaml.Unmarshal(yourFile, &service)
if err != nil {
    panic(err)
}

fmt.Print(service.Metadata.Name)

Problem

I'm trying to parse a yaml file with Go. Unfortunately I can't figure out how. The yaml file I have is this: ``` --- firewall_network_rules: rule1: src: blablabla-host dst: blabla-hostname ... ``` I have this Go code, but it does not work: ``` package main import ( "fmt" "io/ioutil" "path/filepath" "gopkg.in/yaml.v2" ) type Config struct { Firewall_network_rules map[string][]string } func main() { filename, _ := filepath.Abs("./fruits.yml") yamlFile, err := ioutil.ReadFile(filename) if err != nil { panic(err) } var config Config err = yaml.Unmarshal(yamlFile, &config) if err != nil { panic(err) } fmt.Printf("Value: %#v\n", config.Firewall_network_rules) } ``` When I run this, I get an error. I think it's because I haven't created a struct for the src and dst key/values. FYI: when I change that to a list, it works. So above code parses this: ``` --- firewall_network_rules: rule1: - value1 - value2 ... ```

Original source