Skip to content

Unable to deserialize duplicated resource names #2384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
schrodit opened this issue Apr 22, 2025 · 7 comments
Open

Unable to deserialize duplicated resource names #2384

schrodit opened this issue Apr 22, 2025 · 7 comments

Comments

@schrodit
Copy link
Contributor

Describe the bug

The generic client is unable to correctly deserialize resources correctly that overlap the kind name.
E.g. querying a custom resource of kind Probe with group monitoring.coreos.com/v1 results in an empty class of type V1Probe.
This is because the serializer does not take the group into account while deserializing.

Client Version
e.g. 1.1.2

Server Version
e.g. 1.30.1

To Reproduce

  1. Create a custom resource with an overlapping name (e.g. install the prometheus operator).
  2. create an instance
  3. try to query that instance: see code snippet

Expected behavior

The client should return the plane K8s object when the type is unknown.

Example Code

const kc = new KubeConfig();
kc.loadFromDefault();
const client = new KubernetesObjectApi(kc);
const p = await client.read({
    apiVersion: 'monitoring.coreos.com/v1',
    kind: 'Probe',
    metadata: {
        name: 'my-probe',
        namespace: 'default',
    },
});

Environment (please complete the following information):

  • OS: Linux
  • Node.js version: 20

Additional context

I think to correctly fix this, the ObjectSerializer has to use the whole unique name of a resource (group version and kind) to identify an object.
The group information is currently not available so I guess the converter has to be adapted to provide that info.

@brendandburns
Copy link
Contributor

Happy to take PRs to address this.

@schrodit
Copy link
Contributor Author

@brendandburns do you know if there is a similar info like the register.go files we have in the go client?

@schrodit
Copy link
Contributor Author

I started working in a fix for this. But it requires a change in the generator to add the group and version information to every type.

See the related PR: kubernetes-client/gen#279

@brendandburns
Copy link
Contributor

fwiw, I think instead of this generator changes it might be useful to do something similar to what we did in Java:

https://github.com/kubernetes-client/java/blob/043f86810ce7c7a532ea46c5fe43d67f21dbadc2/util/src/main/java/io/kubernetes/client/util/ModelMapper.java#L52

We can use the discovery endpoint on the server to dynamically discover and register GVK+Type into the ModelMapper.

@schrodit
Copy link
Contributor Author

schrodit commented Apr 30, 2025

@brendandburns

https://github.com/kubernetes-client/java/blob/043f86810ce7c7a532ea46c5fe43d67f21dbadc2/util/src/main/java/io/kubernetes/client/util/ModelMapper.java#L52

I'm not sure if that works as expected. If I read the code correctly, it does read the classes from io.kubernetes.client.openapi.models (e.g. V1DeamoSet). Then the apiGroup is parsed from the class name in getApiGroup. But the classnames do not include the groupname (e.g. V1DeamonSet) so we always end up in the else case where the group is set to null. This leads to all classes being in the core group. The class should be named AppsV1DaemonSet to properly work.

sidenote: some classes like CoreV1Endpoint include the group. But the majority does not include the group name.

Also the java implementation uses some hardcoded mapping (in initApiGroupMap) This mapping has to be manually maintained and is therefore error prone. Although it might be ok as the core groups do not change that often.

We can use the discovery endpoint on the server to dynamically discover and register GVK+Type into the ModelMapper.

With that issue above, I don't think that the discovery solves that issue fully. In case there is a resource (either from a CRD or a apiextension) with a duplicated kind we end up with a potential wrong assignment?
E.g. if there is a custom resource with kind Deployment but of apiVersion my-company.com/v1.

Also the discovery can be skipped (https://github.com/kubernetes-client/java/blob/master/extended/src/main/java/io/kubernetes/client/extended/kubectl/Kubectl.java#L232) and I guess we should try to solve the issue for both cases?

It was some time ago that I was working with java so I might have missed something here?

@brendandburns
Copy link
Contributor

@schrodit ah, you are right, the code generator we used used to place the group in the class name (e.g. https://github.com/kubernetes-client/java/tree/release-11/kubernetes/src/main/java/io/kubernetes/client/openapi/models) but we switched generators and it looks like it doesn't do that anymore :(

@brendandburns
Copy link
Contributor

@schrodit while we work out the potential generator fixes for this, why don't we add an equivalent of the ModelMapper to the code so that you can at least statically register mappings to solve this particular issue. We're going to need it one way or the other anyway since Typescript doesn't really have reflection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants