diff --git a/README.md b/README.md index 6ff73ad..e68bd2e 100644 --- a/README.md +++ b/README.md @@ -128,20 +128,3 @@ In general, it is a best practice to use additional standard frameworks to imple like [kubernetes-webooks-framework](https://github.com/java-operator-sdk/kubernetes-webooks-framework) with Quarkus or Spring. However, we demonstrate how it works in [this test](https://github.com/java-operator-sdk/jenvtest/blob/main/samples/src/test/java/io/javaoperatorsdk/jenvtest/KubernetesMutationHookHandlingTest.java#L53-L53) - -### How does it work - -In the background Kubernetes and etcd (and kubectl) binaries are downloaded if not found locally. - -All the certificates for the Kube API Server and for the client is generated. The client config file -(`~/kube/config`) file is updated, to any client can be used to talk to the API Server. - -#### Downloading binaries - -Binaries are downloaded automatically under ~/.jenvtest/k8s/[target-platform-and-version] if no binary found locally. -If there are multiple binaries found, the latest if selected (unless a target version is not specified). - -Also [`setup-envtest`](https://pkg.go.dev/sigs.k8s.io/controller-runtime/tools/setup-envtest#section-readme) can be used -to download binaries manually. By executing `setup-envtest use --bin-dir ~/.jenvtest` will download the latest required -binaries to the default directory. This is useful if always running the tests in offline mode. - diff --git a/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfig.java b/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfig.java index 24b9a86..783cf99 100644 --- a/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfig.java +++ b/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfig.java @@ -33,6 +33,9 @@ public class KubeAPIServerConfig { */ private final List apiServerFlags; + /** + * If kube config (in ~/kube/config ) file should be updated. + */ private final boolean updateKubeConfig; KubeAPIServerConfig(String jenvtestDir, String apiServerVersion, boolean offlineMode, diff --git a/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfigBuilder.java b/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfigBuilder.java index bc877b0..dbeb120 100644 --- a/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfigBuilder.java +++ b/core/src/main/java/io/javaoperatorsdk/jenvtest/KubeAPIServerConfigBuilder.java @@ -15,7 +15,7 @@ public final class KubeAPIServerConfigBuilder { private String jenvtestDir; private String apiServerVersion; private Boolean offlineMode; - private boolean updateKubeConfig = true; + private boolean updateKubeConfig = false; private final List apiServerFlags = new ArrayList<>(0); public KubeAPIServerConfigBuilder() {} diff --git a/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/EnableKubeAPIServer.java b/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/EnableKubeAPIServer.java index d430b87..c0fac79 100644 --- a/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/EnableKubeAPIServer.java +++ b/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/EnableKubeAPIServer.java @@ -23,4 +23,6 @@ String kubeAPIVersion() default NOT_SET; String[] apiServerFlags() default {}; + + boolean updateKubeConfigFile() default false; } diff --git a/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/KubeAPIServerExtension.java b/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/KubeAPIServerExtension.java index fbfa967..e48f973 100644 --- a/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/KubeAPIServerExtension.java +++ b/core/src/main/java/io/javaoperatorsdk/jenvtest/junit/KubeAPIServerExtension.java @@ -58,21 +58,30 @@ private void initialize(ExtensionContext extensionContext, boolean staticContext .filter(h -> h.isTargetFieldAvailable(extensionContext, staticContext)) .collect(Collectors.toList()); - startIfAnnotationPresent(extensionContext, targetInjectors.isEmpty()); + startIfAnnotationPresent(extensionContext, !targetInjectors.isEmpty()); targetInjectors.forEach(i -> i.inject(extensionContext, staticContext, kubeApiServer)); } private void startIfAnnotationPresent(ExtensionContext extensionContext, - boolean updateKubeConfig) { + boolean willInjectClient) { extensionContext.getElement().ifPresent(ae -> { var annotation = getExtensionAnnotationInstance(ae); - annotation.ifPresent(a -> startApiServer(a, updateKubeConfig)); + + annotation.ifPresent(a -> { + if (!willInjectClient && !a.updateKubeConfigFile()) { + log.warn( + "Neither kube config file will be updated or client info will be injected into the test. " + + + "This is probably a miss configuration since server won't be easily accessible."); + } + startApiServer(a); + }); }); } - private void startApiServer(EnableKubeAPIServer annotation, boolean updateKubeConfig) { - kubeApiServer = new KubeAPIServer(annotationToConfig(annotation, updateKubeConfig)); + private void startApiServer(EnableKubeAPIServer annotation) { + kubeApiServer = new KubeAPIServer(annotationToConfig(annotation)); kubeApiServer.start(); } @@ -84,8 +93,7 @@ private void stopIfAnnotationPresent(ExtensionContext extensionContext) { }); } - private KubeAPIServerConfig annotationToConfig(EnableKubeAPIServer annotation, - boolean updateKubeConfig) { + private KubeAPIServerConfig annotationToConfig(EnableKubeAPIServer annotation) { var builder = KubeAPIServerConfigBuilder.anAPIServerConfig(); var version = annotation.kubeAPIVersion(); if (!NOT_SET.equals(version)) { @@ -94,7 +102,8 @@ private KubeAPIServerConfig annotationToConfig(EnableKubeAPIServer annotation, if (annotation.apiServerFlags().length > 0) { builder.withApiServerFlags(List.of(annotation.apiServerFlags())); } - builder.withUpdateKubeConfig(updateKubeConfig); + + builder.withUpdateKubeConfig(annotation.updateKubeConfigFile()); return builder.build(); } diff --git a/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/JUnitExtensionKubeConfigUpdateTest.java b/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/JUnitExtensionKubeConfigUpdateTest.java index f1a5089..a482d40 100644 --- a/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/JUnitExtensionKubeConfigUpdateTest.java +++ b/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/JUnitExtensionKubeConfigUpdateTest.java @@ -6,7 +6,7 @@ import static io.javaoperatorsdk.jenvtest.sample.TestUtils.simpleTest; -@EnableKubeAPIServer +@EnableKubeAPIServer(updateKubeConfigFile = true) class JUnitExtensionKubeConfigUpdateTest { @Test diff --git a/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/KubeApiServerTest.java b/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/KubeApiServerTest.java index a2e0039..3e99c50 100644 --- a/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/KubeApiServerTest.java +++ b/core/src/test/java/io/javaoperatorsdk/jenvtest/sample/KubeApiServerTest.java @@ -3,6 +3,7 @@ import org.junit.jupiter.api.Test; import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; import io.javaoperatorsdk.jenvtest.KubeAPIServer; import io.javaoperatorsdk.jenvtest.KubeAPIServerConfigBuilder; @@ -25,6 +26,19 @@ void apiServerWithSpecificVersion() { .build())); } + @Test + void usingKubeConfigFileToInitClient() { + var kubeApi = new KubeAPIServer(KubeAPIServerConfigBuilder.anAPIServerConfig() + .withUpdateKubeConfig(true) + .build()); + kubeApi.start(); + + var client = new KubernetesClientBuilder().build(); + + TestUtils.simpleTest(client); + } + + @Test void usingWildcardVersion() { var kubeApi = new KubeAPIServer(KubeAPIServerConfigBuilder.anAPIServerConfig() @@ -32,7 +46,7 @@ void usingWildcardVersion() { .build()); kubeApi.start(); - var client = new KubernetesClientBuilder().build(); + var client = createClient(kubeApi.getKubeConfigYaml()); TestUtils.simpleTest(client); assertThat(client.getKubernetesVersion().getMinor()).isEqualTo("26"); @@ -46,9 +60,7 @@ void creatingClientFromConfigString() { .build()); kubeApi.start(); - var client = - new KubernetesClientBuilder().withConfig(Config.fromKubeconfig(kubeApi.getKubeConfigYaml())) - .build(); + var client = createClient(kubeApi.getKubeConfigYaml()); TestUtils.simpleTest(client); kubeApi.stop(); @@ -56,7 +68,13 @@ void creatingClientFromConfigString() { void testWithAPIServer(KubeAPIServer kubeApi) { kubeApi.start(); - simpleTest(); + var client = createClient(kubeApi.getKubeConfigYaml()); + simpleTest(client); kubeApi.stop(); } + + KubernetesClient createClient(String yaml) { + return new KubernetesClientBuilder().withConfig(Config.fromKubeconfig(yaml)).build(); + } + } diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..1a5a5e0 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,23 @@ + + +## Configuration Options + + + + + +## How does it work + +In the background Kubernetes and etcd (and kubectl) binaries are downloaded if not found locally. + +All the certificates for the Kube API Server and for the client is generated. The client config file +(`~/kube/config`) file is updated, to any client can be used to talk to the API Server. + +## Downloading binaries + +Binaries are downloaded automatically under ~/.jenvtest/k8s/[target-platform-and-version] if no binary found locally. +If there are multiple binaries found, the latest if selected (unless a target version is not specified). + +Also [`setup-envtest`](https://pkg.go.dev/sigs.k8s.io/controller-runtime/tools/setup-envtest#section-readme) can be used +to download binaries manually. By executing `setup-envtest use --bin-dir ~/.jenvtest` will download the latest required +binaries to the default directory. This is useful if always running the tests in offline mode. \ No newline at end of file