Skip to content

Commit e5b3fa8

Browse files
allow name override on operator without changing name of resources (#433)
* allow name override on operator without changing name of resources * changelog * missing correction in values file * typo * new test * remove focus
1 parent a21bf82 commit e5b3fa8

File tree

11 files changed

+399
-11
lines changed

11 files changed

+399
-11
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
changelog:
2+
- type: NON_USER_FACING
3+
description: Allow name override on operator without changing name of resources.
4+
issueLink: https://github.com/solo-io/skv2/issues/432

codegen/cmd_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,94 @@ var _ = Describe("Cmd", func() {
243243
Expect(envMapField.HeadComment).To(Equal("# Environment variables for the container. For more info, see the [Kubernetes\n# documentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#envvarsource-v1-core)."))
244244
})
245245

246+
It("generates from templates using a name override", func() {
247+
cmd := &Command{
248+
Groups: []Group{
249+
{
250+
GroupVersion: schema.GroupVersion{
251+
Group: "things.test.io",
252+
Version: "v1",
253+
},
254+
Module: "github.com/solo-io/skv2",
255+
Resources: []Resource{
256+
{
257+
Kind: "Paint",
258+
Spec: Field{Type: Type{Name: "PaintSpec"}},
259+
Status: &Field{Type: Type{Name: "PaintStatus"}},
260+
},
261+
{
262+
Kind: "ClusterResource",
263+
Spec: Field{Type: Type{Name: "ClusterResourceSpec"}},
264+
ClusterScoped: true,
265+
},
266+
},
267+
RenderManifests: true,
268+
RenderTypes: true,
269+
RenderClients: true,
270+
RenderController: true,
271+
MockgenDirective: true,
272+
ApiRoot: "codegen/test/api",
273+
CustomTemplates: contrib.AllGroupCustomTemplates,
274+
},
275+
},
276+
AnyVendorConfig: skv2Imports,
277+
RenderProtos: true,
278+
279+
Chart: &Chart{
280+
Operators: []Operator{
281+
{
282+
Name: "painter-original-name",
283+
ValuesFileNameOverride: "override-name",
284+
Deployment: Deployment{
285+
Container: Container{
286+
Image: Image{
287+
Tag: "v0.0.0",
288+
Repository: "painter",
289+
Registry: "quay.io/solo-io",
290+
PullPolicy: "IfNotPresent",
291+
},
292+
Args: []string{"foo"},
293+
},
294+
},
295+
},
296+
},
297+
Values: nil,
298+
ValuesInlineDocs: &ValuesInlineDocs{
299+
LineLengthLimit: 80,
300+
},
301+
Data: Data{
302+
ApiVersion: "v1",
303+
Description: "",
304+
Name: "Painting Operator",
305+
Version: "v0.0.1",
306+
Home: "https://docs.solo.io/skv2/latest",
307+
Sources: []string{
308+
"https://github.com/solo-io/skv2",
309+
},
310+
},
311+
},
312+
313+
ManifestRoot: "codegen/test/name_override_chart",
314+
}
315+
316+
err := cmd.Execute()
317+
Expect(err).NotTo(HaveOccurred())
318+
319+
fileContents, err := os.ReadFile("codegen/test/name_override_chart/values.yaml")
320+
Expect(err).NotTo(HaveOccurred())
321+
valuesString := string(fileContents)
322+
323+
Expect(valuesString).NotTo(ContainSubstring("painterOriginalName"))
324+
Expect(valuesString).To(ContainSubstring("overrideName"))
325+
326+
fileContents, err = os.ReadFile("codegen/test/name_override_chart/templates/deployment.yaml")
327+
Expect(err).NotTo(HaveOccurred())
328+
deploymentString := string(fileContents)
329+
330+
Expect(deploymentString).NotTo(ContainSubstring("$.Values.painterOriginalName"))
331+
Expect(deploymentString).To(ContainSubstring("$.Values.overrideName"))
332+
})
333+
246334
It("generates json schema for the values file", func() {
247335
type CustomType1 struct {
248336
Field1 string `json:"customField1"`

codegen/model/chart.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ type JsonSchema struct {
6565
type Operator struct {
6666
Name string
6767

68+
// (Optional) To change the name referenced in the values file. If not specified a camelcase version of name is used
69+
ValuesFileNameOverride string
70+
6871
// (Optional) For nesting operators in values API (e.g. a value of "agent" would place an operator at "agent.<operatorName>" )
6972
ValuePath string
7073

@@ -175,8 +178,9 @@ func (c Chart) BuildChartValues() values.UserHelmValues {
175178
}
176179

177180
helmValues.Operators = append(helmValues.Operators, values.UserOperatorValues{
178-
Name: operator.Name,
179-
ValuePath: operator.ValuePath,
181+
Name: operator.Name,
182+
ValuesFileNameOverride: operator.ValuesFileNameOverride,
183+
ValuePath: operator.ValuePath,
180184
Values: values.UserValues{
181185
UserContainerValues: makeContainerDocs(operator.Deployment.Container),
182186
Sidecars: sidecars,

codegen/model/values/helm_chart_values.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ type UserHelmValues struct {
1616
}
1717

1818
type UserOperatorValues struct {
19-
Name string
20-
ValuePath string
21-
Values UserValues
22-
CustomValues interface{}
19+
Name string
20+
ValuesFileNameOverride string
21+
ValuePath string
22+
Values UserValues
23+
CustomValues interface{}
2324
}
2425

2526
type UserValuesInlineDocs struct {

codegen/render/funcs.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func makeTemplateFuncs(customFuncs template.FuncMap) template.FuncMap {
9494

9595
"get_operator_values": func(o values.UserOperatorValues) map[string]interface{} {
9696
opValues := map[string]interface{}{
97-
strcase.ToLowerCamel(o.Name): o.Values,
97+
opName(o.Name, o.ValuesFileNameOverride): o.Values,
9898
}
9999
if o.ValuePath != "" {
100100
splitPath := strings.Split(o.ValuePath, ".")
@@ -112,7 +112,7 @@ func makeTemplateFuncs(customFuncs template.FuncMap) template.FuncMap {
112112
opValues := map[string]interface{}{}
113113
if o.CustomValues != nil {
114114
opValues = map[string]interface{}{
115-
strcase.ToLowerCamel(o.Name): o.CustomValues,
115+
opName(o.Name, o.ValuesFileNameOverride): o.CustomValues,
116116
}
117117
if o.ValuePath != "" {
118118
splitPath := strings.Split(o.ValuePath, ".")
@@ -169,14 +169,22 @@ func containerConfigs(op model.Operator) []containerConfig {
169169
}
170170

171171
func opVar(op model.Operator) string {
172-
opVar := fmt.Sprintf("$.Values.%s", strcase.ToLowerCamel(op.Name))
172+
name := opName(op.Name, op.ValuesFileNameOverride)
173+
opVar := fmt.Sprintf("$.Values.%s", name)
173174
if op.ValuePath != "" {
174-
opVar = fmt.Sprintf("$.Values.%s.%s", op.ValuePath, strcase.ToLowerCamel(op.Name))
175-
175+
opVar = fmt.Sprintf("$.Values.%s.%s", op.ValuePath, name)
176176
}
177177
return opVar
178178
}
179179

180+
func opName(name, valuesFileNameOverride string) string {
181+
formattedName := strcase.ToLowerCamel(name)
182+
if valuesFileNameOverride != "" {
183+
formattedName = strcase.ToLowerCamel(valuesFileNameOverride)
184+
}
185+
return formattedName
186+
}
187+
180188
/*
181189
Find the proto messages for a given set of descriptors which need proto_deepcopoy funcs and whose types are not in
182190
the API root package
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Code generated by skv2. DO NOT EDIT.
2+
3+
apiVersion: v1
4+
home: https://docs.solo.io/skv2/latest
5+
name: Painting Operator
6+
sources:
7+
- https://github.com/solo-io/skv2
8+
version: v0.0.1
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Code generated by skv2. DO NOT EDIT.
2+
3+
apiVersion: apiextensions.k8s.io/v1
4+
kind: CustomResourceDefinition
5+
metadata:
6+
annotations:
7+
crd.solo.io/specHash: 80e7931efac2214e
8+
labels:
9+
app: ""
10+
app.kubernetes.io/name: ""
11+
name: paints.things.test.io
12+
spec:
13+
group: things.test.io
14+
names:
15+
kind: Paint
16+
listKind: PaintList
17+
plural: paints
18+
singular: paint
19+
scope: Namespaced
20+
versions:
21+
- name: v1
22+
schema:
23+
openAPIV3Schema:
24+
type: object
25+
x-kubernetes-preserve-unknown-fields: true
26+
served: true
27+
storage: true
28+
subresources:
29+
status: {}
30+
31+
---
32+
apiVersion: apiextensions.k8s.io/v1
33+
kind: CustomResourceDefinition
34+
metadata:
35+
annotations:
36+
crd.solo.io/specHash: 2c0000aa4677e683
37+
labels:
38+
app: ""
39+
app.kubernetes.io/name: ""
40+
name: clusterresources.things.test.io
41+
spec:
42+
group: things.test.io
43+
names:
44+
kind: ClusterResource
45+
listKind: ClusterResourceList
46+
plural: clusterresources
47+
singular: clusterresource
48+
scope: Cluster
49+
versions:
50+
- name: v1
51+
schema:
52+
openAPIV3Schema:
53+
type: object
54+
x-kubernetes-preserve-unknown-fields: true
55+
served: true
56+
storage: true
57+
subresources: {}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Code generated by skv2. DO NOT EDIT.
2+
3+
4+
5+
{{/* Below are library functions provided by skv2 */}}
6+
7+
{{- /*
8+
9+
"skv2.utils.merge" takes an array of three values:
10+
- the top context
11+
- the yaml block that will be merged in (override)
12+
- the name of the base template (source)
13+
14+
note: the source must be a named template (helm partial). This is necessary for the merging logic.
15+
16+
The behaviour is as follows, to align with already existing helm behaviour:
17+
- If no source is found (template is empty), the merged output will be empty
18+
- If no overrides are specified, the source is rendered as is
19+
- If overrides are specified and source is not empty, overrides will be merged in to the source.
20+
21+
Overrides can replace / add to deeply nested dictionaries, but will completely replace lists.
22+
Examples:
23+
24+
┌─────────────────────┬───────────────────────┬────────────────────────┐
25+
│ Source (template) │ Overrides │ Result │
26+
├─────────────────────┼───────────────────────┼────────────────────────┤
27+
│ metadata: │ metadata: │ metadata: │
28+
│ labels: │ labels: │ labels: │
29+
│ app: gloo │ app: gloo1 │ app: gloo1 │
30+
│ cluster: useast │ author: infra-team │ author: infra-team │
31+
│ │ │ cluster: useast │
32+
├─────────────────────┼───────────────────────┼────────────────────────┤
33+
│ lists: │ lists: │ lists: │
34+
│ groceries: │ groceries: │ groceries: │
35+
│ - apple │ - grapes │ - grapes │
36+
│ - banana │ │ │
37+
└─────────────────────┴───────────────────────┴────────────────────────┘
38+
39+
skv2.utils.merge is a fork of a helm library chart function (https://github.com/helm/charts/blob/master/incubator/common/templates/_util.tpl).
40+
This includes some optimizations to speed up chart rendering time, and merges in a value (overrides) with a named template, unlike the upstream
41+
version, which merges two named templates.
42+
43+
*/ -}}
44+
{{- define "skv2.utils.merge" -}}
45+
{{- $top := first . -}}
46+
{{- $overrides := (index . 1) -}}
47+
{{- $tpl := fromYaml (include (index . 2) $top) -}}
48+
{{- if or (empty $overrides) (empty $tpl) -}}
49+
{{ include (index . 2) $top }} {{/* render source as is */}}
50+
{{- else -}}
51+
{{- $merged := merge $overrides $tpl -}}
52+
{{- toYaml $merged -}} {{/* render source with overrides as YAML */}}
53+
{{- end -}}
54+
{{- end -}}

0 commit comments

Comments
 (0)