From bcac65f72e943ec3cd15de5ce036bc8d81be9ff1 Mon Sep 17 00:00:00 2001 From: Ye Cao Date: Mon, 17 Jul 2023 15:48:38 +0800 Subject: [PATCH] * Add an option for enable/disable webhook for a standard operator generated by kubebuilder. * Use regular expressions to match the containerPort of the webhook. Signed-off-by: Ye Cao --- README.md | 1 + cmd/helmify/flags.go | 1 + pkg/config/config.go | 2 ++ pkg/processor/deployment/deployment.go | 29 +++++++++++++++++++++++++- pkg/processor/service/service.go | 4 ++++ pkg/processor/webhook/cert.go | 23 ++++++++++++++------ pkg/processor/webhook/issuer.go | 15 ++++++++++--- pkg/processor/webhook/mutating.go | 17 +++++++++++---- pkg/processor/webhook/validating.go | 17 +++++++++++---- 9 files changed, 91 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 32c3cfd..f2ad50a 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Usage: | -image-pull-secrets | Allows the user to use existing secrets as imagePullSecrets | `helmify -image-pull-secrets` | | -cert-manager-as-subchart | Allows the user to install cert-manager as a subchart | `helmify -cert-manager-as-subchart` | | -cert-manager-version | Allows the user to specify cert-manager subchart version. Only useful with cert-manager-as-subchart. (default "v1.12.2") | `helmify -cert-manager-as-subchart` | +| -add-webhook-option | Adds an option to enable/disable webhook installation | `helmify -add-webhook-option`| ## Status Supported k8s resources: - Deployment, DaemonSet, StatefulSet diff --git a/cmd/helmify/flags.go b/cmd/helmify/flags.go index 4b410d2..fddb2f0 100644 --- a/cmd/helmify/flags.go +++ b/cmd/helmify/flags.go @@ -67,6 +67,7 @@ func ReadFlags() config.Config { 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.") flag.BoolVar(&result.FilesRecursively, "r", false, "Scan dirs from -f option recursively") flag.Var(&files, "f", "File or directory containing k8s manifests") + flag.BoolVar(&result.AddWebhookOption, "add-webhook-option", false, "Allows the user to add webhook option in values.yaml") flag.Parse() if h || help { diff --git a/pkg/config/config.go b/pkg/config/config.go index e7b57b5..1a9faa3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -34,6 +34,8 @@ type Config struct { Files []string // FilesRecursively read Files recursively FilesRecursively bool + // AddWebhookOption enables the generation of a webhook option in values.yamlß + AddWebhookOption bool } func (c *Config) Validate() error { diff --git a/pkg/processor/deployment/deployment.go b/pkg/processor/deployment/deployment.go index b538533..1d21b37 100644 --- a/pkg/processor/deployment/deployment.go +++ b/pkg/processor/deployment/deployment.go @@ -3,6 +3,7 @@ package deployment import ( "fmt" "io" + "regexp" "strings" "text/template" @@ -120,9 +121,11 @@ func (d deployment) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstr if err != nil { return true, nil, err } + if appMeta.Config().AddWebhookOption { + spec = addWebhookOption(spec) + } spec = strings.ReplaceAll(spec, "'", "") - return true, &result{ values: values, data: struct { @@ -143,6 +146,30 @@ func (d deployment) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstr }, nil } +func addWebhookOption(manifest string) string { + webhookOptionHeader := " {{- if .Values.webhook.enabled }}" + webhookOptionFooter := " {{- end }}" + volumes := ` - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert` + volumeMounts := ` - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true` + manifest = strings.ReplaceAll(manifest, volumes, fmt.Sprintf("%s\n%s\n%s", + webhookOptionHeader, volumes, webhookOptionFooter)) + manifest = strings.ReplaceAll(manifest, volumeMounts, fmt.Sprintf("%s\n%s\n%s", + webhookOptionHeader, volumeMounts, webhookOptionFooter)) + + re := regexp.MustCompile(` - containerPort: \d+ + name: webhook-server + protocol: TCP`) + + manifest = re.ReplaceAllString(manifest, fmt.Sprintf("%s\n%s\n%s", webhookOptionHeader, + re.FindString(manifest), webhookOptionFooter)) + return manifest +} + func processReplicas(name string, deployment *appsv1.Deployment, values *helmify.Values) (string, error) { if deployment.Spec.Replicas == nil { return "", nil diff --git a/pkg/processor/service/service.go b/pkg/processor/service/service.go index 72557f1..57edabc 100644 --- a/pkg/processor/service/service.go +++ b/pkg/processor/service/service.go @@ -95,8 +95,12 @@ func (r svc) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } ports[i] = pMap } + _ = unstructured.SetNestedSlice(values, ports, shortNameCamel, "ports") res := meta + fmt.Sprintf(svcTempSpec, shortNameCamel, selector, appMeta.ChartName()) + if shortNameCamel == "webhookService" && appMeta.Config().AddWebhookOption { + res = fmt.Sprintf("{{- if .Values.webhook.enabled }}\n%s\n{{- end }}", res) + } return true, &result{ name: shortName, data: res, diff --git a/pkg/processor/webhook/cert.go b/pkg/processor/webhook/cert.go index e067f59..76115ef 100644 --- a/pkg/processor/webhook/cert.go +++ b/pkg/processor/webhook/cert.go @@ -16,7 +16,9 @@ import ( ) const ( - certTempl = `apiVersion: cert-manager.io/v1 + WebhookHeader = `{{- if .Values.webhook.enabled }}` + WebhookFooter = `{{- end }}` + certTempl = `apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: {{ include "%[1]s.fullname" . }}-%[2]s @@ -93,16 +95,25 @@ func (c cert) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructure } else { tmpl = certTempl } + values := helmify.Values{} + if appMeta.Config().AddWebhookOption { + // Add webhook.enabled value to values.yaml + _, _ = values.Add(true, "webhook", "enabled") + + tmpl = fmt.Sprintf("%s\n%s\n%s", WebhookHeader, tmpl, WebhookFooter) + } res := fmt.Sprintf(tmpl, appMeta.ChartName(), name, string(spec)) return true, &certResult{ - name: name, - data: []byte(res), + name: name, + data: []byte(res), + values: values, }, nil } type certResult struct { - name string - data []byte + name string + data []byte + values helmify.Values } func (r *certResult) Filename() string { @@ -110,7 +121,7 @@ func (r *certResult) Filename() string { } func (r *certResult) Values() helmify.Values { - return helmify.Values{} + return r.values } func (r *certResult) Write(writer io.Writer) error { diff --git a/pkg/processor/webhook/issuer.go b/pkg/processor/webhook/issuer.go index 196c11e..6e5d5b6 100644 --- a/pkg/processor/webhook/issuer.go +++ b/pkg/processor/webhook/issuer.go @@ -53,6 +53,7 @@ func (i issuer) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructu return false, nil, nil } name := appMeta.TrimName(obj.GetName()) + spec, _ := yaml.Marshal(obj.Object["spec"]) spec = yamlformat.Indent(spec, 2) spec = bytes.TrimRight(spec, "\n ") @@ -62,6 +63,13 @@ func (i issuer) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructu } else { tmpl = issuerTempl } + values := helmify.Values{} + if appMeta.Config().AddWebhookOption { + // Add webhook.enabled value to values.yaml + _, _ = values.Add(true, "webhook", "enabled") + + tmpl = fmt.Sprintf("%s\n%s\n%s", WebhookHeader, tmpl, WebhookFooter) + } res := fmt.Sprintf(tmpl, appMeta.ChartName(), name, string(spec)) return true, &issResult{ name: name, @@ -70,8 +78,9 @@ func (i issuer) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructu } type issResult struct { - name string - data []byte + name string + data []byte + values helmify.Values } func (r *issResult) Filename() string { @@ -79,7 +88,7 @@ func (r *issResult) Filename() string { } func (r *issResult) Values() helmify.Values { - return helmify.Values{} + return r.values } func (r *issResult) Write(writer io.Writer) error { diff --git a/pkg/processor/webhook/mutating.go b/pkg/processor/webhook/mutating.go index 7709900..d06aa58 100644 --- a/pkg/processor/webhook/mutating.go +++ b/pkg/processor/webhook/mutating.go @@ -66,7 +66,15 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } certName = strings.TrimPrefix(certName, appMeta.Namespace()+"/") certName = appMeta.TrimName(certName) - res := fmt.Sprintf(mwhTempl, appMeta.ChartName(), name, certName, string(webhooks)) + tmpl := mwhTempl + values := helmify.Values{} + if appMeta.Config().AddWebhookOption { + // Add webhook.enabled value to values.yaml + _, _ = values.Add(true, "webhook", "enabled") + + tmpl = fmt.Sprintf("%s\n%s\n%s", WebhookHeader, mwhTempl, WebhookFooter) + } + res := fmt.Sprintf(tmpl, appMeta.ChartName(), name, certName, string(webhooks)) return true, &mwhResult{ name: name, data: []byte(res), @@ -74,8 +82,9 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } type mwhResult struct { - name string - data []byte + name string + data []byte + values helmify.Values } func (r *mwhResult) Filename() string { @@ -83,7 +92,7 @@ func (r *mwhResult) Filename() string { } func (r *mwhResult) Values() helmify.Values { - return helmify.Values{} + return r.values } func (r *mwhResult) Write(writer io.Writer) error { diff --git a/pkg/processor/webhook/validating.go b/pkg/processor/webhook/validating.go index f35a228..bd90627 100644 --- a/pkg/processor/webhook/validating.go +++ b/pkg/processor/webhook/validating.go @@ -66,7 +66,15 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } certName = strings.TrimPrefix(certName, appMeta.Namespace()+"/") certName = appMeta.TrimName(certName) - res := fmt.Sprintf(vwhTempl, appMeta.ChartName(), name, certName, string(webhooks)) + tmpl := vwhTempl + values := helmify.Values{} + if appMeta.Config().AddWebhookOption { + // Add webhook.enabled value to values.yaml + _, _ = values.Add(true, "webhook", "enabled") + + tmpl = fmt.Sprintf("%s\n%s\n%s", WebhookHeader, mwhTempl, WebhookFooter) + } + res := fmt.Sprintf(tmpl, appMeta.ChartName(), name, certName, string(webhooks)) return true, &vwhResult{ name: name, data: []byte(res), @@ -74,8 +82,9 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } type vwhResult struct { - name string - data []byte + name string + data []byte + values helmify.Values } func (r *vwhResult) Filename() string { @@ -83,7 +92,7 @@ func (r *vwhResult) Filename() string { } func (r *vwhResult) Values() helmify.Values { - return helmify.Values{} + return r.values } func (r *vwhResult) Write(writer io.Writer) error {