From fe0610a41869dd9a0c036b054889211c35fc0a8f Mon Sep 17 00:00:00 2001 From: Lukas Kral Date: Fri, 16 Aug 2024 10:34:18 +0200 Subject: [PATCH] add 'retry' and log collection for Keycloak Signed-off-by: Lukas Kral --- .../strimzi/systemtest/logs/LogCollector.java | 4 + .../utils/specific/KeycloakUtils.java | 184 +++++++++++------- 2 files changed, 119 insertions(+), 69 deletions(-) diff --git a/systemtest/src/main/java/io/strimzi/systemtest/logs/LogCollector.java b/systemtest/src/main/java/io/strimzi/systemtest/logs/LogCollector.java index fc9aeaea43c..5b141861ef9 100644 --- a/systemtest/src/main/java/io/strimzi/systemtest/logs/LogCollector.java +++ b/systemtest/src/main/java/io/strimzi/systemtest/logs/LogCollector.java @@ -221,6 +221,10 @@ private void collectLogsForTestSuite(final Pod pod) { LOGGER.debug("Collecting logs for TestSuite: {}, and Jaeger Pods: {}/{}", this.collectorElement.getTestClassName(), pod.getMetadata().getNamespace(), pod.getMetadata().getName()); pod.getStatus().getContainerStatuses().forEach( containerStatus -> scrapeAndCreateLogs(namespacePath, pod.getMetadata().getName(), containerStatus, pod.getMetadata().getNamespace())); + } else if (pod.getMetadata().getName().contains("keycloak") || pod.getMetadata().getName().contains("keycloak")) { + LOGGER.debug("Collecting logs for TestSuite: {}, and Keycloak Pods: {}/{}", this.collectorElement.getTestClassName(), pod.getMetadata().getNamespace(), pod.getMetadata().getName()); + pod.getStatus().getContainerStatuses().forEach( + containerStatus -> scrapeAndCreateLogs(namespacePath, pod.getMetadata().getName(), containerStatus, pod.getMetadata().getNamespace())); } } diff --git a/systemtest/src/main/java/io/strimzi/systemtest/utils/specific/KeycloakUtils.java b/systemtest/src/main/java/io/strimzi/systemtest/utils/specific/KeycloakUtils.java index d57245e1243..10bd9635296 100644 --- a/systemtest/src/main/java/io/strimzi/systemtest/utils/specific/KeycloakUtils.java +++ b/systemtest/src/main/java/io/strimzi/systemtest/utils/specific/KeycloakUtils.java @@ -8,10 +8,14 @@ import io.strimzi.systemtest.Environment; import io.strimzi.systemtest.TestConstants; import io.strimzi.systemtest.resources.ResourceManager; +import io.strimzi.test.TestUtils; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import static io.strimzi.test.k8s.KubeClusterResource.cmdKubeClient; @@ -20,31 +24,35 @@ public class KeycloakUtils { public final static String LATEST_KEYCLOAK_VERSION = "25.0.2"; private final static LabelSelector SCRAPER_SELECTOR = new LabelSelector(null, Map.of(TestConstants.APP_POD_LABEL, TestConstants.SCRAPER_NAME)); + private static final Logger LOGGER = LogManager.getLogger(KeycloakUtils.class); private KeycloakUtils() {} /** * Returns token from Keycloak API - * @param keycloakNamespace namespace where keycloak instance is located + * @param namespaceName namespace where keycloak instance is located * @param baseURI base uri for accessing Keycloak API * @param userName name of user * @param password password of user * @return user token */ - public static String getToken(String keycloakNamespace, String baseURI, String userName, String password) { + public static String getToken(String namespaceName, String baseURI, String userName, String password) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPods(Environment.TEST_SUITE_NAMESPACE, SCRAPER_SELECTOR).get(0).getMetadata().getName(); return new JsonObject( - cmdKubeClient(keycloakNamespace).execInPod( + executeRequestAndReturnData( + namespaceName, testSuiteScraperPodName, - "curl", - "-v", - "--insecure", - "-X", - "POST", - "-d", "client_id=admin-cli&client_secret=aGVsbG8td29ybGQtcHJvZHVjZXItc2VjcmV0&grant_type=password&username=" + userName + "&password=" + password, - baseURI + "/realms/master/protocol/openid-connect/token" - ).out()).getString("access_token"); + new String[]{ + "curl", + "-v", + "--insecure", + "-X", + "POST", + "-d", "client_id=admin-cli&client_secret=aGVsbG8td29ybGQtcHJvZHVjZXItc2VjcmV0&grant_type=password&username=" + userName + "&password=" + password, + baseURI + "/realms/master/protocol/openid-connect/token" + } + )).getString("access_token"); } /** @@ -58,16 +66,19 @@ public static String getToken(String keycloakNamespace, String baseURI, String u public static JsonObject getKeycloakRealm(String namespaceName, String baseURI, String token, String desiredRealm) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPods(Environment.TEST_SUITE_NAMESPACE, SCRAPER_SELECTOR).get(0).getMetadata().getName(); - return new JsonObject(cmdKubeClient(namespaceName).execInPod( + return new JsonObject(executeRequestAndReturnData( + namespaceName, testSuiteScraperPodName, - "curl", - "-v", - "--insecure", - "-X", - "GET", - baseURI + "/admin/realms/" + desiredRealm, - "-H", "Authorization: Bearer " + token - ).out()); + new String[]{ + "curl", + "-v", + "--insecure", + "-X", + "GET", + baseURI + "/admin/realms/" + desiredRealm, + "-H", "Authorization: Bearer " + token + } + )); } /** @@ -81,16 +92,19 @@ public static JsonObject getKeycloakRealm(String namespaceName, String baseURI, public static JsonArray getKeycloakRealmClients(String namespaceName, String baseURI, String token, String desiredRealm) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPods(Environment.TEST_SUITE_NAMESPACE, SCRAPER_SELECTOR).get(0).getMetadata().getName(); - return new JsonArray(cmdKubeClient(namespaceName).execInPod( + return new JsonArray(executeRequestAndReturnData( + namespaceName, testSuiteScraperPodName, - "curl", - "-v", - "--insecure", - "-X", - "GET", - baseURI + "/admin/realms/" + desiredRealm + "/clients", - "-H", "Authorization: Bearer " + token - ).out()); + new String[]{ + "curl", + "-v", + "--insecure", + "-X", + "GET", + baseURI + "/admin/realms/" + desiredRealm + "/clients", + "-H", "Authorization: Bearer " + token + } + )); } /** @@ -119,16 +133,19 @@ public static JsonArray getPoliciesFromRealmClient(String namespaceName, String private static JsonArray getConfigFromResourceServerOfRealm(String namespaceName, String baseURI, String token, String desiredRealm, String clientId, String endpoint) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPods(Environment.TEST_SUITE_NAMESPACE, SCRAPER_SELECTOR).get(0).getMetadata().getName(); - return new JsonArray(cmdKubeClient(namespaceName).execInPod( - testSuiteScraperPodName, - "curl", - "-v", - "--insecure", - "-X", - "GET", - baseURI + "/admin/realms/" + desiredRealm + "/clients/" + clientId + "/authz/resource-server/" + endpoint, - "-H", "Authorization: Bearer " + token - ).out()); + return new JsonArray(executeRequestAndReturnData( + namespaceName, + testSuiteScraperPodName, + new String[]{ + "curl", + "-v", + "--insecure", + "-X", + "GET", + baseURI + "/admin/realms/" + desiredRealm + "/clients/" + clientId + "/authz/resource-server/" + endpoint, + "-H", "Authorization: Bearer " + token + }) + ); } /** @@ -138,23 +155,25 @@ private static JsonArray getConfigFromResourceServerOfRealm(String namespaceName * @param token admin token * @param desiredRealm realm where the config should be put * @param config configuration we want to put into the realm - * @return response from server */ - public static String putConfigurationToRealm(String namespaceName, String baseURI, String token, JsonObject config, String desiredRealm) { + public static void putConfigurationToRealm(String namespaceName, String baseURI, String token, JsonObject config, String desiredRealm) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPods(Environment.TEST_SUITE_NAMESPACE, SCRAPER_SELECTOR).get(0).getMetadata().getName(); - return cmdKubeClient(namespaceName).execInPod( - testSuiteScraperPodName, - "curl", - "-v", - "--insecure", - "-X", - "PUT", - baseURI + "/admin/realms/" + desiredRealm, - "-H", "Authorization: Bearer " + token, - "-d", config.toString(), - "-H", "Content-Type: application/json" - ).out(); + executeRequestAndReturnData( + namespaceName, + testSuiteScraperPodName, + new String[]{ + "curl", + "-v", + "--insecure", + "-X", + "PUT", + baseURI + "/admin/realms/" + desiredRealm, + "-H", "Authorization: Bearer " + token, + "-d", config.toString(), + "-H", "Content-Type: application/json" + } + ); } /** @@ -165,23 +184,25 @@ public static String putConfigurationToRealm(String namespaceName, String baseUR * @param desiredRealm realm where the client policies should be updated * @param policy new updated policies * @param clientId id of client where we want to update policies - * @return response from server */ - public static String updatePolicyOfRealmClient(String namespaceName, String baseURI, String token, JsonObject policy, String desiredRealm, String clientId) { + public static void updatePolicyOfRealmClient(String namespaceName, String baseURI, String token, JsonObject policy, String desiredRealm, String clientId) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPodsByPrefixInName(Environment.TEST_SUITE_NAMESPACE, TestConstants.SCRAPER_NAME).get(0).getMetadata().getName(); - return cmdKubeClient(namespaceName).execInPod( + executeRequestAndReturnData( + namespaceName, testSuiteScraperPodName, - "curl", - "-v", - "--insecure", - "-X", - "PUT", - baseURI + "/admin/realms/" + desiredRealm + "/clients/" + clientId + "/authz/resource-server/policy/" + policy.getValue("id"), - "-H", "Authorization: Bearer " + token, - "-d", policy.toString(), - "-H", "Content-Type: application/json" - ).out(); + new String[]{ + "curl", + "-v", + "--insecure", + "-X", + "PUT", + baseURI + "/admin/realms/" + desiredRealm + "/clients/" + clientId + "/authz/resource-server/policy/" + policy.getValue("id"), + "-H", "Authorization: Bearer " + token, + "-d", policy.toString(), + "-H", "Content-Type: application/json" + } + ); } /** @@ -195,8 +216,10 @@ public static String updatePolicyOfRealmClient(String namespaceName, String base public static String importRealm(String namespaceName, String baseURI, String token, String realmData) { final String testSuiteScraperPodName = ResourceManager.kubeClient().listPodsByPrefixInName(Environment.TEST_SUITE_NAMESPACE, TestConstants.SCRAPER_NAME).get(0).getMetadata().getName(); - return cmdKubeClient(namespaceName).execInPod( - testSuiteScraperPodName, + return executeRequestAndReturnData( + namespaceName, + testSuiteScraperPodName, + new String[]{ "curl", "--insecure", "-X", @@ -205,6 +228,29 @@ public static String importRealm(String namespaceName, String baseURI, String to "-d", realmData, baseURI + "/admin/realms", "-H", "Authorization: Bearer " + token - ).out().trim(); + } + ); + } + + public static String executeRequestAndReturnData(String namespaceName, String scraperPodName, String[] request) { + AtomicReference response = new AtomicReference<>(""); + + TestUtils.waitFor("request to Keycloak API will be successful", TestConstants.GLOBAL_POLL_INTERVAL_5_SECS, TestConstants.GLOBAL_STATUS_TIMEOUT, () -> { + try { + String commandOutput = cmdKubeClient(namespaceName).execInPod(scraperPodName, request).out().trim(); + + if (!commandOutput.contains("Connection refused")) { + response.set(commandOutput); + return true; + } + + return false; + } catch (Exception e) { + LOGGER.warn("Exception occurred during doing request on Keycloak API: " + e.getMessage()); + return false; + } + }); + + return response.get(); } }