kubernetes: MutatingAdmissionWebhook cannot modify the apiVersion

i want to use MutatingAdmissionWebhook to modify the apiVersion of resource and find it is not feasible, but modify the content of spec/metadata.

my test code is as follows:

func updateApiVersion()([]byte, error)  {
    var patch []patchOperation
    patch = append(patch, patchOperation{
        Op: "replace",
        Path: "/group",
        Value: "apps",
    })
    patch = append(patch, patchOperation{
        Op: "replace",
        Path: "/version",
        Value: "v1",
    })
    patch = append(patch, patchOperation{
        Op: "replace",
        Path: "/metadata/name",
        Value: "helios",

    })
    patch = append(patch, patchOperation{
        Op: "replace",
        Path: "/spec/replicas",
        Value: 2,
    })
    return json.Marshal(patch)
}

...

    patchBytes, err := updateApiVersion()
    glog.Infof("patchBytes is :", string(patchBytes))
    if err != nil {
        return &v1beta1.AdmissionResponse{
            Result: &metav1.Status{
                Message: err.Error(),
            },
        }
    }

    glog.Infof("AdmissionResponse: patch=%v\n", string(patchBytes))
    return &v1beta1.AdmissionResponse{
        Allowed: true,
        Patch:   patchBytes,
        Result: &metav1.Status{
            TypeMeta: metav1.TypeMeta{
                APIVersion: "apps/v1",
            },
        },
        PatchType: func() *v1beta1.PatchType {
            pt := v1beta1.PatchTypeJSONPatch
            return &pt
        }(),
    }

when submitting a resource, the output is:

I0326 11:29:07.229993       1 webhook.go:319] patchBytes is :%!(EXTRA string=[{"op":"replace","path":"/group","value":"apps"},{"op":"replace","path":"/version","value":"v1"},{"op":"replace","path":"/metadata/name","value":"helios"},{"op":"replace","path":"/spec/replicas","value":2}])
I0326 11:29:07.230023       1 webhook.go:328] AdmissionResponse: patch=[{"op":"replace","path":"/group","value":"apps"},{"op":"replace","path":"/version","value":"v1"},{"op":"replace","path":"/metadata/name","value":"helios"},{"op":"replace","path":"/spec/replicas","value":2}]
I0326 11:29:07.230050       1 webhook.go:398] Ready to write reponse ...%!(EXTRA string={"response":{"uid":"01422e64-6f55-11ea-97b3-5254008356fe","allowed":true,"status":{"apiVersion":"apps/v1","metadata":{}},"patch":"W3sib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii9ncm91cCIsInZhbHVlIjoiYXBwcyJ9LHsib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii92ZXJzaW9uIiwidmFsdWUiOiJ2MSJ9LHsib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii9tZXRhZGF0YS9uYW1lIiwidmFsdWUiOiJoZWxpb3MifSx7Im9wIjoicmVwbGFjZSIsInBhdGgiOiIvc3BlYy9yZXBsaWNhcyIsInZhbHVlIjoyfV0=","patchType":"JSONPatch"}})

# echo -n "W3sib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii9ncm91cCIsInZhbHVlIjoiYXBwcyJ9LHsib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii92ZXJzaW9uIiwidmFsdWUiOiJ2MSJ9LHsib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii9tZXRhZGF0YS9uYW1lIiwidmFsdWUiOiJoZWxpb3MifSx7Im9wIjoicmVwbGFjZSIsInBhdGgiOiIvc3BlYy9yZXBsaWNhcyIsInZhbHVlIjoyfV0=" | base64 --decode
[{"op":"replace","path":"/group","value":"apps"},{"op":"replace","path":"/version","value":"v1"},{"op":"replace","path":"/metadata/name","value":"helios"},{"op":"replace","path":"/spec/replicas","value":2}]

MutatingWebhookConfiguration as follow:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  name: mutating-webhook-example-cfg
  labels:
    app: admission-webhook-example
webhooks:
  - name: mutating-example.banzaicloud.com
    clientConfig:
      service:
        name: admission-webhook-example-svc
        namespace: default
        path: "/mutate"
      caBundle: ${CA_BUNDLE}
    rules:
      - operations: [ "CREATE" ]
        apiGroups: ["apps", "extensions", ""]
        apiVersions: ["v1", "v1beta1"]
        resources: ["deployments","services"]
    namespaceSelector:
      matchLabels:
        admission-webhook-example: enabled

i also looked at some source code because it is here but not sure:

is it because NewVersionedAttributesConvertVersionedAttributes are converted to the Kind type of the request here?

had some question:

  • addPatchAnnotation call AddAnnotationWithLevel and finds that there is no specific storage data.
  • when does kube-apiserver store the webhook patch data in etcd? i did not find the corresponding code~

thanks~~

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (7 by maintainers)

Most upvoted comments

The apiVersion determines the endpoint the client submits the request to. For example:

  • An extensions/v1beta1 Deployment gets submitted to /apis/extensions/v1beta1/namespaces/$namespace/deployments
  • An apps/v1 Deployment gets submitted to /apis/apps/v1/namespaces/$namespace/deployments

In 1.16, by default, the extensions/v1beta1 endpoint no longer exists. Clients that attempt to submit things to that endpoint will receive a 404 error.

Also, admission happens after an incoming request has been deserialized into typed structs. Trying to do conversion to a different apiVersion after that has happened is too late.

sig/api-machinery area/apiserver

@helios741: The label(s) sig/, area/ cannot be applied, because the repository doesn’t have them

In response to this:

/sig api-machinery /area apiserver

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

/sig api-machinery /area apiserver