issue on update Service , empty loadBalance error
xsir317 opened this issue · 4 comments
i created a service, when i query it by the api, i printed the return, its like this:
{"kind":"ServiceList","apiVersion":"v1","metadata":{"selfLink":"/api/v1/namespaces/hujie/services","resourceVersion":"2181987"},"items":[{"metadata":{"name":"redis-master","namespace":"hujie","selfLink":"/api/v1/namespaces/hujie/services/redis-master","uid":"cc37eaf4-6e1e-11e8-82d7-d4ae526f781c","resourceVersion":"2180527","creationTimestamp":"2018-06-12T08:58:38Z"},"spec":{"ports":[{"protocol":"TCP","port":6379,"targetPort":6379,"nodePort":31003}],"selector":{"tier":"redis"},"clusterIP":"10.68.87.72","type":"NodePort","sessionAffinity":"None","externalTrafficPolicy":"Cluster"},"status":{"loadBalancer":{}}}]}
you see the loadBalancer is an empty object like {}.
but when you json_decode($bodyResponse,true), it will become an empty array , and it is not an empty object anymore.
Then i want edit it, change its port and update it
$service = $client->services()->setFieldSelector([ 'metadata.name' => 'redis-master',])->first(); $values = $service->toArray(); var_export($values); //edit $values['spec']['ports'][0]['nodePort'] = 31003; //re-create an update object $service_upd = new Service($values); //and update $client->services()->update($service_upd);
i got an error:
Exception 'Maclof\Kubernetes\Exceptions\BadRequestException' with message '{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Service in version "v1" cannot be handled as a Service: v1.Service: Status: v1.ServiceStatus: LoadBalancer: readObjectStart: expect { or n, parsing 822 ...lancer": [... at {\n "kind": "Service",\n "apiVersion": "v1",\n "metadata": {\n "name": "redis-master-rename",\n "namespace": "hujie",\n "selfLink": "\/api\/v1\/namespaces\/hujie\/services\/redis-master",\n "uid": "cc37eaf4-6e1e-11e8-82d7-d4ae526f781c",\n "resourceVersion": "2175754",\n "creationTimestamp": "2018-06-12T08:58:38Z"\n },\n "spec": {\n "ports": [\n {\n "protocol": "TCP",\n "port": 6379,\n "targetPort": 6379,\n "nodePort": 31002\n }\n ],\n "selector": {\n "tier": "redis"\n },\n "clusterIP": "10.68.87.72",\n "type": "NodePort",\n "sessionAffinity": "None",\n "externalTrafficPolicy": "Cluster"\n },\n "status": {\n "loadBalancer": []\n }\n}","reason":"BadRequest","code":400}
see ? the loadBalancer was an object when the query returns, and when we decode it and encode it, it becomes an array . and the update failed.
still, i can not use JSON_FORCE_OBJECT to fix it, that might cause some other problem.
I'm having a similar issue trying to define an emptyDir
via an array when creating a Deployment. Examples to help anyone unfamiliar w/ how this should look:
"volumes" => [
[
"name" => "app",
"emptyDir" => "{}",
],
]
volumes:
- name: app
emptyDir: {}
I noticed this was addressed when creating a Deployment from a yaml file in #46, but I couldn't see if there was a way to handle {}
when creating w/ an array.
Sounds like these two cases may be similar if I'm understanding correctly?
@jlaswell you should be able to define an emptyDir as simply an empty array in PHP? I do it this way in my production deployment builder:
case 'empty_dir':
$volumes[] = [
'name' => $volume->name,
'emptyDir' => [],
];
break;
This gets translated to an empty object {} when it is encoded as JSON.
🤦 Thanks for the reminder! I appreciate the tip.
@xsir317 this is now fixed, I tried using JSON_FORCE_OBJECT too, but it breaks the encoding of other parts of the schema, like the port mappings. Instead I have opted to str_replace() the empty arrays as json objects. Please give it a try, I have tested it on my production cluster and all works well for me.