Skip to content

Commit cb1fc4e

Browse files
author
Alex Stockinger
authored
String interpolation for kubectl (#59)
1 parent 2c5176f commit cb1fc4e

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

src/main/java/com/dajudge/kindcontainer/kubectl/ApplyFluent.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33
import com.dajudge.kindcontainer.BaseSidecarContainer.ExecInContainer;
44
import com.dajudge.kindcontainer.BaseSidecarContainer.FileTarget;
55
import com.dajudge.kindcontainer.exception.ExecutionException;
6-
import org.testcontainers.utility.MountableFile;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
import org.testcontainers.images.builder.Transferable;
9+
import org.testcontainers.shaded.org.apache.commons.io.IOUtils;
710

811
import java.io.IOException;
912
import java.util.ArrayList;
1013
import java.util.List;
14+
import java.util.function.Function;
15+
16+
import static java.lang.Thread.currentThread;
17+
import static java.util.Arrays.asList;
18+
import static java.util.function.Function.identity;
1119

1220
public class ApplyFluent<P> {
21+
private static final Logger LOG = LoggerFactory.getLogger(ApplyFluent.class);
1322
private final ExecInContainer exec;
1423
private final FileTarget fileTarget;
1524
private final P parent;
@@ -29,17 +38,36 @@ public ApplyFluent<P> namespace(final String namespace) {
2938
}
3039

3140
public ApplyFluent<P> fileFromClasspath(final String resourceName) {
41+
return fileFromClasspath(resourceName, identity());
42+
}
43+
44+
public ApplyFluent<P> fileFromClasspath(final String resourceName, final Function<byte[], byte[]> transform) {
3245
final String path = "/tmp/classpath:" + resourceName
3346
.replaceAll("_", "__")
3447
.replaceAll("[^a-zA-Z0-9.]", "_");
3548
files.add(path);
36-
preExecutionRunnables.add(() -> fileTarget.copyFileToContainer(
37-
MountableFile.forClasspathResource(resourceName),
38-
path
39-
));
49+
final byte[] bytes = transform.apply(resourceToByteArray(resourceName));
50+
final Transferable transferable = Transferable.of(bytes);
51+
preExecutionRunnables.add(() -> fileTarget.copyFileToContainer(transferable, path));
4052
return this;
4153
}
4254

55+
private byte[] resourceToByteArray(final String resourceName) {
56+
final List<ClassLoader> classloaders = asList(
57+
ApplyFluent.class.getClassLoader(),
58+
currentThread().getContextClassLoader(),
59+
ClassLoader.getSystemClassLoader()
60+
);
61+
for (final ClassLoader classloader : classloaders) {
62+
try {
63+
return IOUtils.resourceToByteArray(resourceName, ApplyFluent.class.getClassLoader());
64+
} catch (final IOException e) {
65+
LOG.debug("Failed to read classpath resource '{}' via classloader '{}'", resourceName, classloader, e);
66+
}
67+
}
68+
throw new IllegalArgumentException("Unable to locate resource: " + resourceName);
69+
}
70+
4371
public P run() throws IOException, ExecutionException, InterruptedException {
4472
final List<String> cmdline = new ArrayList<>();
4573
cmdline.add("kubectl");
Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,39 @@
11
package com.dajudge.kindcontainer;
22

3+
import io.fabric8.kubernetes.api.model.ConfigMap;
34
import org.junit.ClassRule;
45
import org.junit.Test;
56

7+
import java.util.Objects;
8+
import java.util.function.Function;
9+
610
import static com.dajudge.kindcontainer.TestUtils.runWithClient;
7-
import static org.junit.Assert.assertNotNull;
8-
import static org.testcontainers.utility.MountableFile.forClasspathResource;
11+
import static java.nio.charset.StandardCharsets.UTF_8;
12+
import static java.util.concurrent.TimeUnit.SECONDS;
13+
import static org.junit.Assert.assertEquals;
14+
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
915

1016
public class KubectlTest {
1117

18+
private static final Function<byte[], byte[]> APPLY_PLACEHOLDERS = bytes -> new String(bytes, UTF_8)
19+
.replace("{{ my-value }}", "Hello, world!")
20+
.getBytes(UTF_8);
1221
@ClassRule
1322
public static ApiServerContainer<?> K8S = new ApiServerContainer<>()
1423
.withKubectl(kubectl -> kubectl.apply
15-
.fileFromClasspath("manifests/config_map_1.yaml")
24+
.fileFromClasspath("manifests/config_map_1.yaml", APPLY_PLACEHOLDERS)
1625
.run());
1726

1827
@Test
19-
public void can_apply_manifest() throws Exception {
28+
public void can_apply_manifest() {
2029
runWithClient(K8S, client -> {
21-
assertNotNull(client.configMaps().inNamespace("configmap1").withName("configmap1").get());
30+
final ConfigMap configMap = await()
31+
.timeout(10, SECONDS)
32+
.until(
33+
() -> client.configMaps().inNamespace("configmap1").withName("configmap1").get(),
34+
Objects::nonNull
35+
);
36+
assertEquals("Hello, world!", configMap.getData().get("my-key"));
2237
});
2338
}
2439
}

src/test/resources/manifests/config_map_1.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ kind: ConfigMap
88
metadata:
99
name: configmap1
1010
namespace: configmap1
11+
data:
12+
my-key: {{ my-value }}

0 commit comments

Comments
 (0)