Skip to content

Commit

Permalink
chore(config) use a patch to add Secret hooks
Browse files Browse the repository at this point in the history
Split the webhook manifest into the generated manifest and additional
rule patches. Kubebuilder limitations require writing your own rules to
use objectSelectors.

Remove the kubebuilder Secret hook generation directive and document the
workaround.

Refactor the envtest runner to build a webhook manifest via Kustomize,
rather than reading a static manifest.
  • Loading branch information
rainest committed Apr 15, 2024
1 parent ba2cad3 commit 90df090
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 56 deletions.
4 changes: 3 additions & 1 deletion config/default/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ bases:
- ../manager
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
#- ../webhook
# NOTE we enable this to allow patching the generated webhook. We do not have the crd/kustomization.yaml config
# enabled, as we don't use the mutating hooks in there currently.
- ../webhook
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
#- ../certmanager
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
Expand Down
58 changes: 58 additions & 0 deletions config/webhook/additional_secret_hooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# https://github.com/kubernetes-sigs/controller-tools/issues/553
# controller-tools, and by extension kubebuilder, do not support specifying objectSelector,
# which we need for the Secret rules.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /
failurePolicy: Fail
matchPolicy: Equivalent
name: secrets.credentials.validation.ingress-controller.konghq.com
objectSelector:
matchExpressions:
- key: "konghq.com/credential"
operator: "Exists"
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- secrets
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /
failurePolicy: Fail
matchPolicy: Equivalent
name: secrets.plugins.validation.ingress-controller.konghq.com
objectSelector:
matchExpressions:
- key: "konghq.com/validate"
operator: "Exists"
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- secrets
sideEffects: None
7 changes: 7 additions & 0 deletions config/webhook/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- manifests.yaml

patchesStrategicMerge:
- additional_secret_hooks.yaml
50 changes: 0 additions & 50 deletions config/webhook/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -195,56 +195,6 @@ webhooks:
resources:
- kongvaults
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /
failurePolicy: Fail
matchPolicy: Equivalent
name: secrets.credentials.validation.ingress-controller.konghq.com
objectSelector:
matchExpressions:
- key: "konghq.com/credential"
operator: "Exists"
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- secrets
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /
failurePolicy: Fail
matchPolicy: Equivalent
name: secrets.plugins.validation.ingress-controller.konghq.com
objectSelector:
matchExpressions:
- key: "konghq.com/validate"
operator: "Exists"
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- secrets
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
Expand Down
5 changes: 4 additions & 1 deletion internal/admission/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ func (h RequestHandler) handleKongClusterPlugin(
return responseBuilder.Allowed(ok).WithMessage(message).Build(), nil
}

// +kubebuilder:webhook:verbs=create;update,groups=core,resources=secrets,versions=v1,name=secrets.validation.ingress-controller.konghq.com,path=/,webhookVersions=v1,matchPolicy=equivalent,mutating=false,failurePolicy=fail,sideEffects=None,admissionReviewVersions=v1
// NOTE this handler _does not_ use a kubebuilder directive, as our Secret handling requires webhook features
// kubebuilder does not support (objectSelector). Instead, config/webhook/additional_secret_hooks.yaml includes
// handwritten webhook rules that we patch into the webhook manifest.
// See https://github.com/kubernetes-sigs/controller-tools/issues/553 for further info.

func (h RequestHandler) handleSecret(
ctx context.Context,
Expand Down
8 changes: 4 additions & 4 deletions test/envtest/admission_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"bytes"
"context"
"fmt"
"os"
"testing"

"github.com/kong/kubernetes-testing-framework/pkg/utils/kubernetes/kubectl"
"github.com/samber/lo"
"github.com/stretchr/testify/require"
admregv1 "k8s.io/api/admissionregistration/v1"
Expand All @@ -29,13 +29,13 @@ func setupValidatingWebhookConfiguration(
}

func validatingWebhookConfigWithClientConfig(t *testing.T, clientConfig admregv1.WebhookClientConfig) *admregv1.ValidatingWebhookConfiguration {
file, err := os.ReadFile("../../config/webhook/manifests.yaml")
manifest, err := kubectl.RunKustomize("../../config/webhook/")
require.NoError(t, err)
file = bytes.ReplaceAll(file, []byte("---"), []byte("")) // We're only expecting one document in the file.
manifest = bytes.ReplaceAll(manifest, []byte("---"), []byte("")) // We're only expecting one document in the file.

// Load the webhook configuration from the generated manifest.
webhookConfig := &admregv1.ValidatingWebhookConfiguration{}
require.NoError(t, yaml.Unmarshal(file, webhookConfig))
require.NoError(t, yaml.Unmarshal(manifest, webhookConfig))

// Set the client config.
for i := range webhookConfig.Webhooks {
Expand Down

0 comments on commit 90df090

Please sign in to comment.