Error while applying JSON Patch to Kubernetes Custom Resource Error while applying JSON Patch to Kubernetes Custom Resource kubernetes kubernetes

Error while applying JSON Patch to Kubernetes Custom Resource


Found the (or at least, a partial) answer while still typing the question...

The Kubernetes API server will not recursively create nested objects for a JSON patch input. This behaviour is consistent with the JSON Patch specification in RFC 6902, section A.12:

A.12. Adding to a Nonexistent Target

An example target JSON document:

{ "foo": "bar" }

A JSON Patch document:

[  { "op": "add", "path": "/baz/bat", "value": "qux" }]

This JSON Patch document, applied to the target JSON document above,would result in an error (therefore, it would not be applied),because the "add" operation's target location that references neitherthe root of the document, nor a member of an existing object, nor amember of an existing array.

This is why the original request fails, when the Custom Resources does not have a .status property to begin with. The following two subsequent calls (the second one being the original one) will complete successfully:

$ kubectl patch mycrd.example.com test --type=json \    -p '[{"op": "replace", "path": "/status", "value": {}}]'mycrd.example.com/test patched$ kubectl patch mycrd.example.com test --type=json \    -p '[{"op": "replace", "path": "/status/foo", "value": "bar"}]'mycrd.example.com/test patched

Obviously, replaceing the entire .status property with {} is not a good idea if that property already contains data that you want to keep.

A suitable alternative to a JSON patch in this scenario is a JSON Merge Patch:

PATCH /apis/example.com/v1alpha1/namespaces/default/mycrd/test HTTP/1.1Accept: application/jsonContent-Type: application/merge-patch+json[other headers omitted for brevity...]{  "status": {    "foo": "bar"  }}

Or, alternatively, using kubectl:

$ kubectl patch mycrd.example.com test --type=merge \    -p '{"status": {"foo": "bar"}}'mycrd.example.com/test patched