Skip to content

Commit

Permalink
Access param values directly
Browse files Browse the repository at this point in the history
[#103]

Co-authored-by: Sam Coward <scoward@vmware.com>
  • Loading branch information
emmjohnson and idoru committed Sep 20, 2021
1 parent e1ba79c commit dae9438
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 104 deletions.
27 changes: 11 additions & 16 deletions pkg/templates/interpolator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,13 @@ var _ = Describe("Interpolator", func() {
}

tagInterpolator.Context = struct {
Params []templates.Param `json:"params"`
Generic GenericType `json:"generic"`
Params templates.Params `json:"params"`
Generic GenericType `json:"generic"`
}{
Params: []templates.Param{
{
Name: "an amazing param",
Value: apiextensionsv1.JSON{Raw: []byte(`"exactly what you want"`)},
},
{
Name: "another_param",
Value: apiextensionsv1.JSON{Raw: []byte(`"everything you need"`)},
},

Params: templates.Params{
"an-amazing-param": apiextensionsv1.JSON{Raw: []byte(`"exactly what you want"`)},
"another_param": apiextensionsv1.JSON{Raw: []byte(`"everything you need"`)},
},
Generic: GenericType{
Name: "generic-name",
Expand Down Expand Up @@ -233,7 +228,7 @@ var _ = Describe("Interpolator", func() {

Context("given a template referencing a missing list element", func() {
BeforeEach(func() {
template = []byte("in an empty input, you won't find $(params[0].value)$")
template = []byte("in an empty input, you won't find $(params[0])$")
})

It("Returns an error that it cannot evaluate the path", func() {
Expand All @@ -245,7 +240,7 @@ var _ = Describe("Interpolator", func() {

Context("given a template referencing a list element by index", func() {
BeforeEach(func() {
template = []byte("with the populated input, you can find $(params[1].value)$")
template = []byte("with the populated input, you can find $(params.another_param)$")
})

It("returns the proper string", func() {
Expand All @@ -260,7 +255,7 @@ var _ = Describe("Interpolator", func() {

Context("given a template referencing a list element by attribute", func() {
BeforeEach(func() {
template = []byte(`with the populated input, you can find $(params[?(@.name=="an amazing param")].value)$`)
template = []byte(`with the populated input, you can find $(params['an-amazing-param'])$`)
})

It("returns the proper string", func() {
Expand All @@ -275,13 +270,13 @@ var _ = Describe("Interpolator", func() {

Context("given a template referencing a list element by attribute but an unknown key", func() {
BeforeEach(func() {
template = []byte(`with the populated input, you can find $(params[?(@.name=="an amazing param")].notknown)$`)
template = []byte(`with the populated input, you can find $(params['notknown])$`)
})

It("Returns an error that it cannot find the value notknown", func() {
_, err := templates.InterpolateLeafNode(fasttemplate.ExecuteFuncStringWithErr, template, tagInterpolator)
Expect(err).To(BeMeaningful("interpolate tag: "))
Expect(err).To(BeMeaningful("evaluate jsonpath: evaluate: find results: notknown is not found"))
Expect(err).To(BeMeaningful("evaluate jsonpath: evaluate: jsonpath parse path '{.params['notknown]}': invalid array index 'notknown"))
})
})
})
Expand Down
17 changes: 3 additions & 14 deletions pkg/templates/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,18 @@ import (
"github.com/vmware-tanzu/cartographer/pkg/apis/v1alpha1"
)

type Param struct {
Name string `json:"name"`
Value apiextensionsv1.JSON `json:"value"`
}

type Params map[string]Param
type Params map[string]apiextensionsv1.JSON

func ParamsBuilder(defaultParams v1alpha1.DefaultParams, componentParams []v1alpha1.SupplyChainParam) Params {
newParams := Params{}
for _, param := range defaultParams {
newParams[param.Name] = Param{
Name: param.Name,
Value: param.DefaultValue,
}
newParams[param.Name] = param.DefaultValue
}

for key := range newParams {
for _, override := range componentParams {
if key == override.Name {
newParams[key] = Param{
Name: key,
Value: override.Value,
}
newParams[key] = override.Value
}
}
}
Expand Down
6 changes: 2 additions & 4 deletions pkg/templates/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,8 @@ var _ = Describe("OverrideDefaultParams", func() {
params := templates.ParamsBuilder(defaultParams, componentParams)

Expect(params).To(HaveLen(2))
Expect(params["foo"].Name).To(Equal("foo"))
Expect(params["foo"].Value.Raw).To(Equal([]byte("bar")))
Expect(params["fizz"].Name).To(Equal("fizz"))
Expect(params["fizz"].Value.Raw).To(Equal([]byte("buzz")))
Expect(params["foo"].Raw).To(Equal([]byte("bar")))
Expect(params["fizz"].Raw).To(Equal([]byte("buzz")))
})
})
})
72 changes: 28 additions & 44 deletions pkg/templates/stamper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import (
"context"
"os"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gstruct"
v1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -130,28 +131,16 @@ var _ = Describe("Stamper", func() {
}
params := templates.Params{
"sub": {
Name: "sub",
Value: apiextensionsv1.JSON{
Raw: []byte(subJSON),
},
Raw: []byte(subJSON),
},
"extra-for-nested": {
Name: "extra-for-nested",
Value: apiextensionsv1.JSON{
Raw: []byte(`"nested"`),
},
Raw: []byte(`"nested"`),
},
"infinite-recurse": {
Name: "infinite-recurse",
Value: apiextensionsv1.JSON{
Raw: []byte(`"$(params.sub.value)$"`),
},
Raw: []byte(`"$(params.sub)$"`),
},
"bigger-infinite-recurse": {
Name: "bigger-infinite-recurse",
Value: apiextensionsv1.JSON{
Raw: []byte(`"$(params.infinite-recurse.value)$"`),
},
Raw: []byte(`"$(params.infinite-recurse)$"`),
},
}

Expand Down Expand Up @@ -184,49 +173,49 @@ var _ = Describe("Stamper", func() {
`$($()$`, `"some-value"`, "", "unrecognized character in action"),

Entry(`Single tag, string value and type preserved`,
`$(params.sub.value)$`, `"5"`, "5", ""),
`$(params.sub)$`, `"5"`, "5", ""),

Entry(`Single tag, string value with nested tag`,
`$(params.sub.value)$`, `"$(params.extra-for-nested.value)$"`, "nested", ""),
`$(params.sub)$`, `"$(params.extra-for-nested)$"`, "nested", ""),

Entry(`Single tag, number value and type preserved`,
`$(params.sub.value)$`, `5`, float64(5), ""),
`$(params.sub)$`, `5`, float64(5), ""),

Entry(`Single tag, map value and type preserved, nested tags evaluated`,
`$(params.sub.value)$`, `{"foo": "$(params.extra-for-nested.value)$"}`, map[string]interface{}{"foo": "nested"}, ""),
`$(params.sub)$`, `{"foo": "$(params.extra-for-nested)$"}`, map[string]interface{}{"foo": "nested"}, ""),

Entry(`Single tag, array value and type preserved, nested tags evaluated`,
`$(params.sub.value)$`, `["foo", "$(params['extra-for-nested'].value)$"]`, []interface{}{"foo", "nested"}, ""),
`$(params.sub)$`, `["foo", "$(params['extra-for-nested'])$"]`, []interface{}{"foo", "nested"}, ""),

Entry(`Multiple tags, result becomes a string`,
`$(params.sub.value)$$(params.sub.value)$`, `5`, "55", ""),
`$(params.sub)$$(params.sub)$`, `5`, "55", ""),

Entry(`Adjacent non-tag (letter), result becomes a string`,
`b$(params.sub.value)$`, `5`, "b5", ""),
`b$(params.sub)$`, `5`, "b5", ""),

Entry(`Adjacent non-tag (number), result still becomes a string`,
`5$(params.sub.value)$`, `5`, "55", ""),
`5$(params.sub)$`, `5`, "55", ""),

Entry(`Adjacent non-tag, string value with nested tag`,
`HI:$(params.sub.value)$`, `"$(params.extra-for-nested.value)$"`, "HI:nested", ""),
`HI:$(params.sub)$`, `"$(params.extra-for-nested)$"`, "HI:nested", ""),

Entry(`Looks like an array, but result must be preserved as string`,
`[$(params.sub.value)$]`, `5`, "[5]", ""),
`[$(params.sub)$]`, `5`, "[5]", ""),

Entry(`Looks like a map, but result must be preserved as string`,
`{\"foo\": $(params.sub.value)$}`, `5`, `{"foo": 5}`, ""),
`{\"foo\": $(params.sub)$}`, `5`, `{"foo": 5}`, ""),

Entry(`Infinite recursion should error`,
`$(params.sub.value)$`, `"$(params.infinite-recurse.value)$"`, nil, "infinite tag loop detected: $(params.sub.value)$ -> $(params.infinite-recurse.value)$ -> $(params.sub.value)$"),
`$(params.sub)$`, `"$(params.infinite-recurse)$"`, nil, "infinite tag loop detected: $(params.sub)$ -> $(params.infinite-recurse)$ -> $(params.sub)$"),

Entry(`Infinite recursion should error`,
`$(params.sub.value)$`, `"$(params.bigger-infinite-recurse.value)$"`, nil, "infinite tag loop detected: $(params.sub.value)$ -> $(params.bigger-infinite-recurse.value)$ -> $(params.infinite-recurse.value)$ -> $(params.sub.value)$"),
`$(params.sub)$`, `"$(params.bigger-infinite-recurse)$"`, nil, "infinite tag loop detected: $(params.sub)$ -> $(params.bigger-infinite-recurse)$ -> $(params.infinite-recurse)$ -> $(params.sub)$"),

Entry(`Infinite recursion with a map should error`,
`$(params.sub.value)$`, `{"foo": "$(params.infinite-recurse.value)$"}`, nil, "infinite tag loop detected: $(params.sub.value)$ -> $(params.infinite-recurse.value)$ -> $(params.sub.value)$"),
`$(params.sub)$`, `{"foo": "$(params.infinite-recurse)$"}`, nil, "infinite tag loop detected: $(params.sub)$ -> $(params.infinite-recurse)$ -> $(params.sub)$"),

Entry(`Infinite recursion with an array should error`,
`$(params.sub.value)$`, `["foo", "$(params.infinite-recurse.value)$"]`, nil, "infinite tag loop detected: $(params.sub.value)$ -> $(params.infinite-recurse.value)$ -> $(params.sub.value)$"),
`$(params.sub)$`, `["foo", "$(params.infinite-recurse)$"]`, nil, "infinite tag loop detected: $(params.sub)$ -> $(params.infinite-recurse)$ -> $(params.sub)$"),
)

DescribeTable("tag evaluation of ytt template",
Expand All @@ -242,12 +231,7 @@ key: ` + tmpl + `
`,
}
params := templates.Params{
{
Name: "sub",
Value: apiextensionsv1.JSON{
Raw: []byte(subJSON),
},
},
"sub": apiextensionsv1.JSON{Raw: []byte(subJSON)},
}

owner := &v1.ConfigMap{}
Expand Down Expand Up @@ -283,18 +267,18 @@ key: ` + tmpl + `
},

Entry(`String value and type preserved`,
`#@ data.values.params[0].value`, `"5"`, "5", "", ""),
`#@ data.values.params.sub`, `"5"`, "5", "", ""),
Entry(`Number value and type preserved`,
`#@ data.values.params[0].value`, `5`, int64(5), "", ""),
`#@ data.values.params.sub`, `5`, int64(5), "", ""),
Entry(`Map value and type preserved`,
`#@ data.values.params[0].value`, `{"foo": "bar"}`, map[string]interface{}{"foo": "bar"}, "", ""),
`#@ data.values.params.sub`, `{"foo": "bar"}`, map[string]interface{}{"foo": "bar"}, "", ""),

Entry(`Invalid template`,
"#@ data.values.invalid.value", `""`, nil, "", "unable to apply ytt template:"),
"#@ data.values.invalid", `""`, nil, "", "unable to apply ytt template:"),
Entry(`Invalid context`,
"#@ data.values.params[0].value", `"`, nil, "", "unable to marshal template context:"),
"#@ data.values.params['sub']", `"`, nil, "", "unable to marshal template context:"),
Entry(`Invalid ytt`,
"#@ data.values.params[0].value", `""`, nil, "/not/a/path/to/ytt", "unable to apply ytt template: fork/exec"),
"#@ data.values.params['sub']", `""`, nil, "/not/a/path/to/ytt", "unable to apply ytt template: fork/exec"),
)
})
})
15 changes: 14 additions & 1 deletion site/content/docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ spec:
# $(sources.<name>.url)$
# $(sources.<name>.revision)$
#
# if there is only one source, it can be consumed as:
#
# $(source.url)$
# $(sources.revision)$
#
# (optional)
sources:
# name of the component to provide the source information. (required)
Expand All @@ -185,6 +190,10 @@ spec:
#
# $(images.<name>.image)
#
# if there is only one image, it can be consumed as:
#
# $(image)
#
images: []

# (optional) set of components that provide kubernetes configuration,
Expand All @@ -193,13 +202,17 @@ spec:
#
# $(configs.<name>.config)
#
# if there is only one config, it can be consumed as:
#
# $(config)
#
configs: []

# parameters to override the defaults from the templates.
# (optional)
# in a template, these can be consumed as:
#
# $(params.<name>.value)
# $(params.<name>)
#
params:
# name of the parameter. (required, unique in this list, and must match
Expand Down
10 changes: 5 additions & 5 deletions tests/kuttl/default-params/00-proper-templates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ spec:
metadata:
name: test-deliverable-source
value:
cat-lives: $(params.number-of-cat-lives.value)$
critters: $(params.broodx-cicadas-per-acre.value)$
cat-lives: $(params.number-of-cat-lives)$
critters: $(params.broodx-cicadas-per-acre)$

---

Expand All @@ -50,7 +50,7 @@ spec:
metadata:
name: test-deliverable-image
value:
hammer: $(params.every-problem.value)$
hammer: $(params.every-problem)$

---

Expand All @@ -71,7 +71,7 @@ spec:
metadata:
name: test-deliverable-config
value:
start_and_end: $(params.bookends.value)$
start_and_end: $(params.bookends)$

---

Expand All @@ -91,4 +91,4 @@ spec:
metadata:
name: test-deliverable
value:
mythic_creatures: $(params.tricksters.value)$
mythic_creatures: $(params.tricksters)$
10 changes: 5 additions & 5 deletions tests/kuttl/default-params/02-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ spec:
metadata:
name: test-deliverable-source
value:
cat-lives: $(params.number-of-cat-lives.value)$
critters: $(params.broodx-cicadas-per-acre.value)$
cat-lives: $(params.number-of-cat-lives)$
critters: $(params.broodx-cicadas-per-acre)$

---

Expand All @@ -115,7 +115,7 @@ spec:
metadata:
name: test-deliverable-image
value:
hammer: $(params.every-problem.value)$
hammer: $(params.every-problem)$

---

Expand All @@ -136,7 +136,7 @@ spec:
metadata:
name: test-deliverable-config
value:
start_and_end: $(params.bookends.value)$
start_and_end: $(params.bookends)$

---

Expand All @@ -156,4 +156,4 @@ spec:
metadata:
name: test-deliverable
value:
mythic_creatures: $(params.tricksters.value)$
mythic_creatures: $(params.tricksters)$
Loading

0 comments on commit dae9438

Please sign in to comment.