-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
AdmissionReview deserialization issue #5034
Comments
Earlier releases had a side effect of registering custom classes with the deserializer. This was removed to prevent situations like #5012 More than likely the resolution for you will be to register your custom class with the deserializer. See #3923 the supported way of doing this is including a /META-INF/services/io.fabric8.kubernetes.api.model.KubernetesResource with your custom resources. We are working towards offering more supported ways of doing this in subsequent releases. |
I'm facing exactly the same issue as described here.
I've also tried to register my custom resource using
but it also didn't help. |
@bachmanity1 from here the issue will lie with the rest of the application - the KubernetesDeserializer that is doing the deserialization must be being created in an isolated classloader - not the same one as you are registering from, nor one that is seeing the META-INF/services. I believe @csviri saw a situation like that before in the operator sdk. |
Hi @bachmanity1 , pls take a look on this project: https://github.com/java-operator-sdk/kubernetes-webooks-framework There are samples (not for webhook, but conversion hook, which essentially work the same way in regards the deserialization). In the most recent release the approach adding the file into: |
The problem was that I didn't have a |
There are two possibilities. Either you are dealing with a KubernetesDeserializer in an isolated classloader. Can you set a breakpoint in the KubernetesDeserializer - Line 163 in 009974f
Do you see it being called multiple times in your application? This is not expected with quarkus as there's a flat classloader and just a single static instance of Mapping expected. Or if it's only called a single time, then check with getKeyFromClass method if you class is passed to that - is it failing to add a mapping because apiGroup or apiVerion are missing? |
This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions! |
Hi @shawkins, I've started to face this issue again since version 6.7.0, I think this is caused by the changes made in the #4662. Since version 6.5.0 I've registered my custom resources using the method shown below (this method is called in the main method when operator is initialized). @SafeVarargs
public static void registerCustomKinds(Class<? extends KubernetesResource>... customKinds) {
for (var customKind : customKinds) {
KubernetesDeserializer.registerCustomKind(HasMetadata.getApiVersion(customKind),
HasMetadata.getKind(customKind), customKind);
}
} and everything worked fine. Then after the API changes made in #4662 I've modified my method as shown below: @SafeVarargs
public static void registerCustomKinds(Class<? extends KubernetesResource>... customKinds) {
final var deserializer = new KubernetesDeserializer();
// final var deserializer = new KubernetesDeserializer(false); also doesn't work
for (var customKind : customKinds) {
deserializer.registerCustomKind(HasMetadata.getApiVersion(customKind),
HasMetadata.getKind(customKind), customKind);
// deserializer.registerKubernetesResource(customKind); also doesn't work
}
} and now it doesn't work and I'm seeing the same error as before, i.e. I've also tried replacing @SafeVarargs
public static void registerCustomKinds(Class<? extends KubernetesResource>... customKinds) {
final var serializer = new KubernetesSerialization();
// final var serializer = new KubernetesSerialization(new ObjectMapper(), false); also doesn't work
for (var customKind : customKinds) {
serializer.registerKubernetesResource(customKind);
}
} I've also tried registering a custom resource using |
KubernetesSerialization is passed to the KubernetesClient via the KubernetesClientBuilder if you want to customize prior to using the client, and you may access it on the client via client.getKubernetesSerialization. |
Yes, after reading #4662 more carefully I've figured out that KubernetesSerialization instance must be passed to the KubernetesClient but this doesn't work for me because in my case deserialization is not handled by the KubernetesClient but by the Spring Boot framework, i.e. AdmissionReview instance is received as a request body. I could resolve my problem by serializing GenericKubernetesResource back to the json string and then deserializing it to the MyCustomResource. Serialization.unmarshal(Serialization.asJson(gkr), MyCustomResource.class) |
One approach would be to share the mapper used by KubernetesSerialization with spring boot. |
How can I do it? |
You can pass a mapper in the KubernetesSerialization constructor. |
Sharing a mapper between KubernetesSerialization and spring boot does indeed prove to be effective. Thanks! |
I'm using
AdmissionReview
to implement webhook, it used to work well in version6.2.0
but after upgrading to version6.5.0
I started facing issues.In version
6.2.0
, when I sent a json shown above to the webhook serverrequest.object
field was deserialized as aCustomResource
class, however in version6.5.0
this same field is deserialized as aGenericKubernetesResource
. I haven't changed anything else just downgrading kubernetes-client version to6.2.0
resolves the problem. How can I achieve same behavior using version6.5.0
?The text was updated successfully, but these errors were encountered: