YAML简述

一、基础

YAMLYet Another Markup Language,是一个JSON的超集,意味着任何有效JSON文件也都是一个YAML文件。它规则如下:

1)大小写敏感

2)使用缩进表示层级关系,但不支持tab缩进,只支持空格

3)缩进的数量不重要但至少一个空格,只要相同层级使用相同数量的空格即可

4)“#”表示注释,从这个字符开始,直到行末,都会被解析器忽略

关于k8sYAML的使用,只有两种类型:MapsListsMaps的子项可以是ListsLists的子项也可以是Maps

Maps:就是一个字典,即key:value的键值对。

---
apiVersion: v1
kind: Pod
metadata:
  name: kube100-site
  labels:
    app: web

第一行是分隔符,并且是可选的。如果在单个文件中只定义了一个服务,那么这种情况下,第一行的分隔符就可以忽略不计。在上面的例子中,可以看出有两个值:v1Pod,对应它们的键是apiVersionkind

metadata这个key对应的值为一个Maps,而嵌套的labels这个key的值又是一个Map。实际使用中可视情况进行多层嵌套。

YAML处理器根据行缩进来知道内容之间的关联。上述例子中,使用两个空格作为缩进,但空格的数据量并不重要,只是至少要求一个空格并且所有缩进保持一致的空格数 。例如,namelabels是相同缩进级别,因此YAML处理器知道他们属于同一map;它知道applables的值,因为app的缩进更大。

Lists:就是一个列表。

args
  -beijing
  -shanghai
  -shenzhen
  -guangzhou

可以有任何数量的项在列表中,项的定义以破折号(-)开头,并且和父元素之间存在缩进。在JSON格式中,表示如下:

{ 
“args”: [“beijing”, “shanghai”, “shenzhen”, “guangzhou”] 
}

一个示例如下:

---
apiVersion: v1
kind: Pod
metadata:
  name: kube100-site
  labels:
    app: web
spec:
  containers:
    - name: front-end
      image: nginx
      ports:
        - containerPort: 80
    - name: flaskapp-demo
      image: jcdemo/flaskapp
      ports: 8080

如上述文件所示,定义一个containersList对象,每个子项都由nameimageports组成,每个ports都有一个KEYcontainerPortMap组成

二、解析

YAML解析规则与JSON相同,可参考JSON的struct与JSON对应解析规则。

YAML文件示例:

version: 1.0.0

fabric:
  configFile: config_sdk.yaml
  orgName: Org1
  orgAdmin: Admin
  orgMspID: org1.kevin.kongyixueyuan.com
  orgEp: peer0.org1.kevin.kongyixueyuan.com
  orgUser: User1
  ordererOrgEp: orderer.kevin.kongyixueyuan.com
  channelID: mycc
  channelConfig: /opt/gopath/src/github.com/hyperledger/logfabric/artifacts/channel.tx
  chaincodeID: mycc
  chaincodeVer: 1.0
  chaincodeGoPath: /opt/gopath
  chaincodePath: github.com/hyperledger/logfabric/chaincode/v1

web:
  addr: :9999

golang语法解析:

package main

import (
    "fmt"
    "io/ioutil"
    "gopkg.in/yaml.v2"
    "flag"
    "os"
)

type SDKInfo struct {
    OrgName        string    `yaml:"orgName"`
    OrgAdmin    string    `yaml:"orgAdmin"`
    OrgMSPID    string    `yaml:"orgMspID"`
    OrgEp        string    `yaml:"orgEp"`
    OrgUser        string    `yaml:"orgUser"`

    OrdererOrgEp    string    `yaml:"ordererOrgEp"`

    // more channels for one peer
    ChannelID    string    `yaml:"channelID"`
    ChannelConfig    string    `yaml:"channelConfig"`

    // more chaincodes for one channel, just one NOW
    ChaincodeID    string    `yaml:"chaincodeID"`
    ChaincodeVer    string    `yaml:"chaincodeVer"`
    ChaincodeGoPath    string    `yaml:"chaincodeGoPath"`
    ChaincodePath    string    `yaml:"chaincodePath"`

    // Only one file to deal with
    ConfigFile    string    `yaml:"configFile"`
    Initialized    bool
}

type SDKInfoYaml struct {
    Version        string    `yaml:"version"`
    Info        SDKInfo    `yaml:"fabric"`
    Web        WebInfo    `yaml:"web"`
}

type WebInfo struct {
    Addr    string    `yaml:"addr"`
}

func NewSDKInfoFromYAML(data []byte) (*SDKInfo, error){
    var s SDKInfoYaml
    err := yaml.Unmarshal(data, &s)
//    var info SDKInfo
//    err := yaml.Unmarshal(data, &info)
    if err != nil {
        return nil, fmt.Errorf("Fabric SDK initialize error: yaml unmarshal error")
    }

    if s.Version != "1.0.0" {
        return nil, fmt.Errorf("Fabric SDK initialize error: yaml version error")
    }

    info := &s.Info
    fmt.Printf("%#v\n", info)
    if info.OrgName ==  "" || info.OrgAdmin == "" || info.OrgMSPID == "" ||
        info.OrgEp == "" || info.OrgUser == "" || info.OrdererOrgEp == "" ||
        info.ChannelID == "" || info.ChannelConfig == "" ||
        info.ChaincodeID == "" || info.ChaincodeVer == "" ||
        info.ChaincodeGoPath == "" || info.ChaincodePath == "" {

        return nil, fmt.Errorf("Fabric SDK initialize error: parameter is nil")
    }

    return info, nil
}

func GetWebAddr(data []byte) (string, error) {
    var s SDKInfoYaml
    err := yaml.Unmarshal(data, &s)

    if err != nil {
        return "", fmt.Errorf("Fabric SDK initialize error: yaml unmarshal error")
    }

    if s.Version != "1.0.0" {
        return "", fmt.Errorf("Fabric SDK initialize error: yaml version error")
    }

    if s.Web.Addr == "" {
        return "", fmt.Errorf("Fabric SDK initialize error: Web Addr is nil")
    }

    return s.Web.Addr, nil
}

func main(){
//    ymlFile := "sdkinfo.yml"
    var ymlFile string = ""
    flag.StringVar(&ymlFile, "config", "sdkinfo.yml", "The path of the config file")
//    bInitialized := flag.Bool("init", false, "Initialize the channel and chaincode or not")
    flag.PrintDefaults()
    flag.Parse()

//    if ymlFile == "" {
//        ymlFile = "sdkinfo.yml"
//    }
    fmt.Println(ymlFile)

    data, err := ioutil.ReadFile(ymlFile)
    if err != nil {
        fmt.Println("Fabric SDK read config file error")
        return
    }

    info, err := NewSDKInfoFromYAML(data)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
//    info.Initialized = *bInitialized
    if len(os.Args) == 2 && os.Args[1] == "initialize" {
        info.Initialized = true
    }

    fmt.Printf("%#v\n", info)

    addr, err := GetWebAddr(data)
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    fmt.Printf("%#v\n", addr)
}

更加复杂的应用,如yaml转json等可使用库github.com/ghodss/yaml,参考:https://github.com/open-ness/edgecontroller/blob/master/cnca/cmd/apply.go

 

参考:

1KubernetesYAML文件

posted @ 2019-04-15 23:29  yuxi_o  阅读(408)  评论(0编辑  收藏  举报