YAML简述
一、基础
YAML(Yet Another Markup Language),是一个JSON的超集,意味着任何有效JSON文件也都是一个YAML文件。它规则如下:
1)大小写敏感
2)使用缩进表示层级关系,但不支持tab缩进,只支持空格
3)缩进的数量不重要但至少一个空格,只要相同层级使用相同数量的空格即可
4)“#”表示注释,从这个字符开始,直到行末,都会被解析器忽略
关于k8s中YAML的使用,只有两种类型:Maps和Lists,Maps的子项可以是Lists,Lists的子项也可以是Maps。
Maps:就是一个字典,即key:value的键值对。
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web
第一行是分隔符,并且是可选的。如果在单个文件中只定义了一个服务,那么这种情况下,第一行的分隔符就可以忽略不计。在上面的例子中,可以看出有两个值:v1和Pod,对应它们的键是apiVersion和kind。
metadata这个key对应的值为一个Maps,而嵌套的labels这个key的值又是一个Map。实际使用中可视情况进行多层嵌套。
YAML处理器根据行缩进来知道内容之间的关联。上述例子中,使用两个空格作为缩进,但空格的数据量并不重要,只是至少要求一个空格并且所有缩进保持一致的空格数 。例如,name和labels是相同缩进级别,因此YAML处理器知道他们属于同一map;它知道app是lables的值,因为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
如上述文件所示,定义一个containers的List对象,每个子项都由name、image、ports组成,每个ports都有一个KEY为containerPort的Map组成
二、解析
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
参考: