Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ webhooks:
path: /mutate-ceph-example-com-v1-mycluster
failurePolicy: Fail
name: mmycluster.kb.io
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- namespace-1
- '{{ .Release.Namespace }}'
- namespace-3
rules:
- apiGroups:
- test.example.com
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ webhooks:
path: /validate-ceph-example-com-v1alpha1-volume
failurePolicy: Fail
name: vvolume.kb.io
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- namespace-1
- '{{ .Release.Namespace }}'
- namespace-3
rules:
- apiGroups:
- test.example.com
Expand Down
25 changes: 25 additions & 0 deletions pkg/processor/webhook/mutating.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/arttor/helmify/pkg/helmify"
v1 "k8s.io/api/admissionregistration/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand Down Expand Up @@ -55,6 +56,7 @@ func (w mwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured
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 }}`)
mutateNamespaceSelector(appMeta, whc.NamespaceSelector)
whConf.Webhooks[i] = whc
}
webhooks, _ := yaml.Marshal(whConf.Webhooks)
Expand Down Expand Up @@ -98,3 +100,26 @@ func (r *mwhResult) Write(writer io.Writer) error {
_, err := writer.Write(r.data)
return err
}

const (
nameLabel = "kubernetes.io/metadata.name"
namespaceTemplate = "{{ .Release.Namespace }}"
)

// Replace the relase namespace in a namespace selector
func mutateNamespaceSelector(appMeta helmify.AppMetadata, sel *metav1.LabelSelector) {
if appMeta.Config().PreserveNs || sel == nil {
return
}
origNamespace := appMeta.Namespace()
for i, me := range sel.MatchExpressions {
if me.Key == nameLabel {
for vi, v := range me.Values {
if v == origNamespace {
me.Values[vi] = namespaceTemplate
}
}
sel.MatchExpressions[i] = me
}
}
}
23 changes: 22 additions & 1 deletion pkg/processor/webhook/mutating_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package webhook
import (
"testing"

"github.com/arttor/helmify/pkg/config"
"github.com/arttor/helmify/pkg/helmify"
"github.com/arttor/helmify/pkg/metadata"

"github.com/arttor/helmify/internal"
Expand All @@ -26,6 +28,14 @@ webhooks:
path: /mutate-ceph-example-com-v1alpha1-volume
failurePolicy: Fail
name: vvolume.kb.io
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- namespace-1
- my-operator-system
- namespace-3
rules:
- apiGroups:
- test.example.com
Expand All @@ -43,7 +53,7 @@ func Test_mwh_Process(t *testing.T) {

t.Run("processed", func(t *testing.T) {
obj := internal.GenerateObj(mwhYaml)
processed, _, err := testInstance.Process(&metadata.Service{}, obj)
processed, _, err := testInstance.Process(testAppMetaWithNamespace(), obj)
assert.NoError(t, err)
assert.Equal(t, true, processed)
})
Expand All @@ -54,3 +64,14 @@ func Test_mwh_Process(t *testing.T) {
assert.Equal(t, false, processed)
})
}

func testAppMetaWithNamespace() helmify.AppMetadata {
// Create an empty meta Service and load a dummy namespaced object.
am := metadata.New(config.Config{})
am.Load(internal.GenerateObj(`apiVersion: v1
kind: Service
metadata:
name: my-operator-controller-manager-metrics-service
namespace: my-operator-system`))
return am
}
1 change: 1 addition & 0 deletions pkg/processor/webhook/validating.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func (w vwh) Process(appMeta helmify.AppMetadata, obj *unstructured.Unstructured
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 }}`)
mutateNamespaceSelector(appMeta, whc.NamespaceSelector)
whConf.Webhooks[i] = whc
}
webhooks, _ := yaml.Marshal(whConf.Webhooks)
Expand Down
10 changes: 9 additions & 1 deletion pkg/processor/webhook/validating_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ webhooks:
path: /validate-ceph-example-com-v1alpha1-volume
failurePolicy: Fail
name: vvolume.kb.io
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- namespace-1
- my-operator-system
- namespace-3
rules:
- apiGroups:
- test.example.com
Expand All @@ -43,7 +51,7 @@ func Test_vwh_Process(t *testing.T) {

t.Run("processed", func(t *testing.T) {
obj := internal.GenerateObj(vwhYaml)
processed, _, err := testInstance.Process(&metadata.Service{}, obj)
processed, _, err := testInstance.Process(testAppMetaWithNamespace(), obj)
assert.NoError(t, err)
assert.Equal(t, true, processed)
})
Expand Down
16 changes: 16 additions & 0 deletions test_data/k8s-operator-kustomize.output
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,14 @@ webhooks:
path: /validate-ceph-example-com-v1alpha1-volume
failurePolicy: Fail
name: vvolume.kb.io
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- namespace-1
- my-operator-system
- namespace-3
rules:
- apiGroups:
- test.example.com
Expand Down Expand Up @@ -835,6 +843,14 @@ webhooks:
path: /mutate-ceph-example-com-v1-mycluster
failurePolicy: Fail
name: mmycluster.kb.io
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- namespace-1
- my-operator-system
- namespace-3
rules:
- apiGroups:
- test.example.com
Expand Down