Add OpenShift support to KeycloakIngressTest (#20030)
This commit is contained in:
parent
c2c5012cfb
commit
983e40ad2b
3 changed files with 88 additions and 31 deletions
29
operator/src/main/java/org/keycloak/operator/Utils.java
Normal file
29
operator/src/main/java/org/keycloak/operator/Utils.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,7 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.keycloak.operator.Utils.isOpenShift;
|
||||||
import static org.keycloak.operator.testsuite.utils.K8sUtils.getResourceFromFile;
|
import static org.keycloak.operator.testsuite.utils.K8sUtils.getResourceFromFile;
|
||||||
|
|
||||||
public abstract class BaseOperatorTest {
|
public abstract class BaseOperatorTest {
|
||||||
|
@ -75,6 +76,7 @@ public abstract class BaseOperatorTest {
|
||||||
protected static String kubernetesIp;
|
protected static String kubernetesIp;
|
||||||
protected static String customImage;
|
protected static String customImage;
|
||||||
private static Operator operator;
|
private static Operator operator;
|
||||||
|
protected static boolean isOpenShift;
|
||||||
|
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
|
@ -91,6 +93,7 @@ public abstract class BaseOperatorTest {
|
||||||
createK8sClient();
|
createK8sClient();
|
||||||
createCRDs();
|
createCRDs();
|
||||||
createNamespace();
|
createNamespace();
|
||||||
|
isOpenShift = isOpenShift(k8sclient);
|
||||||
|
|
||||||
if (operatorDeployment == OperatorDeployment.remote) {
|
if (operatorDeployment == OperatorDeployment.remote) {
|
||||||
createRBACresourcesAndOperatorDeployment();
|
createRBACresourcesAndOperatorDeployment();
|
||||||
|
|
|
@ -25,6 +25,7 @@ import io.quarkus.logging.Log;
|
||||||
import io.quarkus.test.junit.QuarkusTest;
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import org.awaitility.Awaitility;
|
import org.awaitility.Awaitility;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.keycloak.operator.Constants;
|
import org.keycloak.operator.Constants;
|
||||||
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
|
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
|
||||||
|
@ -41,59 +42,80 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
@QuarkusTest
|
@QuarkusTest
|
||||||
public class KeycloakIngressTest extends BaseOperatorTest {
|
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
|
@Test
|
||||||
public void testIngressOnHTTP() {
|
public void testIngressOnHTTP() {
|
||||||
var kc = K8sUtils.getDefaultKeycloakDeployment();
|
var kc = K8sUtils.getDefaultKeycloakDeployment();
|
||||||
kc.getSpec().getHttpSpec().setTlsSecret(null);
|
kc.getSpec().getHttpSpec().setTlsSecret(null);
|
||||||
kc.getSpec().getHttpSpec().setHttpEnabled(true);
|
kc.getSpec().getHttpSpec().setHttpEnabled(true);
|
||||||
var hostnameSpec = new HostnameSpecBuilder()
|
var hostnameSpecBuilder = new HostnameSpecBuilder()
|
||||||
.withStrict(false)
|
.withStrict(false)
|
||||||
.withStrictBackchannel(false)
|
.withStrictBackchannel(false);
|
||||||
.build();
|
String testHostname;
|
||||||
kc.getSpec().setHostnameSpec(hostnameSpec);
|
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);
|
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||||
|
|
||||||
Awaitility.await()
|
testIngressURLs(baseUrl);
|
||||||
.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);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIngressOnHTTPS() {
|
public void testIngressOnHTTPS() {
|
||||||
var kc = K8sUtils.getDefaultKeycloakDeployment();
|
var kc = K8sUtils.getDefaultKeycloakDeployment();
|
||||||
var hostnameSpec = new HostnameSpecBuilder()
|
var hostnameSpecBuilder = new HostnameSpecBuilder()
|
||||||
.withStrict(false)
|
.withStrict(false)
|
||||||
.withStrictBackchannel(false)
|
.withStrictBackchannel(false);
|
||||||
.build();
|
String testHostname;
|
||||||
kc.getSpec().setHostnameSpec(hostnameSpec);
|
if (isOpenShift) {
|
||||||
|
testHostname = "kc-https-" + namespace + "." + baseDomain;
|
||||||
|
hostnameSpecBuilder.withHostname(testHostname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
testHostname = kubernetesIp;
|
||||||
|
}
|
||||||
|
kc.getSpec().setHostnameSpec(hostnameSpecBuilder.build());
|
||||||
|
|
||||||
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
K8sUtils.deployKeycloak(k8sclient, kc, true);
|
||||||
|
|
||||||
|
testIngressURLs("https://" + testHostname + ":443");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testIngressURLs(String baseUrl) {
|
||||||
Awaitility.await()
|
Awaitility.await()
|
||||||
.ignoreExceptions()
|
.ignoreExceptions()
|
||||||
.untilAsserted(() -> {
|
.untilAsserted(() -> {
|
||||||
|
var url = baseUrl + "/realms/master";
|
||||||
|
Log.info("Testing URL: " + url);
|
||||||
|
|
||||||
var output = RestAssured.given()
|
var output = RestAssured.given()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.get("https://" + kubernetesIp + ":443/realms/master")
|
.get(url)
|
||||||
.body()
|
.body()
|
||||||
.jsonPath()
|
.jsonPath()
|
||||||
.getString("realm");
|
.getString("realm");
|
||||||
|
@ -104,9 +126,12 @@ public class KeycloakIngressTest extends BaseOperatorTest {
|
||||||
Awaitility.await()
|
Awaitility.await()
|
||||||
.ignoreExceptions()
|
.ignoreExceptions()
|
||||||
.untilAsserted(() -> {
|
.untilAsserted(() -> {
|
||||||
|
var url = baseUrl + "/admin/master/console";
|
||||||
|
Log.info("Testing URL: " + url);
|
||||||
|
|
||||||
var statusCode = RestAssured.given()
|
var statusCode = RestAssured.given()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.get("https://" + kubernetesIp + ":443/admin/master/console")
|
.get(url)
|
||||||
.statusCode();
|
.statusCode();
|
||||||
|
|
||||||
assertEquals(200, statusCode);
|
assertEquals(200, statusCode);
|
||||||
|
|
Loading…
Reference in a new issue