我从values.yaml
解析结构,并想在template.yaml
中使用它
这是我的values.yaml
文件:
services:
app:
image: matryoshka/app
replicaCount: 1
cron:
image: matryoshka/cron
replicaCount: 1
这是我的template.yaml
(无效代码):
{{- range $key, $value := .Services}}
{{$key}}{{$value}}
{{- end}}
哪个给我错误:
panic: template: template.yaml:1:26: executing "template.yaml" at <.Services>: range can't iterate over {{atryoshka/app 1} {matryoshka/cron 1}}
这是我的.go
代码:
package main
import (
"html/template"
"io/ioutil"
"os"
"path/filepath"
"gopkg.in/yaml.v2"
)
type Values struct {
Services struct {
App struct {
Image string `yaml:"image"`
ReplicaCount string `yaml:"replicaCount"`
} `yaml:"app"`
Cron struct {
Image string `yaml:"image"`
ReplicaCount string `yaml:"replicaCount"`
} `yaml:"cron"`
}
}
func parseValues() Values {
var values Values
filename, _ := filepath.Abs("./values.yaml")
yamlFile, err := ioutil.ReadFile(filename)
err = yaml.Unmarshal(yamlFile, &values)
if err != nil {
panic(err)
}
return values
}
func insertValues(class Values) {
paths := []string{"template.yaml"}
t, err := template.New(paths[0]).ParseFiles(paths...)
if err != nil {
panic(err)
}
err = t.Execute(os.Stdout, class)
if err != nil {
panic(err)
}
}
func main() {
values := parseValues()
insertValues(values)
}
如何正确遍历.Services
中的template.yaml
?我发现{{- range $key, $value := .Services}}
仅提供选项,但不起作用。
答案 0 :(得分:2)
如您所见,您不能在结构的各个字段范围内移动。您只能在切片,数组,地图和通道上进行选择。
最简单的方法就是传递:一张地图。您可以将YAML直接解组到地图或空接口中:
func parseValues() interface{} {
var values interface{}
// ...rest is unchanged
}
func insertValues(class interface{}) {
// ...unchanged
}
稍微更改模板的格式(请注意.services
)
{{- range $key, $value := .services}}
{{$key}} {{$value}}
{{- end}}
使用这些,它的工作原理是:
app map[replicaCount:1 image:matryoshka/app]
cron map[image:matryoshka/cron replicaCount:1]
如果您想继续使用Services
模型,另一种选择是手动准备并传递一部分字段:
insertValues([]interface{}{values.Services.App, values.Services.Cron})
然后是模板:
{{- range $key, $value := .}}
{{$key}} {{$value}}
{{- end}}
然后输出:
0 {matryoshka/app 1}
1 {matryoshka/cron 1}
如果您希望它保持“动态”状态(这意味着您不必手动枚举字段),则可以创建一个使用反射来执行此操作的帮助器函数。有关如何执行此操作的示例,请参见Get all fields from an interface和Iterate through the fields of a struct in Go。