Add OpenShift support to KeycloakIngressTest (#20030)

This commit is contained in:
Václav Muzikář 2023-05-02 14:24:54 +02:00 committed by GitHub
parent c2c5012cfb
commit 983e40ad2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 31 deletions

View file

@ -0,0 +1,29 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.operator;
import io.fabric8.kubernetes.client.KubernetesClient;
/**
* @author Vaclav Muzikar <vmuzikar@redhat.com>
*/
public final class Utils {
public static boolean isOpenShift(KubernetesClient client) {
return client.supports("operator.openshift.io/v1", "OpenShiftAPIServer");
}
}

View file

@ -51,6 +51,7 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.keycloak.operator.Utils.isOpenShift;
import static org.keycloak.operator.testsuite.utils.K8sUtils.getResourceFromFile;
public abstract class BaseOperatorTest {
@ -75,6 +76,7 @@ public abstract class BaseOperatorTest {
protected static String kubernetesIp;
protected static String customImage;
private static Operator operator;
protected static boolean isOpenShift;
@BeforeAll
@ -91,6 +93,7 @@ public abstract class BaseOperatorTest {
createK8sClient();
createCRDs();
createNamespace();
isOpenShift = isOpenShift(k8sclient);
if (operatorDeployment == OperatorDeployment.remote) {
createRBACresourcesAndOperatorDeployment();

View file

@ -25,6 +25,7 @@ import io.quarkus.logging.Log;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.keycloak.operator.Constants;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
@ -41,59 +42,80 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
@QuarkusTest
public class KeycloakIngressTest extends BaseOperatorTest {
private static String baseDomain;
@BeforeAll
public static void beforeKeycloakIngressTest() {
if (isOpenShift) {
Log.info("OpenShift detected, using real domain");
// see https://docs.openshift.com/container-platform/4.12/networking/ingress-operator.html#configuring-ingress
baseDomain = k8sclient.genericKubernetesResources("config.openshift.io/v1", "Ingress")
.withName("cluster")
.get()
.get("spec", "domain");
if (baseDomain == null || baseDomain.isBlank()) {
throw new IllegalStateException("Couldn't fetch the base Ingress domain");
}
}
}
@Test
public void testIngressOnHTTP() {
var kc = K8sUtils.getDefaultKeycloakDeployment();
kc.getSpec().getHttpSpec().setTlsSecret(null);
kc.getSpec().getHttpSpec().setHttpEnabled(true);
var hostnameSpec = new HostnameSpecBuilder()
var hostnameSpecBuilder = new HostnameSpecBuilder()
.withStrict(false)
.withStrictBackchannel(false)
.build();
kc.getSpec().setHostnameSpec(hostnameSpec);
.withStrictBackchannel(false);
String testHostname;
String baseUrl;
if (isOpenShift) {
testHostname = "kc-http-" + namespace + "." + baseDomain;
// on OpenShift, when Keycloak is configured for HTTP only, we use edge TLS termination, i.e. Route still uses TLS
baseUrl = "https://" + testHostname + ":443";
hostnameSpecBuilder.withHostname(testHostname);
}
else {
baseUrl = "http://" + kubernetesIp + ":80";
}
kc.getSpec().setHostnameSpec(hostnameSpecBuilder.build());
K8sUtils.deployKeycloak(k8sclient, kc, true);
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
var output = RestAssured.given()
.get("http://" + kubernetesIp + ":80/realms/master")
.body()
.jsonPath()
.getString("realm");
assertEquals("master", output);
});
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
var statusCode = RestAssured.given()
.get("http://" + kubernetesIp + ":80/admin/master/console")
.statusCode();
assertEquals(200, statusCode);
});
testIngressURLs(baseUrl);
}
@Test
public void testIngressOnHTTPS() {
var kc = K8sUtils.getDefaultKeycloakDeployment();
var hostnameSpec = new HostnameSpecBuilder()
var hostnameSpecBuilder = new HostnameSpecBuilder()
.withStrict(false)
.withStrictBackchannel(false)
.build();
kc.getSpec().setHostnameSpec(hostnameSpec);
.withStrictBackchannel(false);
String testHostname;
if (isOpenShift) {
testHostname = "kc-https-" + namespace + "." + baseDomain;
hostnameSpecBuilder.withHostname(testHostname);
}
else {
testHostname = kubernetesIp;
}
kc.getSpec().setHostnameSpec(hostnameSpecBuilder.build());
K8sUtils.deployKeycloak(k8sclient, kc, true);
testIngressURLs("https://" + testHostname + ":443");
}
private void testIngressURLs(String baseUrl) {
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
var url = baseUrl + "/realms/master";
Log.info("Testing URL: " + url);
var output = RestAssured.given()
.relaxedHTTPSValidation()
.get("https://" + kubernetesIp + ":443/realms/master")
.get(url)
.body()
.jsonPath()
.getString("realm");
@ -104,9 +126,12 @@ public class KeycloakIngressTest extends BaseOperatorTest {
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
var url = baseUrl + "/admin/master/console";
Log.info("Testing URL: " + url);
var statusCode = RestAssured.given()
.relaxedHTTPSValidation()
.get("https://" + kubernetesIp + ":443/admin/master/console")
.get(url)
.statusCode();
assertEquals(200, statusCode);