I'm trying to patch a kube node using the Python kubernetes-client library.
Specifically, I'm trying to cordon the node. Using kubectl, I'm able to do it successfully:
kubectl patch node mynode -json --patch={"op":"replace", "path":"/spec/unschedulable", "value":true}`
But using the python kubernetes-client library fails:
from kubernetes import client, config
config.load_kube_config()
body='{"op":"replace", "path":"/spec/unschedulable", "value":true}'
# also have tried body='[{"op":"replace", "path":"/spec/unschedulable", "value":true}]'
v1=client.CoreV1Api()
ret=v1.patch_node(name="mynode", body=body)
print (ret)
The return contains the message:
"json: cannot unmarshal object into Go value of type jsonpatch.Patch"
Some research led me to this bug. It refers to using the kubernetes api directly, but the issue appears to be the same. Unfortunately, the solution - passing an array - doesn't help.
Unfortunately, the documentation doesn't help, here. The required type for body
is shown as UNKNOWN_BASE_TYPE
, which is not ueful. I've looked at the code, but there's no clue there as to how I should be formatting the body - I'm at a loss.
So, it turns out that json.loads()
is the answer, and upper casing the bool, so that loads()
works. Also, although a non-array body does not raise an error, neither does it actually make the desired change, so an array is required:
from kubernetes import client, config
import json
config.load_kube_config()
v1=client.CoreV1Api()
body='[{"op": "add", "path": "/spec/unschedulable", "value": True}]'
print(json.loads(body)) #Debug
ret=v1.patch_node(name="mynode", body=json.loads(body))
print (ret)
It's worth pointing out that the resulting body has the bool capitalised, whereas for the kubectl command-line operation it must be lower-case.
Also, oddly, if I replace:body=json.loads(body)
withbody="[{'op': 'add', 'path': '/spec/unschedulable', 'value': False}]"
Which is the output of the earlier print statement, it fails in the original manner.