it-swarm.com.de

Gehen Sie auf die Yaml-Datei

Ich versuche, eine yaml-Datei mit Go zu analysieren. Leider weiß ich nicht wie. Die yaml-Datei, die ich habe, ist folgende:

---
firewall_network_rules:
  rule1:
    src:       blablabla-Host
    dst:       blabla-hostname
...

Ich habe diesen Go-Code, aber er funktioniert nicht:

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)
}

Wenn ich das ausführen, erhalte ich eine Fehlermeldung. Ich denke, es liegt daran, dass ich keine Struktur für die Werte von src und dst erstellt habe. FYI: Wenn ich das in eine Liste ändere, funktioniert es.

Der obige Code analysiert das so:

---
firewall_network_rules:
  rule1:
    - value1
    - value2
...
12
Rogier Lommers

Wenn Sie genauer mit Google Cloud oder Kubernetes arbeiten und einen service.yaml so analysieren möchten:

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

Geben Sie ein reales Beispiel, damit Sie wissen, wie Schachteln geschrieben werden kann.

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"`
}

Es gibt einen praktischen Dienst namens json-to-go https://mholt.github.io/json-to-go/ , der Json-to-go-Strukturen konvertiert. Konvertieren Sie einfach Ihre YAML in JSON und geben Sie diesen Dienst ein Holen Sie sich eine automatisch generierte Struktur.

Und der letzte Unmarschall, wie ein voriges Poster schrieb:

var service Service

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

fmt.Print(service.Metadata.Name)
8
JazzCat

Warum organisieren Sie Ihre yaml-Datei nicht wie folgt, wenn Sie sich nicht für den Regelnamen interessieren?

---
firewall_network_rules:
  - 
    name:      rule1
    src:       blablabla-Host
    dst:       blabla-hostname
  - 
    name:      rule2
    src:       bla-Host
    dst:       bla-hostname

Der Code wird also so sein, er ist sauber und erweiterbar:

type Rule struct {
    Name  string  `yaml:"name"`
    Src   string  `yaml:"src"`
    Dst   string  `yaml:"dst"`
}

type Config struct {
   FirewallNetworkRules []Rule  `yaml:"firewall_network_rules"`
}
6
boyal

Ich glaube, ich habe es selbst herausgefunden. Der folgende Code funktioniert gut. Anregungen/Verbesserungen?

package main

import (
    "fmt"
    "io/ioutil"
    "path/filepath"

    "gopkg.in/yaml.v2"
)

type Config struct {
    Firewall_network_rules map[string]Options
}

type Options struct {
    Src string
    Dst 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)
}
6
Rogier Lommers

Wenn Ihre YAML-Datei einfach ist (einfache Verschachtelung), wie folgt

mongo:
    DB: database
    COL: collection
log:
    error: log/error/error.log
api:
    key: jhgwewbcjwefwjfg

Hier können Sie die Schnittstelle verwenden, anstatt die Struktur zu deklarieren.

main(){
  config := Config()
  mongoConfig := config["mongo"]

  mongo.MongoDial(
    String(
        Get(mongoConfig, "DB")
    ), 
    String(
        Get(mongoConfig, "COL")
    )
  )
}

func Config() map[string]interface{} {
    filename, _ := filepath.Abs("configs/config.yaml")
    yamlFile, err := ioutil.ReadFile(filename)

    if err != nil {
        panic(err)
    }

    var config map[string]interface{}

    err = yaml.Unmarshal(yamlFile, &config)
    if err != nil {
        panic(err)
    }

    return config
}
func Get(this interface{}, key string) interface{}  {
    return this.(map[interface{}]interface{})[key]
}
func String(payload interface{}) string  {
    var load string
    if pay, oh := payload.(string); oh {
        load = pay
    }else{
        load = ""
    }
    return load
}

Dies funktioniert gut für die Verschachtelung der Ebene 1. Wenn Sie eine komplexe Verschachtelung haben, wird empfohlen, struct zu verwenden.

0
Reoxey