diff --git a/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/utils/SerializationTest.java b/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/utils/SerializationTest.java index f679b1768dc..5bf5f9ac84a 100644 --- a/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/utils/SerializationTest.java +++ b/kubernetes-client/src/test/java/io/fabric8/kubernetes/client/utils/SerializationTest.java @@ -32,7 +32,6 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.JSONSchemaProps; import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.api.model.batch.v1.Job; import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.model.annotation.Group; import io.fabric8.kubernetes.model.annotation.Version; diff --git a/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java b/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java index eda28a29880..7f5b6faae47 100644 --- a/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java +++ b/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java @@ -33,7 +33,7 @@ import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; - +import com.fasterxml.jackson.databind.exc.InvalidFormatException; import io.fabric8.kubernetes.api.KubernetesResourceMappingProvider; import io.fabric8.kubernetes.api.model.GenericKubernetesResource; import io.fabric8.kubernetes.api.model.HasMetadata; @@ -50,6 +50,9 @@ public class KubernetesDeserializer extends JsonDeserializer private static final Mapping mapping = new Mapping(); + // template deserialization can fail if unless we use generic resources + private static ThreadLocal IN_TEMPLATE = ThreadLocal.withInitial(() -> false); + @Override public KubernetesResource deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode node = jp.readValueAsTree(); @@ -84,7 +87,23 @@ private static KubernetesResource fromObjectNode(JsonParser jp, JsonNode node) t if (resourceType == null) { return jp.getCodec().treeToValue(node, GenericKubernetesResource.class); } else if (KubernetesResource.class.isAssignableFrom(resourceType)){ - return jp.getCodec().treeToValue(node, resourceType); + boolean inTemplate = IN_TEMPLATE.get(); + if (!inTemplate && "io.fabric8.openshift.api.model.Template".equals(resourceType.getName())) { + inTemplate = true; + IN_TEMPLATE.set(true); + } + try { + return jp.getCodec().treeToValue(node, resourceType); + } catch (InvalidFormatException e) { + if (!inTemplate) { + throw e; + } + return jp.getCodec().treeToValue(node, GenericKubernetesResource.class); + } finally { + if (inTemplate) { + IN_TEMPLATE.remove(); + } + } } } return null; diff --git a/kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/TemplateTest.java b/kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/TemplateTest.java index bc497998eba..1321fb170a3 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/TemplateTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/openshift/client/server/mock/TemplateTest.java @@ -16,6 +16,7 @@ package io.fabric8.openshift.client.server.mock; import io.fabric8.kubernetes.api.model.APIGroupListBuilder; +import io.fabric8.kubernetes.api.model.GenericKubernetesResource; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.KubernetesList; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; @@ -26,6 +27,7 @@ import io.fabric8.kubernetes.api.model.ServiceSpec; import io.fabric8.kubernetes.api.model.StatusBuilder; import io.fabric8.kubernetes.client.utils.IOHelpers; +import io.fabric8.kubernetes.client.utils.Serialization; import io.fabric8.openshift.api.model.ParameterBuilder; import io.fabric8.openshift.api.model.Template; import io.fabric8.openshift.api.model.TemplateBuilder; @@ -44,6 +46,7 @@ import java.util.Map; import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -183,6 +186,22 @@ void shouldLoadTemplateWithNumberParameters() { map.put("PORT", "8080"); KubernetesList list = client.templates().withParameters(map).load(getClass().getResourceAsStream("/template-with-number-params.yml")).processLocally(map); assertListIsServiceWithPort8080(list); + assertThat(list.getItems()).singleElement() + .isInstanceOf(Service.class) + .extracting("spec.ports").asList().singleElement() + .hasFieldOrPropertyWithValue("port", 8080); + } + + @Test + void shouldGetTemplateWithNumberParameters() { + OpenShiftClient client = new DefaultOpenShiftClient(new OpenShiftConfigBuilder().withDisableApiGroupCheck(true).build()); + Template template = client.templates().load(getClass().getResourceAsStream("/template-with-number-params.yml")).get(); + assertThat(template) + .extracting(Template::getObjects).asList() + .singleElement() + .isInstanceOf(GenericKubernetesResource.class) + .extracting("additionalProperties.spec.ports").asList().singleElement() + .hasFieldOrPropertyWithValue("port", "${PORT}"); } protected void assertListIsServiceWithPort8080(KubernetesList list) {