Skip to content

Commit

Permalink
Add version parameter to helm3 fluent API (dajudge#276)
Browse files Browse the repository at this point in the history
* Added version parameter to InstallFluent

* Added version parameter to InstallFluent and JavaDoc

* Add test to ensure version parameter is applied

---------

Co-authored-by: Alex Stockinger <mail@alexstockinger.de>
  • Loading branch information
martin-schaefer and dajudge authored Feb 27, 2024
1 parent 9007666 commit 30dfcd6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 9 deletions.
58 changes: 54 additions & 4 deletions src/main/java/com/dajudge/kindcontainer/helm/InstallFluent.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import com.dajudge.kindcontainer.BaseSidecarContainer.ExecInContainer;
import com.dajudge.kindcontainer.exception.ExecutionException;
import org.testcontainers.containers.ContainerState;
import org.testcontainers.utility.MountableFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import static java.util.Arrays.asList;

Expand All @@ -17,6 +16,7 @@ public class InstallFluent<P> {
private final P parent;
private String namespace;
private boolean createNamespace;
private String version;
private final Map<String, String> params = new HashMap<>();

private final List<String> values = new ArrayList<>();
Expand All @@ -26,31 +26,77 @@ public InstallFluent(final ExecInContainer c, final P parent) {
this.parent = parent;
}

/**
* Adds the given key/value as --set parameter to the Helm install command.
* @param key required
* @param value required
* @return The fluent API
*/
public InstallFluent<P> set(final String key, final String value) {
params.put(key, value);
return this;
}

/**
* Adds the given values file as -f parameter to the Helm install command.
* Make sure the values file is available in the Helm container.
* @see ContainerState#copyFileToContainer(MountableFile, String)
* @param path Path to the values file in the Helm container.
* @return The fluent API
*/
public InstallFluent<P> values(final String path) {
values.add(path);
return this;
}

/**
* Sets the given namespace as target namespace (--namespace parameter) for the Helm install command.
* @param namespace required
* @return The fluent API
*/
public InstallFluent<P> namespace(final String namespace) {
this.namespace = namespace;
return this;
}

/**
* Enables or disables the creation of the target namespace for the Helm install command. (--create-namespace parameter)
* @param createNamespace true to enable creation, false otherwise
* @return The fluent API
*/
public InstallFluent<P> createNamespace(final boolean createNamespace) {
this.createNamespace = createNamespace;
return this;
}


/**
* Enables the creation of the target namespace for the Helm install command.
* @return The fluent API
*/
public InstallFluent<P> createNamespace() {
return createNamespace(true);
}

/**
* Sets the version for the Helm chart to be installed. (--version parameter)
* @param version required
* @return The fluent API
*/
public InstallFluent<P> version(final String version) {
this.version = version;
return this;
}

/**
* Runs the Helm install command.
* @param releaseName The release name of the Helm installation
* @param chart The chart name of the Helm installation
* @return Parent container
* @throws IOException
* @throws InterruptedException
* @throws ExecutionException
*/
public P run(final String releaseName, final String chart) throws IOException, InterruptedException, ExecutionException {
try {
final List<String> cmdline = new ArrayList<>(asList("helm", "install"));
Expand All @@ -60,6 +106,9 @@ public P run(final String releaseName, final String chart) throws IOException, I
if (createNamespace) {
cmdline.add("--create-namespace");
}
if (version != null) {
cmdline.addAll(asList("--version", version));
}
params.forEach((k, v) -> cmdline.addAll(asList("--set", String.format("%s=%s", k, v))));
cmdline.addAll(asList(releaseName, chart));
values.forEach(v -> {
Expand All @@ -70,6 +119,7 @@ public P run(final String releaseName, final String chart) throws IOException, I
} finally {
createNamespace = false;
namespace = null;
version = null;
params.clear();
}
}
Expand Down
30 changes: 25 additions & 5 deletions src/test/java/com/dajudge/kindcontainer/Helm3Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,57 @@
import com.dajudge.kindcontainer.util.ContainerVersionHelpers.KubernetesTestPackage;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.testcontainers.utility.MountableFile;

import java.util.stream.Stream;
import org.testcontainers.utility.MountableFile;

import static com.dajudge.kindcontainer.util.ContainerVersionHelpers.allContainers;
import static com.dajudge.kindcontainer.util.ContainerVersionHelpers.runWithK8s;
import static com.dajudge.kindcontainer.util.TestUtils.runWithClient;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class Helm3Test {

private static final String NAMESPACE = "hello";

@TestFactory
public Stream<DynamicTest> can_install_something() {
return allContainers(this::assertCanInstallSomething);
}

@TestFactory
public Stream<DynamicTest> assertInvalidVersionFails() {
return allContainers(this::assertInvalidVersionFails);
}

private void assertCanInstallSomething(final KubernetesTestPackage<? extends KubernetesContainer<?>> testPkg) {
runWithK8s(configureContainer(testPkg.newContainer()), k8s -> runWithClient(k8s, client -> {
assertFalse(client.apps().deployments().inNamespace("hello").list().getItems().isEmpty());
assertCanInstallVersion(testPkg, "0.1.0");
}

private void assertInvalidVersionFails(final KubernetesTestPackage<? extends KubernetesContainer<?>> testPkg) {
assertThrows(RuntimeException.class, () -> assertCanInstallVersion(testPkg, "42.42.42"));
}

private void assertCanInstallVersion(
final KubernetesTestPackage<? extends KubernetesContainer<?>> testPkg,
final String version
) {
runWithK8s(configureContainer(testPkg.newContainer(), version), k8s -> runWithClient(k8s, client -> {
assertFalse(client.apps().deployments().inNamespace(NAMESPACE).list().getItems().isEmpty());
}));
}

private KubernetesContainer<?> configureContainer(KubernetesContainer<?> container) {
private KubernetesContainer<?> configureContainer(final KubernetesContainer<?> container, final String version) {
return container.withHelm3(helm -> {
helm.copyFileToContainer(MountableFile.forClasspathResource("hello-values.yaml"), "/apps/values.yaml");
helm.repo.add.run("examples", "https://helm.github.io/examples");
helm.repo.update.run();
helm.install
.namespace("hello")
.namespace(NAMESPACE)
.createNamespace()
.values("/apps/values.yaml")
.version(version)
.run("hello", "examples/hello-world");
});
}
Expand Down

0 comments on commit 30dfcd6

Please sign in to comment.