From 9ead70586c9444b65390ecc8df1d03cd31a6cab3 Mon Sep 17 00:00:00 2001 From: Jeromy Cannon Date: Thu, 5 Oct 2023 14:37:52 +0100 Subject: [PATCH 1/4] feat: add helm list releases task Signed-off-by: Jeromy Cannon --- fullstack-examples/build.gradle.kts | 3 ++ fullstack-gradle-plugin/build.gradle.kts | 1 + .../gradle/plugin/HelmListReleasesTask.java | 52 +++++++++++++++++++ .../plugin/HelmInstallChartTaskTest.java | 30 ++++++++--- 4 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java diff --git a/fullstack-examples/build.gradle.kts b/fullstack-examples/build.gradle.kts index 54b447777..9af49048a 100644 --- a/fullstack-examples/build.gradle.kts +++ b/fullstack-examples/build.gradle.kts @@ -15,6 +15,7 @@ */ import com.hedera.fullstack.gradle.plugin.HelmInstallChartTask +import com.hedera.fullstack.gradle.plugin.HelmListReleasesTask import com.hedera.fullstack.gradle.plugin.HelmUninstallChartTask plugins { @@ -52,6 +53,8 @@ tasks.register("helmUninstallNginxChart") { release.set("nginx-release") } +tasks.register("helmListRelease") { namespace.set("nginx-ns") } + tasks.check { dependsOn("helmInstallNginxChart") dependsOn("helmUninstallNginxChart") diff --git a/fullstack-gradle-plugin/build.gradle.kts b/fullstack-gradle-plugin/build.gradle.kts index 6a2dc21fd..b530a24aa 100644 --- a/fullstack-gradle-plugin/build.gradle.kts +++ b/fullstack-gradle-plugin/build.gradle.kts @@ -24,6 +24,7 @@ plugins { dependencies { api(platform(project(":fullstack-bom"))) implementation(project(":fullstack-helm-client")) + testImplementation("org.assertj:assertj-core:3.24.2") } gradlePlugin { diff --git a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java new file mode 100644 index 000000000..db2107ab7 --- /dev/null +++ b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.fullstack.gradle.plugin; + +import com.hedera.fullstack.helm.client.HelmClient; +import com.hedera.fullstack.helm.client.HelmClientBuilder; +import com.hedera.fullstack.helm.client.model.release.ReleaseItem; +import java.util.List; +import org.gradle.api.DefaultTask; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.TaskAction; +import org.gradle.api.tasks.options.Option; + +public abstract class HelmListReleasesTask extends DefaultTask { + @Input + @Optional + @Option(option = "namespace", description = "The namespace to use when listing the releases") + public abstract Property getNamespace(); + + @TaskAction + List listReleases() { + HelmClientBuilder helmClientBuilder = HelmClient.builder(); + if (getNamespace().isPresent()) { + helmClientBuilder.defaultNamespace(getNamespace().get()); + } + HelmClient helmClient = helmClientBuilder.build(); + try { + return helmClient.listReleases(); + } catch (Exception e) { + this.getProject() + .getLogger() + .error("HelmListReleasesTask.listReleases() An ERROR occurred while listing the releases: ", e); + throw e; + } + } +} diff --git a/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java b/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java index 101eb4a15..f006623e2 100644 --- a/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java +++ b/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java @@ -17,12 +17,14 @@ package com.hedera.fullstack.gradle.plugin; import static com.hedera.fullstack.base.api.util.ExceptionUtils.suppressExceptions; -import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; import com.hedera.fullstack.helm.client.HelmClient; import com.hedera.fullstack.helm.client.HelmExecutionException; import com.hedera.fullstack.helm.client.model.Chart; import com.hedera.fullstack.helm.client.model.Repository; +import com.hedera.fullstack.helm.client.model.release.ReleaseItem; import java.io.File; import java.io.IOException; import java.util.List; @@ -68,7 +70,7 @@ void testHelmInstallChartTaskForHederaNetworkChart() throws IOException { task.getSet().add("defaults.root.image.repository=hashgraph/full-stack-testing/ubi8-init-dind"); task.getValues().add(valuesFilePath); }); - assertEquals("fst", helmInstallChartTask.getRelease().get()); + assertThat(helmInstallChartTask.getRelease().get()).isEqualTo("fst"); helmInstallChartTask.installChart(); } finally { // TODO: comment this out as workaround until we no longer need manual use of make command @@ -79,8 +81,8 @@ void testHelmInstallChartTaskForHederaNetworkChart() throws IOException { @Test @DisplayName("Simple Helm Install Chart Task") void testHelmInstallChartTaskSimple() { - HelmClient helmClient = - HelmClient.builder().defaultNamespace("simple-test").build(); + final String namespace = "simple-test"; + HelmClient helmClient = HelmClient.builder().defaultNamespace(namespace).build(); suppressExceptions(() -> helmClient.uninstallChart(RELEASE_NAME)); suppressExceptions(() -> helmClient.removeRepository(REPOSITORY)); final List repositories = helmClient.listRepositories(); @@ -92,15 +94,29 @@ void testHelmInstallChartTaskSimple() { .create("helmInstallChart", HelmInstallChartTask.class, task -> { task.getChart().set(CHART.name()); task.getCreateNamespace().set(true); - task.getNamespace().set("simple-test"); + task.getNamespace().set(namespace); task.getRelease().set(RELEASE_NAME); task.getRepo().set(CHART.repoName()); }); - assertEquals(RELEASE_NAME, helmInstallChartTask.getRelease().get()); + assertThat(helmInstallChartTask.getRelease().get()).isEqualTo(RELEASE_NAME); helmInstallChartTask.installChart(); + HelmListReleasesTask helmListReleasesTask = project.getTasks() + .create("helmListReleases", HelmListReleasesTask.class, task -> { + task.getNamespace().set(namespace); + }); + List releaseItems = helmListReleasesTask.listReleases(); + assertThat(releaseItems).isNotNull().isNotEmpty(); + ReleaseItem releaseItem = releaseItems.stream() + .filter(item -> item.name().equals(RELEASE_NAME)) + .findFirst() + .orElse(null); + assertThat(releaseItem).isNotNull(); + assertThat(releaseItem.name()).isEqualTo(RELEASE_NAME); + assertThat(releaseItem.namespace()).isEqualTo(namespace); + assertThat(releaseItem.status()).isEqualTo("deployed"); HelmUninstallChartTask helmUninstallChartTask = project.getTasks() .create("helmUninstallChart", HelmUninstallChartTask.class, task -> { - task.getNamespace().set("simple-test"); + task.getNamespace().set(namespace); task.getRelease().set(RELEASE_NAME); }); helmUninstallChartTask.uninstallChart(); From e7349d8557bc3fd041c373c8b3b259d0549846f8 Mon Sep 17 00:00:00 2001 From: Jeromy Cannon Date: Thu, 5 Oct 2023 17:08:25 +0100 Subject: [PATCH 2/4] converting to HelmReleaseExistsTask Signed-off-by: Jeromy Cannon --- .../gradle/plugin/HelmListReleasesTask.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java index db2107ab7..30016a7f3 100644 --- a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java +++ b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java @@ -27,21 +27,30 @@ import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.options.Option; -public abstract class HelmListReleasesTask extends DefaultTask { +public abstract class HelmReleaseExistsTask extends DefaultTask { + @Input + @Option(option = "release", description = "The release to verify exists") + public abstract Property getRelease(); + @Input @Optional @Option(option = "namespace", description = "The namespace to use when listing the releases") public abstract Property getNamespace(); + @Input + @Optional + @Option(option = "allNamespaces", description = "True if we should list releases in all namespaces") + public abstract Property getAllNamespaces(); + @TaskAction - List listReleases() { + void releaseExists() { HelmClientBuilder helmClientBuilder = HelmClient.builder(); if (getNamespace().isPresent()) { helmClientBuilder.defaultNamespace(getNamespace().get()); } HelmClient helmClient = helmClientBuilder.build(); try { - return helmClient.listReleases(); + List releaseItems = helmClient.listReleases(getAllNamespaces().getOrElse(false)); } catch (Exception e) { this.getProject() .getLogger() From fa47674aac20c086c319a8058eddf33a0780eb30 Mon Sep 17 00:00:00 2001 From: Jeromy Cannon Date: Fri, 6 Oct 2023 17:16:56 +0100 Subject: [PATCH 3/4] converting to HelmReleaseExistsTask with coverage Signed-off-by: Jeromy Cannon --- ...esTask.java => HelmReleaseExistsTask.java} | 33 +++++++--- .../plugin/HelmInstallChartTaskTest.java | 17 ++--- .../plugin/HelmReleaseExistsTaskTest.java | 63 +++++++++++++++++++ 3 files changed, 93 insertions(+), 20 deletions(-) rename fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/{HelmListReleasesTask.java => HelmReleaseExistsTask.java} (61%) create mode 100644 fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTaskTest.java diff --git a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java similarity index 61% rename from fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java rename to fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java index 30016a7f3..c1f453037 100644 --- a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmListReleasesTask.java +++ b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java @@ -20,6 +20,7 @@ import com.hedera.fullstack.helm.client.HelmClientBuilder; import com.hedera.fullstack.helm.client.model.release.ReleaseItem; import java.util.List; +import java.util.Objects; import org.gradle.api.DefaultTask; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -44,18 +45,36 @@ public abstract class HelmReleaseExistsTask extends DefaultTask { @TaskAction void releaseExists() { - HelmClientBuilder helmClientBuilder = HelmClient.builder(); - if (getNamespace().isPresent()) { - helmClientBuilder.defaultNamespace(getNamespace().get()); - } - HelmClient helmClient = helmClientBuilder.build(); + ReleaseItem releaseItem; try { - List releaseItems = helmClient.listReleases(getAllNamespaces().getOrElse(false)); + final String release = getRelease().getOrNull(); + Objects.requireNonNull(release, "release must not be null"); + + HelmClientBuilder helmClientBuilder = HelmClient.builder(); + if (getNamespace().isPresent()) { + helmClientBuilder.defaultNamespace(getNamespace().get()); + } + + HelmClient helmClient = helmClientBuilder.build(); + List releaseItems = + helmClient.listReleases(getAllNamespaces().getOrElse(false)); + releaseItem = releaseItems.stream() + .filter(item -> item.name().equals(release)) + .findFirst() + .orElse(null); } catch (Exception e) { this.getProject() .getLogger() - .error("HelmListReleasesTask.listReleases() An ERROR occurred while listing the releases: ", e); + .error( + "HelmReleaseExistsTask.releaseExists() An ERROR occurred while listing the releases: " + + e.getMessage(), + e); throw e; } + + if (releaseItem == null) { + throw new RuntimeException("HelmReleaseExistsTask.releaseExists(): Release " + + getRelease().get() + " does not exist"); + } } } diff --git a/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java b/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java index f006623e2..358874ab0 100644 --- a/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java +++ b/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmInstallChartTaskTest.java @@ -24,7 +24,6 @@ import com.hedera.fullstack.helm.client.HelmExecutionException; import com.hedera.fullstack.helm.client.model.Chart; import com.hedera.fullstack.helm.client.model.Repository; -import com.hedera.fullstack.helm.client.model.release.ReleaseItem; import java.io.File; import java.io.IOException; import java.util.List; @@ -100,20 +99,12 @@ void testHelmInstallChartTaskSimple() { }); assertThat(helmInstallChartTask.getRelease().get()).isEqualTo(RELEASE_NAME); helmInstallChartTask.installChart(); - HelmListReleasesTask helmListReleasesTask = project.getTasks() - .create("helmListReleases", HelmListReleasesTask.class, task -> { + HelmReleaseExistsTask helmReleaseExistsTask = project.getTasks() + .create("helmReleaseExists", HelmReleaseExistsTask.class, task -> { task.getNamespace().set(namespace); + task.getRelease().set(RELEASE_NAME); }); - List releaseItems = helmListReleasesTask.listReleases(); - assertThat(releaseItems).isNotNull().isNotEmpty(); - ReleaseItem releaseItem = releaseItems.stream() - .filter(item -> item.name().equals(RELEASE_NAME)) - .findFirst() - .orElse(null); - assertThat(releaseItem).isNotNull(); - assertThat(releaseItem.name()).isEqualTo(RELEASE_NAME); - assertThat(releaseItem.namespace()).isEqualTo(namespace); - assertThat(releaseItem.status()).isEqualTo("deployed"); + helmReleaseExistsTask.releaseExists(); HelmUninstallChartTask helmUninstallChartTask = project.getTasks() .create("helmUninstallChart", HelmUninstallChartTask.class, task -> { task.getNamespace().set(namespace); diff --git a/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTaskTest.java b/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTaskTest.java new file mode 100644 index 000000000..31e8db2b8 --- /dev/null +++ b/fullstack-gradle-plugin/src/test/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTaskTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.fullstack.gradle.plugin; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.gradle.api.Project; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class HelmReleaseExistsTaskTest { + private static Project project; + + @BeforeAll + static void beforeAll() { + project = ProjectBuilder.builder().build(); + } + + @Test + @DisplayName("test an error is thrown when the release is not found") + void testErrorThrownWhenReleaseNotFound() { + RuntimeException e = assertThrows(RuntimeException.class, () -> { + HelmReleaseExistsTask helmReleaseExistsTask = project.getTasks() + .create("helmReleaseExistsV1", HelmReleaseExistsTask.class, task -> { + task.getAllNamespaces().set(true); + task.getRelease().set("not-a-release"); + }); + helmReleaseExistsTask.releaseExists(); + }); + assertThat(e.getMessage()) + .isEqualTo("HelmReleaseExistsTask.releaseExists(): Release not-a-release does not exist"); + } + + @Test + @DisplayName("test an error is thrown when the release is not set") + void testErrorThrownWhenReleaseNotSet() { + NullPointerException npe = assertThrows(NullPointerException.class, () -> { + HelmReleaseExistsTask helmReleaseExistsTask = project.getTasks() + .create("helmReleaseExistsV2", HelmReleaseExistsTask.class, task -> { + task.getAllNamespaces().set(true); + }); + helmReleaseExistsTask.releaseExists(); + }); + assertThat(npe.getMessage()).isEqualTo("release must not be null"); + } +} From 43ae501949816248cb7836d730a6c79e9bc0b2ed Mon Sep 17 00:00:00 2001 From: Jeromy Cannon Date: Fri, 6 Oct 2023 18:05:20 +0100 Subject: [PATCH 4/4] gradle example Signed-off-by: Jeromy Cannon --- fullstack-examples/build.gradle.kts | 9 +++++++-- .../fullstack/gradle/plugin/HelmReleaseExistsTask.java | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fullstack-examples/build.gradle.kts b/fullstack-examples/build.gradle.kts index 9af49048a..fa565a645 100644 --- a/fullstack-examples/build.gradle.kts +++ b/fullstack-examples/build.gradle.kts @@ -15,7 +15,7 @@ */ import com.hedera.fullstack.gradle.plugin.HelmInstallChartTask -import com.hedera.fullstack.gradle.plugin.HelmListReleasesTask +import com.hedera.fullstack.gradle.plugin.HelmReleaseExistsTask import com.hedera.fullstack.gradle.plugin.HelmUninstallChartTask plugins { @@ -53,9 +53,14 @@ tasks.register("helmUninstallNginxChart") { release.set("nginx-release") } -tasks.register("helmListRelease") { namespace.set("nginx-ns") } +tasks.register("helmNginxExists") { + allNamespaces.set(true) + namespace.set("nginx-ns") + release.set("nginx-release") +} tasks.check { dependsOn("helmInstallNginxChart") + dependsOn("helmNginxExists") dependsOn("helmUninstallNginxChart") } diff --git a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java index c1f453037..5cafd599e 100644 --- a/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java +++ b/fullstack-gradle-plugin/src/main/java/com/hedera/fullstack/gradle/plugin/HelmReleaseExistsTask.java @@ -73,8 +73,10 @@ void releaseExists() { } if (releaseItem == null) { - throw new RuntimeException("HelmReleaseExistsTask.releaseExists(): Release " - + getRelease().get() + " does not exist"); + final String errorMessage = "HelmReleaseExistsTask.releaseExists(): Release " + + getRelease().get() + " does not exist"; + this.getProject().getLogger().error(errorMessage); + throw new RuntimeException(errorMessage); } } }