Fix Operator tests on OpenShift
Closes #22140 Closes #22142 Closes #22143
This commit is contained in:
parent
cce0778886
commit
b78b498a26
4 changed files with 50 additions and 33 deletions
|
@ -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() {
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue