问题描述
我尝试在 go 函数中对一些 JSON 值进行模板化,这基本上像我期望的那样工作。 但是,如果我尝试将模板字符串与模板函数连接起来,它会失败(有不同的错误,取决于模板字符串的外观)
例如,我有以下几行:
{"APPLICATION_HOST":"http://{{ .NAMESPACE }}-repo.{{ .NAMESPACE }}:3004"}
模板工作并提供以下输出:
{"APPLICATION_HOST":"http://test-repo.test:3004"}
我现在想用 base64 对值进行编码,例如尝试以下操作:
{"APPLICATION_HOST":"{{ http://{{ .NAMESPACE }}-repo.{{ .NAMESPACE }}:3004 | b64encode }}"}
这给出了错误:
“http://”不是函数
如果我只是做以下事情(看起来很可怕):
{"APPLICATION_HOST":"{{ printf "http://{{ .NAMESPACE }}-repo.{{ .NAMESPACE }}:3004"|b64encode }}"}
输出如下:
{"APPLICATION_HOST":"aHR0cDovL3t7IC5OQU1FU1BBQ0UgfX0tcmVwby57eyAuTkFNRVNQQUNFIH19OjMwMDQ="}
解码为:
http://{{ .NAMESPACE }}-repo.{{ .NAMESPACE }}:3004
模板函数目前看起来像这样:
func generateDeFinitionjson(filePath string,bodyBytes []byte) (interface{},error) {
var (
tpl bytes.Buffer
err error
tplInterface,m map[string]interface{}
)
funcMap := template.FuncMap{
// The name "b64encode" is what the function will be called in the template text.
"b64encode": b64encode,}
// read deFinition file
fileContent,err := IoUtil.ReadFile(filePath)
// load deFinition as template
t,err := template.New("").Funcs(funcMap).Parse(string(fileContent))
if err != nil {
logger.Error("Parsing Template Failed: " + err.Error())
} else {
// create value map
err = json.Unmarshal([]byte(bodyEscaped),&m)
mInterfaceStr := fmt.Sprintf("%v",m)
if err != nil {
logger.Error("Failed to create Value Map: " + err.Error())
} else {
// execute template mapping
err = t.Execute(&tpl,m)
logger.Debug(tpl.String())
if err != nil {
logger.Error("Templating Failed: " + err.Error())
}
// unmarshal template into interface
err = json.Unmarshal([]byte(tpl.String()),&tplInterface)
if err != nil {
logger.Error("Couldn't Unmarshal deFinition to interface: " + err.Error())
}
}
}
return tplInterface,err
}
func b64encode(str string) string {
return base64.StdEncoding.EncodetoString([]byte(str))
}
有人知道如何解决这个问题吗?
解决方法
例如,
printf
不会对 {{ .NAMESPACE }}
进行模板扩展。相反,它扩展了 %s
和相关动词。这意味着
{"APPLICATION_HOST":"{{ printf "http://{{ .NAMESPACE }}-repo.{{ .NAMESPACE }}:3004"|b64encode }}"}
应该
{"APPLICATION_HOST":"{{ printf "http://%s-repo.%s:3004" .NAMESPACE .NAMESPACE |b64encode }}"}
但是正确的答案是使用正确的 JSON 封送处理,这样您就可以确定生成了有效的 JSON,并且任何不寻常的字符都被正确转义,等等。