From 53d092f83d7f077e84a323a670291710208f59bd Mon Sep 17 00:00:00 2001 From: Jeromy Cannon Date: Thu, 5 Oct 2023 13:00:32 -0500 Subject: [PATCH] feat: add helm list releases subcommand (#380) Signed-off-by: Jeromy Cannon --- .../fullstack/helm/client/HelmClient.java | 8 +++++ .../helm/client/impl/DefaultHelmClient.java | 7 ++++ .../client/model/release/ReleaseItem.java | 29 ++++++++++++++++ .../request/release/ReleaseListRequest.java | 33 ++++++++++++++++++ .../src/main/java/module-info.java | 1 + .../helm/client/test/HelmClientTest.java | 34 +++++++++++++++++-- 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/model/release/ReleaseItem.java create mode 100644 fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/proxy/request/release/ReleaseListRequest.java diff --git a/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/HelmClient.java b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/HelmClient.java index c04943227..ef5f175e8 100644 --- a/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/HelmClient.java +++ b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/HelmClient.java @@ -22,6 +22,7 @@ import com.hedera.fullstack.helm.client.model.Repository; import com.hedera.fullstack.helm.client.model.chart.Release; import com.hedera.fullstack.helm.client.model.install.InstallChartOptions; +import com.hedera.fullstack.helm.client.model.release.ReleaseItem; import com.hedera.fullstack.helm.client.model.test.TestChartOptions; import java.util.List; @@ -101,6 +102,13 @@ default Release installChart(String releaseName, Chart chart) { */ void testChart(String releaseName, TestChartOptions options); + /** + * Executes the Helm CLI {@code list} sub-command and returns the list of releases. + * @param allNamespaces if {@code true}, list releases across all namespaces. + * @return the list of releases. + */ + List listReleases(boolean allNamespaces); + /** * Executes the Helm CLI {@code dependency update} sub-command and updates the dependencies of the specified Helm * chart. diff --git a/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/impl/DefaultHelmClient.java b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/impl/DefaultHelmClient.java index d8922c042..4984dfed0 100644 --- a/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/impl/DefaultHelmClient.java +++ b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/impl/DefaultHelmClient.java @@ -25,6 +25,7 @@ import com.hedera.fullstack.helm.client.model.Version; import com.hedera.fullstack.helm.client.model.chart.Release; import com.hedera.fullstack.helm.client.model.install.InstallChartOptions; +import com.hedera.fullstack.helm.client.model.release.ReleaseItem; import com.hedera.fullstack.helm.client.model.test.TestChartOptions; import com.hedera.fullstack.helm.client.proxy.request.HelmRequest; import com.hedera.fullstack.helm.client.proxy.request.authentication.KubeAuthentication; @@ -33,6 +34,7 @@ import com.hedera.fullstack.helm.client.proxy.request.chart.ChartTestRequest; import com.hedera.fullstack.helm.client.proxy.request.chart.ChartUninstallRequest; import com.hedera.fullstack.helm.client.proxy.request.common.VersionRequest; +import com.hedera.fullstack.helm.client.proxy.request.release.ReleaseListRequest; import com.hedera.fullstack.helm.client.proxy.request.repository.RepositoryAddRequest; import com.hedera.fullstack.helm.client.proxy.request.repository.RepositoryListRequest; import com.hedera.fullstack.helm.client.proxy.request.repository.RepositoryRemoveRequest; @@ -153,6 +155,11 @@ public void testChart(final String releaseName, final TestChartOptions options) }); } + @Override + public List listReleases(boolean allNamespaces) { + return executeAsList(new ReleaseListRequest(allNamespaces), ReleaseItem.class); + } + @Override public void dependencyUpdate(final String chartName) { executeInternal(new ChartDependencyUpdateRequest(chartName), Void.class, (b, c) -> { diff --git a/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/model/release/ReleaseItem.java b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/model/release/ReleaseItem.java new file mode 100644 index 000000000..a09b3bb7b --- /dev/null +++ b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/model/release/ReleaseItem.java @@ -0,0 +1,29 @@ +/* + * 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.helm.client.model.release; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public record ReleaseItem( + String name, + String namespace, + String revision, + String updated, + String status, + String chart, + String app_version) {} diff --git a/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/proxy/request/release/ReleaseListRequest.java b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/proxy/request/release/ReleaseListRequest.java new file mode 100644 index 000000000..fd256149e --- /dev/null +++ b/fullstack-helm-client/src/main/java/com/hedera/fullstack/helm/client/proxy/request/release/ReleaseListRequest.java @@ -0,0 +1,33 @@ +/* + * 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.helm.client.proxy.request.release; + +import com.hedera.fullstack.helm.client.execution.HelmExecutionBuilder; +import com.hedera.fullstack.helm.client.proxy.request.HelmRequest; + +public record ReleaseListRequest(boolean allNamespaces) implements HelmRequest { + @Override + public void apply(HelmExecutionBuilder builder) { + builder.argument("output", "json"); + + if (allNamespaces) { + builder.flag("--all-namespaces"); + } + + builder.subcommands("list"); + } +} diff --git a/fullstack-helm-client/src/main/java/module-info.java b/fullstack-helm-client/src/main/java/module-info.java index 6e97afa97..074620bd9 100644 --- a/fullstack-helm-client/src/main/java/module-info.java +++ b/fullstack-helm-client/src/main/java/module-info.java @@ -3,6 +3,7 @@ exports com.hedera.fullstack.helm.client.model; exports com.hedera.fullstack.helm.client.model.chart; exports com.hedera.fullstack.helm.client.model.install; + exports com.hedera.fullstack.helm.client.model.release; exports com.hedera.fullstack.helm.client.model.test; exports com.hedera.fullstack.helm.client.execution; exports com.hedera.fullstack.helm.client.proxy.request.chart to diff --git a/fullstack-helm-client/src/test/java/com/hedera/fullstack/helm/client/test/HelmClientTest.java b/fullstack-helm-client/src/test/java/com/hedera/fullstack/helm/client/test/HelmClientTest.java index d106b57bb..61cc6169d 100644 --- a/fullstack-helm-client/src/test/java/com/hedera/fullstack/helm/client/test/HelmClientTest.java +++ b/fullstack-helm-client/src/test/java/com/hedera/fullstack/helm/client/test/HelmClientTest.java @@ -28,6 +28,7 @@ import com.hedera.fullstack.helm.client.model.Repository; import com.hedera.fullstack.helm.client.model.chart.Release; import com.hedera.fullstack.helm.client.model.install.InstallChartOptions; +import com.hedera.fullstack.helm.client.model.release.ReleaseItem; import com.hedera.fullstack.helm.client.model.test.TestChartOptions; import com.jcovalent.junit.logging.JCovalentLoggingSupport; import com.jcovalent.junit.logging.LogEntry; @@ -62,6 +63,8 @@ class HelmClientTest { new Repository("incubator", "https://charts.helm.sh/incubator"); private static final Repository JETSTACK_REPOSITORY = new Repository("jetstack", "https://charts.jetstack.io"); + + private static final String NAMESPACE = "helm-client-test-ns"; private static HelmClient helmClient; private static final int INSTALL_TIMEOUT = 10; @@ -92,7 +95,7 @@ private record ChartInstallOptionsTestParameters(InstallChartOptions options, Li @BeforeAll static void beforeAll() { helmClient = HelmClient.builder() - .defaultNamespace("helm-client-test-ns") + .defaultNamespace(NAMESPACE) .workingDirectory(new File(".").toPath()) .build(); assertThat(helmClient).isNotNull(); @@ -188,11 +191,38 @@ void testInstallChartCommand(final LoggingOutput loggingOutput) { try { suppressExceptions(() -> helmClient.uninstallChart(HAPROXY_RELEASE_NAME)); - Release release = helmClient.installChart(HAPROXY_RELEASE_NAME, HAPROXY_CHART); + final Release release = helmClient.installChart(HAPROXY_RELEASE_NAME, HAPROXY_CHART); + + // verify the returned release object assertThat(release).isNotNull(); assertThat(release.name()).isEqualTo(HAPROXY_RELEASE_NAME); assertThat(release.info().description()).isEqualTo("Install complete"); assertThat(release.info().status()).isEqualTo("deployed"); + + // verify the release through the helm list command using the namespace of the helm client + final List specificNamespaceReleaseItems = helmClient.listReleases(false); + assertThat(specificNamespaceReleaseItems).isNotNull().isNotEmpty(); + final ReleaseItem specificNamespaceReleaseItem = specificNamespaceReleaseItems.stream() + .filter(item -> item.name().equals(HAPROXY_RELEASE_NAME)) + .findFirst() + .orElse(null); + assertThat(specificNamespaceReleaseItem).isNotNull(); + assertThat(specificNamespaceReleaseItem.name()).isEqualTo(HAPROXY_RELEASE_NAME); + assertThat(specificNamespaceReleaseItem.namespace()).isEqualTo(NAMESPACE); + assertThat(specificNamespaceReleaseItem.status()).isEqualTo("deployed"); + HelmClient defaultHelmClient = HelmClient.defaultClient(); + + // verify the release through the helm list command using the default namespace specifying --all-namespaces + final List releaseItems = defaultHelmClient.listReleases(true); + assertThat(releaseItems).isNotNull().isNotEmpty(); + final ReleaseItem releaseItem = releaseItems.stream() + .filter(item -> item.name().equals(HAPROXY_RELEASE_NAME)) + .findFirst() + .orElse(null); + assertThat(releaseItem).isNotNull(); + assertThat(releaseItem.name()).isEqualTo(HAPROXY_RELEASE_NAME); + assertThat(releaseItem.namespace()).isEqualTo(NAMESPACE); + assertThat(releaseItem.status()).isEqualTo("deployed"); } finally { suppressExceptions(() -> helmClient.uninstallChart(HAPROXY_RELEASE_NAME)); }