Fix Operator tests on OpenShift

Closes #22140
Closes #22142
Closes #22143
This commit is contained in:
Václav Muzikář 2023-08-01 12:14:40 +02:00 committed by Alexander Schwartz
parent cce0778886
commit b78b498a26
4 changed files with 50 additions and 33 deletions

View file

@ -41,7 +41,6 @@ import io.quarkus.test.junit.callback.QuarkusTestMethodContext;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.config.ConfigProvider;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.TestInfo;
@ -179,7 +178,11 @@ public class BaseOperatorTest implements QuarkusTestAfterEachCallback {
} }
private static void calculateNamespace() { private static void calculateNamespace() {
namespace = "keycloak-test-" + UUID.randomUUID(); namespace = getNewRandomNamespaceName();
}
public static String getNewRandomNamespaceName() {
return "keycloak-test-" + UUID.randomUUID();
} }
protected static void deployDB() { protected static void deployDB() {

View file

@ -32,6 +32,7 @@ import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpec; import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpec;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpecBuilder; import org.keycloak.operator.crds.v2alpha1.deployment.spec.IngressSpecBuilder;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder; import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.UnsupportedSpecBuilder;
import org.keycloak.operator.testsuite.utils.K8sUtils; import org.keycloak.operator.testsuite.utils.K8sUtils;
import org.keycloak.operator.controllers.KeycloakIngress; import org.keycloak.operator.controllers.KeycloakIngress;
@ -76,6 +77,19 @@ public class KeycloakIngressTest extends BaseOperatorTest {
// on OpenShift, when Keycloak is configured for HTTP only, we use edge TLS termination, i.e. Route still uses TLS // on OpenShift, when Keycloak is configured for HTTP only, we use edge TLS termination, i.e. Route still uses TLS
baseUrl = "https://" + testHostname + ":443"; baseUrl = "https://" + testHostname + ":443";
hostnameSpecBuilder.withHostname(testHostname); hostnameSpecBuilder.withHostname(testHostname);
// see https://github.com/keycloak/keycloak/issues/14400#issuecomment-1659900081
kc.getSpec().setUnsupported(new UnsupportedSpecBuilder()
.withNewPodTemplate()
.withNewSpec()
.addNewContainer()
.addNewEnv()
.withName("KC_PROXY")
.withValue("edge")
.endEnv()
.endContainer()
.endSpec()
.endPodTemplate()
.build());
} }
else { else {
baseUrl = "http://" + kubernetesIp + ":80"; baseUrl = "http://" + kubernetesIp + ":80";

View file

@ -19,6 +19,7 @@ package org.keycloak.operator.testsuite.integration;
import io.fabric8.kubernetes.api.model.LocalObjectReference; import io.fabric8.kubernetes.api.model.LocalObjectReference;
import io.fabric8.kubernetes.api.model.LocalObjectReferenceBuilder; import io.fabric8.kubernetes.api.model.LocalObjectReferenceBuilder;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder; import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.Resource;
@ -110,26 +111,35 @@ public class PodTemplateTest extends BaseOperatorTest {
@Test @Test
public void testPodTemplateIncorrectNamespace() { public void testPodTemplateIncorrectNamespace() {
// Arrange final String wrongNamespace = getNewRandomNamespaceName();
var plainKc = getEmptyPodTemplateKeycloak(); try {
var podTemplate = new PodTemplateSpecBuilder() // Arrange
.withNewMetadata() Log.info("Using incorrect namespace: " + wrongNamespace);
.withNamespace("bar") k8sclient.resource(new NamespaceBuilder().withNewMetadata().withName(wrongNamespace).endMetadata().build()).create(); // OpenShift actually checks existence of the NS
.endMetadata() var plainKc = getEmptyPodTemplateKeycloak();
.build(); var podTemplate = new PodTemplateSpecBuilder()
plainKc.getSpec().getUnsupported().setPodTeplate(podTemplate); .withNewMetadata()
.withNamespace(wrongNamespace)
.endMetadata()
.build();
plainKc.getSpec().getUnsupported().setPodTeplate(podTemplate);
// Act // Act
K8sUtils.set(k8sclient, plainKc); K8sUtils.set(k8sclient, plainKc);
// Assert // Assert
Log.info("Getting status of Keycloak"); Log.info("Getting status of Keycloak");
Awaitility Awaitility
.await() .await()
.ignoreExceptions() .ignoreExceptions()
.atMost(3, MINUTES).untilAsserted(() -> { .atMost(3, MINUTES).untilAsserted(() -> {
CRAssert.assertKeycloakStatusCondition(getCrSelector().get(), HAS_ERRORS, false, "cannot be modified"); CRAssert.assertKeycloakStatusCondition(getCrSelector().get(), HAS_ERRORS, false, "cannot be modified");
}); });
}
finally {
Log.info("Deleting incorrect namespace: " + wrongNamespace);
k8sclient.namespaces().withName(wrongNamespace).delete();
}
} }
@Test @Test

View file

@ -17,13 +17,11 @@
package org.keycloak.operator.testsuite.integration; package org.keycloak.operator.testsuite.integration;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretBuilder; import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.api.model.apps.StatefulSet; import io.fabric8.kubernetes.api.model.apps.StatefulSet;
import io.quarkus.logging.Log; import io.quarkus.logging.Log;
import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.QuarkusTest;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -34,8 +32,6 @@ import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusCondition;
import org.keycloak.operator.crds.v2alpha1.deployment.ValueOrSecret; import org.keycloak.operator.crds.v2alpha1.deployment.ValueOrSecret;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder; import org.keycloak.operator.crds.v2alpha1.deployment.spec.HostnameSpecBuilder;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64; import java.util.Base64;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -98,15 +94,9 @@ public class WatchedSecretsTest extends BaseOperatorTest {
Base64.getEncoder().encodeToString(username.getBytes())); Base64.getEncoder().encodeToString(username.getBytes()));
k8sclient.resource(dbSecret).update(); k8sclient.resource(dbSecret).update();
Pod pod = k8sclient.pods().withName(kc.getMetadata().getName() + "-0").waitUntilCondition( // dynamically check pod 0 to avoid race conditions
p -> p != null && !prevRevision.equals(p.getMetadata().getLabels().get("controller-revision-hash")), Awaitility.await().atMost(1, TimeUnit.MINUTES).ignoreExceptions().until(() ->
30, TimeUnit.SECONDS); k8sclient.pods().withName(kc.getMetadata().getName() + "-0").getLog().contains("password authentication failed for user \"" + username + "\""));
ByteArrayOutputStream logBytes = new ByteArrayOutputStream();
try (var ignored = k8sclient.pods().resource(pod).watchLog(logBytes)) {
Awaitility.await().atMost(1, TimeUnit.MINUTES).until(() -> logBytes.toString(StandardCharsets.UTF_8)
.contains("password authentication failed for user \"" + username + "\""));
}
} }
private StatefulSet getStatefulSet(Keycloak kc) { private StatefulSet getStatefulSet(Keycloak kc) {