Skip to content

KubernetesObjectApi does not properly return typed objects #852

Closed
@schrodit

Description

@schrodit

Describe the bug
When using the general KubernetesObjectApi the objects are not returned as typed objects as defined in the api definitions (https://github.com/kubernetes-client/javascript/tree/master/src/gen/api), but rather the plain json value is returned.

** Client Version **
e.g. 0.16.3

** Server Version **
e.g. 1.21.0

To Reproduce

see code snippet

Expected behavior
I expect that known objects are returned with their proper types.

** Example Code**

const k8s = require('@kubernetes/client-node');

const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
const client = kc.makeApiClient(k8s.KubernetesObjectApi);

client.list('v1', 'Pod', 'default').then(res => {
    const p = res.body.items[0];
    console.log(typeof p.metadata.creationTimestamp); // "string"
})

k8sApi.listNamespacedPod('default').then((res) => {
    const p = res.body.items[0];
    console.log(typeof p.metadata.creationTimestamp.getTime()); // "Object" --> Date
});

Environment (please complete the following information):

  • OS: [e.g. Linux]
  • NodeJS Version [eg. 16]

Enhancement Proposal

I guess that the current behavior is intended to also support unknown objects.
Also one can currently work around the described issue by using the ObjectSerializer like that

const k8s = require('@kubernetes/client-node');
const res = await client.read({apiVersion: 'v1', 'kind': 'Pod', metadata: {'name': 'a', 'namespace': 'default'}});
const pod = res.body; // type: KubernetesObject
pod.metadata.creationTimestamp // type "string"

const p = ObjectSerializer.serialize(pod, 'V1Pod');

But I think there could be a good opportunity to simplify the way the generic client can be used and improve the typing
Maybe something like that:

class KubernetesObjectApi {
    public read<T extends KubernetesObject | KubernetesObject>(spec: T, ...): {res: http.response, body: T} {
        // do the stuff that is currently done
        return this.requestPromise(localVarRequestOptions, this.getKnownType(spec));
    }
    
    private getKnownType(spec: KubernetesObject): string {
      // get type from spec + V1APIResource
    }

}

const spec: V1Pod = {apiVersion: 'v1', 'kind': 'Pod', metadata: {'name': 'a', 'namespace': 'default'}};
const res = await client.read(spec);
const pod = res.body; // type V1Pod
pod.metadata.creationTimestamp // type "Date"

Further this example might be enhanced so that even custom types could be added to the known types that the ObjectSerializer can also serialize CRDs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions