This is an automated email from the ASF dual-hosted git repository. gfournier pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 1fc60bb577e CAMEL-21855: camel-jbang - k8s delete may not work any more 1fc60bb577e is described below commit 1fc60bb577e0c227022db2a92d1790e9569b18fb Author: Thomas Diesler <tdies...@redhat.com> AuthorDate: Tue Mar 11 13:47:33 2025 +0100 CAMEL-21855: camel-jbang - k8s delete may not work any more --- .../core/commands/kubernetes/KubernetesDelete.java | 48 +++++++++---------- .../core/commands/kubernetes/KubernetesRun.java | 3 -- .../commands/kubernetes/KubernetesCommandTest.java | 2 +- .../commands/kubernetes/KubernetesDeleteTest.java | 54 +++++++++++----------- 4 files changed, 50 insertions(+), 57 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDelete.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDelete.java index c22c3823f88..0901676947b 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDelete.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDelete.java @@ -21,65 +21,61 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import io.fabric8.kubernetes.api.model.StatusDetails; import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext; import io.fabric8.openshift.client.OpenShiftClient; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; -import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.BaseTrait; -import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; import org.codehaus.plexus.util.ExceptionUtils; import picocli.CommandLine; import static org.apache.camel.dsl.jbang.core.commands.kubernetes.KubernetesHelper.getKubernetesClient; +import static org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.BaseTrait.KUBERNETES_LABEL_NAME; @CommandLine.Command(name = "delete", - description = "Delete Camel application from Kubernetes. This operation will delete all resources associated to this app, such as: Deployment, Routes, Services, etc. filtering by labels \"app.kubernetes.io/managed-by=camel-jbang\" and \"app=<app name>\".", + description = "Delete Camel application from Kubernetes. This operation will delete all resources associated to this app, such as: Deployment, Routes, Services, etc. filtering by label \"app.kubernetes.io/name=<name>\".", sortOptions = false) public class KubernetesDelete extends KubernetesBaseCommand { - @CommandLine.Parameters(description = "The deployed application name", arity = "1", paramLabel = "<app name>") - String appName; - public KubernetesDelete(CamelJBangMain main) { super(main); } public Integer doCall() throws Exception { - printer().printf("Deleting all resources from app: %s%n", appName); - if (ObjectHelper.isEmpty(namespace)) { - namespace = getKubernetesClient().getNamespace(); - } + namespace = Optional.ofNullable(namespace).orElse(getKubernetesClient().getNamespace()); + namespace = Optional.ofNullable(namespace).orElse("default"); + printer().printf("Deleting resources in namespace '%s' with name: %s%n", namespace, name); Map<String, String> labels = new HashMap<>(); - // this label is set in KubernetesRun command - labels.put(BaseTrait.KUBERNETES_LABEL_MANAGED_BY, "camel-jbang"); - labels.put("app", appName); + labels.put(KUBERNETES_LABEL_NAME, name); List<StatusDetails> deleteStatuses = new ArrayList<>(); try { - // delete the most common resources // delete Deployment cascades to pod deleteStatuses .addAll(getKubernetesClient().apps().deployments().inNamespace(namespace).withLabels(labels).delete()); // delete service deleteStatuses.addAll(getKubernetesClient().services().inNamespace(namespace).withLabels(labels).delete()); + // delete configmap + deleteStatuses.addAll(getKubernetesClient().configMaps().inNamespace(namespace).withLabels(labels).delete()); + // delete secrets + deleteStatuses.addAll(getKubernetesClient().secrets().inNamespace(namespace).withLabels(labels).delete()); // delete knative-services - ResourceDefinitionContext knativeServices = new ResourceDefinitionContext.Builder() + var knativeServices = getKubernetesClient().genericKubernetesResources(new ResourceDefinitionContext.Builder() .withGroup("serving.knative.dev") .withVersion("v1") .withKind("Service") .withNamespaced(true) - .build(); - deleteStatuses - .addAll(getKubernetesClient().genericKubernetesResources(knativeServices).inNamespace(namespace) - .withLabels(labels).delete()); - // delete configmap - deleteStatuses.addAll(getKubernetesClient().configMaps().inNamespace(namespace).withLabels(labels).delete()); - // delete secrets - deleteStatuses.addAll(getKubernetesClient().secrets().inNamespace(namespace).withLabels(labels).delete()); + .build()) + .inNamespace(namespace).withLabels(labels); + try { + deleteStatuses.addAll(knativeServices.delete()); + } catch (Exception ex) { + // ignore + } ClusterType clusterType = KubernetesHelper.discoverClusterType(); if (ClusterType.OPENSHIFT == clusterType) { - // openshift specific: BuildConfig, ImageStreams, Route - BuildConfig casacade delete to Build and ConfigMap + // openshift specific: BuildConfig, ImageStreams, Route - BuildConfig cascade delete to Build and ConfigMap OpenShiftClient ocpClient = getKubernetesClient().adapt(OpenShiftClient.class); // BuildConfig deleteStatuses.addAll(ocpClient.buildConfigs().inNamespace(namespace).withLabels(labels).delete()); @@ -88,12 +84,12 @@ public class KubernetesDelete extends KubernetesBaseCommand { // Route deleteStatuses.addAll(ocpClient.routes().inNamespace(namespace).withLabels(labels).delete()); } - if (deleteStatuses.size() > 0) { + if (!deleteStatuses.isEmpty()) { deleteStatuses.forEach( s -> printer().printf("Deleted: %s/%s '%s'%n", s.getGroup(), StringHelper.capitalize(s.getKind()), s.getName())); } else { - printer().println("No deployment found with name: " + appName); + printer().println("No deployment found with name: " + name); } } catch (Exception ex) { // there could be various chained exceptions, so we want to get the root cause diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java index 45e17cbb6ed..e13814e2239 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java @@ -366,9 +366,6 @@ public class KubernetesRun extends KubernetesBaseCommand { private KubernetesExport configureExport(String workingDir) { detectCluster(); - // jkube automatically sets the "app.kubernetes.io/managed-by: jkube" label - // given this is a deployment managed by this plugin, we will replace the value for "camel-jbang" - buildProperties.add("jkube.enricher.jkube-well-known-labels.managedBy=camel-jbang"); KubernetesExport.ExportConfigurer configurer = new KubernetesExport.ExportConfigurer( runtime, quarkusVersion, diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesCommandTest.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesCommandTest.java index c76ecad1a4a..d20df61591f 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesCommandTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesCommandTest.java @@ -64,7 +64,7 @@ class KubernetesCommandTest extends KubernetesBaseTest { Assertions.assertEquals("route", deployment.getMetadata().getLabels().get(BaseTrait.KUBERNETES_LABEL_NAME)); Assertions.assertEquals("route", deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getName()); Assertions.assertEquals("route", matchLabels.get(BaseTrait.KUBERNETES_LABEL_NAME)); - Assertions.assertEquals("camel-jbang", matchLabels.get(BaseTrait.KUBERNETES_LABEL_MANAGED_BY)); + Assertions.assertEquals("jkube", matchLabels.get(BaseTrait.KUBERNETES_LABEL_MANAGED_BY)); Assertions.assertEquals("camel-test/route:1.0-SNAPSHOT", deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage()); Assertions.assertEquals("IfNotPresent", diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDeleteTest.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDeleteTest.java index bd92ecfcbb9..c27e197c3fb 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDeleteTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/test/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesDeleteTest.java @@ -60,7 +60,7 @@ class KubernetesDeleteTest { public void shouldDeleteNonExistentApp() throws Exception { KubernetesDelete command = new KubernetesDelete(new CamelJBangMain().withPrinter(printer)); command.withClient(client); - command.appName = "does-not-exist"; + command.name = "does-not-exist"; int exit = command.doCall(); boolean errorOutput = printer.getOutput().contains("Error trying to delete the app"); if (errorOutput) { @@ -88,7 +88,7 @@ class KubernetesDeleteTest { KubernetesDelete command = new KubernetesDelete(new CamelJBangMain().withPrinter(printer)); command.withClient(client); - command.appName = "does-not-exist"; + command.name = "does-not-exist"; int exit = command.doCall(); boolean errorOutput = printer.getOutput().contains("Error trying to delete the app"); if (errorOutput) { @@ -114,7 +114,7 @@ class KubernetesDeleteTest { KubernetesDelete command = new KubernetesDelete(new CamelJBangMain().withPrinter(printer)); command.withClient(client); - command.appName = "does-not-exist"; + command.name = "does-not-exist"; int exit = command.doCall(); boolean errorOutput = printer.getOutput().contains("Error trying to delete the app"); if (errorOutput) { @@ -127,33 +127,33 @@ class KubernetesDeleteTest { @Test public void shouldDeleteOnKubernetes() throws Exception { - String appName = "my-route"; + String name = "my-route"; // Mock the delete request expectation serverDeleteExpect( - "/apis/apps/v1/namespaces/test/deployments?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/apps/v1/namespaces/test/deployments?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/api/v1/namespaces/test/services?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/api/v1/namespaces/test/services?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/apis/serving.knative.dev/v1/namespaces/test/services?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/serving.knative.dev/v1/namespaces/test/services?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/api/v1/namespaces/test/configmaps?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/api/v1/namespaces/test/configmaps?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/api/v1/namespaces/test/secrets?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/api/v1/namespaces/test/secrets?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); // Execute delete command KubernetesDelete command = new KubernetesDelete(new CamelJBangMain().withPrinter(printer)); command.withClient(client); command.namespace = "test"; - command.appName = appName; + command.name = name; int exit = command.doCall(); // Verify command execution Assertions.assertEquals(0, exit, printer.getOutput()); // Verify deployment was deleted - Assertions.assertNull(client.apps().deployments().withName(appName).get()); - Assertions.assertNull(client.services().withName(appName).get()); + Assertions.assertNull(client.apps().deployments().withName(name).get()); + Assertions.assertNull(client.services().withName(name).get()); } @Test @@ -169,31 +169,31 @@ class KubernetesDeleteTest { serverExpect("/apis/config.openshift.io/v1/clusterversions/version", versionCR); - String appName = "my-route"; + String name = "my-route"; // Mock the delete request expectations for openshift resources serverDeleteExpect( - "/apis/apps/v1/namespaces/test/deployments?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/apps/v1/namespaces/test/deployments?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/api/v1/namespaces/test/services?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/api/v1/namespaces/test/services?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/apis/build.openshift.io/v1/namespaces/test/buildconfigs?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/build.openshift.io/v1/namespaces/test/buildconfigs?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/apis/image.openshift.io/v1/namespaces/test/imagestreams?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/image.openshift.io/v1/namespaces/test/imagestreams?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/apis/route.openshift.io/v1/namespaces/test/routes?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/route.openshift.io/v1/namespaces/test/routes?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/apis/serving.knative.dev/v1/namespaces/test/services?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/apis/serving.knative.dev/v1/namespaces/test/services?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/api/v1/namespaces/test/configmaps?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/api/v1/namespaces/test/configmaps?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); serverDeleteExpect( - "/api/v1/namespaces/test/secrets?labelSelector=app%3Dmy-route%2Capp.kubernetes.io%2Fmanaged-by%3Dcamel-jbang"); + "/api/v1/namespaces/test/secrets?labelSelector=app.kubernetes.io%2Fname%3Dmy-route"); // Execute delete command KubernetesDelete command = new KubernetesDelete(new CamelJBangMain().withPrinter(printer)); command.withClient(client); command.namespace = "test"; - command.appName = appName; + command.name = name; int exit = command.doCall(); // Verify command execution @@ -202,11 +202,11 @@ class KubernetesDeleteTest { OpenShiftClient ocpClient = client.adapt(OpenShiftClient.class); // Verify deployment was deleted - Assertions.assertNull(client.apps().deployments().withName(appName).get()); - Assertions.assertNull(client.services().withName(appName).get()); - Assertions.assertNull(ocpClient.buildConfigs().withName(appName).get()); - Assertions.assertNull(ocpClient.imageStreams().withName(appName).get()); - Assertions.assertNull(ocpClient.routes().withName(appName).get()); + Assertions.assertNull(client.apps().deployments().withName(name).get()); + Assertions.assertNull(client.services().withName(name).get()); + Assertions.assertNull(ocpClient.buildConfigs().withName(name).get()); + Assertions.assertNull(ocpClient.imageStreams().withName(name).get()); + Assertions.assertNull(ocpClient.routes().withName(name).get()); } private void serverDeleteExpect(String path) {