converts the keycloak services to dependent resources (#22257)

Closes #22207
This commit is contained in:
Steven Hawkins 2023-08-10 09:56:13 -04:00 committed by GitHub
parent b4e876364a
commit 1d444ff862
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 144 additions and 134 deletions

View file

@ -41,6 +41,7 @@ import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatus;
import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusAggregator;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@ -50,7 +51,9 @@ import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT
@ControllerConfiguration(namespaces = WATCH_CURRENT_NAMESPACE,
dependents = {
@Dependent(type = KeycloakAdminSecretDependentResource.class)
@Dependent(type = KeycloakAdminSecretDependentResource.class),
@Dependent(type = KeycloakServiceDependentResource.class, useEventSourceWithName = "serviceSource"),
@Dependent(type = KeycloakDiscoveryServiceDependentResource.class, useEventSourceWithName = "serviceSource")
})
public class KeycloakController implements Reconciler<Keycloak>, EventSourceInitializer<Keycloak>, ErrorStatusHandler<Keycloak> {
@ -95,9 +98,11 @@ public class KeycloakController implements Reconciler<Keycloak>, EventSourceInit
EventSource servicesEvent = new InformerEventSource<>(servicesIC, context);
EventSource ingressesEvent = new InformerEventSource<>(ingressesIC, context);
return EventSourceInitializer.nameEventSources(statefulSetEvent,
servicesEvent,
ingressesEvent, watchedSecrets.getWatchedSecretsEventSource());
Map<String, EventSource> sources = new HashMap<>();
sources.put("serviceSource", servicesEvent);
sources.putAll(EventSourceInitializer.nameEventSources(statefulSetEvent,
ingressesEvent, watchedSecrets.getWatchedSecretsEventSource()));
return sources;
}
@Override
@ -121,11 +126,6 @@ public class KeycloakController implements Reconciler<Keycloak>, EventSourceInit
kcDeployment.createOrUpdateReconciled();
kcDeployment.updateStatus(statusAggregator);
var kcService = new KeycloakService(client, kc);
kcService.createOrUpdateReconciled();
var kcDiscoveryService = new KeycloakDiscoveryService(client, kc);
kcDiscoveryService.createOrUpdateReconciled();
var kcIngress = new KeycloakIngress(client, kc);
kcIngress.createOrUpdateReconciled();

View file

@ -232,7 +232,7 @@ public class KeycloakDeployment extends OperatorManagedResource<StatefulSet> {
// probes
var tlsConfigured = isTlsConfigured(keycloakCR);
var protocol = !tlsConfigured ? "HTTP" : "HTTPS";
var kcPort = KeycloakService.getServicePort(keycloakCR);
var kcPort = KeycloakServiceDependentResource.getServicePort(keycloakCR);
// Relative path ends with '/'
var kcRelativePath = Optional.ofNullable(readConfigurationValue(Constants.KEYCLOAK_HTTP_RELATIVE_PATH_KEY))

View file

@ -1,69 +0,0 @@
/*
* Copyright 2021 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.controllers;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServiceSpec;
import io.fabric8.kubernetes.api.model.ServiceSpecBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.keycloak.operator.Constants;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import java.util.Optional;
public class KeycloakDiscoveryService extends OperatorManagedResource {
public KeycloakDiscoveryService(KubernetesClient client, Keycloak keycloakCR) {
super(client, keycloakCR);
}
private ServiceSpec getServiceSpec() {
return new ServiceSpecBuilder()
.addNewPort()
.withProtocol("TCP")
.withPort(Constants.KEYCLOAK_DISCOVERY_SERVICE_PORT)
.endPort()
.withSelector(getInstanceLabels())
.withClusterIP("None")
.withPublishNotReadyAddresses(Boolean.TRUE)
.build();
}
@Override
protected Optional<HasMetadata> getReconciledResource() {
return Optional.of(newService());
}
private Service newService() {
Service service = new ServiceBuilder()
.withNewMetadata()
.withName(getName())
.withNamespace(getNamespace())
.endMetadata()
.withSpec(getServiceSpec())
.build();
return service;
}
@Override
public String getName() {
return cr.getMetadata().getName() + Constants.KEYCLOAK_DISCOVERY_SERVICE_SUFFIX;
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright 2021 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.controllers;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServiceSpec;
import io.fabric8.kubernetes.api.model.ServiceSpecBuilder;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
import org.keycloak.operator.Constants;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import java.util.Optional;
@KubernetesDependent(labelSelector = Constants.DEFAULT_LABELS_AS_STRING, resourceDiscriminator = KeycloakDiscoveryServiceDependentResource.NameResourceDiscriminator.class)
public class KeycloakDiscoveryServiceDependentResource extends CRUDKubernetesDependentResource<Service, Keycloak> {
public static class NameResourceDiscriminator implements ResourceDiscriminator<Service, Keycloak> {
@Override
public Optional<Service> distinguish(Class<Service> resource, Keycloak primary, Context<Keycloak> context) {
return KeycloakServiceDependentResource.getService(KeycloakDiscoveryServiceDependentResource::getName, primary, context);
}
}
public KeycloakDiscoveryServiceDependentResource() {
super(Service.class);
}
private ServiceSpec getServiceSpec(Keycloak keycloak) {
return new ServiceSpecBuilder()
.addNewPort()
.withProtocol("TCP")
.withPort(Constants.KEYCLOAK_DISCOVERY_SERVICE_PORT)
.endPort()
.withSelector(OperatorManagedResource.allInstanceLabels(keycloak))
.withClusterIP("None")
.withPublishNotReadyAddresses(Boolean.TRUE)
.build();
}
@Override
protected Service desired(Keycloak primary, Context<Keycloak> context) {
Service service = new ServiceBuilder()
.withNewMetadata()
.withName(getName(primary))
.withNamespace(primary.getMetadata().getNamespace())
.addToLabels(OperatorManagedResource.allInstanceLabels(primary))
.endMetadata()
.withSpec(getServiceSpec(primary))
.build();
return service;
}
public static String getName(Keycloak keycloak) {
return keycloak.getMetadata().getName() + Constants.KEYCLOAK_DISCOVERY_SERVICE_SUFFIX;
}
}

View file

@ -55,7 +55,7 @@ public class KeycloakIngress extends OperatorManagedResource {
}
private Ingress newIngress() {
var port = KeycloakService.getServicePort(keycloak);
var port = KeycloakServiceDependentResource.getServicePort(keycloak);
var annotations = new HashMap<String, String>();
// set default annotations
@ -80,7 +80,7 @@ public class KeycloakIngress extends OperatorManagedResource {
.withIngressClassName(optionalSpec.map(IngressSpec::getIngressClassName).orElse(null))
.withNewDefaultBackend()
.withNewService()
.withName(KeycloakService.getServiceName(keycloak))
.withName(KeycloakServiceDependentResource.getServiceName(keycloak))
.withNewPort()
.withNumber(port)
.withName("") // for SSA to clear the name if already set
@ -94,7 +94,7 @@ public class KeycloakIngress extends OperatorManagedResource {
.withPathType("ImplementationSpecific")
.withNewBackend()
.withNewService()
.withName(KeycloakService.getServiceName(keycloak))
.withName(KeycloakServiceDependentResource.getServiceName(keycloak))
.withNewPort()
.withNumber(port)
.withName("") // for SSA to clear the name if already set

View file

@ -21,26 +21,44 @@ import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServiceSpec;
import io.fabric8.kubernetes.api.model.ServiceSpecBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ResourceDiscriminator;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
import io.javaoperatorsdk.operator.processing.event.ResourceID;
import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource;
import org.keycloak.operator.Constants;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.spec.HttpSpec;
import java.util.Optional;
import java.util.function.Function;
import static org.keycloak.operator.crds.v2alpha1.CRDUtils.isTlsConfigured;
public class KeycloakService extends OperatorManagedResource {
@KubernetesDependent(labelSelector = Constants.DEFAULT_LABELS_AS_STRING, resourceDiscriminator = KeycloakServiceDependentResource.NameResourceDiscriminator.class)
public class KeycloakServiceDependentResource extends CRUDKubernetesDependentResource<Service, Keycloak> {
private final Keycloak keycloak;
public KeycloakService(KubernetesClient client, Keycloak keycloakCR) {
super(client, keycloakCR);
this.keycloak = keycloakCR;
public static class NameResourceDiscriminator implements ResourceDiscriminator<Service, Keycloak> {
@Override
public Optional<Service> distinguish(Class<Service> resource, Keycloak primary, Context<Keycloak> context) {
return getService(KeycloakServiceDependentResource::getServiceName, primary, context);
}
}
private ServiceSpec getServiceSpec() {
public static Optional<Service> getService(Function<Keycloak, String> nameFunction, Keycloak primary, Context<Keycloak> context) {
InformerEventSource<Service, Keycloak> ies = (InformerEventSource<Service, Keycloak>) context
.eventSourceRetriever().getResourceEventSourceFor(Service.class);
return ies.get(new ResourceID(nameFunction.apply(primary), primary.getMetadata().getNamespace()));
}
public KeycloakServiceDependentResource() {
super(Service.class);
}
private ServiceSpec getServiceSpec(Keycloak keycloak) {
String name = isTlsConfigured(keycloak) ? Constants.KEYCLOAK_HTTPS_PORT_NAME : Constants.KEYCLOAK_HTTP_PORT_NAME;
return new ServiceSpecBuilder()
.addNewPort()
@ -48,31 +66,23 @@ public class KeycloakService extends OperatorManagedResource {
.withName(name)
.withProtocol(Constants.KEYCLOAK_SERVICE_PROTOCOL)
.endPort()
.withSelector(getInstanceLabels())
.withSelector(OperatorManagedResource.allInstanceLabels(keycloak))
.build();
}
@Override
protected Optional<HasMetadata> getReconciledResource() {
return Optional.of(newService());
}
private Service newService() {
protected Service desired(Keycloak primary, Context<Keycloak> context) {
Service service = new ServiceBuilder()
.withNewMetadata()
.withName(getName())
.withNamespace(getNamespace())
.withName(getServiceName(primary))
.withNamespace(primary.getMetadata().getNamespace())
.addToLabels(OperatorManagedResource.allInstanceLabels(primary))
.endMetadata()
.withSpec(getServiceSpec())
.withSpec(getServiceSpec(primary))
.build();
return service;
}
@Override
public String getName() {
return getServiceName(cr);
}
public static String getServiceName(HasMetadata keycloak) {
return keycloak.getMetadata().getName() + Constants.KEYCLOAK_SERVICE_SUFFIX;
}

View file

@ -31,7 +31,7 @@ import io.restassured.RestAssured;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.keycloak.operator.Constants;
import org.keycloak.operator.controllers.KeycloakService;
import org.keycloak.operator.controllers.KeycloakServiceDependentResource;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusCondition;
import org.keycloak.operator.crds.v2alpha1.realmimport.KeycloakRealmImport;
@ -172,8 +172,7 @@ public class ClusteringTest extends BaseOperatorTest {
.untilAsserted(() -> assertThat(crSelector.scale().getStatus().getReplicas()).isEqualTo(2));
// get the service
var service = new KeycloakService(k8sclient, kc);
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT;
String url = "https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT;
Awaitility.await().atMost(5, MINUTES).untilAsserted(() -> {
Log.info("Starting curl Pod to test if the realm is available");
@ -275,7 +274,7 @@ public class ClusteringTest extends BaseOperatorTest {
// This is to test passing through the "Service", not 100% deterministic, but a smoke test that things are working as expected
// Executed here to avoid paying the setup time again
var service = new KeycloakService(k8sclient, kc);
String serviceName = KeycloakServiceDependentResource.getServiceName(kc);
Awaitility.await()
.atMost(20, MINUTES)
.pollDelay(5, SECONDS)
@ -286,7 +285,7 @@ public class ClusteringTest extends BaseOperatorTest {
for (int i = 0; i < (targetInstances + 1); i++) {
if (token2 == null) {
var tokenUrl = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/token-test/protocol/openid-connect/token";
var tokenUrl = "https://" + serviceName + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/token-test/protocol/openid-connect/token";
Log.info("Checking url: " + tokenUrl);
var tokenOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "--insecure", "-s", "--data", "grant_type=password&client_id=token-test-client&username=test&password=test&scope=openid", tokenUrl);
@ -296,7 +295,7 @@ public class ClusteringTest extends BaseOperatorTest {
token2 = tokenAnswer.get("access_token").asText();
}
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/token-test/protocol/openid-connect/userinfo";
String url = "https://" + serviceName + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/token-test/protocol/openid-connect/userinfo";
Log.info("Checking url: " + url);
var curlOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "--insecure", "-s", "-H", "Authorization: Bearer " + token2, url);

View file

@ -38,7 +38,7 @@ import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import org.keycloak.operator.Constants;
import org.keycloak.operator.controllers.KeycloakAdminSecretDependentResource;
import org.keycloak.operator.controllers.KeycloakDistConfigurator;
import org.keycloak.operator.controllers.KeycloakService;
import org.keycloak.operator.controllers.KeycloakServiceDependentResource;
import org.keycloak.operator.crds.v2alpha1.deployment.Keycloak;
import org.keycloak.operator.crds.v2alpha1.deployment.KeycloakStatusCondition;
import org.keycloak.operator.crds.v2alpha1.deployment.ValueOrSecret;
@ -254,11 +254,10 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
var kc = getTestKeycloakDeployment(true);
deployKeycloak(k8sclient, kc, true);
var service = new KeycloakService(k8sclient, kc);
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT;
String url = "https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT;
Log.info("Checking url: " + url);
var curlOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "--insecure", "-s", "-w", "%{certs}", url);
@ -283,11 +282,10 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
var kc = getTestKeycloakDeployment(true);
deployKeycloak(k8sclient, kc, true);
var service = new KeycloakService(k8sclient, kc);
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/admin/master/console/";
String url = "https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/admin/master/console/";
Log.info("Checking url: " + url);
var curlOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "-s", "--insecure", "-H", "Host: foo.bar", url);
@ -308,11 +306,10 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
deployKeycloak(k8sclient, kc, true);
var service = new KeycloakService(k8sclient, kc);
Awaitility.await()
.ignoreExceptions()
.untilAsserted(() -> {
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/admin/master/console/";
String url = "https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/admin/master/console/";
Log.info("Checking url: " + url);
var curlOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "-s", "--insecure", "-H", "Host: foo.bar", url);
@ -395,7 +392,6 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
deployDB();
deployKeycloak(k8sclient, kc, true);
var decoder = Base64.getDecoder();
var service = new KeycloakService(k8sclient, kc);
AtomicReference<String> adminUsername = new AtomicReference<>();
AtomicReference<String> adminPassword = new AtomicReference<>();
@ -412,7 +408,7 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
adminUsername.set(new String(decoder.decode(adminSecret.getData().get("username").getBytes(StandardCharsets.UTF_8))));
adminPassword.set(new String(decoder.decode(adminSecret.getData().get("password").getBytes(StandardCharsets.UTF_8))));
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/master/protocol/openid-connect/token";
String url = "https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/master/protocol/openid-connect/token";
Log.info("Checking url: " + url);
var curlOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "--insecure", "-s", "--data", "grant_type=password&client_id=admin-cli&username=" + adminUsername.get() + "&password=" + adminPassword.get(), url);
@ -437,7 +433,7 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
var newPassword = new String(decoder.decode(adminSecret.getData().get("password").getBytes(StandardCharsets.UTF_8)));
String url = "https://" + service.getName() + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/master/protocol/openid-connect/token";
String url = "https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + Constants.KEYCLOAK_HTTPS_PORT + "/realms/master/protocol/openid-connect/token";
Log.info("Checking url: " + url);
var curlOutput = K8sUtils.inClusterCurl(k8sclient, namespace, "--insecure", "-s", "--data", "grant_type=password&client_id=admin-cli&username=" + adminUsername.get() + "&password=" + adminPassword.get(), url);
@ -631,7 +627,7 @@ public class KeycloakDeploymentTest extends BaseOperatorTest {
.untilAsserted(() -> {
String protocol = https ? "https" : "http";
String serviceName = KeycloakService.getServiceName(kc);
String serviceName = KeycloakServiceDependentResource.getServiceName(kc);
assertThat(k8sclient.resources(Service.class).withName(serviceName).require().getSpec().getPorts()
.stream().map(ServicePort::getName).anyMatch(protocol::equals));

View file

@ -20,10 +20,11 @@ package org.keycloak.operator.testsuite.integration;
import io.fabric8.kubernetes.api.model.ServiceSpecBuilder;
import io.quarkus.logging.Log;
import io.quarkus.test.junit.QuarkusTest;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.keycloak.operator.controllers.KeycloakDiscoveryService;
import org.keycloak.operator.controllers.KeycloakService;
import org.keycloak.operator.controllers.KeycloakDiscoveryServiceDependentResource;
import org.keycloak.operator.controllers.KeycloakServiceDependentResource;
import org.keycloak.operator.testsuite.utils.K8sUtils;
import java.time.Duration;
@ -37,8 +38,8 @@ public class KeycloakServicesTest extends BaseOperatorTest {
public void testMainServiceDurability() {
var kc = getTestKeycloakDeployment(true);
K8sUtils.deployKeycloak(k8sclient, kc, true);
var service = new KeycloakService(k8sclient, kc);
var serviceSelector = k8sclient.services().inNamespace(namespace).withName(service.getName());
String serviceName = KeycloakServiceDependentResource.getServiceName(kc);
var serviceSelector = k8sclient.services().inNamespace(namespace).withName(serviceName);
Log.info("Trying to delete the service");
assertThat(serviceSelector.delete()).isNotNull();
@ -61,7 +62,6 @@ public class KeycloakServicesTest extends BaseOperatorTest {
var origSpecs = new ServiceSpecBuilder(currentService.getSpec()).build(); // deep copy
// a managed change
currentService.getSpec().getPorts().get(0).setProtocol("UDP");
currentService.getSpec().getPorts().get(0).setName(null);
currentService.getMetadata().getLabels().putAll(labels);
@ -86,8 +86,7 @@ public class KeycloakServicesTest extends BaseOperatorTest {
public void testDiscoveryServiceDurability() {
var kc = getTestKeycloakDeployment(true);
K8sUtils.deployKeycloak(k8sclient, kc, true);
var discoveryService = new KeycloakDiscoveryService(k8sclient, kc);
var discoveryServiceSelector = k8sclient.services().inNamespace(namespace).withName(discoveryService.getName());
var discoveryServiceSelector = k8sclient.services().inNamespace(namespace).withName(KeycloakDiscoveryServiceDependentResource.getName(kc));
Log.info("Trying to delete the discovery service");
assertThat(discoveryServiceSelector.delete()).isNotNull();
@ -113,7 +112,7 @@ public class KeycloakServicesTest extends BaseOperatorTest {
var origDiscoverySpecs = new ServiceSpecBuilder(currentDiscoveryService.getSpec()).build(); // deep copy
// a managed change
currentDiscoveryService.getSpec().getPorts().get(0).setProtocol("UDP");
currentDiscoveryService.getSpec().getPorts().get(0).setName(null);
currentDiscoveryService.getMetadata().setResourceVersion(null);
k8sclient.resource(currentDiscoveryService).update();

View file

@ -26,10 +26,10 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import org.keycloak.operator.controllers.KeycloakServiceDependentResource;
import org.keycloak.operator.crds.v2alpha1.realmimport.KeycloakRealmImport;
import org.keycloak.operator.testsuite.utils.CRAssert;
import org.keycloak.operator.testsuite.utils.K8sUtils;
import org.keycloak.operator.controllers.KeycloakService;
import org.keycloak.operator.crds.v2alpha1.realmimport.KeycloakRealmImport;
import java.util.Arrays;
import java.util.stream.Collectors;
@ -39,11 +39,11 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.keycloak.operator.Constants.KEYCLOAK_HTTPS_PORT;
import static org.keycloak.operator.controllers.KeycloakDistConfigurator.getKeycloakOptionEnvVarName;
import static org.keycloak.operator.testsuite.utils.K8sUtils.deployKeycloak;
import static org.keycloak.operator.testsuite.utils.K8sUtils.inClusterCurl;
import static org.keycloak.operator.crds.v2alpha1.realmimport.KeycloakRealmImportStatusCondition.DONE;
import static org.keycloak.operator.crds.v2alpha1.realmimport.KeycloakRealmImportStatusCondition.HAS_ERRORS;
import static org.keycloak.operator.crds.v2alpha1.realmimport.KeycloakRealmImportStatusCondition.STARTED;
import static org.keycloak.operator.testsuite.utils.K8sUtils.deployKeycloak;
import static org.keycloak.operator.testsuite.utils.K8sUtils.inClusterCurl;
@QuarkusTest
public class RealmImportTest extends BaseOperatorTest {
@ -123,7 +123,7 @@ public class RealmImportTest extends BaseOperatorTest {
assertThat(job.getSpec().getTemplate().getSpec().getImagePullSecrets().get(0).getName()).isEqualTo("my-empty-secret");
String url =
"https://" + KeycloakService.getServiceName(kc) + "." + namespace + ":" + KEYCLOAK_HTTPS_PORT + "/realms/count0";
"https://" + KeycloakServiceDependentResource.getServiceName(kc) + "." + namespace + ":" + KEYCLOAK_HTTPS_PORT + "/realms/count0";
Awaitility.await().atMost(10, MINUTES).ignoreExceptions().untilAsserted(() -> {
Log.info("Starting curl Pod to test if the realm is available");