diff --git a/operator/src/main/java/org/keycloak/operator/Constants.java b/operator/src/main/java/org/keycloak/operator/Constants.java index 05e8f73989f..f3efcf84e24 100644 --- a/operator/src/main/java/org/keycloak/operator/Constants.java +++ b/operator/src/main/java/org/keycloak/operator/Constants.java @@ -39,6 +39,7 @@ public final class Constants { public static final String KEYCLOAK_RECREATE_UPDATE_ANNOTATION = "operator.keycloak.org/recreate-update"; public static final String KEYCLOAK_UPDATE_REASON_ANNOTATION = "operator.keycloak.org/update-reason"; public static final String KEYCLOAK_UPDATE_REVISION_ANNOTATION = "operator.keycloak.org/update-revision"; + public static final String APP_LABEL = "app"; public static final String DEFAULT_LABELS_AS_STRING = "app=keycloak,app.kubernetes.io/managed-by=keycloak-operator"; diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakUpdateJobDependentResource.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakUpdateJobDependentResource.java index 52013bcef2d..f9e7b5aa294 100644 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakUpdateJobDependentResource.java +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakUpdateJobDependentResource.java @@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; +import io.fabric8.kubernetes.api.model.HasMetadata; import org.keycloak.operator.Constants; import org.keycloak.operator.ContextUtils; import org.keycloak.operator.Utils; @@ -57,6 +58,10 @@ public class KeycloakUpdateJobDependentResource extends CRUDKubernetesDependentR // Annotations public static final String KEYCLOAK_CR_HASH_ANNOTATION = "operator.keycloak.org/keycloak-hash"; + // Label + private static final String APP_LABEL_VALUE = "keycloak-update-job"; + private static final String LABEL_SELECTOR = "app=keycloak-update-job,app.kubernetes.io/managed-by=keycloak-operator"; + // container configuration private static final String INIT_CONTAINER_NAME = "actual"; private static final String CONTAINER_NAME = "desired"; @@ -73,7 +78,7 @@ public class KeycloakUpdateJobDependentResource extends CRUDKubernetesDependentR super(Job.class); this.configureWith(new KubernetesDependentResourceConfigBuilder() .withKubernetesDependentInformerConfig(InformerConfiguration.builder(resourceType()) - .withLabelSelector(Constants.DEFAULT_LABELS_AS_STRING) + .withLabelSelector(LABEL_SELECTOR) .build()) .build()); } @@ -110,7 +115,7 @@ public class KeycloakUpdateJobDependentResource extends CRUDKubernetesDependentR var builder = new ObjectMetaBuilder(); builder.withName(name) .withNamespace(keycloak.getMetadata().getNamespace()) - .withLabels(Utils.allInstanceLabels(keycloak)) + .withLabels(getLabels(keycloak)) .withAnnotations(Map.of(KEYCLOAK_CR_HASH_ANNOTATION, keycloakHash(keycloak))); return builder.build(); } @@ -209,4 +214,9 @@ public class KeycloakUpdateJobDependentResource extends CRUDKubernetesDependentR return Utils.hash(List.of(keycloak.getSpec())); } + private static Map getLabels(HasMetadata keycloak) { + var labels = Utils.allInstanceLabels(keycloak); + labels.put(Constants.APP_LABEL, APP_LABEL_VALUE); + return labels; + } } diff --git a/operator/src/test/java/org/keycloak/operator/testsuite/integration/UpdateTest.java b/operator/src/test/java/org/keycloak/operator/testsuite/integration/UpdateTest.java index 71fb9b3585d..b5656ba6196 100644 --- a/operator/src/test/java/org/keycloak/operator/testsuite/integration/UpdateTest.java +++ b/operator/src/test/java/org/keycloak/operator/testsuite/integration/UpdateTest.java @@ -18,6 +18,7 @@ package org.keycloak.operator.testsuite.integration; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -32,12 +33,15 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.client.dsl.Gettable; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfSystemProperty; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import org.keycloak.operator.Utils; import org.keycloak.operator.controllers.KeycloakUpdateJobDependentResource; import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak; import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusCondition; @@ -48,6 +52,7 @@ import org.keycloak.operator.testsuite.utils.CRAssert; import org.keycloak.operator.update.UpdateStrategy; import org.keycloak.operator.update.impl.AutoUpdateLogic; +import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.batch.v1.Job; import io.fabric8.kubernetes.api.model.batch.v1.JobStatus; import io.quarkus.test.junit.QuarkusTest; @@ -218,6 +223,20 @@ public class UpdateTest extends BaseOperatorTest { var finished = maybeStatus.map(JobStatus::getSucceeded).orElse(0) + maybeStatus.map(JobStatus::getFailed).orElse(0); assertEquals(1, finished); + + // check label selector + var jobPodName = AutoUpdateLogic.findPodForJob(k8sclient, job) + .map(Pod::getMetadata) + .map(ObjectMeta::getName) + .orElseThrow(); + var servicePods = k8sclient.pods().inNamespace(namespaceOf(keycloak)) + .withLabels(Utils.allInstanceLabels(keycloak)) + .resources() + .map(Gettable::get) + .map(Pod::getMetadata) + .map(ObjectMeta::getName) + .toList(); + assertFalse(servicePods.contains(jobPodName), "pods: " + servicePods + " / job pod: " + jobPodName); return job; }