From d3e9637ad83acfe9ca3bc28ac8551ec3a6edb271 Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 28 Mar 2025 14:15:20 +0200 Subject: [PATCH 01/13] drop unused methods Signed-off-by: wind57 --- .../tests/commons/native_client/Util.java | 81 ------------------- 1 file changed, 81 deletions(-) diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java index 9fc85e51..7d3607b2 100644 --- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java +++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java @@ -29,7 +29,6 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import io.kubernetes.client.custom.V1Patch; import io.kubernetes.client.openapi.ApiClient; import io.kubernetes.client.openapi.ApiException; import io.kubernetes.client.openapi.Configuration; @@ -40,7 +39,6 @@ import io.kubernetes.client.openapi.apis.NetworkingV1Api; import io.kubernetes.client.openapi.apis.RbacAuthorizationV1Api; import io.kubernetes.client.openapi.models.V1APIService; import io.kubernetes.client.openapi.models.V1ClusterRole; -import io.kubernetes.client.openapi.models.V1ClusterRoleBinding; import io.kubernetes.client.openapi.models.V1ConfigMap; import io.kubernetes.client.openapi.models.V1Deployment; import io.kubernetes.client.openapi.models.V1DeploymentCondition; @@ -55,7 +53,6 @@ import io.kubernetes.client.openapi.models.V1Secret; import io.kubernetes.client.openapi.models.V1Service; import io.kubernetes.client.openapi.models.V1ServiceAccount; import io.kubernetes.client.util.Config; -import io.kubernetes.client.util.PatchUtils; import io.kubernetes.client.util.Yaml; import jakarta.annotation.Nullable; import org.apache.commons.logging.Log; @@ -335,49 +332,6 @@ public final class Util { } - public void setUpClusterWideClusterRoleBinding(String serviceAccountNamespace) { - - try { - V1ServiceAccount serviceAccount = (V1ServiceAccount) yaml("cluster/service-account.yaml"); - CheckedSupplier accountSupplier = () -> coreV1Api - .readNamespacedServiceAccount(serviceAccount.getMetadata().getName(), serviceAccountNamespace, null); - CheckedSupplier accountDefaulter = () -> coreV1Api - .createNamespacedServiceAccount(serviceAccountNamespace, serviceAccount, null, null, null, null); - notExistsHandler(accountSupplier, accountDefaulter); - - V1ClusterRole clusterRole = (V1ClusterRole) yaml("cluster/cluster-role.yaml"); - notExistsHandler(() -> rbacApi.readClusterRole(clusterRole.getMetadata().getName(), null), - () -> rbacApi.createClusterRole(clusterRole, null, null, null, null)); - - V1ClusterRoleBinding clusterRoleBinding = (V1ClusterRoleBinding) yaml("cluster/cluster-role-binding.yaml"); - notExistsHandler(() -> rbacApi.readClusterRoleBinding(clusterRoleBinding.getMetadata().getName(), null), - () -> rbacApi.createClusterRoleBinding(clusterRoleBinding, null, null, null, null)); - } - catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - - } - - public void deleteClusterWideClusterRoleBinding(String serviceAccountNamespace) { - try { - V1ServiceAccount serviceAccount = (V1ServiceAccount) yaml("cluster/service-account.yaml"); - V1ClusterRole clusterRole = (V1ClusterRole) yaml("cluster/cluster-role.yaml"); - V1ClusterRoleBinding clusterRoleBinding = (V1ClusterRoleBinding) yaml("cluster/cluster-role-binding.yaml"); - - coreV1Api.deleteNamespacedServiceAccount(serviceAccount.getMetadata().getName(), serviceAccountNamespace, - null, null, null, null, null, null); - rbacApi.deleteClusterRole(clusterRole.getMetadata().getName(), null, null, null, null, null, null); - rbacApi.deleteClusterRoleBinding(clusterRoleBinding.getMetadata().getName(), null, null, null, null, null, - null); - } - catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - public void setUpClusterWide(String serviceAccountNamespace, Set namespaces) { try { @@ -517,41 +471,6 @@ public final class Util { } - public static void patchWithMerge(String deploymentName, String namespace, String patchBody, - Map podLabels) { - try { - PatchUtils.patch(V1Deployment.class, - () -> new AppsV1Api().patchNamespacedDeploymentCall(deploymentName, namespace, - new V1Patch(patchBody), null, null, null, null, null, null), - V1Patch.PATCH_FORMAT_STRATEGIC_MERGE_PATCH, new CoreV1Api().getApiClient()); - } - catch (ApiException e) { - LOG.error("error : " + e.getResponseBody()); - throw new RuntimeException(e); - } - - waitForDeploymentAfterPatch(deploymentName, namespace, podLabels); - } - - public static void patchWithReplace(String imageName, String deploymentName, String namespace, String patchBody, - Map podLabels) { - String body = patchBody.replace("image_name_here", imageName); - - try { - PatchUtils.patch(V1Deployment.class, - () -> new AppsV1Api().patchNamespacedDeploymentCall(deploymentName, namespace, new V1Patch(body), - null, null, null, null, null, null), - V1Patch.PATCH_FORMAT_JSON_MERGE_PATCH, new CoreV1Api().getApiClient()); - } - catch (ApiException e) { - LOG.error("error : " + e.getResponseBody()); - throw new RuntimeException(e); - } - - waitForDeploymentAfterPatch(deploymentName, namespace, podLabels); - - } - private String deploymentName(V1Deployment deployment) { return deployment.getMetadata().getName(); } From 6d507424b0e656bbf3203bcfb8407abc31f184fc Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 28 Mar 2025 14:56:12 +0200 Subject: [PATCH 02/13] first Signed-off-by: wind57 --- .../watcher/ActuatorRefreshIT.java | 4 +- .../ActuatorRefreshMultipleNamespacesIT.java | 4 +- .../it/DiscoveryServerClientBase.java | 4 +- .../it/DiscoveryServerClientIT.java | 8 +- .../KubernetesClientDiscoverySimpleIT.java | 4 +- .../apps/ConfigurationWatcherBusKafkaIT.java | 12 +- .../src/test/resources/app/app-service.yaml | 3 +- .../src/test/resources/ingress/ingress.yaml | 16 -- .../apps/ConfigurationWatcherBusAmqpIT.java | 11 +- .../config-watcher/watcher-service.yaml | 3 +- .../src/test/resources/ingress/ingress.yaml | 16 -- .../client/reload/it/K8sClientReloadBase.java | 8 +- .../tests/commons/native_client/Util.java | 140 ++---------------- .../resources/wiremock/wiremock-ingress.yaml | 17 --- 14 files changed, 42 insertions(+), 208 deletions(-) delete mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/ingress/ingress.yaml delete mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/ingress/ingress.yaml delete mode 100644 spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-ingress.yaml diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java index da62ad2a..fa3660fd 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java @@ -114,10 +114,10 @@ class ActuatorRefreshIT { deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setEnv(envVars); if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, deployment, service, null, true); + util.createAndWait(NAMESPACE, null, deployment, service, true); } else { - util.deleteAndWait(NAMESPACE, deployment, service, null); + util.deleteAndWait(NAMESPACE, deployment, service); } } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java index b74dbc03..df642892 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java @@ -128,10 +128,10 @@ class ActuatorRefreshMultipleNamespacesIT { .yaml("config-watcher/spring-cloud-kubernetes-configuration-watcher-service.yaml"); if (phase.equals(Phase.CREATE)) { - util.createAndWait(DEFAULT_NAMESPACE, null, deployment, service, null, true); + util.createAndWait(DEFAULT_NAMESPACE, null, deployment, service, true); } else { - util.deleteAndWait(DEFAULT_NAMESPACE, deployment, service, null); + util.deleteAndWait(DEFAULT_NAMESPACE, deployment, service); } } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientBase.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientBase.java index 5506d4b3..cbbf11ea 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientBase.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientBase.java @@ -93,10 +93,10 @@ abstract class DiscoveryServerClientBase { V1Service service = (V1Service) util.yaml("manifests/discoveryserver-service.yaml"); if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, deployment, service, null, true); + util.createAndWait(NAMESPACE, null, deployment, service, true); } else { - util.deleteAndWait(NAMESPACE, deployment, service, null); + util.deleteAndWait(NAMESPACE, deployment, service); } } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java index ab3de7a6..42818b30 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java @@ -78,8 +78,8 @@ class DiscoveryServerClientIT extends DiscoveryServerClientBase { discoveryServer(Phase.CREATE); Images.loadWiremock(K3S); - util.wiremock(NAMESPACE_LEFT, "/wiremock-" + NAMESPACE_LEFT, Phase.CREATE, false); - util.wiremock(NAMESPACE_RIGHT, "/wiremock-" + NAMESPACE_RIGHT, Phase.CREATE, false); + util.wiremock(NAMESPACE_LEFT, Phase.CREATE); + util.wiremock(NAMESPACE_RIGHT, Phase.CREATE); } @AfterAll @@ -87,8 +87,8 @@ class DiscoveryServerClientIT extends DiscoveryServerClientBase { serviceAccount(Phase.DELETE); discoveryServer(Phase.DELETE); - util.wiremock(NAMESPACE_LEFT, "/wiremock-" + NAMESPACE_LEFT, Phase.DELETE, false); - util.wiremock(NAMESPACE_RIGHT, "/wiremock-" + NAMESPACE_RIGHT, Phase.DELETE, false); + util.wiremock(NAMESPACE_LEFT, Phase.DELETE); + util.wiremock(NAMESPACE_RIGHT, Phase.DELETE); util.deleteNamespace(NAMESPACE_LEFT); util.deleteNamespace(NAMESPACE_RIGHT); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java index e00c3b01..472fcd6b 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java @@ -64,13 +64,13 @@ class KubernetesClientDiscoverySimpleIT extends KubernetesClientDiscoveryBase { util.busybox(NAMESPACE, Phase.CREATE); externalNameService = (V1Service) util.yaml("external-name-service.yaml"); - util.createAndWait(NAMESPACE, null, null, externalNameService, null, true); + util.createAndWait(NAMESPACE, null, null, externalNameService, true); } @AfterEach void afterEach() { util.busybox(NAMESPACE, Phase.DELETE); - util.deleteAndWait(NAMESPACE, null, externalNameService, null); + util.deleteAndWait(NAMESPACE, null, externalNameService); } @Test diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusKafkaIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusKafkaIT.java index 7361bf5a..72a09967 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusKafkaIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusKafkaIT.java @@ -22,7 +22,6 @@ import java.util.Objects; import io.kubernetes.client.openapi.models.V1ConfigMap; import io.kubernetes.client.openapi.models.V1ConfigMapBuilder; import io.kubernetes.client.openapi.models.V1Deployment; -import io.kubernetes.client.openapi.models.V1Ingress; import io.kubernetes.client.openapi.models.V1Service; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -153,7 +152,7 @@ class ConfigurationWatcherBusKafkaIT { util.createAndWait(NAMESPACE, configMap, null); WebClient.Builder builder = builder(); - WebClient serviceClient = builder.baseUrl("http://localhost:80/app").build(); + WebClient serviceClient = builder.baseUrl("http://localhost:32321/app").build(); Boolean[] value = new Boolean[1]; await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(240)).until(() -> { @@ -173,13 +172,12 @@ class ConfigurationWatcherBusKafkaIT { private void app(Phase phase) { V1Deployment deployment = (V1Deployment) util.yaml("app/app-deployment.yaml"); V1Service service = (V1Service) util.yaml("app/app-service.yaml"); - V1Ingress ingress = (V1Ingress) util.yaml("ingress/ingress.yaml"); if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, deployment, service, ingress, true); + util.createAndWait(NAMESPACE, null, deployment, service, true); } else if (phase.equals(Phase.DELETE)) { - util.deleteAndWait(NAMESPACE, deployment, service, ingress); + util.deleteAndWait(NAMESPACE, deployment, service); } } @@ -188,10 +186,10 @@ class ConfigurationWatcherBusKafkaIT { V1Service service = (V1Service) util.yaml("config-watcher/watcher-kus-kafka-service.yaml"); if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, deployment, service, null, true); + util.createAndWait(NAMESPACE, null, deployment, service, true); } else if (phase.equals(Phase.DELETE)) { - util.deleteAndWait(NAMESPACE, deployment, service, null); + util.deleteAndWait(NAMESPACE, deployment, service); } } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/app/app-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/app/app-service.yaml index f9cb695f..3be7e66c 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/app/app-service.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/app/app-service.yaml @@ -9,6 +9,7 @@ spec: - name: http port: 8081 targetPort: 8081 + nodePort: 32321 selector: app: app - type: ClusterIP + type: NodePort diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/ingress/ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/ingress/ingress.yaml deleted file mode 100644 index faa02ba6..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-kafka-configmap-reload/kafka-configmap-test-app/src/test/resources/ingress/ingress.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: it-ingress-app - namespace: default -spec: - rules: - - http: - paths: - - path: /app - pathType: Prefix - backend: - service: - name: app - port: - number: 8081 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java index 2d9a764f..041bcf56 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java @@ -103,7 +103,7 @@ class ConfigurationWatcherBusAmqpIT { util.createAndWait(NAMESPACE, null, secret); WebClient.Builder builder = builder(); - WebClient serviceClient = builder.baseUrl("http://localhost:80/app").build(); + WebClient serviceClient = builder.baseUrl("http://localhost:32321/app").build(); Boolean[] value = new Boolean[1]; await().pollInterval(Duration.ofSeconds(3)).atMost(Duration.ofSeconds(240)).until(() -> { @@ -122,13 +122,12 @@ class ConfigurationWatcherBusAmqpIT { private void appA(Phase phase) { V1Deployment deployment = (V1Deployment) util.yaml("app/app-deployment.yaml"); V1Service service = (V1Service) util.yaml("app/app-service.yaml"); - V1Ingress ingress = (V1Ingress) util.yaml("ingress/ingress.yaml"); if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, deployment, service, ingress, true); + util.createAndWait(NAMESPACE, null, deployment, service, true); } else if (phase.equals(Phase.DELETE)) { - util.deleteAndWait(NAMESPACE, deployment, service, ingress); + util.deleteAndWait(NAMESPACE, deployment, service); } } @@ -137,10 +136,10 @@ class ConfigurationWatcherBusAmqpIT { V1Service service = (V1Service) util.yaml("config-watcher/watcher-service.yaml"); if (phase.equals(Phase.CREATE)) { - util.createAndWait(NAMESPACE, null, deployment, service, null, true); + util.createAndWait(NAMESPACE, null, deployment, service, true); } else if (phase.equals(Phase.DELETE)) { - util.deleteAndWait(NAMESPACE, deployment, service, null); + util.deleteAndWait(NAMESPACE, deployment, service); } } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml index 3ab3a8ec..8428eede 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml @@ -9,6 +9,7 @@ spec: - name: http port: 8888 targetPort: 8888 + nodePort: 32321 selector: app: configuration-watcher - type: ClusterIP + type: NodePort diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/ingress/ingress.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/ingress/ingress.yaml deleted file mode 100644 index 46ea6693..00000000 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/ingress/ingress.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: it-ingress - namespace: default -spec: - rules: - - http: - paths: - - path: /app - pathType: Prefix - backend: - service: - name: app - port: - number: 8080 diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientReloadBase.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientReloadBase.java index cc91acce..6cbcefbf 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientReloadBase.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientReloadBase.java @@ -105,11 +105,11 @@ abstract class K8sClientReloadBase { if (phase.equals(Phase.CREATE)) { util.createAndWait(namespace, configMap, null); - util.createAndWait(namespace, imageName, deployment, service, null, true); + util.createAndWait(namespace, imageName, deployment, service, true); } else { util.deleteAndWait(namespace, configMap, null); - util.deleteAndWait(namespace, deployment, service, null); + util.deleteAndWait(namespace, deployment, service); } } @@ -122,11 +122,11 @@ abstract class K8sClientReloadBase { if (phase.equals(Phase.CREATE)) { util.createAndWait(namespace, null, secret); - util.createAndWait(namespace, imageName, deployment, service, null, true); + util.createAndWait(namespace, imageName, deployment, service, true); } else { util.deleteAndWait(namespace, null, secret); - util.deleteAndWait(namespace, deployment, service, null); + util.deleteAndWait(namespace, deployment, service); } } diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java index 7d3607b2..9ef42492 100644 --- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java +++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java @@ -35,7 +35,6 @@ import io.kubernetes.client.openapi.Configuration; import io.kubernetes.client.openapi.apis.ApiregistrationV1Api; import io.kubernetes.client.openapi.apis.AppsV1Api; import io.kubernetes.client.openapi.apis.CoreV1Api; -import io.kubernetes.client.openapi.apis.NetworkingV1Api; import io.kubernetes.client.openapi.apis.RbacAuthorizationV1Api; import io.kubernetes.client.openapi.models.V1APIService; import io.kubernetes.client.openapi.models.V1ClusterRole; @@ -43,9 +42,6 @@ import io.kubernetes.client.openapi.models.V1ConfigMap; import io.kubernetes.client.openapi.models.V1Deployment; import io.kubernetes.client.openapi.models.V1DeploymentCondition; import io.kubernetes.client.openapi.models.V1DeploymentList; -import io.kubernetes.client.openapi.models.V1Ingress; -import io.kubernetes.client.openapi.models.V1IngressLoadBalancerIngress; -import io.kubernetes.client.openapi.models.V1IngressLoadBalancerStatus; import io.kubernetes.client.openapi.models.V1NamespaceBuilder; import io.kubernetes.client.openapi.models.V1Role; import io.kubernetes.client.openapi.models.V1RoleBinding; @@ -79,8 +75,6 @@ public final class Util { private final AppsV1Api appsV1Api; - private final NetworkingV1Api networkingV1Api; - private final RbacAuthorizationV1Api rbacApi; private final K3sContainer container; @@ -101,7 +95,6 @@ public final class Util { this.container = container; this.coreV1Api = new CoreV1Api(); this.appsV1Api = new AppsV1Api(); - this.networkingV1Api = new NetworkingV1Api(); rbacApi = new RbacAuthorizationV1Api(); } @@ -113,7 +106,7 @@ public final class Util { * */ public void createAndWait(String namespace, String name, V1Deployment deployment, V1Service service, - @Nullable V1Ingress ingress, boolean changeVersion) { + boolean changeVersion) { try { coreV1Api.createNamespacedService(namespace, service, null, null, null, null); @@ -143,10 +136,6 @@ public final class Util { waitForDeployment(namespace, deployment); } - if (ingress != null) { - networkingV1Api.createNamespacedIngress(namespace, ingress, null, null, null, null); - waitForIngress(namespace, ingress); - } } catch (Exception e) { if (e instanceof ApiException apiException) { @@ -204,8 +193,7 @@ public final class Util { } } - public void deleteAndWait(String namespace, V1Deployment deployment, V1Service service, - @Nullable V1Ingress ingress) { + public void deleteAndWait(String namespace, V1Deployment deployment, V1Service service) { if (deployment != null) { try { @@ -226,20 +214,6 @@ public final class Util { } } - - String serviceName = serviceName(service); - try { - coreV1Api.deleteNamespacedService(serviceName, namespace, null, null, null, null, null, null); - if (ingress != null) { - String ingressName = ingressName(ingress); - networkingV1Api.deleteNamespacedIngress(ingressName, namespace, null, null, null, null, null, null); - waitForIngressToBeDeleted(ingressName, namespace); - } - - } - catch (ApiException e) { - throw new RuntimeException(e); - } } public void busybox(String namespace, Phase phase) { @@ -251,10 +225,10 @@ public final class Util { V1Service service = (V1Service) yaml("busybox/service.yaml"); if (phase.equals(Phase.CREATE)) { - createAndWait(namespace, "busybox", deployment, service, null, false); + createAndWait(namespace, "busybox", deployment, service, false); } else if (phase.equals(Phase.DELETE)) { - deleteAndWait(namespace, deployment, service, null); + deleteAndWait(namespace, deployment, service); } } @@ -268,10 +242,10 @@ public final class Util { V1Service service = (V1Service) yaml("kafka/kafka-service.yaml"); if (phase.equals(Phase.CREATE)) { - createAndWait(namespace, "kafka", deployment, service, null, false); + createAndWait(namespace, "kafka", deployment, service, false); } else if (phase.equals(Phase.DELETE)) { - deleteAndWait(namespace, deployment, service, null); + deleteAndWait(namespace, deployment, service); } } @@ -285,10 +259,10 @@ public final class Util { V1Service service = (V1Service) yaml("rabbitmq/rabbitmq-service.yaml"); if (phase.equals(Phase.CREATE)) { - createAndWait(namespace, "rabbitmq", deployment, service, null, false); + createAndWait(namespace, "rabbitmq", deployment, service, false); } else if (phase.equals(Phase.DELETE)) { - deleteAndWait(namespace, deployment, service, null); + deleteAndWait(namespace, deployment, service); } } @@ -436,10 +410,10 @@ public final class Util { } public void wiremock(String namespace, String path, Phase phase) { - wiremock(namespace, path, phase, true); + wiremock(namespace, phase); } - public void wiremock(String namespace, String path, Phase phase, boolean withIngress) { + public void wiremock(String namespace, Phase phase) { V1Deployment deployment = (V1Deployment) yaml("wiremock/wiremock-deployment.yaml"); String imageWithoutVersion = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage(); @@ -448,25 +422,13 @@ public final class Util { V1Service service = (V1Service) yaml("wiremock/wiremock-service.yaml"); - V1Ingress ingress = null; - if (phase.equals(Phase.CREATE)) { - - if (withIngress) { - ingress = (V1Ingress) yaml("wiremock/wiremock-ingress.yaml"); - ingress.getMetadata().setNamespace(namespace); - ingress.getSpec().getRules().get(0).getHttp().getPaths().get(0).setPath(path); - } - deployment.getMetadata().setNamespace(namespace); service.getMetadata().setNamespace(namespace); - createAndWait(namespace, "wiremock", deployment, service, ingress, false); + createAndWait(namespace, "wiremock", deployment, service, false); } else { - if (withIngress) { - ingress = (V1Ingress) yaml("wiremock/wiremock-ingress.yaml"); - } - deleteAndWait(namespace, deployment, service, ingress); + deleteAndWait(namespace, deployment, service); } } @@ -475,14 +437,6 @@ public final class Util { return deployment.getMetadata().getName(); } - private String serviceName(V1Service service) { - return service.getMetadata().getName(); - } - - private String ingressName(V1Ingress ingress) { - return ingress.getMetadata().getName(); - } - private String configMapName(V1ConfigMap configMap) { return configMap.getMetadata().getName(); } @@ -532,43 +486,6 @@ public final class Util { }); } - private void waitForIngress(String namespace, V1Ingress ingress) { - String ingressName = ingressName(ingress); - await().timeout(Duration.ofSeconds(90)).pollInterval(Duration.ofSeconds(3)).until(() -> { - try { - V1IngressLoadBalancerStatus status = networkingV1Api.readNamespacedIngress(ingressName, namespace, null) - .getStatus() - .getLoadBalancer(); - - if (status == null) { - LOG.info("ingress : " + ingressName + " not ready yet (loadbalancer not yet present)"); - return false; - } - - List loadBalancerIngress = status.getIngress(); - if (loadBalancerIngress == null) { - LOG.info("ingress : " + ingressName + " not ready yet (loadbalancer ingress not yet present)"); - return false; - } - - String ip = loadBalancerIngress.get(0).getIp(); - if (ip == null) { - LOG.info("ingress : " + ingressName + " not ready yet"); - return false; - } - - LOG.info("ingress : " + ingressName + " ready with ip : " + ip); - return true; - } - catch (ApiException e) { - if (e.getCode() == HttpURLConnection.HTTP_NOT_FOUND) { - return false; - } - throw new RuntimeException(e); - } - }); - } - private void waitForDeploymentToBeDeleted(String deploymentName, String namespace) { await().timeout(Duration.ofSeconds(180)).until(() -> { try { @@ -603,21 +520,6 @@ public final class Util { }); } - private void waitForIngressToBeDeleted(String ingressName, String namespace) { - await().timeout(Duration.ofSeconds(90)).until(() -> { - try { - networkingV1Api.readNamespacedIngress(ingressName, namespace, null); - return false; - } - catch (ApiException e) { - if (e.getCode() == HttpURLConnection.HTTP_NOT_FOUND) { - return true; - } - throw new RuntimeException(e); - } - }); - } - private boolean isDeploymentReady(String deploymentName, String namespace) throws ApiException { V1DeploymentList deployments = appsV1Api.listNamespacedDeployment(namespace, null, null, null, "metadata.name=" + deploymentName, null, null, null, null, null, null, null); @@ -648,24 +550,6 @@ public final class Util { } } - private static void waitForDeploymentAfterPatch(String deploymentName, String namespace, - Map podLabels) { - try { - await().pollDelay(Duration.ofSeconds(4)) - .pollInterval(Duration.ofSeconds(3)) - .atMost(60, TimeUnit.SECONDS) - .until(() -> isDeploymentReadyAfterPatch(deploymentName, namespace, podLabels)); - } - catch (Exception e) { - if (e instanceof ApiException apiException) { - LOG.error("Error: "); - LOG.error(apiException.getResponseBody()); - } - throw new RuntimeException(e); - } - - } - private static boolean isDeploymentReadyAfterPatch(String deploymentName, String namespace, Map podLabels) throws ApiException { diff --git a/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-ingress.yaml b/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-ingress.yaml deleted file mode 100644 index 18d50519..00000000 --- a/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-ingress.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: wiremock-ingress - namespace: default -spec: - rules: - - http: - paths: - - path: /wiremock/ - pathType: Prefix - backend: - service: - name: service-wiremock - port: - number: 8080 - From 8ce9256e37303434624e42e9a4cfb0012ec76238 Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 28 Mar 2025 15:00:38 +0200 Subject: [PATCH 03/13] checkstyle Signed-off-by: wind57 --- .../watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java index 041bcf56..3a5da266 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/multiple/apps/ConfigurationWatcherBusAmqpIT.java @@ -20,7 +20,6 @@ import java.time.Duration; import java.util.Objects; import io.kubernetes.client.openapi.models.V1Deployment; -import io.kubernetes.client.openapi.models.V1Ingress; import io.kubernetes.client.openapi.models.V1Secret; import io.kubernetes.client.openapi.models.V1SecretBuilder; import io.kubernetes.client.openapi.models.V1Service; From e0a5629cb2ea4173076e0f5009cb3bb0cb08546d Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 28 Mar 2025 17:02:24 +0200 Subject: [PATCH 04/13] fix test Signed-off-by: wind57 --- .../kubernetes/configuration/watcher/ActuatorRefreshIT.java | 6 ++---- .../watcher/ActuatorRefreshMultipleNamespacesIT.java | 4 ++-- .../cloud/kubernetes/configuration/watcher/TestUtil.java | 4 ++-- .../integration/tests/commons/native_client/Util.java | 4 ---- .../src/main/resources/wiremock/wiremock-service.yaml | 3 ++- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java index fa3660fd..000c9ba8 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java @@ -44,8 +44,6 @@ import static org.springframework.cloud.kubernetes.configuration.watcher.TestUti */ class ActuatorRefreshIT { - private static final String WIREMOCK_PATH = "/"; - private static final String NAMESPACE = "default"; private static final K3sContainer K3S = Commons.container(); @@ -72,12 +70,12 @@ class ActuatorRefreshIT { @BeforeEach void setup() { - util.wiremock(NAMESPACE, WIREMOCK_PATH, Phase.CREATE); + util.wiremock(NAMESPACE, Phase.CREATE); } @AfterEach void after() { - util.wiremock(NAMESPACE, WIREMOCK_PATH, Phase.DELETE); + util.wiremock(NAMESPACE, Phase.DELETE); } /* diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java index df642892..266aa3aa 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java @@ -60,7 +60,7 @@ class ActuatorRefreshMultipleNamespacesIT { util = new Util(K3S); util.createNamespace(LEFT_NAMESPACE); util.createNamespace(RIGHT_NAMESPACE); - util.wiremock(DEFAULT_NAMESPACE, "/", Phase.CREATE); + util.wiremock(DEFAULT_NAMESPACE, Phase.CREATE); util.setUpClusterWide(DEFAULT_NAMESPACE, Set.of(DEFAULT_NAMESPACE, LEFT_NAMESPACE, RIGHT_NAMESPACE)); configWatcher(Phase.CREATE); } @@ -68,7 +68,7 @@ class ActuatorRefreshMultipleNamespacesIT { @AfterAll static void afterAll() { configWatcher(Phase.DELETE); - util.wiremock(DEFAULT_NAMESPACE, "/", Phase.DELETE); + util.wiremock(DEFAULT_NAMESPACE, Phase.DELETE); util.deleteClusterWide(DEFAULT_NAMESPACE, Set.of(DEFAULT_NAMESPACE, LEFT_NAMESPACE, RIGHT_NAMESPACE)); util.deleteNamespace(LEFT_NAMESPACE); util.deleteNamespace(RIGHT_NAMESPACE); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java index 1eb5ad82..7a3a995b 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/TestUtil.java @@ -46,7 +46,7 @@ final class TestUtil { private static final String WIREMOCK_HOST = "localhost"; - private static final int WIREMOCK_PORT = 80; + private static final int WIREMOCK_PORT = 32321; static final String SPRING_CLOUD_K8S_CONFIG_WATCHER_APP_NAME = "spring-cloud-kubernetes-configuration-watcher"; @@ -60,7 +60,7 @@ final class TestUtil { // is ready to take a request via 'Wiremock::stubFor' (because sometimes it fails) // As such, get the existing mappings and retrySpec() makes sure we retry until // we get a response back. - WebClient client = builder().baseUrl("http://localhost:80/__admin/mappings").build(); + WebClient client = builder().baseUrl("http://localhost:32321/__admin/mappings").build(); client.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec()).block(); StubMapping stubMapping = WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/actuator/refresh")) diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java index 9ef42492..86c8b24f 100644 --- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java +++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java @@ -409,10 +409,6 @@ public final class Util { .noneMatch(x -> x.getMetadata().getName().equals(name))); } - public void wiremock(String namespace, String path, Phase phase) { - wiremock(namespace, phase); - } - public void wiremock(String namespace, Phase phase) { V1Deployment deployment = (V1Deployment) yaml("wiremock/wiremock-deployment.yaml"); diff --git a/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-service.yaml b/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-service.yaml index af4d4e00..57b31e31 100644 --- a/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-service.yaml +++ b/spring-cloud-kubernetes-test-support/src/main/resources/wiremock/wiremock-service.yaml @@ -9,6 +9,7 @@ spec: - name: http port: 8080 targetPort: 8080 + nodePort: 32321 selector: app: service-wiremock - type: ClusterIP + type: NodePort From 629ceaa9ac1f980dcadc1c3aa4cac71493778c1e Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 28 Mar 2025 17:42:39 +0200 Subject: [PATCH 05/13] fix compilation Signed-off-by: wind57 --- .../k8s/client/discovery/KubernetesClientReactiveIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java index 2f00f4f1..c24af79b 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java @@ -60,12 +60,12 @@ class KubernetesClientReactiveIT extends KubernetesClientDiscoveryBase { @BeforeEach void beforeEach() { Images.loadWiremock(K3S); - util.wiremock(NAMESPACE, "/", Phase.CREATE); + util.wiremock(NAMESPACE, Phase.CREATE); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE, "/", Phase.DELETE); + util.wiremock(NAMESPACE, Phase.DELETE); } /** From 63f119cd26599b5f1c3d94869c6a44a711dfebc0 Mon Sep 17 00:00:00 2001 From: wind57 Date: Fri, 28 Mar 2025 18:27:29 +0200 Subject: [PATCH 06/13] fix compilation Signed-off-by: wind57 --- .../k8s/client/discovery/KubernetesClientBlockingIT.java | 4 ++-- .../discovery/KubernetesClientDiscoveryFilterIT.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java index 7ff34634..6d75d346 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java @@ -60,12 +60,12 @@ class KubernetesClientBlockingIT extends KubernetesClientDiscoveryBase { @BeforeEach void beforeEach() { Images.loadWiremock(K3S); - util.wiremock(NAMESPACE, "/", Phase.CREATE); + util.wiremock(NAMESPACE, Phase.CREATE); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE, "/", Phase.DELETE); + util.wiremock(NAMESPACE, Phase.DELETE); } /** diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java index 189dd3d7..2cfb3a40 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java @@ -63,14 +63,14 @@ class KubernetesClientDiscoveryFilterIT extends KubernetesClientDiscoveryBase { util.createNamespace(NAMESPACE_B_UAT); Images.loadWiremock(K3S); - util.wiremock(NAMESPACE_A_UAT, "/", Phase.CREATE); - util.wiremock(NAMESPACE_B_UAT, "/", Phase.CREATE); + util.wiremock(NAMESPACE_A_UAT, Phase.CREATE); + util.wiremock(NAMESPACE_B_UAT, Phase.CREATE); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE_A_UAT, "/", Phase.DELETE); - util.wiremock(NAMESPACE_B_UAT, "/", Phase.DELETE); + util.wiremock(NAMESPACE_A_UAT, Phase.DELETE); + util.wiremock(NAMESPACE_B_UAT, Phase.DELETE); util.deleteNamespace(NAMESPACE_A_UAT); util.deleteNamespace(NAMESPACE_B_UAT); From 52d47e20cc5c22a6f886b427e96f6a76969fbbd5 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sat, 29 Mar 2025 20:30:36 +0200 Subject: [PATCH 07/13] first Signed-off-by: wind57 --- .../config/reload/ConfigReloadUtil.java | 9 ++ .../config/reload/ConfigReloadUtilTests.java | 51 ++++++-- ...8sClientSecretMountBootstrapPollingIT.java | 118 ++++++++++++++++++ 3 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java index c8df2821..f066da4c 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.cloud.bootstrap.config.BootstrapPropertySource; import org.springframework.cloud.bootstrap.config.PropertySourceLocator; import org.springframework.cloud.kubernetes.commons.config.MountConfigMapPropertySource; +import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySource; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; @@ -110,6 +111,10 @@ public final class ConfigReloadUtil { // we know that the type is correct here managedSources.add((S) mountConfigMapPropertySource); } + else if (source instanceof SecretsPropertySource secretsPropertySource) { + // we know that the type is correct here + managedSources.add((S) secretsPropertySource); + } else if (source instanceof BootstrapPropertySource bootstrapPropertySource) { PropertySource propertySource = bootstrapPropertySource.getDelegate(); LOG.debug(() -> "bootstrap delegate class : " + propertySource.getClass()); @@ -120,6 +125,10 @@ public final class ConfigReloadUtil { // we know that the type is correct here managedSources.add((S) mountConfigMapPropertySource); } + else if (propertySource instanceof SecretsPropertySource secretsPropertySource) { + // we know that the type is correct here + managedSources.add((S) secretsPropertySource); + } } } diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java index 280d95f9..2d8430f7 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java @@ -27,6 +27,8 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.bootstrap.config.BootstrapPropertySource; import org.springframework.cloud.kubernetes.commons.config.MountConfigMapPropertySource; +import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySource; +import org.springframework.cloud.kubernetes.commons.config.SourceData; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.MapPropertySource; @@ -127,8 +129,8 @@ class ConfigReloadUtilTests { MockEnvironment environment = new MockEnvironment(); MutablePropertySources propertySources = environment.getPropertySources(); propertySources.addFirst(new OneComposite()); - propertySources.addFirst(new PlainPropertySource("plain")); - propertySources.addFirst(new OneBootstrap(new EnumerablePropertySource<>("enumerable") { + propertySources.addFirst(new PlainPropertySource<>("plain")); + propertySources.addFirst(new OneBootstrap<>(new EnumerablePropertySource<>("enumerable") { @Override public String[] getPropertyNames() { return new String[0]; @@ -143,11 +145,35 @@ class ConfigReloadUtilTests { List result = ConfigReloadUtil.findPropertySources(PlainPropertySource.class, environment); - Assertions.assertEquals(4, result.size()); + Assertions.assertEquals(3, result.size()); Assertions.assertEquals("b", result.get(0).getProperty("a")); Assertions.assertEquals("plain", result.get(1).getProperty("")); - Assertions.assertEquals("from-bootstrap", result.get(2).getProperty("")); - Assertions.assertEquals("from-inner-two-composite", result.get(3).getProperty("")); + Assertions.assertEquals("from-inner-two-composite", result.get(2).getProperty("")); + } + + @Test + void testSecretsPropertySource() { + MockEnvironment environment = new MockEnvironment(); + MutablePropertySources propertySources = environment.getPropertySources(); + propertySources.addFirst(new SecretsPropertySource(new SourceData("secret", Map.of("a", "b")))); + + List result = ConfigReloadUtil.findPropertySources(PlainPropertySource.class, + environment); + assertThat(result.size()).isEqualTo(1); + assertThat(result.get(0).getProperty("a")).isEqualTo("b"); + } + + @Test + void testBootstrapSecretsPropertySource() { + MockEnvironment environment = new MockEnvironment(); + MutablePropertySources propertySources = environment.getPropertySources(); + propertySources + .addFirst(new OneBootstrap<>(new SecretsPropertySource(new SourceData("secret", Map.of("a", "b"))))); + + List result = ConfigReloadUtil.findPropertySources(PlainPropertySource.class, + environment); + assertThat(result.size()).isEqualTo(1); + assertThat(result.get(0).getProperty("a")).isEqualTo("b"); } private static final class OneComposite extends CompositePropertySource { @@ -171,12 +197,12 @@ class ConfigReloadUtilTests { @Override public Collection> getPropertySources() { - return List.of(new PlainPropertySource("from-inner-two-composite")); + return List.of(new PlainPropertySource<>("from-inner-two-composite")); } } - private static final class PlainPropertySource extends PropertySource { + private static final class PlainPropertySource extends PropertySource { private PlainPropertySource(String name) { super(name); @@ -189,15 +215,18 @@ class ConfigReloadUtilTests { } - private static final class OneBootstrap extends BootstrapPropertySource { + private static final class OneBootstrap extends BootstrapPropertySource { - private OneBootstrap(EnumerablePropertySource delegate) { + private final EnumerablePropertySource delegate; + + private OneBootstrap(EnumerablePropertySource delegate) { super(delegate); + this.delegate = delegate; } @Override - public PropertySource getDelegate() { - return new PlainPropertySource("from-bootstrap"); + public PropertySource getDelegate() { + return delegate; } } diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java new file mode 100644 index 00000000..e4094c20 --- /dev/null +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java @@ -0,0 +1,118 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * 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 + * + * https://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.springframework.cloud.kubernetes.k8s.client.reload.it; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Map; + +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1Secret; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.k3s.K3sContainer; + +import org.springframework.cloud.kubernetes.integration.tests.commons.Commons; +import org.springframework.cloud.kubernetes.integration.tests.commons.Phase; +import org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util; +import org.springframework.http.HttpMethod; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.builder; +import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.retrySpec; + +/** + * @author wind57 + */ +class K8sClientSecretMountBootstrapPollingIT extends K8sClientReloadBase { + + private static final String IMAGE_NAME = "spring-cloud-kubernetes-k8s-client-reload"; + + private static final String NAMESPACE = "default"; + + private static final K3sContainer K3S = Commons.container(); + + private static Util util; + + private static CoreV1Api coreV1Api; + + @BeforeAll + static void beforeAllLocal() throws Exception { + K3S.start(); + Commons.validateImage(IMAGE_NAME, K3S); + Commons.loadSpringCloudKubernetesImage(IMAGE_NAME, K3S); + + util = new Util(K3S); + coreV1Api = new CoreV1Api(); + util.setUp(NAMESPACE); + manifestsSecret(Phase.CREATE, util, NAMESPACE, IMAGE_NAME); + } + + @AfterAll + static void afterAll() { + manifestsSecret(Phase.DELETE, util, NAMESPACE, IMAGE_NAME); + } + + /** + *
+	 *     - we have bootstrap enabled
+	 *     - we will 'locate' property sources from secrets.
+	 *     - there are no explicit secrets to search for, but what we will also read,
+	 *     	 is 'spring.cloud.kubernetes.secret.paths', which we have set to
+	 *     	 '/tmp/application.properties'
+	 *       in this test. That is populated by the volumeMounts (see mount/deployment-with-secret.yaml)
+	 *     - we first assert that we are actually reading the path based source
+	 *
+	 *     - we then change the secret content, wait for k8s to pick it up and replace them
+	 *     - our polling will then detect that change, and trigger a reload.
+	 * 
+ */ + @Test + void test() throws Exception { + WebClient webClient = builder().baseUrl("http://localhost:32321/secret").build(); + String result = webClient.method(HttpMethod.GET) + .retrieve() + .bodyToMono(String.class) + .retryWhen(retrySpec()) + .block(); + + // we first read the initial value from the configmap + assertThat(result).isEqualTo("initial"); + + // replace data in secret and wait for k8s to pick it up + // our polling will detect that and restart the app + V1Secret secret = (V1Secret) util.yaml("mount/secret.yaml"); + secret.setData(Map.of("from.properties.secret.key", "as-mount-changed".getBytes(StandardCharsets.UTF_8))); + coreV1Api.replaceNamespacedSecret("secret-reload", NAMESPACE, secret, null, null, null, null); + + Commons.waitForLogStatement("Detected change in config maps/secrets, reload will be triggered", K3S, + IMAGE_NAME); + + await().atMost(Duration.ofSeconds(120)) + .pollInterval(Duration.ofSeconds(1)) + .until(() -> (Boolean) webClient.method(HttpMethod.GET) + .retrieve() + .bodyToMono(String.class) + .retryWhen(retrySpec()) + .block() + .equals("as-mount-changed")); + } + +} From a07196d216ef282602a72ed493bbc7f46dcb6203 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sat, 29 Mar 2025 21:04:23 +0200 Subject: [PATCH 08/13] fix Signed-off-by: wind57 --- .../reload/it/K8sClientSecretMountBootstrapPollingIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java index e4094c20..c6b0f88f 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/test/java/org/springframework/cloud/kubernetes/k8s/client/reload/it/K8sClientSecretMountBootstrapPollingIT.java @@ -103,11 +103,11 @@ class K8sClientSecretMountBootstrapPollingIT extends K8sClientReloadBase { coreV1Api.replaceNamespacedSecret("secret-reload", NAMESPACE, secret, null, null, null, null); Commons.waitForLogStatement("Detected change in config maps/secrets, reload will be triggered", K3S, - IMAGE_NAME); + IMAGE_NAME); await().atMost(Duration.ofSeconds(120)) .pollInterval(Duration.ofSeconds(1)) - .until(() -> (Boolean) webClient.method(HttpMethod.GET) + .until(() -> webClient.method(HttpMethod.GET) .retrieve() .bodyToMono(String.class) .retryWhen(retrySpec()) From 05859a328b4ab4c6d099ba79adff94b10e2e5cbe Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 30 Mar 2025 17:43:20 +0300 Subject: [PATCH 09/13] fix tests Signed-off-by: wind57 --- .../cloud/kubernetes/k8s/client/discovery/TestAssertions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java index 8c0a8c62..f00bf32a 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java @@ -133,7 +133,7 @@ final class TestAssertions { assertThat(wiremockInstance.getServiceId()).isEqualTo("service-wiremock"); assertThat(wiremockInstance.getInstanceId()).isNotNull(); assertThat(wiremockInstance.getHost()).isNotNull(); - assertThat(wiremockInstance.getMetadata()).isEqualTo(Map.of("k8s_namespace", "default", "type", "ClusterIP", + assertThat(wiremockInstance.getMetadata()).isEqualTo(Map.of("k8s_namespace", "default", "type", "NodePort", "port.http", "8080", "app", "service-wiremock")); } @@ -147,7 +147,7 @@ final class TestAssertions { assertThat(wiremockInstance.getServiceId()).isEqualTo("service-wiremock"); assertThat(wiremockInstance.getInstanceId()).isNotNull(); assertThat(wiremockInstance.getHost()).isNotNull(); - assertThat(wiremockInstance.getMetadata()).isEqualTo(Map.of("k8s_namespace", "default", "type", "ClusterIP", + assertThat(wiremockInstance.getMetadata()).isEqualTo(Map.of("k8s_namespace", "default", "type", "NodePort", "port.http", "8080", "app", "service-wiremock")); } From 8bfbfa7dbe52e6885d07a226da0b6bba36bb328f Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 30 Mar 2025 18:26:48 +0300 Subject: [PATCH 10/13] fix tests Signed-off-by: wind57 --- .../client/discovery/Fabric8DiscoveryFilterIT.java | 8 ++++---- .../tests/commons/fabric8_client/Util.java | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/discovery/Fabric8DiscoveryFilterIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/discovery/Fabric8DiscoveryFilterIT.java index dfbe1ad2..2bdf0a24 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/discovery/Fabric8DiscoveryFilterIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/discovery/Fabric8DiscoveryFilterIT.java @@ -51,16 +51,16 @@ class Fabric8DiscoveryFilterIT extends Fabric8DiscoveryBase { util.createNamespace(NAMESPACE_A_UAT); util.createNamespace(NAMESPACE_B_UAT); - util.wiremock(NAMESPACE_A_UAT, Phase.CREATE); - util.wiremock(NAMESPACE_B_UAT, Phase.CREATE); + util.wiremock(NAMESPACE_A_UAT, Phase.CREATE, false); + util.wiremock(NAMESPACE_B_UAT, Phase.CREATE, false); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE_A_UAT, Phase.DELETE); - util.wiremock(NAMESPACE_B_UAT, Phase.DELETE); + util.wiremock(NAMESPACE_A_UAT, Phase.DELETE, false); + util.wiremock(NAMESPACE_B_UAT, Phase.DELETE, false); util.deleteNamespace(NAMESPACE_A_UAT); util.deleteNamespace(NAMESPACE_B_UAT); diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java index e47f04c6..d8e0a81f 100644 --- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java +++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java @@ -295,7 +295,12 @@ public final class Util { }); } - public void wiremock(String namespace, Phase phase) { + /** + * 'withNodePort' specifies if we add the NodePort or not. It is needed because we + * sometimes deploy two instances of wiremock, and they can't have the same NodePort + * exposed + */ + public void wiremock(String namespace, Phase phase, boolean withNodePort) { InputStream deploymentStream = inputStream("wiremock/wiremock-deployment.yaml"); InputStream serviceStream = inputStream("wiremock/wiremock-service.yaml"); @@ -305,6 +310,11 @@ public final class Util { deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage(imageWithVersion); Service service = client.services().load(serviceStream).item(); + if (!withNodePort) { + // we assume we only have one 'http' port + service.getSpec().getPorts().get(0).setNodePort(null); + service.getSpec().setType("ClusterIP"); + } if (phase.equals(Phase.CREATE)) { deployment.getMetadata().setNamespace(namespace); From a0d2ab4ed9b52d1258ae77976a02e5d6ace0b961 Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 30 Mar 2025 19:14:46 +0300 Subject: [PATCH 11/13] fix tests Signed-off-by: wind57 --- .../configuration/watcher/ActuatorRefreshIT.java | 4 ++-- .../watcher/ActuatorRefreshMultipleNamespacesIT.java | 4 ++-- .../discoveryclient/it/DiscoveryServerClientIT.java | 8 ++++---- .../client/discovery/KubernetesClientBlockingIT.java | 4 ++-- .../discovery/KubernetesClientDiscoveryFilterIT.java | 8 ++++---- .../k8s/client/discovery/TestAssertions.java | 8 ++++---- .../tests/commons/native_client/Util.java | 12 +++++++++++- 7 files changed, 29 insertions(+), 19 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java index 000c9ba8..83c825dd 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshIT.java @@ -70,12 +70,12 @@ class ActuatorRefreshIT { @BeforeEach void setup() { - util.wiremock(NAMESPACE, Phase.CREATE); + util.wiremock(NAMESPACE, Phase.CREATE, true); } @AfterEach void after() { - util.wiremock(NAMESPACE, Phase.DELETE); + util.wiremock(NAMESPACE, Phase.DELETE, true); } /* diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java index 266aa3aa..54e602ee 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-configuration-watcher/src/test/java/org/springframework/cloud/kubernetes/configuration/watcher/ActuatorRefreshMultipleNamespacesIT.java @@ -60,7 +60,7 @@ class ActuatorRefreshMultipleNamespacesIT { util = new Util(K3S); util.createNamespace(LEFT_NAMESPACE); util.createNamespace(RIGHT_NAMESPACE); - util.wiremock(DEFAULT_NAMESPACE, Phase.CREATE); + util.wiremock(DEFAULT_NAMESPACE, Phase.CREATE, true); util.setUpClusterWide(DEFAULT_NAMESPACE, Set.of(DEFAULT_NAMESPACE, LEFT_NAMESPACE, RIGHT_NAMESPACE)); configWatcher(Phase.CREATE); } @@ -68,7 +68,7 @@ class ActuatorRefreshMultipleNamespacesIT { @AfterAll static void afterAll() { configWatcher(Phase.DELETE); - util.wiremock(DEFAULT_NAMESPACE, Phase.DELETE); + util.wiremock(DEFAULT_NAMESPACE, Phase.DELETE, true); util.deleteClusterWide(DEFAULT_NAMESPACE, Set.of(DEFAULT_NAMESPACE, LEFT_NAMESPACE, RIGHT_NAMESPACE)); util.deleteNamespace(LEFT_NAMESPACE); util.deleteNamespace(RIGHT_NAMESPACE); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java index 42818b30..3dd8cab7 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery-server/src/test/java/org/springframework/cloud/kubernetes/discoveryclient/it/DiscoveryServerClientIT.java @@ -78,8 +78,8 @@ class DiscoveryServerClientIT extends DiscoveryServerClientBase { discoveryServer(Phase.CREATE); Images.loadWiremock(K3S); - util.wiremock(NAMESPACE_LEFT, Phase.CREATE); - util.wiremock(NAMESPACE_RIGHT, Phase.CREATE); + util.wiremock(NAMESPACE_LEFT, Phase.CREATE, false); + util.wiremock(NAMESPACE_RIGHT, Phase.CREATE, false); } @AfterAll @@ -87,8 +87,8 @@ class DiscoveryServerClientIT extends DiscoveryServerClientBase { serviceAccount(Phase.DELETE); discoveryServer(Phase.DELETE); - util.wiremock(NAMESPACE_LEFT, Phase.DELETE); - util.wiremock(NAMESPACE_RIGHT, Phase.DELETE); + util.wiremock(NAMESPACE_LEFT, Phase.DELETE, false); + util.wiremock(NAMESPACE_RIGHT, Phase.DELETE, false); util.deleteNamespace(NAMESPACE_LEFT); util.deleteNamespace(NAMESPACE_RIGHT); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java index 6d75d346..2ca22a60 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientBlockingIT.java @@ -60,12 +60,12 @@ class KubernetesClientBlockingIT extends KubernetesClientDiscoveryBase { @BeforeEach void beforeEach() { Images.loadWiremock(K3S); - util.wiremock(NAMESPACE, Phase.CREATE); + util.wiremock(NAMESPACE, Phase.CREATE, true); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE, Phase.DELETE); + util.wiremock(NAMESPACE, Phase.DELETE, true); } /** diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java index 2cfb3a40..31e61c80 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoveryFilterIT.java @@ -63,14 +63,14 @@ class KubernetesClientDiscoveryFilterIT extends KubernetesClientDiscoveryBase { util.createNamespace(NAMESPACE_B_UAT); Images.loadWiremock(K3S); - util.wiremock(NAMESPACE_A_UAT, Phase.CREATE); - util.wiremock(NAMESPACE_B_UAT, Phase.CREATE); + util.wiremock(NAMESPACE_A_UAT, Phase.CREATE, false); + util.wiremock(NAMESPACE_B_UAT, Phase.CREATE, false); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE_A_UAT, Phase.DELETE); - util.wiremock(NAMESPACE_B_UAT, Phase.DELETE); + util.wiremock(NAMESPACE_A_UAT, Phase.DELETE, false); + util.wiremock(NAMESPACE_B_UAT, Phase.DELETE, false); util.deleteNamespace(NAMESPACE_A_UAT); util.deleteNamespace(NAMESPACE_B_UAT); diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java index f00bf32a..14c71111 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/TestAssertions.java @@ -133,8 +133,8 @@ final class TestAssertions { assertThat(wiremockInstance.getServiceId()).isEqualTo("service-wiremock"); assertThat(wiremockInstance.getInstanceId()).isNotNull(); assertThat(wiremockInstance.getHost()).isNotNull(); - assertThat(wiremockInstance.getMetadata()).isEqualTo(Map.of("k8s_namespace", "default", "type", "NodePort", - "port.http", "8080", "app", "service-wiremock")); + assertThat(wiremockInstance.getMetadata()).isEqualTo( + Map.of("k8s_namespace", "default", "type", "NodePort", "port.http", "8080", "app", "service-wiremock")); } @@ -147,8 +147,8 @@ final class TestAssertions { assertThat(wiremockInstance.getServiceId()).isEqualTo("service-wiremock"); assertThat(wiremockInstance.getInstanceId()).isNotNull(); assertThat(wiremockInstance.getHost()).isNotNull(); - assertThat(wiremockInstance.getMetadata()).isEqualTo(Map.of("k8s_namespace", "default", "type", "NodePort", - "port.http", "8080", "app", "service-wiremock")); + assertThat(wiremockInstance.getMetadata()).isEqualTo( + Map.of("k8s_namespace", "default", "type", "NodePort", "port.http", "8080", "app", "service-wiremock")); } diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java index 86c8b24f..92619aaf 100644 --- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java +++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/native_client/Util.java @@ -208,6 +208,10 @@ public final class Util { labelSelector(podLabels), null, null, null, null, null, null, null, null); waitForDeploymentToBeDeleted(deploymentName, namespace); waitForDeploymentPodsToBeDeleted(podLabels, namespace); + + service.getMetadata().setNamespace(namespace); + coreV1Api.deleteNamespacedService(service.getMetadata().getName(), service.getMetadata().getNamespace(), + null, null, null, null, null, null); } catch (Exception e) { throw new RuntimeException(e); @@ -409,7 +413,7 @@ public final class Util { .noneMatch(x -> x.getMetadata().getName().equals(name))); } - public void wiremock(String namespace, Phase phase) { + public void wiremock(String namespace, Phase phase, boolean withNodePort) { V1Deployment deployment = (V1Deployment) yaml("wiremock/wiremock-deployment.yaml"); String imageWithoutVersion = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage(); @@ -417,6 +421,12 @@ public final class Util { deployment.getSpec().getTemplate().getSpec().getContainers().get(0).setImage(imageWithVersion); V1Service service = (V1Service) yaml("wiremock/wiremock-service.yaml"); + service.getMetadata().setNamespace(namespace); + if (!withNodePort) { + // we assume we only have one 'http' port + service.getSpec().getPorts().get(0).setNodePort(null); + service.getSpec().setType("ClusterIP"); + } if (phase.equals(Phase.CREATE)) { deployment.getMetadata().setNamespace(namespace); From c9df5b4ddd4c7fe1adc2ca27e755cb5ad15df8dd Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 30 Mar 2025 19:18:36 +0300 Subject: [PATCH 12/13] fix tests Signed-off-by: wind57 --- .../k8s/client/discovery/KubernetesClientReactiveIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java index c24af79b..7fe1a897 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientReactiveIT.java @@ -60,12 +60,12 @@ class KubernetesClientReactiveIT extends KubernetesClientDiscoveryBase { @BeforeEach void beforeEach() { Images.loadWiremock(K3S); - util.wiremock(NAMESPACE, Phase.CREATE); + util.wiremock(NAMESPACE, Phase.CREATE, true); } @AfterEach void afterEach() { - util.wiremock(NAMESPACE, Phase.DELETE); + util.wiremock(NAMESPACE, Phase.DELETE, true); } /** From bb3b7cd3402a88294d5a7882c6e84040f0a71d4d Mon Sep 17 00:00:00 2001 From: wind57 Date: Sun, 30 Mar 2025 22:19:45 +0300 Subject: [PATCH 13/13] fix tests Signed-off-by: wind57 --- .../src/test/resources/app/app-service.yaml | 3 ++- .../src/test/resources/config-watcher/watcher-service.yaml | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/app/app-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/app/app-service.yaml index 292541f7..0f5318b7 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/app/app-service.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/app/app-service.yaml @@ -9,6 +9,7 @@ spec: - name: http port: 8080 targetPort: 8080 + nodePort: 32321 selector: app: app - type: ClusterIP + type: NodePort diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml index 8428eede..3ab3a8ec 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-rabbitmq-secret-reload/rabbitmq-secret-test-app/src/test/resources/config-watcher/watcher-service.yaml @@ -9,7 +9,6 @@ spec: - name: http port: 8888 targetPort: 8888 - nodePort: 32321 selector: app: configuration-watcher - type: NodePort + type: ClusterIP