Skip to content

Commit

Permalink
provisioner: add json template function
Browse files Browse the repository at this point in the history
This change adds `json` function that enables use of
json-formatted strings in templates.

This could be used to define structured configuration values or
repeated chunks in templates that require modification of several values,
see provisiner/testdata/json.template.yaml for and example use.

Signed-off-by: Alexander Yastrebov <[email protected]>
  • Loading branch information
AlexanderYastrebov committed Oct 20, 2023
1 parent ed15c5c commit 48cb0d4
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
7 changes: 7 additions & 0 deletions provisioner/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/x509"
"encoding/base64"
"encoding/binary"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
Expand Down Expand Up @@ -113,6 +114,7 @@ func renderTemplate(context *templateContext, file string) (string, error) {
"azID": azID,
"azCount": azCount,
"split": split,
"json": parseJson,
"mountUnitName": mountUnitName,
"accountID": accountID,
"portRanges": portRanges,
Expand Down Expand Up @@ -294,6 +296,11 @@ func accountID(account string) (string, error) {
return items[1], nil
}

func parseJson(input string) (result interface{}, err error) {

Check failure on line 299 in provisioner/template.go

View workflow job for this annotation

GitHub Actions / tests

var-naming: func parseJson should be parseJSON (revive)

Check failure on line 299 in provisioner/template.go

View workflow job for this annotation

GitHub Actions / tests

var-naming: func parseJson should be parseJSON (revive)
err = json.Unmarshal([]byte(input), &result)
return
}

type HostPort struct {
Host string
Port string
Expand Down
49 changes: 49 additions & 0 deletions provisioner/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package provisioner

import (
"fmt"
"os"
"strconv"
"testing"

Expand Down Expand Up @@ -1164,3 +1165,51 @@ func TestNodePoolGroupsProfile(t *testing.T) {
})
}
}

func TestJson(t *testing.T) {
t.Run("object", func(t *testing.T) {
result, err := renderSingle(
t,
`{{ with json .Values.data }}name={{ .name }} value={{ .value }}{{end}}`,
`{"name": "foo", "value": "bar"}`)

require.NoError(t, err)
require.Equal(t, "name=foo value=bar", result)
})

t.Run("range over array", func(t *testing.T) {
result, err := renderSingle(
t,
`{{ range json .Values.data }}{{ .name }}={{ .value }} {{end}}`,
`[{"name": "foo", "value": "bar"}, {"name": "baz", "value": "qux"}]`)

require.NoError(t, err)
require.Equal(t, "foo=bar baz=qux ", result)
})

t.Run("range over object", func(t *testing.T) {
result, err := renderSingle(
t,
`{{ range $key, $value := json .Values.data }}{{ $key }}={{ $value }} {{end}}`,
`{"name": "foo", "value": "bar"}`)

require.NoError(t, err)
require.Equal(t, "name=foo value=bar ", result)
})

t.Run("example manifest", func(t *testing.T) {
template, err := os.ReadFile("testdata/json.template.yaml")
require.NoError(t, err)

expected, err := os.ReadFile("testdata/json.expected.yaml")
require.NoError(t, err)

result, err := renderSingle(
t,
string(template),
"")

require.NoError(t, err)
require.Equal(t, string(expected), result)
})
}
37 changes: 37 additions & 0 deletions provisioner/testdata/json.expected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "stable"
namespace: kube-system
labels:
application: app
version: "v1"
spec:

selector:
matchLabels:
deployment: "stable"
template: |
omitted for clarity
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "alpha"
namespace: kube-system
labels:
application: app
version: "v2"
spec:

replicas: 1

selector:
matchLabels:
deployment: "alpha"
template: |
omitted for clarity
23 changes: 23 additions & 0 deletions provisioner/testdata/json.template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{ range json `[
{"name": "stable", "version": "v1"},
{"name": "alpha", "version": "v2", "replicas": 1}
]` }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .name }}"
namespace: kube-system
labels:
application: app
version: "{{ .version }}"
spec:
{{ if index . "replicas" }}
replicas: {{ .replicas }}
{{ end }}
selector:
matchLabels:
deployment: "{{ .name }}"
template: |
omitted for clarity
{{ end }}

0 comments on commit 48cb0d4

Please sign in to comment.