Home > Software design >  How do I parse external JSON file in a Helm _helpers.tpl
How do I parse external JSON file in a Helm _helpers.tpl

Time:03-03

I am writing a Helm _helpers.tpl file. This helper needs to

  1. read a JSON value from a file not in the yaml/values of the charts.
  2. Use variables in the charts/values/yaml to determine which field of the external JSON to read
  3. store the value extracted from the JSON into a local Go variable
  4. combine the values if the Go variable and the chart variables to output into a final value.

My external JSON file looks like this:

{
  "java": {
    "8": {
      "version": "0.1.8"
    },
    "11": {
      "version": "0.1.11"
    }
  },
  "node": {
    "14": {
      "version": "14.5.0"
    },
    "16": {
      "version": "16.4.0"
    }
  }
}

I have the following variables at my disposal in my values /Charts

  • .Values.type
  • .Values.typeVersion

my _helpers.tpl looks like this:

{{- $imageversions := (.Files.Get "../../../../common/versions.json" | toJson | jq ".".Values.type".".Values.typeVersion"."version) -}}
{{- printf "artifactory.myco.com/docker/%s/ubuntu20-slim-%s%s.0f:%s" .Values.type .Values.type .Values.typeVersion $imageversions }}

The first line of this code (above) is where I am needing help. Currently, I

  • use .Files.Get to extract the file contents
  • ensure it is interpretted as JSON by using toJson
  • try to read the specific field I am interested using jq
  • assign local variable $imageversions (far left) to the value found in the JSON

I think I have everything ok, except I don't have jq on this computer. How can I parse the JSON and get the value I need in this Helm Go template helper?

CodePudding user response:

Once you call .Files.Get to retrieve the file and then call fromJson to parse it, you can then use ordinary Helm templating syntax to navigate within it. You might find the standard index function helpful here: it takes an object and any number of subscripts, and does either map or array lookups on each subscript in turn.

{{-/* Get the contents of the file */-}}
{{- $versions := .Files.Get "common/versions.json" | fromJson -}}

{{-/* Extract the specific image tag from it */-}}
{{- $tag := index $versions .Values.type .Values.typeVersion "version" -}}

{{-/* Construct the complete image name */-}}
{{- printf "artifactory.myco.com/docker/%s/ubuntu20-slim-%s%s.0f:%s" .Values.type .Values.type .Values.typeVersion $tag }}

This may not fully solve your problem, though. In particular, .Files.Get can only retrieve files that are within the chart directory, but not templates. (The implementation actually preloads all of the non-template files into memory and just returns one of them when you call .Files.Get.)

A simpler approach may be to have your deployment system supply the complete image name, maybe passing the repository, name, and tag as separate Helm values. What you show here looks like you're trying to deploy a locally-built language runtime without a connected application, and it may also be a better approach to make the image string be the in the application image's Dockerfile FROM line.

  • Related