diff --git a/CHANGELOG.md b/CHANGELOG.md index bbc7f2b3a6..93acaa6137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Usage: ### 1.18-SNAPSHOT * Fix #1125: Support WebFlux SpringBoot projects when it comes to generate probes for actuators * Fix #2844: `oc:build` on openshift use `pods/log` to retrieve logs from build +* Fix #2375: Add support for generating helm test resources via fragments * Fix #3354: Build fails with `imageStream` for `buildRecreate` value ### 1.17.0 (2024-08-13) diff --git a/jkube-kit/doc/src/main/asciidoc/inc/helm/_jkube_helm.adoc b/jkube-kit/doc/src/main/asciidoc/inc/helm/_jkube_helm.adoc index fa1a8bcc88..72552f5147 100644 --- a/jkube-kit/doc/src/main/asciidoc/inc/helm/_jkube_helm.adoc +++ b/jkube-kit/doc/src/main/asciidoc/inc/helm/_jkube_helm.adoc @@ -271,6 +271,7 @@ For the `values.yaml` file you can provide a `values.helm.yaml` fragment in the These fragments will be merged with the opinionated and configured defaults. The values provided in the fragments will override any of the generated default values taking precedence over them. +For providing https://helm.sh/docs/topics/chart_tests/[Helm Chart Test] files, you can provide a fragment ending with `.test.helm.yaml` suffix in `src/main/jkube` directory. // TODO: Remove if Once header depth is aligned in both plugins ifeval::["{plugin-type}" == "maven"] === Installing the generated Helm chart diff --git a/jkube-kit/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmService.java b/jkube-kit/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmService.java index f54dafd389..5da2a20c8e 100644 --- a/jkube-kit/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmService.java +++ b/jkube-kit/helm/src/main/java/org/eclipse/jkube/kit/resource/helm/HelmService.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.function.Consumer; @@ -41,6 +42,7 @@ import com.marcnuri.helm.LintResult; import com.marcnuri.helm.Release; import com.marcnuri.helm.UninstallCommand; +import io.fabric8.kubernetes.api.model.GenericKubernetesResource; import org.eclipse.jkube.kit.common.JKubeConfiguration; import org.eclipse.jkube.kit.common.JKubeException; import org.eclipse.jkube.kit.common.KitLogger; @@ -77,6 +79,7 @@ public class HelmService { + private static final String YML_EXTENSION = ".yml"; private static final String YAML_EXTENSION = ".yaml"; public static final String CHART_FILENAME = "Chart" + YAML_EXTENSION; private static final String VALUES_FILENAME = "values" + YAML_EXTENSION; @@ -84,6 +87,9 @@ public class HelmService { private static final String CHART_FRAGMENT_REGEX = "^chart\\.helm\\.(?yaml|yml|json)$"; public static final Pattern CHART_FRAGMENT_PATTERN = Pattern.compile(CHART_FRAGMENT_REGEX, Pattern.CASE_INSENSITIVE); + private static final String CHART_TEST_FRAGMENT_REGEX = "^.+\\.test\\.helm\\.(?yaml|yml|json)$"; + private static final Pattern CHART_TEST_FRAGMENT_PATTERN = Pattern.compile(CHART_TEST_FRAGMENT_REGEX, Pattern.CASE_INSENSITIVE); + private static final String VALUES_FRAGMENT_REGEX = "^values\\.helm\\.(?yaml|yml|json)$"; public static final Pattern VALUES_FRAGMENT_PATTERN = Pattern.compile(VALUES_FRAGMENT_REGEX, Pattern.CASE_INSENSITIVE); private static final String SYSTEM_LINE_SEPARATOR_REGEX = "\r?\n"; @@ -123,6 +129,8 @@ public void generateHelmCharts(HelmConfig helmConfig) throws IOException { createChartYaml(helmConfig, outputDir); logger.debug("Copying additional files"); copyAdditionalFiles(helmConfig, outputDir); + logger.debug("Copying test files"); + processTestFiles(templatesDir); logger.debug("Gathering parameters for placeholders"); final List parameters = collectParameters(helmConfig); logger.debug("Generating values.yaml"); @@ -146,6 +154,7 @@ public void generateHelmCharts(HelmConfig helmConfig) throws IOException { } } + /** * Uploads the charts defined in the provided {@link HelmConfig} to the applicable configured repository. * @@ -189,9 +198,9 @@ public void dependencyUpdate(HelmConfig helmConfig) { if (helmConfig.isDependencySkipRefresh()) { dependencyUpdateCommand.skipRefresh(); } - Arrays.stream(dependencyUpdateCommand.call() + Arrays.stream(dependencyUpdateCommand.call() .split(SYSTEM_LINE_SEPARATOR_REGEX)) - .forEach(l -> logger.info("[[W]]%s", l)); + .forEach(l -> logger.info("[[W]]%s", l)); } } @@ -324,20 +333,31 @@ private static File prepareOutputDir(HelmConfig helmConfig, HelmConfig.HelmType return outputDir; } - public static boolean containsYamlFiles(File directory) { return !listYamls(directory).isEmpty(); } + private void processTestFiles(File templatesDir) throws IOException { + final File templatesTestsDir = new File(templatesDir, "tests"); + final Set helmTestFragments = findHelmFragmentsInResourceDir(CHART_TEST_FRAGMENT_PATTERN, resourceServiceConfig) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + for (File testFragment : helmTestFragments) { + final GenericKubernetesResource testTemplate = readFragment(testFragment, GenericKubernetesResource.class); + final String fileName = FileUtil.stripPostfix(FileUtil.stripPostfix(FileUtil.stripPostfix(testFragment.getName(), YML_EXTENSION), YAML_EXTENSION), ".test.helm") + YAML_EXTENSION; + ResourceUtil.save(new File(templatesTestsDir, fileName), testTemplate, ResourceFileType.yaml); + } + } + private static void processSourceFiles(File sourceDir, File templatesDir) throws IOException { for (File file : listYamls(sourceDir)) { final KubernetesResource dto = Serialization.unmarshal(file); if (dto instanceof Template) { splitAndSaveTemplate((Template) dto, templatesDir); } else { - final String fileName = FileUtil.stripPostfix(FileUtil.stripPostfix(file.getName(), ".yml"), YAML_EXTENSION) + YAML_EXTENSION; + final String fileName = FileUtil.stripPostfix(FileUtil.stripPostfix(file.getName(), YML_EXTENSION), YAML_EXTENSION) + YAML_EXTENSION; File targetFile = new File(templatesDir, fileName); - // lets escape any {{ or }} characters to avoid creating invalid templates + // let's escape any {{ or }} characters to avoid creating invalid templates String text = FileUtils.readFileToString(file, Charset.defaultCharset()); text = escapeYamlTemplate(text); FileUtils.write(targetFile, text, Charset.defaultCharset()); @@ -356,7 +376,7 @@ private static void splitAndSaveTemplate(Template template, File templatesDir) t private void createChartYaml(HelmConfig helmConfig, File outputDir) throws IOException { final Chart chartFromHelmConfig = chartFromHelmConfig(helmConfig); - final Chart chartFromFragment = readFragment(CHART_FRAGMENT_PATTERN, Chart.class); + final Chart chartFromFragment = readFragment(resolveHelmFragment(CHART_FRAGMENT_PATTERN, resourceServiceConfig), Chart.class); final Chart mergedChart = Serialization.merge(chartFromHelmConfig, chartFromFragment); ResourceUtil.save(new File(outputDir, CHART_FILENAME), mergedChart, ResourceFileType.yaml); } @@ -378,8 +398,7 @@ private static Chart chartFromHelmConfig(HelmConfig helmConfig) { .build(); } - private T readFragment(Pattern filePattern, Class type) { - final File helmChartFragment = resolveHelmFragment(filePattern, resourceServiceConfig); + private T readFragment(File helmChartFragment, Class type) { if (helmChartFragment != null) { try { return Serialization.unmarshal( @@ -392,18 +411,22 @@ private T readFragment(Pattern filePattern, Class type) { } private static File resolveHelmFragment(Pattern filePattern, ResourceServiceConfig resourceServiceConfig) { + return findHelmFragmentsInResourceDir(filePattern, resourceServiceConfig).findAny().orElse(null); + } + + private static Stream findHelmFragmentsInResourceDir(Pattern filePattern, ResourceServiceConfig resourceServiceConfig) { final List fragmentDirs = resourceServiceConfig.getResourceDirs(); if (fragmentDirs != null) { for (File fragmentDir : fragmentDirs) { if (fragmentDir.exists() && fragmentDir.isDirectory()) { final File[] fragments = fragmentDir.listFiles((dir, name) -> filePattern.matcher(name).matches()); if (fragments != null) { - return Stream.of(fragments).filter(File::exists).findAny().orElse(null); + return Stream.of(fragments).filter(File::exists); } } } } - return null; + return Stream.empty(); } private static void copyAdditionalFiles(HelmConfig helmConfig, File outputDir) throws IOException { @@ -451,7 +474,7 @@ private void createValuesYaml(List helmParameters, File outputDir // Placeholders replaced by Go expressions don't need to be persisted in the values.yaml file .filter(hp -> !hp.isGolangExpression()) .collect(Collectors.toMap(HelmParameter::getName, HelmParameter::getValue)); - final Map valuesFromFragment = readFragment(VALUES_FRAGMENT_PATTERN, Map.class); + final Map valuesFromFragment = readFragment(resolveHelmFragment(VALUES_FRAGMENT_PATTERN, resourceServiceConfig), Map.class); final Map mergedValues = Serialization.merge(getNestedMap(valuesFromParameters), valuesFromFragment); final Map sortedValues = sortValuesYaml(mergedValues); ResourceUtil.save(new File(outputDir, VALUES_FILENAME), sortedValues, ResourceFileType.yaml); diff --git a/jkube-kit/helm/src/test/java/org/eclipse/jkube/kit/resource/helm/HelmServiceTest.java b/jkube-kit/helm/src/test/java/org/eclipse/jkube/kit/resource/helm/HelmServiceTest.java index 6cb73e7a92..2a1bbaf59a 100644 --- a/jkube-kit/helm/src/test/java/org/eclipse/jkube/kit/resource/helm/HelmServiceTest.java +++ b/jkube-kit/helm/src/test/java/org/eclipse/jkube/kit/resource/helm/HelmServiceTest.java @@ -26,6 +26,9 @@ import java.util.Properties; import com.fasterxml.jackson.core.type.TypeReference; +import io.fabric8.kubernetes.api.model.Container; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.PodSpec; import org.assertj.core.api.InstanceOfAssertFactories; import org.eclipse.jkube.kit.common.JKubeConfiguration; import org.eclipse.jkube.kit.common.JavaProject; @@ -37,6 +40,8 @@ import org.eclipse.jkube.kit.resource.helm.HelmConfig.HelmType; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -111,106 +116,168 @@ void generateHelmCharts() throws IOException { ); } - @Test - void generateHelmCharts_withInvalidChartYamlFragmentProvided_throwsException() { - // Given - helmConfig.types(Collections.singletonList(HelmType.KUBERNETES)); - resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( - new File(Objects.requireNonNull(getClass().getResource("/invalid-helm-chart-fragment")).getFile()))) - .build(); - // When + Then - assertThatIllegalArgumentException() - .isThrownBy(() -> - new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()).generateHelmCharts(helmConfig.build())) - .withMessageStartingWith("Failure in parsing Helm fragment (Chart.helm.yaml): "); - } + @Nested + @DisplayName("generateHelmCharts with fragments") + class GenerateHelmChartsWithFragments { + @BeforeEach + void setUp() { + helmConfig.types(Collections.singletonList(HelmType.KUBERNETES)); + } - @Test - void generateHelmCharts_withInvalidValuesYamlFragmentProvided_throwsException() { - // Given - helmConfig.types(Collections.singletonList(HelmType.KUBERNETES)); - resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( - new File(Objects.requireNonNull(getClass().getResource("/invalid-helm-values-fragment")).getFile()))) - .build(); - // When + Then - assertThatIllegalArgumentException() - .isThrownBy(() -> - new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()).generateHelmCharts(helmConfig.build())) - .withMessageStartingWith("Failure in parsing Helm fragment (values.helm.yaml): "); - } + @Nested + @DisplayName("valid fragments") + class ValidFragments { + @BeforeEach + void setUp() { + resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( + new File(Objects.requireNonNull(getClass().getResource("/valid-helm-fragments")).getFile()))) + .build(); + } - @Test - void generateHelmCharts_withValidChartYamlFragment_usesMergedChart() throws Exception { - // Given - jKubeConfiguration.getProject().getProperties().put("chart.name", "name-from-fragment"); - resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( - new File(Objects.requireNonNull(getClass().getResource("/valid-helm-fragments")).getFile()))) - .build(); - helmConfig - .types(Collections.singletonList(HelmType.KUBERNETES)) - .apiVersion("v1") - .chart("Chart Name") - .version("1337") - .description("Description from helmconfig") - .home("https://example.com") - .sources(Collections.singletonList("https://source.example.com")) - .keywords(Collections.singletonList("ci")) - .maintainers(Collections.singletonList(Maintainer.builder().name("maintainer-from-config").build())) - .icon("test-icon") - .appVersion("1.33.7") - .engine("gotpl") - .dependencies(Collections.singletonList(HelmDependency.builder().name("dependency-from-config").build())); - // When - new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()) - .generateHelmCharts(helmConfig.build()); - // Then - final Map savedChart = Serialization.unmarshal(helmOutputDirectory.resolve("kubernetes").resolve("Chart.yaml").toFile(), Map.class); - assertThat(savedChart) - .hasFieldOrPropertyWithValue("apiVersion", "v1") - .hasFieldOrPropertyWithValue("name", "name-from-fragment") - .hasFieldOrPropertyWithValue("version", "version-from-fragment") - .hasFieldOrPropertyWithValue("description", "Description from helmconfig") - .hasFieldOrPropertyWithValue("home", "https://example.com") - .hasFieldOrPropertyWithValue("icon", "test-icon") - .hasFieldOrPropertyWithValue("appVersion", "1.33.7") - .hasFieldOrPropertyWithValue("engine", "gotpl") - .hasFieldOrPropertyWithValue("keywords", Collections.singletonList("fragment")) - .hasFieldOrPropertyWithValue("sources", Collections.singletonList("https://source.example.com")) - .hasFieldOrPropertyWithValue("maintainers", Collections.singletonList(Collections.singletonMap("name", "maintainer-from-config"))) - .hasFieldOrPropertyWithValue("dependencies", Collections.singletonList(Collections.singletonMap("name", "dependency-from-config"))) - .extracting("annotations").asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class)) - .containsOnly(entry("example.com/jkube", "norad")); - } + @Test + @DisplayName("when valid chart.yaml fragment provided, then merge chart.yaml") + void withValidChartYamlFragment_usesMergedChart() throws Exception { + // Given + jKubeConfiguration.getProject().getProperties().put("chart.name", "name-from-fragment"); + helmConfig + .apiVersion("v1") + .chart("Chart Name") + .version("1337") + .description("Description from helmconfig") + .home("https://example.com") + .sources(Collections.singletonList("https://source.example.com")) + .keywords(Collections.singletonList("ci")) + .maintainers(Collections.singletonList(Maintainer.builder().name("maintainer-from-config").build())) + .icon("test-icon") + .appVersion("1.33.7") + .engine("gotpl") + .dependencies(Collections.singletonList(HelmDependency.builder().name("dependency-from-config").build())); + // When + new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()) + .generateHelmCharts(helmConfig.build()); + // Then + final Map savedChart = Serialization.unmarshal(helmOutputDirectory.resolve("kubernetes").resolve("Chart.yaml").toFile(), Map.class); + assertThat(savedChart) + .hasFieldOrPropertyWithValue("apiVersion", "v1") + .hasFieldOrPropertyWithValue("name", "name-from-fragment") + .hasFieldOrPropertyWithValue("version", "version-from-fragment") + .hasFieldOrPropertyWithValue("description", "Description from helmconfig") + .hasFieldOrPropertyWithValue("home", "https://example.com") + .hasFieldOrPropertyWithValue("icon", "test-icon") + .hasFieldOrPropertyWithValue("appVersion", "1.33.7") + .hasFieldOrPropertyWithValue("engine", "gotpl") + .hasFieldOrPropertyWithValue("keywords", Collections.singletonList("fragment")) + .hasFieldOrPropertyWithValue("sources", Collections.singletonList("https://source.example.com")) + .hasFieldOrPropertyWithValue("maintainers", Collections.singletonList(Collections.singletonMap("name", "maintainer-from-config"))) + .hasFieldOrPropertyWithValue("dependencies", Collections.singletonList(Collections.singletonMap("name", "dependency-from-config"))) + .extracting("annotations").asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class)) + .containsOnly(entry("example.com/jkube", "norad")); + } - @Test - void generateHelmCharts_withValidValuesYamlFragment_usesMergedValues() throws Exception { - // Given - jKubeConfiguration.getProject().getProperties().put("property.in.fragment", "the-value"); - resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( - new File(Objects.requireNonNull(getClass().getResource("/valid-helm-fragments")).getFile()))) - .build(); - helmConfig - .types(Collections.singletonList(HelmType.KUBERNETES)) - .parameters(Arrays.asList( - HelmParameter.builder().name("ingress.name").value("the-ingress-from-parameter").build(), - HelmParameter.builder().name("ingress.enabled").value("is overridden").build() - )); - // When - new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()) - .generateHelmCharts(helmConfig.build()); - // Then - final Map savedValues = Serialization.unmarshal(helmOutputDirectory.resolve("kubernetes").resolve("values.yaml").toFile(), Map.class); - assertThat(savedValues) - .hasFieldOrPropertyWithValue("replaceableProperty", "the-value") - .hasFieldOrPropertyWithValue("replicaCount", 1) - .hasFieldOrPropertyWithValue("ingress.name", "the-ingress-from-parameter") - .hasFieldOrPropertyWithValue("ingress.enabled", false) - .hasFieldOrPropertyWithValue("ingress.tls", Collections.emptyList()) - .extracting("ingress.annotations").asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class)) - .containsOnly( - entry("kubernetes.io/ingress.class", "nginx"), - entry("kubernetes.io/tls-acme", "true") - ); + @Test + @DisplayName("when valid values.yaml fragment provided, then merge values.yaml") + void withValidValuesYamlFragment_usesMergedValues() throws Exception { + // Given + jKubeConfiguration.getProject().getProperties().put("property.in.fragment", "the-value"); + helmConfig + .parameters(Arrays.asList( + HelmParameter.builder().name("ingress.name").value("the-ingress-from-parameter").build(), + HelmParameter.builder().name("ingress.enabled").value("is overridden").build() + )); + // When + new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()) + .generateHelmCharts(helmConfig.build()); + // Then + final Map savedValues = Serialization.unmarshal(helmOutputDirectory.resolve("kubernetes").resolve("values.yaml").toFile(), Map.class); + assertThat(savedValues) + .hasFieldOrPropertyWithValue("replaceableProperty", "the-value") + .hasFieldOrPropertyWithValue("replicaCount", 1) + .hasFieldOrPropertyWithValue("ingress.name", "the-ingress-from-parameter") + .hasFieldOrPropertyWithValue("ingress.enabled", false) + .hasFieldOrPropertyWithValue("ingress.tls", Collections.emptyList()) + .extracting("ingress.annotations").asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class)) + .containsOnly( + entry("kubernetes.io/ingress.class", "nginx"), + entry("kubernetes.io/tls-acme", "true") + ); + } + + @Test + @DisplayName("when helm test fragment provided, then helm test resource added to templates/tests directory") + void whenHelmTestFragmentProvided_thenFragmentCopiedToTemplatesTestDir() throws IOException { + // Given + jKubeConfiguration.getProject().getProperties().put("application.name", "name-configured-via-properties"); + jKubeConfiguration.getProject().getProperties().put("application.port", "79"); + resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( + new File(Objects.requireNonNull(getClass().getResource("/valid-helm-fragments")).getFile()))) + .build(); + // When + new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()) + .generateHelmCharts(helmConfig.build()); + // Then + final Pod helmTestConnectionPod = Serialization.unmarshal(helmOutputDirectory.resolve("kubernetes").resolve("templates").resolve("tests").resolve("test-connection.yaml").toFile(), Pod.class); + assertThat(helmTestConnectionPod) + .hasFieldOrPropertyWithValue("apiVersion", "v1") + .hasFieldOrPropertyWithValue("kind", "Pod") + .hasFieldOrPropertyWithValue("metadata.name", "name-configured-via-properties-test-connection") + .hasFieldOrPropertyWithValue("metadata.annotations", Collections.singletonMap("helm.sh/hook", "test")) + .hasFieldOrPropertyWithValue("spec.restartPolicy", "Never") + .extracting(Pod::getSpec) + .extracting(PodSpec::getContainers) + .asInstanceOf(InstanceOfAssertFactories.list(Container.class)) + .singleElement() + .hasFieldOrPropertyWithValue("name", "wget") + .hasFieldOrPropertyWithValue("image", "busybox") + .hasFieldOrPropertyWithValue("command", Collections.singletonList("wget")) + .hasFieldOrPropertyWithValue("args", Collections.singletonList("name-configured-via-properties:79")); + } + } + + @Nested + @DisplayName("invalid fragments") + class InvalidFragments { + @Test + @DisplayName("invalid chart.yaml fragment, throw exception") + void withInvalidChartYamlFragmentProvided_throwsException() { + // Given + givenResourceDir("/invalid-helm-chart-fragment"); + // When + Then + assertThatIllegalArgumentException() + .isThrownBy(() -> + new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()).generateHelmCharts(helmConfig.build())) + .withMessageStartingWith("Failure in parsing Helm fragment (Chart.helm.yaml): "); + } + + @Test + @DisplayName("invalid values.yaml fragment, throw exception") + void withInvalidValuesYamlFragmentProvided_throwsException() { + // Given + givenResourceDir("/invalid-helm-values-fragment"); + // When + Then + assertThatIllegalArgumentException() + .isThrownBy(() -> + new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()).generateHelmCharts(helmConfig.build())) + .withMessageStartingWith("Failure in parsing Helm fragment (values.helm.yaml): "); + } + + @Test + @DisplayName("invalid test.helm.yaml fragment, throw exception") + void withInvalidHelmTestYamlFragmentProvided_throwsException() { + // Given + givenResourceDir("/invalid-helm-test-fragment"); + // When + Then + assertThatIllegalArgumentException() + .isThrownBy(() -> + new HelmService(jKubeConfiguration, resourceServiceConfig, new KitLogger.SilentLogger()).generateHelmCharts(helmConfig.build())) + .withMessageStartingWith("Failure in parsing Helm fragment (test-pod.test.helm.yaml)"); + } + } + + private void givenResourceDir(String resourceDir) { + resourceServiceConfig = ResourceServiceConfig.builder().resourceDirs(Collections.singletonList( + new File(Objects.requireNonNull(getClass().getResource(resourceDir)).getFile()))) + .build(); + } } @Test @@ -279,7 +346,7 @@ void createChartYamlWithDependencies() throws Exception { entry("name", "Chart Name"), entry("version", "1337") ) - .extracting("dependencies").asList().singleElement() + .extracting("dependencies").asInstanceOf(InstanceOfAssertFactories.list(HelmDependency.class)).singleElement() .asInstanceOf(InstanceOfAssertFactories.map(String.class, String.class)) .contains( entry("name", "nginx"), diff --git a/jkube-kit/helm/src/test/resources/invalid-helm-test-fragment/test-pod.test.helm.yaml b/jkube-kit/helm/src/test/resources/invalid-helm-test-fragment/test-pod.test.helm.yaml new file mode 100644 index 0000000000..162b44b73a --- /dev/null +++ b/jkube-kit/helm/src/test/resources/invalid-helm-test-fragment/test-pod.test.helm.yaml @@ -0,0 +1 @@ +invalid-yaml: invalid: invalid \ No newline at end of file diff --git a/jkube-kit/helm/src/test/resources/valid-helm-fragments/test-connection.test.helm.yaml b/jkube-kit/helm/src/test/resources/valid-helm-fragments/test-connection.test.helm.yaml new file mode 100644 index 0000000000..c17a922978 --- /dev/null +++ b/jkube-kit/helm/src/test/resources/valid-helm-fragments/test-connection.test.helm.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: ${application.name}-test-connection + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['${application.name}:${application.port}'] + restartPolicy: Never \ No newline at end of file