<p>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. </p>

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

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

<p>I tried following approaches </p>

<ol>
<li>Json patching approach explained here <a href="https://banzaicloud.com/blog/k8s-admission-webhooks/" rel="nofollow noreferrer">https://banzaicloud.com/blog/k8s-admission-webhooks/</a> This gives error that the custom resource not found. i.e. it expects the custom resource for which we are updating the status.</li>
<li>Get and update status using go client <a href="https://book-v1.book.kubebuilder.io/basics/status_subresource.html" rel="nofollow noreferrer">https://book-v1.book.kubebuilder.io/basics/status_subresource.html</a></li>
</ol>

<p>but none of the approach worked for me.</p>

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

<p>When a Custom Resource Definition (CRD) set in <code>.spec.versions[].subresources</code> a subresource the mutating and validating admission webhooks has to include in the <code>.webhooks[].rules[].resources</code> both <code>&lt;custom resource name&gt;</code> and <code>&lt;custom resource name&gt;/&lt;subresource name&gt;</code> values in order to mutate and validate both the resource and the subresource.</p>
<p>For example for a test CRD:</p>
<pre class="lang-yaml prettyprint-override"><code>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: { }
</code></pre>
<p>You will have to define a mutating admission webhook like so:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: test
webhooks:
  - name: test
    sideEffects: None
    rules:
      - operations: [&quot;CREATE&quot;, &quot;UPDATE&quot;]
        apiGroups: [&quot;test&quot;]
        apiVersions: [&quot;*&quot;]
        resources: [&quot;test&quot;, &quot;test/status&quot;]
    failurePolicy: Fail
    clientConfig:
      service:
        namespace: test
        name: test
        path: '/test'
      caBundle: &lt;the certificate in base64&gt;
    admissionReviewVersions: [&quot;v1&quot;]
</code></pre>
<p>Similar for the validating admission webhook:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: test
webhooks:
  - name: test
    sideEffects: None
    rules:
      - operations: [&quot;CREATE&quot;, &quot;UPDATE&quot;]
        apiGroups: [&quot;test&quot;]
        apiVersions: [&quot;*&quot;]
        resources: [&quot;test&quot;, &quot;test/status&quot;]
    failurePolicy: Fail
    clientConfig:
      service:
        namespace: test
        name: test
        path: '/test'
      caBundle: &lt;the certificate in base64&gt;
    admissionReviewVersions: [&quot;v1&quot;]
</code></pre>
<p>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 <code>.request.subResource</code>. 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.</p>
<p>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.</p>
