From 1d444ff86228b741f85fd68aacf6e06e9d53031d Mon Sep 17 00:00:00 2001 From: Steven Hawkins Date: Thu, 10 Aug 2023 09:56:13 -0400 Subject: [PATCH] converts the keycloak services to dependent resources (#22257) Closes #22207 --- .../controllers/KeycloakController.java | 18 ++--- .../controllers/KeycloakDeployment.java | 2 +- .../controllers/KeycloakDiscoveryService.java | 69 ----------------- ...loakDiscoveryServiceDependentResource.java | 75 +++++++++++++++++++ .../operator/controllers/KeycloakIngress.java | 6 +- ... => KeycloakServiceDependentResource.java} | 54 +++++++------ .../testsuite/integration/ClusteringTest.java | 11 ++- .../integration/KeycloakDeploymentTest.java | 18 ++--- .../integration/KeycloakServicesTest.java | 15 ++-- .../integration/RealmImportTest.java | 10 +-- 10 files changed, 144 insertions(+), 134 deletions(-) delete mode 100644 operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryService.java create mode 100644 operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryServiceDependentResource.java rename operator/src/main/java/org/keycloak/operator/controllers/{KeycloakService.java => KeycloakServiceDependentResource.java} (54%) diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakController.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakController.java index efb75f298a..41bf7e21ad 100644 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakController.java +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakController.java @@ -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, EventSourceInitializer, ErrorStatusHandler { @@ -95,9 +98,11 @@ public class KeycloakController implements Reconciler, EventSourceInit EventSource servicesEvent = new InformerEventSource<>(servicesIC, context); EventSource ingressesEvent = new InformerEventSource<>(ingressesIC, context); - return EventSourceInitializer.nameEventSources(statefulSetEvent, - servicesEvent, - ingressesEvent, watchedSecrets.getWatchedSecretsEventSource()); + Map 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, 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(); diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java index 30f321d2e2..b014e067ef 100644 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java @@ -232,7 +232,7 @@ public class KeycloakDeployment extends OperatorManagedResource { // 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)) diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryService.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryService.java deleted file mode 100644 index 80611bab21..0000000000 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryService.java +++ /dev/null @@ -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 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; - } -} diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryServiceDependentResource.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryServiceDependentResource.java new file mode 100644 index 0000000000..266e6cb91c --- /dev/null +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDiscoveryServiceDependentResource.java @@ -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 { + + public static class NameResourceDiscriminator implements ResourceDiscriminator { + @Override + public Optional distinguish(Class resource, Keycloak primary, Context 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 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; + } +} diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakIngress.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakIngress.java index a27ec5e782..e0c38d0def 100644 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakIngress.java +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakIngress.java @@ -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(); // 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 diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakService.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakServiceDependentResource.java similarity index 54% rename from operator/src/main/java/org/keycloak/operator/controllers/KeycloakService.java rename to operator/src/main/java/org/keycloak/operator/controllers/KeycloakServiceDependentResource.java index fb7c6be19d..2182d1dfe1 100644 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakService.java +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakServiceDependentResource.java @@ -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 { - private final Keycloak keycloak; - - public KeycloakService(KubernetesClient client, Keycloak keycloakCR) { - super(client, keycloakCR); - this.keycloak = keycloakCR; + public static class NameResourceDiscriminator implements ResourceDiscriminator { + @Override + public Optional distinguish(Class resource, Keycloak primary, Context context) { + return getService(KeycloakServiceDependentResource::getServiceName, primary, context); + } } - private ServiceSpec getServiceSpec() { + public static Optional getService(Function nameFunction, Keycloak primary, Context context) { + InformerEventSource ies = (InformerEventSource) 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 getReconciledResource() { - return Optional.of(newService()); - } - - private Service newService() { + protected Service desired(Keycloak primary, Context 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; } diff --git a/operator/src/test/java/org/keycloak/operator/testsuite/integration/ClusteringTest.java b/operator/src/test/java/org/keycloak/operator/testsuite/integration/ClusteringTest.java index 4813670059..d764bf4324 100644 --- a/operator/src/test/java/org/keycloak/operator/testsuite/integration/ClusteringTest.java +++ b/operator/src/test/java/org/keycloak/operator/testsuite/integration/ClusteringTest.java @@ -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); diff --git a/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java b/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java index 24777b1bf2..340f02d98e 100644 --- a/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java +++ b/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java @@ -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 adminUsername = new AtomicReference<>(); AtomicReference 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)); diff --git a/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakServicesTest.java b/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakServicesTest.java index e1440c770d..13e28954bf 100644 --- a/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakServicesTest.java +++ b/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakServicesTest.java @@ -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(); diff --git a/operator/src/test/java/org/keycloak/operator/testsuite/integration/RealmImportTest.java b/operator/src/test/java/org/keycloak/operator/testsuite/integration/RealmImportTest.java index eea22d3379..4b12de7d11 100644 --- a/operator/src/test/java/org/keycloak/operator/testsuite/integration/RealmImportTest.java +++ b/operator/src/test/java/org/keycloak/operator/testsuite/integration/RealmImportTest.java @@ -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");