Skip to content

Commit 29de8cd

Browse files
committed
add the ability to wrap CRDs in a conditional
1 parent 61603cb commit 29de8cd

File tree

5 files changed

+77
-11
lines changed

5 files changed

+77
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ testbin/*
2828

2929
dist/
3030

31+
vendor/

cmd/helmify/flags.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,18 @@ func ReadFlags() config.Config {
6161
flag.BoolVar(&result.Verbose, "v", false, "Enable verbose output (print WARN & INFO). Example: helmify -v")
6262
flag.BoolVar(&result.VeryVerbose, "vv", false, "Enable very verbose output. Same as verbose but with DEBUG. Example: helmify -vv")
6363
flag.BoolVar(&crd, "crd-dir", false, "Enable crd install into 'crds' directory.\nWarning: CRDs placed in 'crds' directory will not be templated by Helm.\nSee https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations\nExample: helmify -crd-dir")
64-
flag.BoolVar(&result.ImagePullSecrets, "image-pull-secrets", false, "Allows the user to use existing secrets as imagePullSecrets in values.yaml")
64+
flag.BoolVar(&result.ImagePullSecrets, "image-pull-secrets", false, "Allows the user to use existing secrets as imagePullSecrets in values.yaml.")
6565
flag.BoolVar(&result.GenerateDefaults, "generate-defaults", false, "Allows the user to add empty placeholders for typical customization options in values.yaml. Currently covers: topology constraints, node selectors, tolerances")
6666
flag.BoolVar(&result.CertManagerAsSubchart, "cert-manager-as-subchart", false, "Allows the user to add cert-manager as a subchart")
6767
flag.StringVar(&result.CertManagerVersion, "cert-manager-version", "v1.12.2", "Allows the user to specify cert-manager subchart version. Only useful with cert-manager-as-subchart.")
6868
flag.BoolVar(&result.CertManagerInstallCRD, "cert-manager-install-crd", true, "Allows the user to install cert-manager CRD. Only useful with cert-manager-as-subchart.")
6969
flag.BoolVar(&result.FilesRecursively, "r", false, "Scan dirs from -f option recursively")
7070
flag.BoolVar(&result.OriginalName, "original-name", false, "Use the object's original name instead of adding the chart's release name as the common prefix.")
71-
flag.Var(&files, "f", "File or directory containing k8s manifests")
72-
flag.BoolVar(&preservens, "preserve-ns", false, "Use the object's original namespace instead of adding all the resources to a common namespace")
73-
flag.BoolVar(&result.AddWebhookOption, "add-webhook-option", false, "Allows the user to add webhook option in values.yaml")
71+
flag.Var(&files, "f", "File or directory containing k8s manifests.")
72+
flag.BoolVar(&preservens, "preserve-ns", false, "Use the object's original namespace instead of adding all the resources to a common namespace.")
73+
flag.BoolVar(&result.AddWebhookOption, "add-webhook-option", false, "Allows the user to add webhook option in values.yaml.")
74+
flag.BoolVar(&result.WrapCRDs, "wrap-crds", false, "Allows the user to wrap CRDs in a conditional.")
75+
flag.StringVar(&result.WrapCRDsCondition, "wrap-crds-condition", "crds.enabled", "Allows the user to wrap CRDs in helm chart by specifying a condition name.")
7476

7577
flag.Parse()
7678
if h || help {

pkg/config/config.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ type Config struct {
4141
OriginalName bool
4242
// PreserveNs retains the namespaces on the Kubernetes manifests
4343
PreserveNs bool
44-
// AddWebhookOption enables the generation of a webhook option in values.yamlß
44+
// AddWebhookOption enables the generation of a webhook option in values.yaml
4545
AddWebhookOption bool
46+
// WrapCRDs wraps Custom Resource Definitions in a conditional
47+
WrapCRDs bool
48+
// WrapCRDsCondition is the condition used to wrap the Custom Resource Definitions
49+
WrapCRDsCondition string
4650
}
4751

4852
func (c *Config) Validate() error {

pkg/processor/crd/crd.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package crd
33
import (
44
"bytes"
55
"fmt"
6-
"github.com/sirupsen/logrus"
76
"io"
87
"strings"
98

9+
"github.com/sirupsen/logrus"
10+
1011
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1112
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1213
"k8s.io/apimachinery/pkg/runtime"
@@ -129,23 +130,35 @@ func (c crd) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured
129130
res := fmt.Sprintf(crdTeml, obj.GetName(), appMeta.ChartName(), annotations, labels, string(specYaml))
130131
res = strings.ReplaceAll(res, "\n\n", "\n")
131132

133+
values := helmify.Values{}
134+
135+
if appMeta.Config().WrapCRDs {
136+
137+
cond := appMeta.Config().WrapCRDsCondition
138+
res = fmt.Sprintf("{{- if .Values.%s }}\n%s\n{{- end }}", cond, res)
139+
_, _ = values.Add(true, strings.Split(appMeta.Config().WrapCRDsCondition, ".")...)
140+
logrus.WithField("crd", name).WithField("condition", cond).Info("wrapping CRDs in conditional")
141+
}
142+
132143
return true, &result{
133-
name: name + "-crd.yaml",
134-
data: []byte(res),
144+
name: name + "-crd.yaml",
145+
data: []byte(res),
146+
values: values,
135147
}, nil
136148
}
137149

138150
type result struct {
139-
name string
140-
data []byte
151+
name string
152+
data []byte
153+
values helmify.Values
141154
}
142155

143156
func (r *result) Filename() string {
144157
return r.name
145158
}
146159

147160
func (r *result) Values() helmify.Values {
148-
return helmify.Values{}
161+
return r.values
149162
}
150163

151164
func (r *result) Write(writer io.Writer) error {

pkg/processor/crd/crd_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package crd
22

33
import (
4+
"strings"
45
"testing"
56

7+
"github.com/arttor/helmify/pkg/config"
68
"github.com/arttor/helmify/pkg/metadata"
79

810
"github.com/arttor/helmify/internal"
@@ -45,4 +47,48 @@ func Test_crd_Process(t *testing.T) {
4547
assert.NoError(t, err)
4648
assert.Equal(t, false, processed)
4749
})
50+
51+
t.Run("wrapped with condition", func(t *testing.T) {
52+
obj := internal.GenerateObj(strCRD)
53+
54+
conditions := []string{"crds.create", "crds.enabled", "installCRDs"}
55+
56+
for _, cond := range conditions {
57+
t.Run(cond, func(t *testing.T) {
58+
meta := metadata.New(config.Config{WrapCRDs: true, WrapCRDsCondition: cond})
59+
processed, tmpl, err := testInstance.Process(meta, obj)
60+
assert.NoError(t, err)
61+
assert.True(t, processed)
62+
assert.NotNil(t, tmpl)
63+
64+
data := string(tmpl.(*result).data)
65+
66+
assert.Contains(t, data, "{{- if .Values."+cond+" }}", "template should start with conditional")
67+
assert.Contains(t, data, "{{- end }}", "template should end with conditional")
68+
69+
values := tmpl.(*result).values
70+
val, ok := getValue(values, cond)
71+
assert.True(t, ok, "expected key crds."+cond+" in values")
72+
assert.Equal(t, true, val)
73+
})
74+
}
75+
})
76+
}
77+
78+
func getValue(values map[string]any, path string) (any, bool) {
79+
parts := strings.Split(path, ".")
80+
current := any(values)
81+
82+
for _, part := range parts {
83+
m, ok := current.(map[string]any)
84+
if !ok {
85+
return nil, false
86+
}
87+
current, ok = m[part]
88+
if !ok {
89+
return nil, false
90+
}
91+
}
92+
93+
return current, true
4894
}

0 commit comments

Comments
 (0)