Skip to content

Commit

Permalink
feat: provided additional KubernetesClient.resource(InputStream) method
Browse files Browse the repository at this point in the history
Signed-off-by: Marc Nuri <[email protected]>
  • Loading branch information
manusa committed Nov 11, 2022
1 parent b726498 commit 48ff68a
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -286,18 +286,18 @@ MixedOperation<GenericKubernetesResource, GenericKubernetesResourceList, Resourc
NonNamespaceOperation<ComponentStatus, ComponentStatusList, Resource<ComponentStatus>> componentstatuses();

/**
* Load a Kubernetes resource object from file InputStream
* Load Kubernetes resource object(s) from the provided InputStream.
*
* @param is File input stream object containing json/yaml content
* @return deserialized object
* @param is the input stream containing JSON/YAML content
* @return an operation instance to work on the list of Kubernetes Resource objects
*/
ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> load(InputStream is);

/**
* Load a Kubernetes list object
*
* @param s kubernetes list as string
* @return deserialized KubernetesList object
* @return an operation instance to work on the deserialized KubernetesList objects
*/
ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourceList(String s);

Expand Down Expand Up @@ -340,11 +340,20 @@ NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourc
* KubernetesResource operations. You can pass any Kubernetes resource as string object and do
* all operations
*
* @param s Kubernetes resource object as string
* @param s a Kubernetes resource object as string
* @return operations object for Kubernetes resource
*/
NamespaceableResource<HasMetadata> resource(String s);

/**
* KubernetesResource operations. You can pass any Kubernetes resource as an InputStream object and perform
* all operations
*
* @param is the InputStream containing a serialized Kubernetes resource.
* @return operations object for Kubernetes resource.
*/
NamespaceableResource<HasMetadata> resource(InputStream is);

/**
* Operations for Binding resource in APIgroup core/v1
*
Expand Down Expand Up @@ -514,7 +523,7 @@ NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourc

/**
* Visit all resources with the given {@link ApiVisitor}.
*
*
* @param visitor
*/
void visitResources(ApiVisitor visitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,11 @@ public NamespaceableResource<HasMetadata> resource(String s) {
return getClient().resource(s);
}

@Override
public NamespaceableResource<HasMetadata> resource(InputStream is) {
return getClient().resource(is);
}

@Override
public MixedOperation<Binding, KubernetesResourceList<Binding>, Resource<Binding>> bindings() {
return getClient().bindings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,28 @@ public <T extends HasMetadata> NamespaceableResource<T> resource(T item) {
return new NamespaceableResourceAdapter<>(item, op);
}

private NamespaceableResource<HasMetadata> resource(Object resource) {
if (resource instanceof HasMetadata) {
return resource((HasMetadata) resource);
}
throw new KubernetesClientException("Unable to create a valid resource from the provided object (" +
resource.getClass().getName() + ")");
}

/**
* {@inheritDoc}
*/
@Override
public NamespaceableResource<HasMetadata> resource(String s) {
return resource((HasMetadata) Serialization.unmarshal(s));
return resource(Serialization.<Object>unmarshal(s));
}

/**
* {@inheritDoc}
*/
@Override
public NamespaceableResource<HasMetadata> resource(InputStream is) {
return resource(Serialization.<Object>unmarshal(is));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
package io.fabric8.kubernetes.client.impl;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable;
import io.fabric8.kubernetes.client.http.BasicBuilder;
import io.fabric8.kubernetes.client.http.HttpHeaders;
import io.fabric8.kubernetes.client.utils.HttpClientUtils;
Expand All @@ -35,6 +38,7 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Expand All @@ -44,6 +48,8 @@
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -153,4 +159,65 @@ void shouldPropagateImpersonateSettings() {
assertArrayEquals(new String[] { "b" }, currentConfig.getImpersonateGroups());
assertEquals(Collections.singletonList("d"), currentConfig.getImpersonateExtras().get("c"));
}

@Test
@DisplayName("resource(String).get with HasMetadata should deserialize")
void resourceFromStringWithHasMetadata() {
assertThat(new KubernetesClientImpl().resource("apiVersion: v1\nkind: Pod").get())
.isInstanceOf(Pod.class);
}

@Test
@DisplayName("resource(String) with no HasMetadata should throwException")
void resourceFromStringWithInvalid() {
final KubernetesClient kc = new KubernetesClientImpl();
assertThatExceptionOfType(KubernetesClientException.class)
.isThrownBy(() -> kc.resource("NotAPod"))
.withMessageStartingWith("Unable to create a valid resource from the provided object");
}

@Test
@DisplayName("resource(InputStream).get with HasMetadata should deserialize")
void resourceFromInputStreamWithHasMetadata() throws IOException {
final String podYaml = "apiVersion: v1\nkind: Pod";
try (InputStream is = new ByteArrayInputStream(podYaml.getBytes(StandardCharsets.UTF_8))) {
assertThat(new KubernetesClientImpl().resource(is).get())
.isInstanceOf(Pod.class);
}
}

@Test
@DisplayName("resource(InputStream) with no HasMetadata should throwException")
void resourceFromInputStreamWithInvalid() throws IOException {
final KubernetesClient kc = new KubernetesClientImpl();
final String podYaml = "NotAPod";
try (InputStream is = new ByteArrayInputStream(podYaml.getBytes(StandardCharsets.UTF_8))) {
assertThatExceptionOfType(KubernetesClientException.class)
.isThrownBy(() -> kc.resource(is))
.withMessageStartingWith("Unable to create a valid resource from the provided object");
}
}

@Test
@DisplayName("load(InputStream).get with HasMetadata should deserialize")
void loadFromInputStreamWithHasMetadata() throws IOException {
final String podYaml = "apiVersion: v1\nkind: Pod";
try (InputStream is = new ByteArrayInputStream(podYaml.getBytes(StandardCharsets.UTF_8))) {
assertThat(new KubernetesClientImpl().load(is).get())
.containsExactly(new Pod());
}
}

@Test
@DisplayName("load(InputStream).get with no HasMetadata should throwException")
void loadFromInputStreamWithInvalid() throws IOException {
final String podYaml = "NotAPod";
try (InputStream is = new ByteArrayInputStream(podYaml.getBytes(StandardCharsets.UTF_8))) {
final ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> load =
new KubernetesClientImpl().load(is);
assertThatIllegalArgumentException()
.isThrownBy(load::get)
.withMessageStartingWith("Could not convert item to a list of HasMetadata");
}
}
}

0 comments on commit 48ff68a

Please sign in to comment.