3

I am writing the mutate and validate admission webhooks for the CRDs. I am using kubebuilder to setup the CRDs. Spec and status subresources are behaving correctly.

As a part of mutation, I am having a requirement where I need to update the status subresources.

For example, Exam is my CR and status.status is the Exam status. I want to set the status to "NotDone" in mutation.

I tried following approaches

  1. Json patching approach explained here https://banzaicloud.com/blog/k8s-admission-webhooks/ This gives error that the custom resource not found. i.e. it expects the custom resource for which we are updating the status.
  2. Get and update status using go client https://book-v1.book.kubebuilder.io/basics/status_subresource.html

but none of the approach worked for me.

I am wondering if it is even possible to update the status subresources in the admission webhooks?

Yudi
  • 831
  • 4
  • 10
  • 19
  • version of kubernetes? And can you provide the CRD in yaml format – Arghya Sadhu Jan 02 '20 at 14:22
  • "resource not found" may indicate that your client is missing the RBAC to do so? subresource/status needs it's own permission, also when adding the subresource annotation it modifies the CRD, make sure that's up to date as well. – Eytan Avisror May 02 '20 at 22:20

1 Answers1

3

When a Custom Resource Definition (CRD) set in .spec.versions[].subresources a subresource the mutating and validating admission webhooks has to include in the .webhooks[].rules[].resources both <custom resource name> and <custom resource name>/<subresource name> values in order to mutate and validate both the resource and the subresource.

For example for a test CRD:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: test.test
spec:
  group: test
  scope: Namespaced
  names:
    kind: Test
    listKind: TestList
    plural: tests
    singular: test
    shortNames:
      - tst
  versions:
    - name: v1
      served: true
      storage: true
      subresources:
        status: { }

You will have to define a mutating admission webhook like so:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: test
webhooks:
  - name: test
    sideEffects: None
    rules:
      - operations: ["CREATE", "UPDATE"]
        apiGroups: ["test"]
        apiVersions: ["*"]
        resources: ["test", "test/status"]
    failurePolicy: Fail
    clientConfig:
      service:
        namespace: test
        name: test
        path: '/test'
      caBundle: <the certificate in base64>
    admissionReviewVersions: ["v1"]

Similar for the validating admission webhook:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: test
webhooks:
  - name: test
    sideEffects: None
    rules:
      - operations: ["CREATE", "UPDATE"]
        apiGroups: ["test"]
        apiVersions: ["*"]
        resources: ["test", "test/status"]
    failurePolicy: Fail
    clientConfig:
      service:
        namespace: test
        name: test
        path: '/test'
      caBundle: <the certificate in base64>
    admissionReviewVersions: ["v1"]

The mutating and validating webhook in this example will then be called twice on creation. First time for the resource and second time for the subresource. You can figure out in the request if the call is for the resource or the subresource by reading the field .request.subResource. It will be empty for the resource and it will contain the subresource name for the subresource. This is important for validation since mutation on the subresource will only be available when the webhook is called for the subresource.

It is very important to note here that the mutating and validating webhook for the subresource will not be called synchronously during the creation of the custom resource. Instead they are called asynchronously after the custom resource has been created so that a failing validation of the subresource will not block creation of the custom resource.

teoincontatto
  • 1,565
  • 1
  • 9
  • 8
  • Very helpful, but won't solve the actual problem. Goal was to update the status subresource as part of the main resource hooks. Your suggestion won't trigger the status update call when the main resource is touched, thus status patching is not possible. I've created an [example scenario](https://www.katacoda.com/exotrom/scenarios/webhook-status-update), [sources](https://github.com/HYMXDEV/katacoda-scenarios/tree/main/webhook-status-update/assets). Workaround might be to update the status async (wait for the resource to be created/updated and then update the status with the kubernetes API). – HYMXDEV Jan 05 '22 at 13:35
  • What is the reason for this? I couldn't find anything regarding this in the docs, why do we have to include both parent resource and subresource in the webhook? – VIAGC Nov 01 '22 at 06:54