Skip to content

Commit

Permalink
allow name override on operator without changing name of resources (#433
Browse files Browse the repository at this point in the history
)

* allow name override on operator without changing name of resources

* changelog

* missing correction in values file

* typo

* new test

* remove focus
  • Loading branch information
josh-pritchard authored Mar 15, 2023
1 parent a21bf82 commit e5b3fa8
Show file tree
Hide file tree
Showing 11 changed files with 399 additions and 11 deletions.
4 changes: 4 additions & 0 deletions changelog/v0.29.1/operator-name-override.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
changelog:
- type: NON_USER_FACING
description: Allow name override on operator without changing name of resources.
issueLink: https://github.com/solo-io/skv2/issues/432
88 changes: 88 additions & 0 deletions codegen/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,94 @@ var _ = Describe("Cmd", func() {
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)."))
})

It("generates from templates using a name override", func() {
cmd := &Command{
Groups: []Group{
{
GroupVersion: schema.GroupVersion{
Group: "things.test.io",
Version: "v1",
},
Module: "github.com/solo-io/skv2",
Resources: []Resource{
{
Kind: "Paint",
Spec: Field{Type: Type{Name: "PaintSpec"}},
Status: &Field{Type: Type{Name: "PaintStatus"}},
},
{
Kind: "ClusterResource",
Spec: Field{Type: Type{Name: "ClusterResourceSpec"}},
ClusterScoped: true,
},
},
RenderManifests: true,
RenderTypes: true,
RenderClients: true,
RenderController: true,
MockgenDirective: true,
ApiRoot: "codegen/test/api",
CustomTemplates: contrib.AllGroupCustomTemplates,
},
},
AnyVendorConfig: skv2Imports,
RenderProtos: true,

Chart: &Chart{
Operators: []Operator{
{
Name: "painter-original-name",
ValuesFileNameOverride: "override-name",
Deployment: Deployment{
Container: Container{
Image: Image{
Tag: "v0.0.0",
Repository: "painter",
Registry: "quay.io/solo-io",
PullPolicy: "IfNotPresent",
},
Args: []string{"foo"},
},
},
},
},
Values: nil,
ValuesInlineDocs: &ValuesInlineDocs{
LineLengthLimit: 80,
},
Data: Data{
ApiVersion: "v1",
Description: "",
Name: "Painting Operator",
Version: "v0.0.1",
Home: "https://docs.solo.io/skv2/latest",
Sources: []string{
"https://github.com/solo-io/skv2",
},
},
},

ManifestRoot: "codegen/test/name_override_chart",
}

err := cmd.Execute()
Expect(err).NotTo(HaveOccurred())

fileContents, err := os.ReadFile("codegen/test/name_override_chart/values.yaml")
Expect(err).NotTo(HaveOccurred())
valuesString := string(fileContents)

Expect(valuesString).NotTo(ContainSubstring("painterOriginalName"))
Expect(valuesString).To(ContainSubstring("overrideName"))

fileContents, err = os.ReadFile("codegen/test/name_override_chart/templates/deployment.yaml")
Expect(err).NotTo(HaveOccurred())
deploymentString := string(fileContents)

Expect(deploymentString).NotTo(ContainSubstring("$.Values.painterOriginalName"))
Expect(deploymentString).To(ContainSubstring("$.Values.overrideName"))
})

It("generates json schema for the values file", func() {
type CustomType1 struct {
Field1 string `json:"customField1"`
Expand Down
8 changes: 6 additions & 2 deletions codegen/model/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ type JsonSchema struct {
type Operator struct {
Name string

// (Optional) To change the name referenced in the values file. If not specified a camelcase version of name is used
ValuesFileNameOverride string

// (Optional) For nesting operators in values API (e.g. a value of "agent" would place an operator at "agent.<operatorName>" )
ValuePath string

Expand Down Expand Up @@ -175,8 +178,9 @@ func (c Chart) BuildChartValues() values.UserHelmValues {
}

helmValues.Operators = append(helmValues.Operators, values.UserOperatorValues{
Name: operator.Name,
ValuePath: operator.ValuePath,
Name: operator.Name,
ValuesFileNameOverride: operator.ValuesFileNameOverride,
ValuePath: operator.ValuePath,
Values: values.UserValues{
UserContainerValues: makeContainerDocs(operator.Deployment.Container),
Sidecars: sidecars,
Expand Down
9 changes: 5 additions & 4 deletions codegen/model/values/helm_chart_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ type UserHelmValues struct {
}

type UserOperatorValues struct {
Name string
ValuePath string
Values UserValues
CustomValues interface{}
Name string
ValuesFileNameOverride string
ValuePath string
Values UserValues
CustomValues interface{}
}

type UserValuesInlineDocs struct {
Expand Down
18 changes: 13 additions & 5 deletions codegen/render/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func makeTemplateFuncs(customFuncs template.FuncMap) template.FuncMap {

"get_operator_values": func(o values.UserOperatorValues) map[string]interface{} {
opValues := map[string]interface{}{
strcase.ToLowerCamel(o.Name): o.Values,
opName(o.Name, o.ValuesFileNameOverride): o.Values,
}
if o.ValuePath != "" {
splitPath := strings.Split(o.ValuePath, ".")
Expand All @@ -112,7 +112,7 @@ func makeTemplateFuncs(customFuncs template.FuncMap) template.FuncMap {
opValues := map[string]interface{}{}
if o.CustomValues != nil {
opValues = map[string]interface{}{
strcase.ToLowerCamel(o.Name): o.CustomValues,
opName(o.Name, o.ValuesFileNameOverride): o.CustomValues,
}
if o.ValuePath != "" {
splitPath := strings.Split(o.ValuePath, ".")
Expand Down Expand Up @@ -169,14 +169,22 @@ func containerConfigs(op model.Operator) []containerConfig {
}

func opVar(op model.Operator) string {
opVar := fmt.Sprintf("$.Values.%s", strcase.ToLowerCamel(op.Name))
name := opName(op.Name, op.ValuesFileNameOverride)
opVar := fmt.Sprintf("$.Values.%s", name)
if op.ValuePath != "" {
opVar = fmt.Sprintf("$.Values.%s.%s", op.ValuePath, strcase.ToLowerCamel(op.Name))

opVar = fmt.Sprintf("$.Values.%s.%s", op.ValuePath, name)
}
return opVar
}

func opName(name, valuesFileNameOverride string) string {
formattedName := strcase.ToLowerCamel(name)
if valuesFileNameOverride != "" {
formattedName = strcase.ToLowerCamel(valuesFileNameOverride)
}
return formattedName
}

/*
Find the proto messages for a given set of descriptors which need proto_deepcopoy funcs and whose types are not in
the API root package
Expand Down
8 changes: 8 additions & 0 deletions codegen/test/name_override_chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Code generated by skv2. DO NOT EDIT.

apiVersion: v1
home: https://docs.solo.io/skv2/latest
name: Painting Operator
sources:
- https://github.com/solo-io/skv2
version: v0.0.1
57 changes: 57 additions & 0 deletions codegen/test/name_override_chart/crds/things.test.io_v1_crds.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Code generated by skv2. DO NOT EDIT.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
crd.solo.io/specHash: 80e7931efac2214e
labels:
app: ""
app.kubernetes.io/name: ""
name: paints.things.test.io
spec:
group: things.test.io
names:
kind: Paint
listKind: PaintList
plural: paints
singular: paint
scope: Namespaced
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources:
status: {}

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
crd.solo.io/specHash: 2c0000aa4677e683
labels:
app: ""
app.kubernetes.io/name: ""
name: clusterresources.things.test.io
spec:
group: things.test.io
names:
kind: ClusterResource
listKind: ClusterResourceList
plural: clusterresources
singular: clusterresource
scope: Cluster
versions:
- name: v1
schema:
openAPIV3Schema:
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources: {}
54 changes: 54 additions & 0 deletions codegen/test/name_override_chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Code generated by skv2. DO NOT EDIT.



{{/* Below are library functions provided by skv2 */}}

{{- /*
"skv2.utils.merge" takes an array of three values:
- the top context
- the yaml block that will be merged in (override)
- the name of the base template (source)
note: the source must be a named template (helm partial). This is necessary for the merging logic.
The behaviour is as follows, to align with already existing helm behaviour:
- If no source is found (template is empty), the merged output will be empty
- If no overrides are specified, the source is rendered as is
- If overrides are specified and source is not empty, overrides will be merged in to the source.
Overrides can replace / add to deeply nested dictionaries, but will completely replace lists.
Examples:
┌─────────────────────┬───────────────────────┬────────────────────────┐
│ Source (template) │ Overrides │ Result │
├─────────────────────┼───────────────────────┼────────────────────────┤
│ metadata: │ metadata: │ metadata: │
│ labels: │ labels: │ labels: │
│ app: gloo │ app: gloo1 │ app: gloo1 │
│ cluster: useast │ author: infra-team │ author: infra-team │
│ │ │ cluster: useast │
├─────────────────────┼───────────────────────┼────────────────────────┤
│ lists: │ lists: │ lists: │
│ groceries: │ groceries: │ groceries: │
│ - apple │ - grapes │ - grapes │
│ - banana │ │ │
└─────────────────────┴───────────────────────┴────────────────────────┘
skv2.utils.merge is a fork of a helm library chart function (https://github.com/helm/charts/blob/master/incubator/common/templates/_util.tpl).
This includes some optimizations to speed up chart rendering time, and merges in a value (overrides) with a named template, unlike the upstream
version, which merges two named templates.
*/ -}}
{{- define "skv2.utils.merge" -}}
{{- $top := first . -}}
{{- $overrides := (index . 1) -}}
{{- $tpl := fromYaml (include (index . 2) $top) -}}
{{- if or (empty $overrides) (empty $tpl) -}}
{{ include (index . 2) $top }} {{/* render source as is */}}
{{- else -}}
{{- $merged := merge $overrides $tpl -}}
{{- toYaml $merged -}} {{/* render source with overrides as YAML */}}
{{- end -}}
{{- end -}}
Loading

0 comments on commit e5b3fa8

Please sign in to comment.