假设我有一大组 Helm 图表,我想编辑每个图表的
deployment.yaml
目录中的每个 templates
文件,手动执行此操作是一项繁琐的任务。
我尝试使用Python的
pyyaml
和benedict
来做这样的事情:
content = read_file() # reads the deployment.yaml file
deployment = yaml.unsafe_load(content)
deployment = benedict(deployment)
但我明白了:
yaml.parser.ParserError: while parsing a flow node
expected the node content, but found '-'
in "<unicode string>", line 3, column 4:
{{- include "something.labels" ...
我认为由于 Helm 模板
deployment.yaml
不是有效的 YAML,因此 pyyaml 无法解码它。
有人知道另一种方法吗?
Helm 模板只是 Go 模板。文字方面的工作。理论上,你可以将它们解析成代表 Go 模板语法的语法树,但这不是你想要的。
只有经过模板处理后,输入才会成为有效的 YAML 结构。因此,您通常无法使代码同时理解 Go 模板和生成的 YAML 的结构,您需要能够以结构感知的方式修改原始文件。
给我一个研究团队和五年时间,我也许能做到……
由于实际上不可能从结构上做到这一点,所以只需做每个人都会做的事情并使用
sed
调用。
你可以使用jinja2,一个简单的例子是:
模板/deployment.yaml.j2
apiVersion: {{ spec.api_version }}
kind: Deployment
metadata:
{% for m in spec.metadata %}
{{ m | indent(2, true) }}
{% endfor %}
spec:
containers:
- image: {{ spec.image }}
脚本.py
from jinja2 import Environment, FileSystemLoader
spec = {
"image": "nginx:1.23.2",
"apiVersion": "apps/v1",
"metadata": ["name: nginx"]
}
def get_template(__file):
j2 = Environment(loader=FileSystemLoader(searchPath="templates")).get_template(__file)
return template = j2.render(spec=spec)
def generate_template(__target_file, template):
with open(__target_file, "w") as f:
f.write(template)
# could loop through multiple deployment.yaml.j2 files
template = get_template("deployment.yaml.j2")
generate_template("my_chart/templates/deployment.yaml", template)
这里的权衡是,您将拥有一组 jinja/python 将操作的模板,然后为您的图表生成静态模板。
也许有更好的选择,但我决定分享我对类似事情采取的方法。当然,这个示例非常简单,只需使用值文件就可以更好地解决,但想法是您可以从那里扩展它并根据您认为合适的方式对文件进行模板化。