From 78ca19d69f124f7566311c17790cb00d3c2454b0 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Tue, 26 Oct 2021 16:07:23 +0530 Subject: [PATCH] Fix #1052: Add k8sHelm task to Kubernetes Gradle Plugin Add `k8s:helm` maven equivalent `k8sHelm` task to Kubernetes Gradle Plugin. Signed-off-by: Rohan Kumar --- .../jkube/gradle/plugin/KubernetesPlugin.java | 3 + .../plugin/task/KubernetesHelmTask.java | 47 +++++++++++ .../gradle/plugin/KubernetesPluginTest.java | 5 +- .../plugin/task/KubernetesHelmTaskTest.java | 80 +++++++++++++++++++ .../gradle/plugin/task/TaskEnvironment.java | 4 + .../kit/resource/helm/HelmServiceUtil.java | 6 +- 6 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTask.java create mode 100644 gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTaskTest.java diff --git a/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/KubernetesPlugin.java b/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/KubernetesPlugin.java index 5325fed3b5..895b0ef393 100644 --- a/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/KubernetesPlugin.java +++ b/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/KubernetesPlugin.java @@ -23,6 +23,7 @@ import org.eclipse.jkube.gradle.plugin.task.KubernetesBuildTask; import org.eclipse.jkube.gradle.plugin.task.KubernetesConfigViewTask; import org.eclipse.jkube.gradle.plugin.task.KubernetesDebugTask; +import org.eclipse.jkube.gradle.plugin.task.KubernetesHelmTask; import org.eclipse.jkube.gradle.plugin.task.KubernetesLogTask; import org.eclipse.jkube.gradle.plugin.task.KubernetesPushTask; import org.eclipse.jkube.gradle.plugin.task.KubernetesResourceTask; @@ -43,6 +44,7 @@ public Map>> getTaskPrecedence() { ret.put("k8sApply", Collections.singletonList(KubernetesResourceTask.class)); ret.put("k8sDebug", Arrays.asList(KubernetesBuildTask.class, KubernetesResourceTask.class, KubernetesApplyTask.class)); ret.put("k8sPush", Collections.singletonList(KubernetesBuildTask.class)); + ret.put("k8sHelm", Collections.singletonList(KubernetesResourceTask.class)); return ret; } @@ -56,6 +58,7 @@ protected void jKubeApply(Project project) { register(project, "k8sPush", KubernetesPushTask.class); register(project, "k8sResource", KubernetesResourceTask.class); register(project, "k8sUndeploy", KubernetesUndeployTask.class); + register(project, "k8sHelm", KubernetesHelmTask.class); } } diff --git a/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTask.java b/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTask.java new file mode 100644 index 0000000000..9c0c8f6f46 --- /dev/null +++ b/gradle-plugin/kubernetes/src/main/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTask.java @@ -0,0 +1,47 @@ +/** + * 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 org.eclipse.jkube.kit.resource.helm.HelmConfig; + +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; + +import static org.eclipse.jkube.kit.resource.helm.HelmServiceUtil.initHelmConfig; + +public class KubernetesHelmTask extends AbstractJKubeTask { + @Inject + public KubernetesHelmTask(Class extensionClass) { + super(extensionClass); + setDescription("Generates a Helm chart for the kubernetes resources."); + } + + @Override + public void run() { + try { + File manifest = kubernetesExtension.getKubernetesManifestOrDefault(); + if (manifest == null || !manifest.isFile()) { + kitLogger.warn("No kubernetes manifest file has been generated yet by the k8sResource task at: " + manifest); + } + HelmConfig helm = initHelmConfig(kubernetesExtension.getDefaultHelmType(), kubernetesExtension.javaProject, + kubernetesExtension.getKubernetesManifestOrDefault(), kubernetesExtension.getKubernetesTemplateOrDefault(), + kubernetesExtension.helm).build(); + jKubeServiceHub.getHelmService().generateHelmCharts(helm); + } catch (IOException exception) { + throw new IllegalStateException(exception.getMessage()); + } + } +} diff --git a/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/KubernetesPluginTest.java b/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/KubernetesPluginTest.java index 9aea0840cb..0675fb6772 100644 --- a/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/KubernetesPluginTest.java +++ b/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/KubernetesPluginTest.java @@ -80,10 +80,11 @@ public void getTaskPrecedence_withValidProject_shouldReturnTaskPrecedence() { final Map>> result = new KubernetesPlugin().getTaskPrecedence(); // Then assertThat(result) - .hasSize(3) + .hasSize(4) .containsEntry("k8sApply", Collections.singletonList(KubernetesResourceTask.class)) .containsEntry("k8sDebug", Arrays.asList(KubernetesBuildTask.class, KubernetesResourceTask.class, KubernetesApplyTask.class)) - .containsEntry("k8sPush", Collections.singletonList(KubernetesBuildTask.class)); + .containsEntry("k8sPush", Collections.singletonList(KubernetesBuildTask.class)) + .containsEntry("k8sHelm", Collections.singletonList(KubernetesResourceTask.class)); } } diff --git a/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTaskTest.java b/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTaskTest.java new file mode 100644 index 0000000000..7f4c55e7c7 --- /dev/null +++ b/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/KubernetesHelmTaskTest.java @@ -0,0 +1,80 @@ +/** + * 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 org.eclipse.jkube.gradle.plugin.TestKubernetesExtension; +import org.eclipse.jkube.kit.resource.helm.HelmService; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.MockedConstruction; + +import java.io.IOException; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class KubernetesHelmTaskTest { + @Rule + public TaskEnvironment taskEnvironment = new TaskEnvironment(); + + private TestKubernetesExtension extension; + private MockedConstruction helmServiceMockedConstruction; + + @Before + public void setUp() throws IOException { + extension = new TestKubernetesExtension(); + extension.isUseColor = false; + helmServiceMockedConstruction = mockConstruction(HelmService.class); + when(taskEnvironment.project.getExtensions().getByType(KubernetesExtension.class)).thenReturn(extension); + } + + @Test + public void runTask_withNoTemplateDir_shouldThrowException() { + // Given + KubernetesHelmTask kubernetesHelmTask = new KubernetesHelmTask(KubernetesExtension.class); + + // When + IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, kubernetesHelmTask::runTask); + + // Then + assertThat(illegalStateException) + .hasMessageContaining("META-INF/jkube/kubernetes (No such file or directory)"); + } + + @Test + public void runTask_withTemplateDir_shouldCallHelmService() throws IOException { + // Given + taskEnvironment.withKubernetesTemplate(); + KubernetesHelmTask kubernetesHelmTask = new KubernetesHelmTask(KubernetesExtension.class); + + // When + kubernetesHelmTask.runTask(); + + // Then + verify((helmServiceMockedConstruction.constructed().iterator().next()), times(1)).generateHelmCharts(any()); + } + + @After + public void tearDown() { + helmServiceMockedConstruction.close(); + } +} diff --git a/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/TaskEnvironment.java b/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/TaskEnvironment.java index e7b9a6cd30..00f2838645 100644 --- a/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/TaskEnvironment.java +++ b/gradle-plugin/kubernetes/src/test/java/org/eclipse/jkube/gradle/plugin/task/TaskEnvironment.java @@ -62,4 +62,8 @@ public void withKubernetesManifest() throws IOException { final File manifestsDir = newFolder("build", "classes", "java", "main", "META-INF", "jkube"); FileUtils.touch(new File(manifestsDir, "kubernetes.yml").toPath()); } + + public void withKubernetesTemplate() throws IOException { + newFolder("build", "classes", "java", "main", "META-INF", "jkube", "kubernetes"); + } } diff --git a/jkube-kit/resource/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmServiceUtil.java b/jkube-kit/resource/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmServiceUtil.java index ff26090ab2..7da95bd01d 100644 --- a/jkube-kit/resource/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmServiceUtil.java +++ b/jkube-kit/resource/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmServiceUtil.java @@ -67,7 +67,7 @@ public class HelmServiceUtil { private HelmServiceUtil() { } public static HelmConfig.HelmConfigBuilder initHelmConfig( - HelmConfig.HelmType defaultHelmType, JavaProject project, File manifest, File templateDir, HelmConfig original) + HelmConfig.HelmType defaultHelmType, JavaProject project, File manifest, File template, HelmConfig original) throws IOException { if (original == null) { @@ -81,7 +81,7 @@ public static HelmConfig.HelmConfigBuilder initHelmConfig( if (original.getSources() == null) { original.setSources(project.getScmUrl() != null ? Collections.singletonList(project.getScmUrl()) : Collections.emptyList()); } - if (original.getMaintainers() == null) { + if (original.getMaintainers() == null && project.getMaintainers() != null) { original.setMaintainers(project.getMaintainers().stream() .filter(m -> StringUtils.isNotBlank(m.getName()) || StringUtils.isNotBlank(m.getEmail())) .map(m -> new Maintainer(m.getName(), m.getEmail())) @@ -90,7 +90,7 @@ public static HelmConfig.HelmConfigBuilder initHelmConfig( original.setIcon(resolveFromPropertyOrDefault(PROPERTY_ICON, project, original::getIcon, findIconURL(manifest))); original.setAdditionalFiles(getAdditionalFiles(original, project)); if (original.getTemplates() == null) { - original.setTemplates(findTemplates(templateDir)); + original.setTemplates(findTemplates(template)); } original.setTypes(resolveHelmTypes(defaultHelmType, project));