Skip to content

Commit

Permalink
fix(kubernetes): teach KubernetesManifest to support kubernetes resou…
Browse files Browse the repository at this point in the history
…rces where the spec is not a map (#5814)

* fix(kubernetes): teach KubernetesManifest to support kubernetes resources where the spec is not a map

For example, the openAPIV3Schema in a custom resource definition defines its spec property as an array, e.g.

$ cat mycrd.json | jq -r .spec.versions[0].schema.openAPIV3Schema.properties.spec.type
array

* test(kubernetes): verify that KubernetesDeployManifestOperation can deploy a custom resource whose spec is a list
  • Loading branch information
dbyron-sf committed Nov 17, 2022
1 parent 2723211 commit 1d4e5a0
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ public List<OwnerReference> getOwnerReferences() {
@JsonIgnore
@SuppressWarnings("unchecked")
public KubernetesManifestSelector getManifestSelector() {
if (!containsKey("spec")) {
Map<String, Object> spec = getSpecAsMap();
if (spec == null) {
return null;
}

Map<String, Object> spec = (Map<String, Object>) get("spec");
if (!spec.containsKey("selector")) {
return null;
}
Expand Down Expand Up @@ -233,13 +233,26 @@ public Map<String, String> getAnnotations() {
}

@JsonIgnore
@SuppressWarnings("unchecked")
public Integer getReplicas() {
private Map<String, Object> getSpecAsMap() {
if (!containsKey("spec")) {
return null;
}

Map<String, Object> spec = (Map<String, Object>) get("spec");
Object specObject = get("spec");
if (!(specObject instanceof Map)) {
return null;
}

return (Map<String, Object>) specObject;
}

@JsonIgnore
@SuppressWarnings("unchecked")
public Integer getReplicas() {
Map<String, Object> spec = getSpecAsMap();
if (spec == null) {
return null;
}
if (!spec.containsKey("replicas")) {
return null;
}
Expand All @@ -250,22 +263,20 @@ public Integer getReplicas() {
@JsonIgnore
@SuppressWarnings("unchecked")
public void setReplicas(Number replicas) {
if (!containsKey("spec")) {
Map<String, Object> spec = getSpecAsMap();
if (spec == null) {
return;
}

Map<String, Object> spec = (Map<String, Object>) get("spec");
spec.put("replicas", replicas.intValue());
}

@JsonIgnore
@SuppressWarnings("unchecked")
public Optional<Map<String, String>> getSpecTemplateLabels() {
if (!containsKey("spec")) {
Map<String, Object> spec = getSpecAsMap();
if (spec == null) {
return Optional.empty();
}

Map<String, Object> spec = (Map<String, Object>) get("spec");
if (!spec.containsKey("template")) {
return Optional.empty();
}
Expand Down Expand Up @@ -296,11 +307,11 @@ public Optional<Map<String, String>> getSpecTemplateLabels() {
@JsonIgnore
@SuppressWarnings("unchecked")
public Optional<Map<String, String>> getSpecTemplateAnnotations() {
if (!containsKey("spec")) {
Map<String, Object> spec = getSpecAsMap();
if (spec == null) {
return Optional.empty();
}

Map<String, Object> spec = (Map<String, Object>) get("spec");
if (!spec.containsKey("template")) {
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,19 @@ class KubernetesManifestSpec extends Specification {
manifest.getApiVersion().toString() == CRD_API_VERSION
manifest.getSpecTemplateAnnotations() == Optional.empty()
}

void "correctly reads fields a custom resource where spec is a list"() {
when:
def sourceJson = KubernetesManifest.class.getResource("crd-manifest-spec-is-list.json").getText("utf-8")
def testPayload = gsonObj.fromJson(sourceJson, Object)
KubernetesManifest manifest = objectToManifest(testPayload)

then:
manifest.getName() == CRD_NAME
manifest.getKindName() == CRD_KIND
manifest.getApiVersion().toString() == CRD_API_VERSION
manifest.getReplicas() == null
manifest.getSpecTemplateLabels() == Optional.empty()
manifest.getSpecTemplateAnnotations() == Optional.empty()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,13 @@ void deploysBindingUnmodifiedConfigMap() {
.containsExactlyInAnyOrder("my-name-v000", "myconfig-v001");
}

@Test
void deploysCrdWhereSpecIsList() {
KubernetesDeployManifestDescription deployManifestDescription =
baseDeployDescription("deploy/crd-manifest-spec-is-list.yml");
deploy(deployManifestDescription);
}

private static KubernetesDeployManifestDescription baseDeployDescription(String manifest) {
KubernetesDeployManifestDescription deployManifestDescription =
new KubernetesDeployManifestDescription()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "test.example/v1alpha1",
"kind": "Custom1",
"metadata": {
"labels": {
"app": "app1"
},
"name": "default-custom1"
},
"spec": [
{
"id": "my-id",
"description": "my-description"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: test.example/v1alpha1
kind: Custom1
metadata:
name: default-custom1
labels:
app: app1
spec:
- id: my-id
description: my-description

0 comments on commit 1d4e5a0

Please sign in to comment.