kubernetes / community

Kubernetes community content
Apache License 2.0
12.02k stars 5.17k forks source link

API Conventions: PUT does not create new resource #876

Open etiennedi opened 7 years ago

etiennedi commented 7 years ago

According to HTTP Verbs section of the API conventions documentation, using the HTTP Verb PUT, we can update or create a resource if it does not exist.

However, this doesn't seem to reflect reality. It might be true only for specific resources and endpoints, but we cannot seem to create a resource of type Deployment using the Kubernetes API on a Minikube test setup: (tested with Kubernetes Version 1.5.3 and 1.7.0)

Consider the following request:

PUT /apis/extensions/v1beta1/namespaces/default/deployments/test-deployment HTTP/1.1
Host: 127.0.0.1:8001
Content-Type: application/json

{
    "metadata": {
        "name": "test-deployment"
    },
    "spec": {
        "template": {
            "metadata": {
                "labels": {
                    "app": "test-app"
                }
            },
            "spec": {
                "containers": [
                    {
                        "name": "test-app",
                        "image": "nginx"
                    }
                ]
            }
        }
    }
}

This request fails if the resource does not exist. It succeeds if the resource has previously been created. Using PUT does therefore not seem to 'Create or Update a Resource', but rather only 'Update a Resource'.

Is the documentation incorrect or does it for some reason not apply to the resource type Deployments? (We have also tested with Services and seen the same behavior).

Thanks for your help.

bgrant0607 commented 7 years ago

Sadly:

https://github.com/kubernetes/kubernetes/issues/2114

fejta-bot commented 6 years ago

Issues go stale after 90d of inactivity. Mark the issue as fresh with /remove-lifecycle stale. Stale issues rot after an additional 30d of inactivity and eventually close.

Prevent issues from auto-closing with an /lifecycle frozen comment.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or @fejta. /lifecycle stale

bgrant0607 commented 6 years ago

/remove-lifecycle stale

dorshay6 commented 6 years ago

Any news?

liggitt commented 2 years ago

the mentioned doc is now at https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#verbs-on-resources

Some resources support create on update (PUT), but it is not consistent, only these allow it:

grep -R -A 1 ") AllowCreateOnUpdate" pkg staging | grep -B 1 true | grep Allow | grep -v test
pkg/registry/rbac/role/strategy.go:func (strategy) AllowCreateOnUpdate() bool {
pkg/registry/rbac/clusterrolebinding/strategy.go:func (strategy) AllowCreateOnUpdate() bool {
pkg/registry/rbac/clusterrole/strategy.go:func (strategy) AllowCreateOnUpdate() bool {
pkg/registry/rbac/rolebinding/strategy.go:func (strategy) AllowCreateOnUpdate() bool {
pkg/registry/core/endpoint/strategy.go:func (endpointsStrategy) AllowCreateOnUpdate() bool {
pkg/registry/core/limitrange/strategy.go:func (limitrangeStrategy) AllowCreateOnUpdate() bool {
pkg/registry/core/service/strategy.go:func (svcStrategy) AllowCreateOnUpdate() bool {
pkg/registry/core/event/strategy.go:func (eventStrategy) AllowCreateOnUpdate() bool {
pkg/registry/coordination/lease/strategy.go:func (leaseStrategy) AllowCreateOnUpdate() bool {
pkg/registry/node/runtimeclass/strategy.go:func (strategy) AllowCreateOnUpdate() bool {

The documentation should clarify that support for create via PUT is resource-specific.

With server-side apply, all resources support create-or-update via PATCH with the server-side apply content type. Clients wanting to collapse to a single API request that will create if needed should use that mechanism. @apelisse, is that aspect highlighted in SSA docs? That patch type could be added to this doc and the create-on-update aspect mentioned

apelisse commented 2 years ago

I was looking at SSA page and it's not that great with that regard. This point is mentioned in that pull-request though:

application/apply-patch+yaml : Server Side Apply YAML (a Kubernetes-specific extension, based on YAML). All JSON documents are valid YAML, so you can also submit JSON using this media type. See Server Side Apply serialization for more details.
To Kubernetes, this is a create operation if the object does not exist, or a patch operation if the object already exists.

palnabarun commented 1 year ago

/area contributor-guide

joseclaris6500 commented 1 year ago

Is there any new news on this issue?

svas258 commented 1 week ago

Not sure it was already updated just adding. PUT is used to update existing resources only and will not create new resources. If the resource does not exist, a 404 Not Found error will be returned. https://kubernetes.io/docs/reference/using-api/api-concepts/#update-mechanism-choose