How to parse helm chart yaml file using python
Asked Answered
N

3

6

I am trying to parse a helm chart YAML file using python. The file contains some curly braces, that's why I am unable to parse the YAML file.

a sample YAML file

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.nginx.name }}-config-map
  labels:
    app: {{ .Values.nginx.name }}-config-map
data:
  SERVER_NAME: 12.121.112.12
  CLIENT_MAX_BODY: 500M
  READ_TIME_OUT: '500000'

Basically, I could not figure out how to ignore the values present at right side.

Negotiant answered 20/8, 2020 at 7:49 Comment(0)
J
4

You would have to write an implementation of Go's text/template library in Python. A better option is probably to push your content through helm template first and then parse it.

Johnnajohnnie answered 20/8, 2020 at 9:36 Comment(1)
Helm template docsUnsettle
N
0

I solved it by wrapping quotes wherever I use the template.

like this

apiVersion: v1
kind: ConfigMap
metadata:
    name: "{{ .Values.nginx.name }}-config-map"
    labels:
         app: "{{ .Values.nginx.name }}-config-map"
data:
    SERVER_NAME: 12.121.112.12
    CLIENT_MAX_BODY: 500M
    READ_TIME_OUT: '500000'

Helm can read this and I can parse this using python YAML as it's a valid YAML file.

Negotiant answered 1/2, 2021 at 7:27 Comment(1)
This isn't a perfect solution. It works fine so long as your templates don't contain quotes and your templates all resolve to strings. If you need your template to output a number, the quoting will make it a string and Kubernetes will complain (for example, replicas or port numbers).Schmid
O
0

If prerendering the helmfile is not an option then you have 2 options:

  1. Escape the curly brackets before parsing the chart, process it and then bring back the curly brackets like this:
    def escape_go_templates(content: str) -> str:
    return re.sub(r"\s{{(.*?)}}", r" __GO_TEMPLATE__\1__GO_TEMPLATE__", content)
    
    def unescape_go_templates(content: str) -> str:
    return re.sub(r"__GO_TEMPLATE__(.+?)__GO_TEMPLATE__", r"{{\1}}", content)
  1. Utilize ruamel.yaml and jinja2 templates

Construct your representer that will ignore the curly brackets when loading the yaml file:

represent_str(representer: SafeRepresenter, data: str | None) -> ScalarNode:
    if data and data.startswith("{{"):
        return representer.represent_scalar("tag:yaml.org,2002:str", data, style="-")

    return representer.represent_str(data)

init your yaml instance:

from ruamel.yaml import YAML

yaml = YAML(typ="jinja2")
yaml.width = 4096 # This is because lines in charts can get very long.
yaml.representer.add_representer(str, _represent_str)

this will allow to parse helm charts with python you can find more details in my blogpost

Octahedrite answered 28/9 at 9:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.