Repository: kubernetes
Issue: CREATE request for already existing object is denied with `exceeded quota`
Labels: kind/bug,area/apiserver,sig/api-machinery,triage/accepted

### What happened?

CREATE request for already existing object is denied with `exceeded quota` by the ResourceQuota admission plugin.

### What did you expect to happen?

CREATE request for already existing object (and when the resourcequota is exhausted) to be denied with `already exists` (`409 Conflict`).

### How can we reproduce it (as minimally and precisely as possible)?

1. Create a test namespace `foo`
   ```
   k create ns foo
   ```

2. Create a resourcequota that allows only 1 Pod.
   ```yaml
   apiVersion: v1
   kind: ResourceQuota
   metadata:
     name: resource-quota
   spec:
     hard:
       pods: "1"
   ```

    ```
    k -n foo create -f resource-qouta.yaml
    ```

3. Create a Pod

   ```yaml
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.14.2
       ports:
       - containerPort: 80
   ```

   ```
   k -n foo create -f pod.yaml
    ```

4. Try to create the Pod again and make sure that it fails with `exceeded quota`

   ```
   k -n foo create -f pod.yaml
   Error from server (Forbidden): error when creating "pod.yaml": pods "nginx" is forbidden: exceeded quota: resource-quota, requested: pods=1, used: pods=1, limited: pods=1
   ```

### Anything else we need to know?

On server side we have an admission component (let's call it "authorizer") similar to the kubelet's [`NodeAuthorizer`](https://kubernetes.io/docs/reference/access-authn-authz/node/) . The "authorizer" allows certain verbs on resources only if there is a "relation" between the requesting component and the requested resource - similar to the NodeAuthorizer that allows operations for secrets, configmaps, pvcs, pv related to pods bound to the kubelet's node. This authorizer would actually reject a GET request for non-existing object. That's why the client's strategy is "create or get and patch". We rely on the CREATE request to return `already exists` (`409 Conflict`).

### Kubernetes version

<details>

```console
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:31:21Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.16", GitCommit:"e37e4ab4cc8dcda84f1344dda47a97bb1927d074", GitTreeState:"clean", BuildDate:"2021-10-27T16:20:18Z", GoVersion:"go1.15.15", Compiler:"gc", Platform:"linux/amd64"}
```

</details>


### Cloud provider

<details>
Not applicable
</details>


### OS version

<details>

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
```

</details>


### Install tools

<details>

</details>


### Container runtime (CRI) and and version (if applicable)

<details>

</details>


### Related plugins (CNI, CSI, ...) and versions (if applicable)

<details>

</details>