From 2095958e6502e6ce567328dadb044c3b89dd2313 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Mon, 12 Aug 2024 17:16:54 +0200 Subject: [PATCH] fix: inject DeserializedKubernetesResourcesBuildItem optionally Signed-off-by: Chris Laprun --- .../bundle/deployment/BundleProcessor.java | 86 ++++++------------- .../deployment/helm/HelmChartProcessor.java | 72 +++++++++------- 2 files changed, 68 insertions(+), 90 deletions(-) diff --git a/bundle-generator/deployment/src/main/java/io/quarkiverse/operatorsdk/bundle/deployment/BundleProcessor.java b/bundle-generator/deployment/src/main/java/io/quarkiverse/operatorsdk/bundle/deployment/BundleProcessor.java index 3610a7acc..c58d1b95f 100644 --- a/bundle-generator/deployment/src/main/java/io/quarkiverse/operatorsdk/bundle/deployment/BundleProcessor.java +++ b/bundle-generator/deployment/src/main/java/io/quarkiverse/operatorsdk/bundle/deployment/BundleProcessor.java @@ -43,7 +43,6 @@ import io.quarkus.deployment.builditem.GeneratedFileSystemResourceBuildItem; import io.quarkus.deployment.pkg.builditem.JarBuildItem; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; -import io.quarkus.kubernetes.deployment.KubernetesCommonHelper; import io.quarkus.kubernetes.deployment.KubernetesConfig; import io.quarkus.kubernetes.deployment.ResourceNameUtil; @@ -136,37 +135,6 @@ CSVMetadataBuildItem gatherCSVMetadata(KubernetesConfig kubernetesConfig, return new CSVMetadataBuildItem(csvGroups); } - private static String getDefaultProviderURLFromSCMInfo(ApplicationInfoBuildItem appConfiguration, - JarBuildItem jarBuildItem) { - final var maybeProject = KubernetesCommonHelper.createProject(appConfiguration, Optional.empty(), - jarBuildItem.getPath()); - return maybeProject.map(project -> { - final var scmInfo = project.getScmInfo(); - if (scmInfo != null) { - var origin = scmInfo.getRemote().get("origin"); - if (origin != null) { - try { - int atSign = origin.indexOf('@'); - if (atSign > 0) { - origin = origin.substring(atSign + 1); - origin = origin.replaceFirst(":", "/"); - origin = "https://" + origin; - } - - int dotGit = origin.indexOf(".git"); - if (dotGit > 0 && dotGit < origin.length() - 1) { - origin = origin.substring(0, dotGit); - } - return origin; - } catch (Exception e) { - log.warnv("Couldn't parse SCM information: {0}", origin); - } - } - } - return null; - }).orElse(null); - } - private static ReconcilerAugmentedClassInfo augmentReconcilerInfo( ReconcilerAugmentedClassInfo reconcilerInfo) { // if primary resource is a CR, check if it is annotated with CSVMetadata and augment it if it is @@ -224,7 +192,7 @@ void generateBundle(ApplicationInfoBuildItem configuration, VersionBuildItem versionBuildItem, BuildProducer doneGeneratingCSV, GeneratedCRDInfoBuildItem generatedCustomResourcesDefinitions, - DeserializedKubernetesResourcesBuildItem generatedKubernetesResources, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional maybeGeneratedKubeResources, BuildProducer generatedCSVs) { final var crds = generatedCustomResourcesDefinitions.getCRDGenerationInfo().getCrds() .values().stream() @@ -238,36 +206,38 @@ void generateBundle(ApplicationInfoBuildItem configuration, final var roles = new LinkedList(); final var deployments = new LinkedList(); - final var resources = generatedKubernetesResources.getResources(); - resources.forEach(r -> { - if (r instanceof ServiceAccount) { - serviceAccounts.add((ServiceAccount) r); - return; - } + maybeGeneratedKubeResources.ifPresent(generatedKubeResources -> { + final var resources = generatedKubeResources.getResources(); + resources.forEach(r -> { + if (r instanceof ServiceAccount) { + serviceAccounts.add((ServiceAccount) r); + return; + } - if (r instanceof ClusterRoleBinding) { - clusterRoleBindings.add((ClusterRoleBinding) r); - return; - } + if (r instanceof ClusterRoleBinding) { + clusterRoleBindings.add((ClusterRoleBinding) r); + return; + } - if (r instanceof ClusterRole) { - clusterRoles.add((ClusterRole) r); - return; - } + if (r instanceof ClusterRole) { + clusterRoles.add((ClusterRole) r); + return; + } - if (r instanceof RoleBinding) { - roleBindings.add((RoleBinding) r); - return; - } + if (r instanceof RoleBinding) { + roleBindings.add((RoleBinding) r); + return; + } - if (r instanceof Role) { - roles.add((Role) r); - return; - } + if (r instanceof Role) { + roles.add((Role) r); + return; + } - if (r instanceof Deployment) { - deployments.add((Deployment) r); - } + if (r instanceof Deployment) { + deployments.add((Deployment) r); + } + }); }); final var deploymentName = ResourceNameUtil.getResourceName(kubernetesConfig, configuration); diff --git a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/helm/HelmChartProcessor.java b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/helm/HelmChartProcessor.java index 20e97d393..822257f20 100644 --- a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/helm/HelmChartProcessor.java +++ b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/helm/HelmChartProcessor.java @@ -10,6 +10,7 @@ import java.nio.file.Path; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import org.jboss.logging.Logger; @@ -156,21 +157,24 @@ void addClusterRolesForReconcilers(HelmTargetDirectoryBuildItem helmTargetDirect @BuildStep @Produce(ArtifactResultBuildItem.class) - void addExplicitlyAddedKubernetesResources(DeserializedKubernetesResourcesBuildItem generatedKubernetesResources, + void addExplicitlyAddedKubernetesResources( + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional maybedGeneratedKubeRes, HelmTargetDirectoryBuildItem helmDirBI, ApplicationInfoBuildItem appInfo, KubernetesConfig kubernetesConfig) { - var resources = generatedKubernetesResources.getResources(); - resources = filterOutStandardResources(resources, ResourceNameUtil.getResourceName(kubernetesConfig, appInfo)); - if (!resources.isEmpty()) { - final var kubernetesManifest = helmDirBI.getPathToTemplatesDir().resolve("kubernetes.yml"); - // Generate a possibly multi-document YAML - String yaml = resources.stream().map(FileUtils::asYaml).collect(Collectors.joining()); - try { - Files.writeString(kubernetesManifest, yaml); - } catch (IOException e) { - throw new IllegalStateException(e); + maybedGeneratedKubeRes.ifPresent(generatedKubernetesResources -> { + var resources = generatedKubernetesResources.getResources(); + resources = filterOutStandardResources(resources, ResourceNameUtil.getResourceName(kubernetesConfig, appInfo)); + if (!resources.isEmpty()) { + final var kubernetesManifest = helmDirBI.getPathToTemplatesDir().resolve("kubernetes.yml"); + // Generate a possibly multi-document YAML + String yaml = resources.stream().map(FileUtils::asYaml).collect(Collectors.joining()); + try { + Files.writeString(kubernetesManifest, yaml); + } catch (IOException e) { + throw new IllegalStateException(e); + } } - } + }); } private List filterOutStandardResources(List resources, String operatorName) { @@ -202,29 +206,33 @@ private void addTemplateFiles(HelmTargetDirectoryBuildItem helmDirBI) { @BuildStep @Produce(ArtifactResultBuildItem.class) void addGeneratedDeployment(HelmTargetDirectoryBuildItem helmDirBI, - DeserializedKubernetesResourcesBuildItem deserializedKubernetesResources, + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional maybeDeserializedKubeResources, ControllerConfigurationsBuildItem controllerConfigurations, ApplicationInfoBuildItem appInfo) { - // add an env var for each reconciler's watch namespace in the operator's deployment - var deployment = (Deployment) deserializedKubernetesResources.getResources().stream() - .filter(Deployment.class::isInstance).findFirst() - .orElseThrow(); - // copy the deployment so that changes are not propagated outside of this method - final var firstContainer = deployment.edit().editSpec().editTemplate().editSpec().editFirstContainer(); - controllerConfigurations.getControllerConfigs() - .forEach((name, unused) -> firstContainer.addNewEnv() - .withName(ConfigurationUtils.getNamespacesPropertyName(name, true)) - .withValue("{watchNamespaces}").endEnv()); - deployment = firstContainer.endContainer().endSpec().endTemplate().endSpec().build(); + if (maybeDeserializedKubeResources.isEmpty()) { + log.warn("No Kubernetes manifests were found, no Helm chart will be generated"); + } else { + // add an env var for each reconciler's watch namespace in the operator's deployment + var deployment = (Deployment) maybeDeserializedKubeResources.get().getResources().stream() + .filter(Deployment.class::isInstance).findFirst() + .orElseThrow(); + // copy the deployment so that changes are not propagated outside of this method + final var firstContainer = deployment.edit().editSpec().editTemplate().editSpec().editFirstContainer(); + controllerConfigurations.getControllerConfigs() + .forEach((name, unused) -> firstContainer.addNewEnv() + .withName(ConfigurationUtils.getNamespacesPropertyName(name, true)) + .withValue("{watchNamespaces}").endEnv()); + deployment = firstContainer.endContainer().endSpec().endTemplate().endSpec().build(); - // a bit hacky solution to get the exact placeholder without brackets - final var template = FileUtils.asYaml(deployment); - var res = template.replace("\"{watchNamespaces}\"", "{{ .Values.watchNamespaces }}"); - res = res.replaceAll(appInfo.getVersion(), "{{ .Chart.AppVersion }}"); - try { - Files.writeString(helmDirBI.getPathToTemplatesDir().resolve("deployment.yaml"), res); - } catch (IOException e) { - throw new IllegalStateException(e); + // a bit hacky solution to get the exact placeholder without brackets + final var template = FileUtils.asYaml(deployment); + var res = template.replace("\"{watchNamespaces}\"", "{{ .Values.watchNamespaces }}"); + res = res.replaceAll(appInfo.getVersion(), "{{ .Chart.AppVersion }}"); + try { + Files.writeString(helmDirBI.getPathToTemplatesDir().resolve("deployment.yaml"), res); + } catch (IOException e) { + throw new IllegalStateException(e); + } } }