From 947c1b526379af715851d7442d151af6d4f761ef Mon Sep 17 00:00:00 2001 From: rebenkoy Date: Tue, 25 Jul 2023 16:43:23 +0300 Subject: [PATCH 1/3] parametrize webhook failurePolicy --- pkg/processor/webhook/mutating.go | 38 +++++++++++++++++++++++------ pkg/processor/webhook/validating.go | 36 +++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/pkg/processor/webhook/mutating.go b/pkg/processor/webhook/mutating.go index 77099008..c6b90ae9 100644 --- a/pkg/processor/webhook/mutating.go +++ b/pkg/processor/webhook/mutating.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/arttor/helmify/pkg/helmify" + "github.com/iancoleman/strcase" "github.com/pkg/errors" v1 "k8s.io/api/admissionregistration/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -47,15 +48,24 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured return false, nil, nil } name := appMeta.TrimName(obj.GetName()) + nameCamel := strcase.ToLowerCamel(name) whConf := v1.MutatingWebhookConfiguration{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &whConf) if err != nil { return true, nil, errors.Wrap(err, "unable to cast to MutatingWebhookConfiguration") } + + values := helmify.Values{} + unstructured.SetNestedMap(values, make(map[string]interface{}), nameCamel) + for i, whc := range whConf.Webhooks { - whc.ClientConfig.Service.Name = appMeta.TemplatedName(whc.ClientConfig.Service.Name) - whc.ClientConfig.Service.Namespace = strings.ReplaceAll(whc.ClientConfig.Service.Namespace, appMeta.Namespace(), `{{ .Release.Namespace }}`) + whcField := strcase.ToLowerCamel(whc.Name) + whcValues, err := ProcessMWH(appMeta, &whc, fmt.Sprintf(".Values.%s.%s", nameCamel, whcField)) + if err != nil { + return true, nil, errors.Wrap(err, fmt.Sprintf("unable to Process WebHook config: %s / %s", name, whc.Name)) + } + unstructured.SetNestedField(values, whcValues, nameCamel, whcField) whConf.Webhooks[i] = whc } webhooks, _ := yaml.Marshal(whConf.Webhooks) @@ -68,14 +78,28 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured certName = appMeta.TrimName(certName) res := fmt.Sprintf(mwhTempl, appMeta.ChartName(), name, certName, string(webhooks)) return true, &mwhResult{ - name: name, - data: []byte(res), + values: values, + name: name, + data: []byte(res), }, nil } +func ProcessMWH(appMeta helmify.AppMetadata, whc *v1.MutatingWebhook, valuesRoot string) (map[string]interface{}, error) { + values := make(map[string]interface{}) + failurePolicyField := "failurePolicy" + failurePolicy := v1.FailurePolicyType(fmt.Sprintf("{{ %s.%s }}", valuesRoot, failurePolicyField)) + values[failurePolicyField] = "Fail" + + whc.ClientConfig.Service.Name = appMeta.TemplatedName(whc.ClientConfig.Service.Name) + whc.ClientConfig.Service.Namespace = strings.ReplaceAll(whc.ClientConfig.Service.Namespace, appMeta.Namespace(), `{{ .Release.Namespace }}`) + whc.FailurePolicy = &failurePolicy + return values, nil +} + type mwhResult struct { - name string - data []byte + name string + data []byte + values helmify.Values } func (r *mwhResult) Filename() string { @@ -83,7 +107,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 f35a2281..26b7cf96 100644 --- a/pkg/processor/webhook/validating.go +++ b/pkg/processor/webhook/validating.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/arttor/helmify/pkg/helmify" + "github.com/iancoleman/strcase" "github.com/pkg/errors" v1 "k8s.io/api/admissionregistration/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -47,13 +48,24 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured return false, nil, nil } name := appMeta.TrimName(obj.GetName()) + nameCamel := strcase.ToLowerCamel(name) whConf := v1.ValidatingWebhookConfiguration{} err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &whConf) if err != nil { return true, nil, errors.Wrap(err, "unable to cast to ValidatingWebhookConfiguration") } + + values := helmify.Values{} + unstructured.SetNestedMap(values, make(map[string]interface{}), nameCamel) + for i, whc := range whConf.Webhooks { + whcField := strcase.ToLowerCamel(whc.Name) + whcValues, err := ProcessVWH(appMeta, &whc, fmt.Sprintf(".Values.%s.%s", nameCamel, whcField)) + if err != nil { + return true, nil, errors.Wrap(err, fmt.Sprintf("unable to Process WebHook config: %s / %s", name, whc.Name)) + } + unstructured.SetNestedField(values, whcValues, nameCamel, whcField) whc.ClientConfig.Service.Name = appMeta.TemplatedName(whc.ClientConfig.Service.Name) whc.ClientConfig.Service.Namespace = strings.ReplaceAll(whc.ClientConfig.Service.Namespace, appMeta.Namespace(), `{{ .Release.Namespace }}`) whConf.Webhooks[i] = whc @@ -68,14 +80,28 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured certName = appMeta.TrimName(certName) res := fmt.Sprintf(vwhTempl, appMeta.ChartName(), name, certName, string(webhooks)) return true, &vwhResult{ - name: name, - data: []byte(res), + values: values, + name: name, + data: []byte(res), }, nil } +func ProcessVWH(appMeta helmify.AppMetadata, whc *v1.ValidatingWebhook, valuesRoot string) (map[string]interface{}, error) { + values := make(map[string]interface{}) + failurePolicyField := "failurePolicy" + failurePolicy := v1.FailurePolicyType(fmt.Sprintf("{{ %s.%s }}", valuesRoot, failurePolicyField)) + values[failurePolicyField] = "Fail" + + whc.ClientConfig.Service.Name = appMeta.TemplatedName(whc.ClientConfig.Service.Name) + whc.ClientConfig.Service.Namespace = strings.ReplaceAll(whc.ClientConfig.Service.Namespace, appMeta.Namespace(), `{{ .Release.Namespace }}`) + whc.FailurePolicy = &failurePolicy + return values, nil +} + type vwhResult struct { - name string - data []byte + name string + data []byte + values helmify.Values } func (r *vwhResult) Filename() string { @@ -83,7 +109,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 { From 7f11fbf46bc72fff38f5269fec5fb4a7cd15013a Mon Sep 17 00:00:00 2001 From: rebenkoy Date: Mon, 31 Jul 2023 14:52:52 +0300 Subject: [PATCH 2/3] error handling for unstructired setNested* in MWH / VWH parametrisation --- pkg/processor/webhook/mutating.go | 10 ++++++++-- pkg/processor/webhook/validating.go | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pkg/processor/webhook/mutating.go b/pkg/processor/webhook/mutating.go index c6b90ae9..dbf8cf3b 100644 --- a/pkg/processor/webhook/mutating.go +++ b/pkg/processor/webhook/mutating.go @@ -57,7 +57,10 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } values := helmify.Values{} - unstructured.SetNestedMap(values, make(map[string]interface{}), nameCamel) + err = unstructured.SetNestedMap(values, make(map[string]interface{}), nameCamel) + if err != nil { + return true, nil, errors.Wrap(err, fmt.Sprintf("can not set webhook parameter map for %s", name)) + } for i, whc := range whConf.Webhooks { whcField := strcase.ToLowerCamel(whc.Name) @@ -65,7 +68,10 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured if err != nil { return true, nil, errors.Wrap(err, fmt.Sprintf("unable to Process WebHook config: %s / %s", name, whc.Name)) } - unstructured.SetNestedField(values, whcValues, nameCamel, whcField) + err = unstructured.SetNestedField(values, whcValues, nameCamel, whcField) + if err != nil { + return true, nil, errors.Wrap(err, fmt.Sprintf("can not set webhook parameters for %s / %s", name, whc.Name)) + } whConf.Webhooks[i] = whc } webhooks, _ := yaml.Marshal(whConf.Webhooks) diff --git a/pkg/processor/webhook/validating.go b/pkg/processor/webhook/validating.go index 26b7cf96..616f8826 100644 --- a/pkg/processor/webhook/validating.go +++ b/pkg/processor/webhook/validating.go @@ -57,7 +57,10 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured } values := helmify.Values{} - unstructured.SetNestedMap(values, make(map[string]interface{}), nameCamel) + err = unstructured.SetNestedMap(values, make(map[string]interface{}), nameCamel) + if err != nil { + return true, nil, errors.Wrap(err, fmt.Sprintf("can not set webhook parameter map for %s", name)) + } for i, whc := range whConf.Webhooks { whcField := strcase.ToLowerCamel(whc.Name) @@ -66,6 +69,9 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured return true, nil, errors.Wrap(err, fmt.Sprintf("unable to Process WebHook config: %s / %s", name, whc.Name)) } unstructured.SetNestedField(values, whcValues, nameCamel, whcField) + if err != nil { + return true, nil, errors.Wrap(err, fmt.Sprintf("can not set webhook parameters for %s / %s", name, whc.Name)) + } whc.ClientConfig.Service.Name = appMeta.TemplatedName(whc.ClientConfig.Service.Name) whc.ClientConfig.Service.Namespace = strings.ReplaceAll(whc.ClientConfig.Service.Namespace, appMeta.Namespace(), `{{ .Release.Namespace }}`) whConf.Webhooks[i] = whc From 6666ec4a3446cd2545b4b8019f5e7421d7d1b4a6 Mon Sep 17 00:00:00 2001 From: rebenkoy Date: Mon, 31 Jul 2023 15:45:13 +0300 Subject: [PATCH 3/3] follow up for 7f11fbf46bc72fff38f5269fec5fb4a7cd15013a --- pkg/processor/webhook/validating.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/processor/webhook/validating.go b/pkg/processor/webhook/validating.go index 616f8826..9c1ff263 100644 --- a/pkg/processor/webhook/validating.go +++ b/pkg/processor/webhook/validating.go @@ -68,7 +68,7 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured if err != nil { return true, nil, errors.Wrap(err, fmt.Sprintf("unable to Process WebHook config: %s / %s", name, whc.Name)) } - unstructured.SetNestedField(values, whcValues, nameCamel, whcField) + err = unstructured.SetNestedField(values, whcValues, nameCamel, whcField) if err != nil { return true, nil, errors.Wrap(err, fmt.Sprintf("can not set webhook parameters for %s / %s", name, whc.Name)) }