From c9c4946859909bebf42d2fb8bfcdb8433017d230 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 24 Feb 2023 15:13:21 +0200 Subject: [PATCH] Add the ability to customize k8s client config This gives users the ability to alter the configuration provided by Quarkus in arbitrary ways The pattern implemented is exactly the same as the one used in other extensions Relates to: #31395 --- docs/src/main/asciidoc/kubernetes-client.adoc | 11 +++-- .../kubernetes-client/deployment/pom.xml | 5 +++ .../deployment/KubernetesClientCDITest.java | 40 +++++++++++++++++++ .../client/KubernetesConfigCustomizer.java | 25 ++++++++++++ .../runtime/KubernetesConfigProducer.java | 14 ++++++- 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 extensions/kubernetes-client/deployment/src/test/java/io/quarkus/kubernetes/client/deployment/KubernetesClientCDITest.java create mode 100644 extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/KubernetesConfigCustomizer.java diff --git a/docs/src/main/asciidoc/kubernetes-client.adoc b/docs/src/main/asciidoc/kubernetes-client.adoc index 15aab18ee1f0b..afd2d0653debe 100644 --- a/docs/src/main/asciidoc/kubernetes-client.adoc +++ b/docs/src/main/asciidoc/kubernetes-client.adoc @@ -57,10 +57,15 @@ Note that the full list of properties is available in the link:#quarkus-kubernet In dev mode and when running tests, xref:kubernetes-dev-services.adoc[Dev Services for Kubernetes] automatically starts a Kubernetes API server. -=== Overriding +=== Customizing and overriding -The extension also allows application code to override either of `io.fabric8.kubernetes.client.Config` or `io.fabric8.kubernetes.client.KubernetesClient` which are -normally provided by the extension by simply declaring custom versions of those beans. +Quarkus provides multiple integration points for influencing the Kubernetes Client provided as a CDI bean. + +The first integration point is the use of the `io.quarkus.kubernetes.client.KubernetesConfigCustomizer` interface. When such a bean exists, +it allows for arbitrary customizations of the `io.fabric8.kubernetes.client.Config` created by Quarkus (which takes into account the `quarkus.kubernetes-client.*` properties). + +Alternatively, application code can override the `io.fabric8.kubernetes.client.Config` or even the `io.fabric8.kubernetes.client.KubernetesClient` bean (which are +normally provided by the extension) by simply declaring custom versions of those beans. An example of this can be seen in the following snippet: diff --git a/extensions/kubernetes-client/deployment/pom.xml b/extensions/kubernetes-client/deployment/pom.xml index bd989bda54851..0f4acad427f0b 100644 --- a/extensions/kubernetes-client/deployment/pom.xml +++ b/extensions/kubernetes-client/deployment/pom.xml @@ -29,6 +29,11 @@ io.quarkus quarkus-vertx-deployment + + io.quarkus + quarkus-junit5-internal + test + diff --git a/extensions/kubernetes-client/deployment/src/test/java/io/quarkus/kubernetes/client/deployment/KubernetesClientCDITest.java b/extensions/kubernetes-client/deployment/src/test/java/io/quarkus/kubernetes/client/deployment/KubernetesClientCDITest.java new file mode 100644 index 0000000000000..d9202ab71d5ba --- /dev/null +++ b/extensions/kubernetes-client/deployment/src/test/java/io/quarkus/kubernetes/client/deployment/KubernetesClientCDITest.java @@ -0,0 +1,40 @@ +package io.quarkus.kubernetes.client.deployment; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import jakarta.inject.Inject; +import jakarta.inject.Singleton; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.quarkus.kubernetes.client.KubernetesConfigCustomizer; +import io.quarkus.test.QuarkusUnitTest; + +public class KubernetesClientCDITest { + + @Inject + KubernetesClient client; + + @Test + public void test() { + assertEquals("-1", client.getConfiguration().getApiVersion()); + } + + @RegisterExtension + static QuarkusUnitTest runner = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(Customizer.class)) + .overrideConfigKey("quarkus.kubernetes-client.devservices.enabled", "false"); + + @Singleton + public static class Customizer implements KubernetesConfigCustomizer { + @Override + public void customize(Config config) { + config.setApiVersion("-1"); + } + } + +} diff --git a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/KubernetesConfigCustomizer.java b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/KubernetesConfigCustomizer.java new file mode 100644 index 0000000000000..1ff0a573bfe7c --- /dev/null +++ b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/KubernetesConfigCustomizer.java @@ -0,0 +1,25 @@ +package io.quarkus.kubernetes.client; + +import java.util.List; + +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.quarkus.kubernetes.client.runtime.KubernetesClientBuildConfig; +import io.quarkus.kubernetes.client.runtime.KubernetesClientProducer; +import io.quarkus.kubernetes.client.runtime.KubernetesConfigProducer; +import io.quarkus.runtime.TlsConfig; + +/** + * Meant to be implemented by a CDI bean that provided arbitrary customization for the default {@link Config} created by + * Quarkus. + *

+ * The {@link Config} is in turn used to produce the default {@link KubernetesClient} + *

+ * + * @see KubernetesConfigProducer#config(KubernetesClientBuildConfig, TlsConfig, List) } + * @see KubernetesClientProducer#kubernetesClient(Config) } + */ +public interface KubernetesConfigCustomizer { + + void customize(Config config); +} diff --git a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigProducer.java b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigProducer.java index 8c9bf33a70da1..468f092ea28a1 100644 --- a/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigProducer.java +++ b/extensions/kubernetes-client/runtime/src/main/java/io/quarkus/kubernetes/client/runtime/KubernetesConfigProducer.java @@ -1,10 +1,14 @@ package io.quarkus.kubernetes.client.runtime; +import java.util.List; + import jakarta.enterprise.inject.Produces; import jakarta.inject.Singleton; import io.fabric8.kubernetes.client.Config; +import io.quarkus.arc.All; import io.quarkus.arc.DefaultBean; +import io.quarkus.kubernetes.client.KubernetesConfigCustomizer; import io.quarkus.runtime.TlsConfig; @Singleton @@ -13,7 +17,13 @@ public class KubernetesConfigProducer { @DefaultBean @Singleton @Produces - public Config config(KubernetesClientBuildConfig buildConfig, TlsConfig tlsConfig) { - return KubernetesClientUtils.createConfig(buildConfig, tlsConfig); + public Config config(KubernetesClientBuildConfig buildConfig, + TlsConfig tlsConfig, + @All List customizers) { + var result = KubernetesClientUtils.createConfig(buildConfig, tlsConfig); + for (KubernetesConfigCustomizer customizer : customizers) { + customizer.customize(result); + } + return result; } }