From f6e1c5c01235807daabb6eaa4708c03e315f29fc Mon Sep 17 00:00:00 2001 From: Kieron Browne Date: Mon, 27 Jun 2022 16:00:10 +0000 Subject: [PATCH] Introduce kpack build pod mutating webhook The mutating webhook sets a security policy in the kpack build pods' containers that matches the `restricted` pod security enforced by the workload namespace The webhook is a workaround to kpack issue https://github.com/pivotal/kpack/issues/972. Once the issue is resolved and a fix is adopted, we should probably revert the commit and adopt the kpack fix. Issue: https://github.com/cloudfoundry/korifi/issues/1220 Co-authored-by: Danail Branekov nearly working Co-authored-by: Danail Branekov It works Co-authored-by: Danail Branekov --- go.mod | 2 +- go.sum | 1 - .../config/certmanager/certificate.yaml | 25 +++++ .../config/certmanager/kustomization.yaml | 5 + .../config/certmanager/kustomizeconfig.yaml | 16 ++++ .../project_namespace/kustomization.yaml | 60 ++++++------ .../manager_webhook_patch.yaml | 23 +++++ .../webhookcainjection_patch.yaml | 15 +++ .../config/webhook/kustomization.yaml | 9 ++ .../config/webhook/kustomizeconfig.yaml | 25 +++++ .../config/webhook/manifests.yaml | 27 +++++- .../config/webhook/object_selector_patch.yaml | 10 ++ .../config/webhook/service.yaml | 13 +++ .../podsecurity/buildpack_mutating_webhook.go | 72 ++++++++++++++ .../buildpack_mutating_webhook_test.go | 77 +++++++++++++++ .../controllers/podsecurity/suite_test.go | 96 +++++++++++++++++++ kpack-image-builder/main.go | 6 ++ 17 files changed, 449 insertions(+), 33 deletions(-) create mode 100644 kpack-image-builder/config/certmanager/certificate.yaml create mode 100644 kpack-image-builder/config/certmanager/kustomization.yaml create mode 100644 kpack-image-builder/config/certmanager/kustomizeconfig.yaml create mode 100644 kpack-image-builder/config/default/project_namespace/manager_webhook_patch.yaml create mode 100644 kpack-image-builder/config/default/project_namespace/webhookcainjection_patch.yaml create mode 100644 kpack-image-builder/config/webhook/kustomization.yaml create mode 100644 kpack-image-builder/config/webhook/kustomizeconfig.yaml create mode 100644 kpack-image-builder/config/webhook/object_selector_patch.yaml create mode 100644 kpack-image-builder/config/webhook/service.yaml create mode 100644 kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook.go create mode 100644 kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook_test.go create mode 100644 kpack-image-builder/controllers/podsecurity/suite_test.go diff --git a/go.mod b/go.mod index ecb462e56..473665e0b 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( k8s.io/apimachinery v0.24.2 k8s.io/client-go v0.24.2 k8s.io/metrics v0.24.2 + k8s.io/pod-security-admission v0.24.2 k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 sigs.k8s.io/controller-runtime v0.12.1 sigs.k8s.io/controller-tools v0.9.0 @@ -50,7 +51,6 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect google.golang.org/genproto v0.0.0-20220422154200-b37d22cd5731 // indirect google.golang.org/grpc v1.46.0 // indirect - k8s.io/pod-security-admission v0.24.2 // indirect ) require ( diff --git a/go.sum b/go.sum index fa302466d..b234a46d0 100644 --- a/go.sum +++ b/go.sum @@ -3299,7 +3299,6 @@ k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByu k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ= k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= k8s.io/component-base v0.23.0/go.mod h1:DHH5uiFvLC1edCpvcTDV++NKULdYYU6pR9Tt3HIKMKI= -k8s.io/component-base v0.24.1 h1:APv6W/YmfOWZfo+XJ1mZwep/f7g7Tpwvdbo9CQLDuts= k8s.io/component-base v0.24.1/go.mod h1:DW5vQGYVCog8WYpNob3PMmmsY8A3L9QZNg4j/dV3s38= k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU= k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM= diff --git a/kpack-image-builder/config/certmanager/certificate.yaml b/kpack-image-builder/config/certmanager/certificate.yaml new file mode 100644 index 000000000..52d866183 --- /dev/null +++ b/kpack-image-builder/config/certmanager/certificate.yaml @@ -0,0 +1,25 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/kpack-image-builder/config/certmanager/kustomization.yaml b/kpack-image-builder/config/certmanager/kustomization.yaml new file mode 100644 index 000000000..bebea5a59 --- /dev/null +++ b/kpack-image-builder/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/kpack-image-builder/config/certmanager/kustomizeconfig.yaml b/kpack-image-builder/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 000000000..90d7c313c --- /dev/null +++ b/kpack-image-builder/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/kpack-image-builder/config/default/project_namespace/kustomization.yaml b/kpack-image-builder/config/default/project_namespace/kustomization.yaml index 426d4a46b..c2585480d 100644 --- a/kpack-image-builder/config/default/project_namespace/kustomization.yaml +++ b/kpack-image-builder/config/default/project_namespace/kustomization.yaml @@ -19,9 +19,9 @@ resources: - ../../base # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- ../webhook +- ../../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager +- ../../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus @@ -37,39 +37,39 @@ patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- manager_webhook_patch.yaml +- manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. # 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml +- webhookcainjection_patch.yaml # the following config is for teaching kustomize how to do var substitution vars: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service +- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace +- name: CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service diff --git a/kpack-image-builder/config/default/project_namespace/manager_webhook_patch.yaml b/kpack-image-builder/config/default/project_namespace/manager_webhook_patch.yaml new file mode 100644 index 000000000..738de350b --- /dev/null +++ b/kpack-image-builder/config/default/project_namespace/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/kpack-image-builder/config/default/project_namespace/webhookcainjection_patch.yaml b/kpack-image-builder/config/default/project_namespace/webhookcainjection_patch.yaml new file mode 100644 index 000000000..f9012c9b8 --- /dev/null +++ b/kpack-image-builder/config/default/project_namespace/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +# --- +# apiVersion: admissionregistration.k8s.io/v1 +# kind: ValidatingWebhookConfiguration +# metadata: +# name: validating-webhook-configuration +# annotations: +# cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/kpack-image-builder/config/webhook/kustomization.yaml b/kpack-image-builder/config/webhook/kustomization.yaml new file mode 100644 index 000000000..84edf7e9f --- /dev/null +++ b/kpack-image-builder/config/webhook/kustomization.yaml @@ -0,0 +1,9 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml + +patchesStrategicMerge: +- object_selector_patch.yaml diff --git a/kpack-image-builder/config/webhook/kustomizeconfig.yaml b/kpack-image-builder/config/webhook/kustomizeconfig.yaml new file mode 100644 index 000000000..25e21e3c9 --- /dev/null +++ b/kpack-image-builder/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/kpack-image-builder/config/webhook/manifests.yaml b/kpack-image-builder/config/webhook/manifests.yaml index cd21505a4..1581c8059 100644 --- a/kpack-image-builder/config/webhook/manifests.yaml +++ b/kpack-image-builder/config/webhook/manifests.yaml @@ -1,2 +1,27 @@ --- - +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-kpack-build-pod + failurePolicy: Ignore + name: mkpackbuildpod.korifi.cloudfoundry.org + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None diff --git a/kpack-image-builder/config/webhook/object_selector_patch.yaml b/kpack-image-builder/config/webhook/object_selector_patch.yaml new file mode 100644 index 000000000..aa5ca1d41 --- /dev/null +++ b/kpack-image-builder/config/webhook/object_selector_patch.yaml @@ -0,0 +1,10 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration +webhooks: +- name: mkpackbuildpod.korifi.cloudfoundry.org + objectSelector: + matchExpressions: + - key: kpack.io/build + operator: Exists diff --git a/kpack-image-builder/config/webhook/service.yaml b/kpack-image-builder/config/webhook/service.yaml new file mode 100644 index 000000000..3f638bd9c --- /dev/null +++ b/kpack-image-builder/config/webhook/service.yaml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook.go b/kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook.go new file mode 100644 index 000000000..0ad6e798e --- /dev/null +++ b/kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook.go @@ -0,0 +1,72 @@ +package podsecurity + +import ( + "context" + "encoding/json" + "net/http" + + corev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// +kubebuilder:webhook:path=/mutate-kpack-build-pod,mutating=true,failurePolicy=ignore,groups="",resources=pods,verbs=create,versions=v1,name=mkpackbuildpod.korifi.cloudfoundry.org,admissionReviewVersions={v1,v1beta1},sideEffects=none + +type PodSecurityAdder struct { + decoder *admission.Decoder +} + +func NewPodSecurityAdder() *PodSecurityAdder { + return &PodSecurityAdder{} +} + +func pointerTo(b bool) *bool { + return &b +} + +func (a *PodSecurityAdder) Handle(ctx context.Context, req admission.Request) admission.Response { + logger := ctrl.Log.WithName("kpack-build-pod-security") + + pod := &corev1.Pod{} + err := a.decoder.Decode(req, pod) + if err != nil { + logger.Error(err, "decode-error") + return admission.Errored(http.StatusBadRequest, err) + } + + patchContainerSecurity(pod.Spec.Containers) + patchContainerSecurity(pod.Spec.InitContainers) + + marshaledPod, err := json.Marshal(pod) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + + logger.Info("patching pod security context", "namespace", req.Namespace, "name", req.Name) + return admission.PatchResponseFromRaw(req.Object.Raw, marshaledPod) +} + +// InjectDecoder injects the decoder. +func (a *PodSecurityAdder) InjectDecoder(d *admission.Decoder) error { + a.decoder = d + return nil +} + +func patchContainerSecurity(containers []corev1.Container) { + for i := range containers { + container := containers[i] + if container.SecurityContext == nil { + container.SecurityContext = new(corev1.SecurityContext) + } + + container.SecurityContext.AllowPrivilegeEscalation = pointerTo(false) + container.SecurityContext.RunAsNonRoot = pointerTo(true) + container.SecurityContext.Capabilities = &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + } + container.SecurityContext.SeccompProfile = &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + } + containers[i] = container + } +} diff --git a/kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook_test.go b/kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook_test.go new file mode 100644 index 000000000..e39fdd8dc --- /dev/null +++ b/kpack-image-builder/controllers/podsecurity/buildpack_mutating_webhook_test.go @@ -0,0 +1,77 @@ +package podsecurity_test + +import ( + "code.cloudfoundry.org/korifi/controllers/controllers/workloads/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("Buildpack Pods Mutating Webhook", func() { + var ( + namespace string + pod *corev1.Pod + ) + + BeforeEach(func() { + namespace = testutils.PrefixedGUID("ns") + err := k8sClient.Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + }) + Expect(err).NotTo(HaveOccurred()) + + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: testutils.PrefixedGUID("pod"), + Namespace: namespace, + }, + Spec: corev1.PodSpec{ + InitContainers: []corev1.Container{{ + Name: "init-1", + Image: "alpine", + Command: []string{"sleep", "1234"}, + }}, + Containers: []corev1.Container{{ + Name: "c-1", + Image: "alpine", + Command: []string{"sleep", "9876"}, + }}, + }, + } + }) + + JustBeforeEach(func() { + Expect(k8sClient.Create(ctx, pod)).To(Succeed()) + lookupKey := client.ObjectKeyFromObject(pod) + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, lookupKey, pod)).To(Succeed()) + }).Should(Succeed()) + }) + + checkSecurityContext := func(securityContext *corev1.SecurityContext) { + ExpectWithOffset(1, securityContext).NotTo(BeNil()) + + ExpectWithOffset(1, securityContext.AllowPrivilegeEscalation).To(PointTo(BeFalse())) + ExpectWithOffset(1, securityContext.RunAsNonRoot).To(PointTo(BeTrue())) + + ExpectWithOffset(1, securityContext.Capabilities).NotTo(BeNil()) + ExpectWithOffset(1, securityContext.Capabilities.Drop).To(ConsistOf(corev1.Capability("ALL"))) + ExpectWithOffset(1, securityContext.Capabilities.Add).To(BeEmpty()) + + ExpectWithOffset(1, securityContext.SeccompProfile).NotTo(BeNil()) + ExpectWithOffset(1, securityContext.SeccompProfile.Type).To(Equal(corev1.SeccompProfileTypeRuntimeDefault)) + } + + It("adds security context to containers", func() { + checkSecurityContext(pod.Spec.Containers[0].SecurityContext) + }) + + It("adds security context to init containers", func() { + checkSecurityContext(pod.Spec.InitContainers[0].SecurityContext) + }) +}) diff --git a/kpack-image-builder/controllers/podsecurity/suite_test.go b/kpack-image-builder/controllers/podsecurity/suite_test.go new file mode 100644 index 000000000..b4af5b8b7 --- /dev/null +++ b/kpack-image-builder/controllers/podsecurity/suite_test.go @@ -0,0 +1,96 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package podsecurity_test + +import ( + "context" + "path/filepath" + "testing" + "time" + + "code.cloudfoundry.org/korifi/kpack-image-builder/controllers/podsecurity" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +var ( + cancel context.CancelFunc + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + ctx context.Context +) + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + SetDefaultEventuallyTimeout(10 * time.Second) + SetDefaultEventuallyPollingInterval(200 * time.Millisecond) + + RunSpecs(t, "PodSecurity Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.Background()) + + testEnv = &envtest.Environment{ + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "config", "webhook", "manifests.yaml")}, + }, + } + + var err error + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme.Scheme, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + mgr.GetWebhookServer().Register("/mutate-kpack-build-pod", &webhook.Admission{Handler: podsecurity.NewPodSecurityAdder()}) + + k8sClient = mgr.GetClient() + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() +}) + +var _ = AfterSuite(func() { + cancel() + Expect(testEnv.Stop()).To(Succeed()) +}) diff --git a/kpack-image-builder/main.go b/kpack-image-builder/main.go index c3dbf96a3..14f208336 100644 --- a/kpack-image-builder/main.go +++ b/kpack-image-builder/main.go @@ -25,18 +25,21 @@ import ( "code.cloudfoundry.org/korifi/kpack-image-builder/config" "code.cloudfoundry.org/korifi/kpack-image-builder/controllers" "code.cloudfoundry.org/korifi/kpack-image-builder/controllers/imageprocessfetcher" + "code.cloudfoundry.org/korifi/kpack-image-builder/controllers/podsecurity" buildv1alpha2 "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" k8sclient "k8s.io/client-go/kubernetes" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/webhook" //+kubebuilder:scaffold:imports ) @@ -126,6 +129,9 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "BuildReconcilerInfo") os.Exit(1) } + + mgr.GetWebhookServer().Register("/mutate-kpack-build-pod", &webhook.Admission{Handler: podsecurity.NewPodSecurityAdder()}) + //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {