Harden operator CI
This commit is contained in:
parent
18f391d8c4
commit
6504c058dd
5 changed files with 42 additions and 14 deletions
|
@ -32,8 +32,8 @@
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<quarkus.operator.sdk.version>3.0.2</quarkus.operator.sdk.version>
|
<quarkus.operator.sdk.version>3.0.4</quarkus.operator.sdk.version>
|
||||||
<quarkus.version>2.6.1.Final</quarkus.version>
|
<quarkus.version>2.7.3.Final</quarkus.version>
|
||||||
<quarkus.container-image.group>keycloak</quarkus.container-image.group>
|
<quarkus.container-image.group>keycloak</quarkus.container-image.group>
|
||||||
<quarkus.jib.base-jvm-image>eclipse-temurin:11</quarkus.jib.base-jvm-image>
|
<quarkus.jib.base-jvm-image>eclipse-temurin:11</quarkus.jib.base-jvm-image>
|
||||||
<quarkus.kubernetes.image-pull-policy>Never</quarkus.kubernetes.image-pull-policy>
|
<quarkus.kubernetes.image-pull-policy>Never</quarkus.kubernetes.image-pull-policy>
|
||||||
|
|
|
@ -37,15 +37,18 @@ import org.keycloak.operator.Constants;
|
||||||
import org.keycloak.operator.v2alpha1.crds.Keycloak;
|
import org.keycloak.operator.v2alpha1.crds.Keycloak;
|
||||||
import org.keycloak.operator.v2alpha1.crds.KeycloakStatus;
|
import org.keycloak.operator.v2alpha1.crds.KeycloakStatus;
|
||||||
import org.keycloak.operator.v2alpha1.crds.KeycloakStatusBuilder;
|
import org.keycloak.operator.v2alpha1.crds.KeycloakStatusBuilder;
|
||||||
|
import org.keycloak.operator.v2alpha1.crds.KeycloakStatusCondition;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_FINALIZER;
|
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_FINALIZER;
|
||||||
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE;
|
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE;
|
||||||
|
|
||||||
@ControllerConfiguration(namespaces = WATCH_CURRENT_NAMESPACE, finalizerName = NO_FINALIZER)
|
// TODO: remove "generationAwareEventProcessing = false" when the race condition is fixed
|
||||||
|
@ControllerConfiguration(namespaces = WATCH_CURRENT_NAMESPACE, finalizerName = NO_FINALIZER, generationAwareEventProcessing = false)
|
||||||
public class KeycloakController implements Reconciler<Keycloak>, EventSourceInitializer<Keycloak>, ErrorStatusHandler<Keycloak> {
|
public class KeycloakController implements Reconciler<Keycloak>, EventSourceInitializer<Keycloak>, ErrorStatusHandler<Keycloak> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -98,13 +101,23 @@ public class KeycloakController implements Reconciler<Keycloak>, EventSourceInit
|
||||||
|
|
||||||
Log.info("--- Reconciliation finished successfully");
|
Log.info("--- Reconciliation finished successfully");
|
||||||
|
|
||||||
|
UpdateControl<Keycloak> updateControl;
|
||||||
if (status.equals(kc.getStatus())) {
|
if (status.equals(kc.getStatus())) {
|
||||||
return UpdateControl.noUpdate();
|
updateControl = UpdateControl.noUpdate();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
kc.setStatus(status);
|
kc.setStatus(status);
|
||||||
return UpdateControl.updateStatus(kc);
|
updateControl = UpdateControl.updateStatus(kc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status
|
||||||
|
.getConditions()
|
||||||
|
.stream()
|
||||||
|
.anyMatch(c -> c.getType().equals(KeycloakStatusCondition.READY) && !c.getStatus())) {
|
||||||
|
updateControl.rescheduleAfter(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -510,6 +510,7 @@ public class KeycloakDeployment extends OperatorManagedResource implements Statu
|
||||||
|| existingDeployment.getStatus().getReadyReplicas() == null
|
|| existingDeployment.getStatus().getReadyReplicas() == null
|
||||||
|| existingDeployment.getStatus().getReadyReplicas() < keycloakCR.getSpec().getInstances()) {
|
|| existingDeployment.getStatus().getReadyReplicas() < keycloakCR.getSpec().getInstances()) {
|
||||||
status.addNotReadyMessage("Waiting for more replicas");
|
status.addNotReadyMessage("Waiting for more replicas");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,24 @@ import io.javaoperatorsdk.operator.processing.event.source.EventSource;
|
||||||
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
|
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
|
||||||
import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers;
|
import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers;
|
||||||
import io.quarkus.logging.Log;
|
import io.quarkus.logging.Log;
|
||||||
|
import org.keycloak.operator.v2alpha1.crds.Keycloak;
|
||||||
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImport;
|
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImport;
|
||||||
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImportStatus;
|
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImportStatus;
|
||||||
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImportStatusBuilder;
|
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImportStatusBuilder;
|
||||||
|
import org.keycloak.operator.v2alpha1.crds.KeycloakRealmImportStatusCondition;
|
||||||
|
import org.keycloak.operator.v2alpha1.crds.KeycloakStatusCondition;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_FINALIZER;
|
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_FINALIZER;
|
||||||
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE;
|
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE;
|
||||||
|
|
||||||
@ControllerConfiguration(namespaces = WATCH_CURRENT_NAMESPACE, finalizerName = NO_FINALIZER)
|
// TODO: remove "generationAwareEventProcessing = false" when the race condition is fixed
|
||||||
|
@ControllerConfiguration(namespaces = WATCH_CURRENT_NAMESPACE, finalizerName = NO_FINALIZER, generationAwareEventProcessing = false)
|
||||||
public class KeycloakRealmImportController implements Reconciler<KeycloakRealmImport>, EventSourceInitializer<KeycloakRealmImport>, ErrorStatusHandler<KeycloakRealmImport> {
|
public class KeycloakRealmImportController implements Reconciler<KeycloakRealmImport>, EventSourceInitializer<KeycloakRealmImport>, ErrorStatusHandler<KeycloakRealmImport> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -83,12 +88,22 @@ public class KeycloakRealmImportController implements Reconciler<KeycloakRealmIm
|
||||||
|
|
||||||
Log.info("--- Realm reconciliation finished successfully");
|
Log.info("--- Realm reconciliation finished successfully");
|
||||||
|
|
||||||
|
UpdateControl<KeycloakRealmImport> updateControl;
|
||||||
if (status.equals(realm.getStatus())) {
|
if (status.equals(realm.getStatus())) {
|
||||||
return UpdateControl.noUpdate();
|
updateControl = UpdateControl.noUpdate();
|
||||||
} else {
|
} else {
|
||||||
realm.setStatus(status);
|
realm.setStatus(status);
|
||||||
return UpdateControl.updateStatus(realm);
|
updateControl = UpdateControl.updateStatus(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status
|
||||||
|
.getConditions()
|
||||||
|
.stream()
|
||||||
|
.anyMatch(c -> c.getType().equals(KeycloakRealmImportStatusCondition.DONE) && !c.getStatus())) {
|
||||||
|
updateControl.rescheduleAfter(10, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,8 +34,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
||||||
|
@ -75,8 +74,8 @@ public final class K8sUtils {
|
||||||
public static void waitForKeycloakToBeReady(KubernetesClient client, Keycloak kc) {
|
public static void waitForKeycloakToBeReady(KubernetesClient client, Keycloak kc) {
|
||||||
Log.infof("Waiting for Keycloak \"%s\"", kc.getMetadata().getName());
|
Log.infof("Waiting for Keycloak \"%s\"", kc.getMetadata().getName());
|
||||||
Awaitility.await()
|
Awaitility.await()
|
||||||
.pollInterval(Duration.ofSeconds(1))
|
.pollInterval(1, TimeUnit.SECONDS)
|
||||||
.timeout(Duration.ofMinutes(5))
|
.timeout(5, TimeUnit.MINUTES)
|
||||||
.ignoreExceptions()
|
.ignoreExceptions()
|
||||||
.untilAsserted(() -> {
|
.untilAsserted(() -> {
|
||||||
var currentKc = client
|
var currentKc = client
|
||||||
|
@ -106,7 +105,7 @@ public final class K8sUtils {
|
||||||
.build())
|
.build())
|
||||||
.done();
|
.done();
|
||||||
Log.info("Waiting for curl Pod to finish running");
|
Log.info("Waiting for curl Pod to finish running");
|
||||||
Awaitility.await().atMost(3, MINUTES)
|
Awaitility.await().atMost(3, TimeUnit.MINUTES)
|
||||||
.until(() -> {
|
.until(() -> {
|
||||||
String phase =
|
String phase =
|
||||||
k8sclient.pods().inNamespace(namespace).withName(podName).get()
|
k8sclient.pods().inNamespace(namespace).withName(podName).get()
|
||||||
|
@ -124,7 +123,7 @@ public final class K8sUtils {
|
||||||
} finally {
|
} finally {
|
||||||
Log.info("Deleting curl Pod");
|
Log.info("Deleting curl Pod");
|
||||||
k8sclient.pods().inNamespace(namespace).withName(podName).delete();
|
k8sclient.pods().inNamespace(namespace).withName(podName).delete();
|
||||||
Awaitility.await().atMost(2, MINUTES)
|
Awaitility.await().atMost(2, TimeUnit.MINUTES)
|
||||||
.until(() -> k8sclient.pods().inNamespace(namespace).withName(podName)
|
.until(() -> k8sclient.pods().inNamespace(namespace).withName(podName)
|
||||||
.get() == null);
|
.get() == null);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue