Skip to content

Commit

Permalink
feat(helm): Helm Uninstall functionality exposed via Maven Mojos / Gr…
Browse files Browse the repository at this point in the history
…adle Tasks

Signed-off-by: Rohan Kumar <[email protected]>
  • Loading branch information
rohanKanojia authored Aug 9, 2024
1 parent 1d2ca4a commit 729dc8a
Show file tree
Hide file tree
Showing 14 changed files with 611 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmLintTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmPushTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmUninstallTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesLogTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesPushTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesRemoteDevTask;
Expand Down Expand Up @@ -55,6 +56,7 @@ public Map<String, Collection<Class<? extends Task>>> getTaskPrecedence() {
ret.put("k8sHelmLint", Collections.singletonList(KubernetesHelmTask.class));
ret.put("k8sHelmDependencyUpdate", Collections.singletonList(KubernetesHelmTask.class));
ret.put("k8sHelmInstall", Collections.singletonList(KubernetesHelmTask.class));
ret.put("k8sHelmUninstall", Arrays.asList(KubernetesHelmTask.class, KubernetesHelmInstallTask.class));
return ret;
}

Expand All @@ -73,6 +75,7 @@ protected void jKubeApply(Project project) {
register(project, "k8sHelmLint", KubernetesHelmLintTask.class);
register(project, "k8sHelmDependencyUpdate", KubernetesHelmDependencyUpdateTask.class);
register(project, "k8sHelmInstall", KubernetesHelmInstallTask.class);
register(project, "k8sHelmUninstall", KubernetesHelmUninstallTask.class);
register(project, "k8sRemoteDev", KubernetesRemoteDevTask.class);
register(project, "k8sWatch", KubernetesWatchTask.class);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.gradle.plugin.task;

import org.eclipse.jkube.gradle.plugin.KubernetesExtension;

import javax.inject.Inject;

public class KubernetesHelmUninstallTask extends AbstractHelmTask {
@Inject
public KubernetesHelmUninstallTask(Class<? extends KubernetesExtension> extensionClass) {
super(extensionClass);
setDescription("Uninstalls the Helm release from Kubernetes cluster");
}

@Override
public void run() {
try {
jKubeServiceHub.getHelmService().uninstall(kubernetesExtension.helm);
} catch (Exception exp) {
kitLogger.error("Error performing helm uninstall", exp);
throw new IllegalStateException(exp.getMessage(), exp);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.jkube.gradle.plugin.task.JKubeTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesApplyTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesBuildTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmInstallTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesResourceTask;

Expand Down Expand Up @@ -81,7 +82,7 @@ void getTaskPrecedence_withValidProject_shouldReturnTaskPrecedence() {
final Map<String, Collection<Class<? extends Task>>> result = new KubernetesPlugin().getTaskPrecedence();
// Then
assertThat(result)
.hasSize(8)
.hasSize(9)
.containsEntry("k8sApply", Collections.singletonList(KubernetesResourceTask.class))
.containsEntry("k8sDebug",
Arrays.asList(KubernetesBuildTask.class, KubernetesResourceTask.class, KubernetesApplyTask.class))
Expand All @@ -90,6 +91,7 @@ void getTaskPrecedence_withValidProject_shouldReturnTaskPrecedence() {
.containsEntry("k8sHelmDependencyUpdate", Collections.singletonList(KubernetesHelmTask.class))
.containsEntry("k8sHelmPush", Collections.singletonList(KubernetesHelmTask.class))
.containsEntry("k8sHelmLint", Collections.singletonList(KubernetesHelmTask.class))
.containsEntry("k8sHelmInstall", Collections.singletonList(KubernetesHelmTask.class));
.containsEntry("k8sHelmInstall", Collections.singletonList(KubernetesHelmTask.class))
.containsEntry("k8sHelmUninstall", Arrays.asList(KubernetesHelmTask.class, KubernetesHelmInstallTask.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.gradle.plugin.task;

import com.marcnuri.helm.Helm;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretListBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
import org.apache.commons.io.FileUtils;
import org.eclipse.jkube.gradle.plugin.KubernetesExtension;
import org.eclipse.jkube.gradle.plugin.TestKubernetesExtension;
import org.eclipse.jkube.kit.common.access.ClusterConfiguration;
import org.eclipse.jkube.kit.resource.helm.HelmConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.eclipse.jkube.kit.common.util.KubernetesMockServerUtil.prepareMockWebServerExpectationsForAggregatedDiscoveryEndpoints;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@EnableKubernetesMockClient(crud = true)
class KubernetesHelmUninstallTaskTest {
@RegisterExtension
private final TaskEnvironmentExtension taskEnvironment = new TaskEnvironmentExtension();
private KubernetesClient kubernetesClient;
private KubernetesMockServer server;
private TestKubernetesExtension extension;

@BeforeEach
void setUp() throws IOException {
extension = new TestKubernetesExtension();
// Remove after https://github.com/fabric8io/kubernetes-client/issues/6062 is fixed
prepareMockWebServerExpectationsForAggregatedDiscoveryEndpoints(server);
Helm.create().withDir(taskEnvironment.getRoot().toPath()).withName("empty-project").call();
Path helmChartOutputDir = taskEnvironment.getRoot().toPath().resolve("build").resolve("jkube").resolve("helm");
Files.createDirectories(helmChartOutputDir.resolve("kubernetes"));
FileUtils.copyDirectory(taskEnvironment.getRoot().toPath().resolve("empty-project").toFile(), helmChartOutputDir.resolve("kubernetes").toFile());
System.setProperty("jkube.kubernetesTemplate", taskEnvironment.getRoot().getAbsolutePath());
extension.helm = HelmConfig.builder()
.chartExtension("tgz")
.disableOpenAPIValidation(true)
.outputDir(helmChartOutputDir.toString()).build();
extension.access = ClusterConfiguration.from(kubernetesClient.getConfiguration()).build();
extension.isUseColor = false;
when(taskEnvironment.project.getName()).thenReturn("empty-project");
when(taskEnvironment.project.getVersion()).thenReturn("0.1.0");
when(taskEnvironment.project.getExtensions().getByType(KubernetesExtension.class)).thenReturn(extension);
}

@AfterEach
void tearDown() {
System.clearProperty("jkube.kubernetesTemplate");
}

@Test
@DisplayName("when Helm Release Installed on Kubernetes Cluster, then uninstall Helm Release")
void runTask_withHelmReleasePresentInKubernetesCluster_shouldSucceed() {
// Given
KubernetesHelmUninstallTask kubernetesHelmUninstallTask = new KubernetesHelmUninstallTask(KubernetesExtension.class);
kubernetesHelmUninstallTask.init();
kubernetesHelmUninstallTask.jKubeServiceHub.getHelmService().install(extension.helm);
// Should be removed once https://github.com/fabric8io/kubernetes-client/issues/6220 gets fixed
Secret secret = kubernetesClient.secrets().withName("sh.helm.release.v1.empty-project.v1").get();
server.expect().get().withPath("/api/v1/namespaces/test/secrets?labelSelector=name%3Dempty-project%2Cowner%3Dhelm")
.andReturn(200, new SecretListBuilder()
.addToItems(secret)
.build())
.once();

// When
kubernetesHelmUninstallTask.runTask();
// Then
verify(taskEnvironment.logger).lifecycle("k8s: release \"empty-project\" uninstalled");
}

@Test
@DisplayName("Helm Release not installed on Kubernetes cluster, then throw exception")
void execute_whenReleaseNotPresent_thenThrowException() {
// Given
KubernetesHelmUninstallTask kubernetesHelmUninstallTask = new KubernetesHelmUninstallTask(KubernetesExtension.class);

// When + Then
assertThatIllegalStateException()
.isThrownBy(kubernetesHelmUninstallTask::runTask)
.withMessageContaining(" not found");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.eclipse.jkube.gradle.plugin.task.KubernetesApplyTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesBuildTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesConfigViewTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmInstallTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesLogTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesResourceTask;
Expand All @@ -32,6 +33,7 @@
import org.eclipse.jkube.gradle.plugin.task.OpenShiftHelmLintTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftHelmPushTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftHelmTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftHelmUninstallTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftPushTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftRemoteDevTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftResourceTask;
Expand Down Expand Up @@ -59,6 +61,7 @@ public Map<String, Collection<Class<? extends Task>>> getTaskPrecedence() {
ret.put("ocHelmLint", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class));
ret.put("ocHelmDependencyUpdate", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class));
ret.put("ocHelmInstall", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class));
ret.put("ocHelmUninstall", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class, KubernetesHelmInstallTask.class, OpenShiftHelmInstallTask.class));
return ret;
}

Expand All @@ -77,6 +80,7 @@ protected void jKubeApply(Project project) {
register(project, "ocHelmLint", OpenShiftHelmLintTask.class);
register(project, "ocHelmDependencyUpdate", OpenShiftHelmDependencyUpdateTask.class);
register(project, "ocHelmInstall", OpenShiftHelmInstallTask.class);
register(project, "ocHelmUninstall", OpenShiftHelmUninstallTask.class);
register(project, "ocRemoteDev", OpenShiftRemoteDevTask.class);
register(project, "ocWatch", OpenShiftWatchTask.class);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.gradle.plugin.task;

import org.eclipse.jkube.gradle.plugin.OpenShiftExtension;

import javax.inject.Inject;

public class OpenShiftHelmUninstallTask extends KubernetesHelmUninstallTask implements OpenShiftJKubeTask {
@Inject
public OpenShiftHelmUninstallTask(Class<? extends OpenShiftExtension> extensionClass) {
super(extensionClass);
setDescription("Uninstalls the Helm release from OpenShift cluster");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

import org.eclipse.jkube.gradle.plugin.task.KubernetesApplyTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesBuildTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmInstallTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmTask;
import org.eclipse.jkube.gradle.plugin.task.KubernetesResourceTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftApplyTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftBuildTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftHelmInstallTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftHelmTask;
import org.eclipse.jkube.gradle.plugin.task.OpenShiftResourceTask;

Expand All @@ -39,7 +41,7 @@ void configurePrecedence_withValidProject_shouldReturnTaskPrecedence() {
final Map<String, Collection<Class<? extends Task>>> result = new OpenShiftPlugin().getTaskPrecedence();
// Then
assertThat(result)
.hasSize(8)
.hasSize(9)
.containsEntry("ocApply", Arrays.asList(KubernetesResourceTask.class, OpenShiftResourceTask.class))
.containsEntry("ocDebug", Arrays.asList(KubernetesBuildTask.class, OpenShiftBuildTask.class,
KubernetesResourceTask.class, OpenShiftResourceTask.class, KubernetesApplyTask.class, OpenShiftApplyTask.class))
Expand All @@ -48,6 +50,7 @@ void configurePrecedence_withValidProject_shouldReturnTaskPrecedence() {
.containsEntry("ocHelmDependencyUpdate", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class))
.containsEntry("ocHelmPush", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class))
.containsEntry("ocHelmLint", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class))
.containsEntry("ocHelmInstall", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class));
.containsEntry("ocHelmInstall", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class))
.containsEntry("ocHelmUninstall", Arrays.asList(KubernetesHelmTask.class, OpenShiftHelmTask.class, KubernetesHelmInstallTask.class, OpenShiftHelmInstallTask.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.gradle.plugin.task;

import com.marcnuri.helm.Helm;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretListBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
import org.apache.commons.io.FileUtils;
import org.eclipse.jkube.gradle.plugin.OpenShiftExtension;
import org.eclipse.jkube.gradle.plugin.TestOpenShiftExtension;
import org.eclipse.jkube.kit.common.access.ClusterConfiguration;
import org.eclipse.jkube.kit.resource.helm.HelmConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.eclipse.jkube.kit.common.util.KubernetesMockServerUtil.prepareMockWebServerExpectationsForAggregatedDiscoveryEndpoints;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@EnableKubernetesMockClient(crud = true)
class OpenShiftHelmUninstallTaskTest {
@RegisterExtension
private final TaskEnvironmentExtension taskEnvironment = new TaskEnvironmentExtension();
private KubernetesClient kubernetesClient;
private KubernetesMockServer server;
private TestOpenShiftExtension extension;

@BeforeEach
void setUp() throws IOException {
extension = new TestOpenShiftExtension();
// Remove after https://github.com/fabric8io/kubernetes-client/issues/6062 is fixed
prepareMockWebServerExpectationsForAggregatedDiscoveryEndpoints(server);
Helm.create().withDir(taskEnvironment.getRoot().toPath()).withName("empty-project").call();
Path helmChartOutputDir = taskEnvironment.getRoot().toPath().resolve("build").resolve("jkube").resolve("helm");
Files.createDirectories(helmChartOutputDir.resolve("openshift"));
FileUtils.copyDirectory(taskEnvironment.getRoot().toPath().resolve("empty-project").toFile(), helmChartOutputDir.resolve("openshift").toFile());
System.setProperty("jkube.kubernetesTemplate", taskEnvironment.getRoot().getAbsolutePath());
extension.helm = HelmConfig.builder()
.chartExtension("tgz")
.disableOpenAPIValidation(true)
.outputDir(helmChartOutputDir.toString()).build();
extension.access = ClusterConfiguration.from(kubernetesClient.getConfiguration()).build();
extension.isUseColor = false;
when(taskEnvironment.project.getName()).thenReturn("empty-project");
when(taskEnvironment.project.getVersion()).thenReturn("0.1.0");
when(taskEnvironment.project.getExtensions().getByType(OpenShiftExtension.class)).thenReturn(extension);
}

@AfterEach
void tearDown() {
System.clearProperty("jkube.kubernetesTemplate");
}

@Test
@DisplayName("when Helm Release Installed on Kubernetes Cluster, then uninstall Helm Release")
void runTask_withHelmReleasePresentInKubernetesCluster_shouldSucceed() {
// Given
OpenShiftHelmUninstallTask openShiftHelmUninstallTask = new OpenShiftHelmUninstallTask(OpenShiftExtension.class);
openShiftHelmUninstallTask.init();
openShiftHelmUninstallTask.jKubeServiceHub.getHelmService().install(extension.helm);
// Should be removed once https://github.com/fabric8io/kubernetes-client/issues/6220 gets fixed
Secret secret = kubernetesClient.secrets().withName("sh.helm.release.v1.empty-project.v1").get();
server.expect().get().withPath("/api/v1/namespaces/test/secrets?labelSelector=name%3Dempty-project%2Cowner%3Dhelm")
.andReturn(200, new SecretListBuilder()
.addToItems(secret)
.build())
.once();

// When
openShiftHelmUninstallTask.runTask();
// Then
verify(taskEnvironment.logger).lifecycle("oc: release \"empty-project\" uninstalled");
}

@Test
@DisplayName("Helm Release not installed on Kubernetes cluster, then throw exception")
void execute_whenReleaseNotPresent_thenThrowException() {
// Given
OpenShiftHelmUninstallTask openShiftHelmUninstallTask = new OpenShiftHelmUninstallTask(OpenShiftExtension.class);

// When + Then
assertThatIllegalStateException()
.isThrownBy(openShiftHelmUninstallTask::runTask)
.withMessageContaining(" not found");
}
}
Loading

0 comments on commit 729dc8a

Please sign in to comment.