Skip to content

Commit

Permalink
Fix #2510: Yaml containing aliases rejected due to FasterXML bug
Browse files Browse the repository at this point in the history
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.