Skip to content

Commit

Permalink
Fix fabric8io#2510: Yaml containing aliases rejected due to FasterXML…
Browse files Browse the repository at this point in the history
… bug

Modify the way we deserialize Yaml objects. Load them into raw HashMap
using SnakeYAML and then use Jackson to convert them to JSON and finally
the required object
  • Loading branch information
rohanKanojia committed Dec 11, 2020
1 parent 8e3f4be commit db1923b
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### 5.0-SNAPSHOT

#### Bugs
Fix #2510 : Yaml containing aliases rejected due to FasterXML bug

#### Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.fabric8.kubernetes.api.model.KubernetesResource;
import io.fabric8.kubernetes.client.KubernetesClientException;
import org.yaml.snakeyaml.Yaml;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
Expand Down Expand Up @@ -132,7 +133,7 @@ public static <T> T unmarshal(InputStream is, ObjectMapper mapper, Map<String, S
bis.reset();

if (intch != '{') {
mapper = YAML_MAPPER;
return unmarshalYaml(bis, null);
}
return mapper.readerFor(KubernetesResource.class).readValue(bis);
} catch (IOException e) {
Expand Down Expand Up @@ -237,15 +238,14 @@ public static <T> T unmarshal(InputStream is, TypeReference<T> type, Map<String,

ObjectMapper mapper = JSON_MAPPER;
if (intch != '{') {
mapper = YAML_MAPPER;
return unmarshalYaml(bis, type);
}
return mapper.readValue(bis, type);
} catch (IOException e) {
throw KubernetesClientException.launderThrowable(e);
}
}


private static List<KubernetesResource> getKubernetesResourceList(Map<String, String> parameters, String specFile) {
return splitSpecFile(specFile).stream().filter(Serialization::validate)
.map(document ->
Expand Down Expand Up @@ -294,4 +294,18 @@ private static String readSpecFileFromInputStream(InputStream inputStream) {
throw new RuntimeException("Unable to read InputStream." + e);
}
}

private static <T> T unmarshalYaml(InputStream is, TypeReference<T> type) throws JsonProcessingException {
final Yaml yaml = new Yaml();
Map<String, Object> obj = yaml.load(is);
String objAsJsonStr = JSON_MAPPER.writeValueAsString(obj);
return unmarshalJsonStr(objAsJsonStr, type);
}

private static <T> T unmarshalJsonStr(String jsonString, TypeReference<T> type) throws JsonProcessingException {
if (type != null) {
return JSON_MAPPER.readValue(jsonString, type);
}
return JSON_MAPPER.readerFor(KubernetesResource.class).readValue(jsonString);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@

import io.fabric8.kubernetes.api.model.KubernetesList;
import io.fabric8.kubernetes.api.model.KubernetesResource;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.api.model.Service;
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 org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Map;
Expand Down Expand Up @@ -139,4 +141,28 @@ void containsMultipleDocumentsWithSingleDocumentAndLinuxLineEnds() {
// Then
assertFalse(result);
}

@Test
void testSerializeYamlWithAlias() {
// Given
InputStream fileInputStream = getClass().getResourceAsStream("/test-pod-manifest-with-aliases.yml");

// When
Pod pod = Serialization.unmarshal(fileInputStream);

// Then
assertNotNull(pod);
assertEquals("test-pod-with-alias", pod.getMetadata().getName());
assertEquals("build", pod.getSpec().getNodeSelector().get("workload"));
assertEquals(1, pod.getSpec().getTolerations().size());
assertEquals(1000, pod.getSpec().getSecurityContext().getRunAsGroup().intValue());
assertEquals(1000, pod.getSpec().getSecurityContext().getRunAsUser().intValue());
assertEquals(2, pod.getSpec().getContainers().size());
assertEquals("ubuntu", pod.getSpec().getContainers().get(0).getName());
assertEquals("ubuntu:bionic", pod.getSpec().getContainers().get(0).getImage());
assertEquals(new Quantity("100m"), pod.getSpec().getContainers().get(0).getResources().getRequests().get("cpu"));
assertEquals("python3", pod.getSpec().getContainers().get(1).getName());
assertEquals("python:3.7", pod.getSpec().getContainers().get(1).getImage());
assertEquals(new Quantity("100m"), pod.getSpec().getContainers().get(1).getResources().getRequests().get("cpu"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: v1
kind: Pod
metadata:
name: test-pod-with-alias
spec:
nodeSelector:
workload: build
tolerations:
- key: nodeType
operator: Equal
value: build
effect: NoSchedule
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- name: ubuntu
image: ubuntu:bionic
imagePullPolicy: Always
command:
- cat
tty: true
resources:
requests: &id001
cpu: 100m
- name: python3
image: python:3.7
imagePullPolicy: Always
command:
- cat
tty: true
resources:
requests: *id001
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package io.fabric8.kubernetes.client.mock;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Namespace;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.api.model.ResourceQuota;
import io.fabric8.kubernetes.api.model.ResourceQuotaBuilder;
Expand All @@ -28,6 +30,8 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
Expand Down Expand Up @@ -113,8 +117,25 @@ public void testeDeleteMulti() {
@Test
public void testLoadFromFile() {
KubernetesClient client = server.getClient();
ResourceQuota resourceQuota = client.resourceQuotas().load(getClass().getResourceAsStream("/test-resourcequota.yml")).get();
assertEquals("compute-quota", resourceQuota.getMetadata().getName());
List<HasMetadata> list = client.load(getClass().getResourceAsStream("/test-resourcequota.yml")).get();
assertEquals(3, list.size());
assertTrue(list.get(0) instanceof ResourceQuota);
assertEquals("compute-quota", list.get(0).getMetadata().getName());
assertEquals("myspace", list.get(0).getMetadata().getNamespace());
assertEquals(new Quantity("1"), ((ResourceQuota) list.get(0)).getSpec().getHard().get("requests.cpu"));
assertEquals(new Quantity("1Gi"), ((ResourceQuota) list.get(0)).getSpec().getHard().get("requests.memory"));
assertEquals(new Quantity("2"), ((ResourceQuota) list.get(0)).getSpec().getHard().get("limits.cpu"));
assertEquals(new Quantity("2Gi"), ((ResourceQuota) list.get(0)).getSpec().getHard().get("limits.memory"));
assertTrue(list.get(1) instanceof ResourceQuota);
assertEquals("object-quota", list.get(1).getMetadata().getName());
assertEquals(new Quantity("10"), ((ResourceQuota) list.get(1)).getSpec().getHard().get("configmaps"));
assertEquals(new Quantity("4"), ((ResourceQuota) list.get(1)).getSpec().getHard().get("persistentvolumeclaims"));
assertEquals(new Quantity("20"), ((ResourceQuota) list.get(1)).getSpec().getHard().get("replicationcontrollers"));
assertEquals(new Quantity("10"), ((ResourceQuota) list.get(1)).getSpec().getHard().get("secrets"));
assertEquals(new Quantity("10"), ((ResourceQuota) list.get(1)).getSpec().getHard().get("services"));
assertEquals(new Quantity("2"), ((ResourceQuota) list.get(1)).getSpec().getHard().get("services.loadbalancers"));
assertTrue(list.get(2) instanceof Namespace);
assertEquals("myspace", list.get(2).getMetadata().getName());
}

@Test
Expand Down

0 comments on commit db1923b

Please sign in to comment.