From 9b2926b7d19605cdd59fe28594ae2694b8713a67 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 6 Jan 2023 14:18:28 +0100 Subject: [PATCH] fix: always apply the CRDs at runtime The rationale for this is that there's really no point in applying the CRDs at build time to a cluster that might not be the one where the code will run. Moreover, this also meant that CRDs would be applied twice. This reverts the behavior introduced by #260. --- .../deployment/OperatorSDKProcessor.java | 9 ------- .../operatorsdk/runtime/OperatorProducer.java | 19 +++++--------- .../src/main/resources/application.properties | 3 ++- .../joke/JokeRequestReconcilerTest.java | 26 +++++++++---------- 4 files changed, 20 insertions(+), 37 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/OperatorSDKProcessor.java b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/OperatorSDKProcessor.java index 9e9cb7cd5..456789eae 100644 --- a/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/OperatorSDKProcessor.java +++ b/core/deployment/src/main/java/io/quarkiverse/operatorsdk/deployment/OperatorSDKProcessor.java @@ -1,7 +1,5 @@ package io.quarkiverse.operatorsdk.deployment; -import static io.quarkiverse.operatorsdk.runtime.CRDUtils.applyCRD; - import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashMap; @@ -236,13 +234,6 @@ ConfigurationServiceBuildItem createConfigurationServiceAndOperator( .build()); } - // apply CRD if enabled - if (crdGeneration.shouldApply()) { - for (String generatedCrdName : crdInfo.getGenerated()) { - applyCRD(kubernetesClientBuildItem.getClient(), crdInfo, generatedCrdName); - } - } - // register classes for reflection registerAssociatedClassesForReflection(reflectionClasses, forcedReflectionClasses, registerForReflection); diff --git a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/OperatorProducer.java b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/OperatorProducer.java index 031e5670a..ee38c6d57 100644 --- a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/OperatorProducer.java +++ b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/OperatorProducer.java @@ -10,7 +10,6 @@ import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.javaoperatorsdk.operator.MissingCRDException; import io.javaoperatorsdk.operator.Operator; import io.javaoperatorsdk.operator.api.config.ConfigurationServiceProvider; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; @@ -52,20 +51,14 @@ Operator operator(QuarkusConfigurationService configuration, Instance reconciler, QuarkusConfigurationService configuration) { - final var config = configuration.getConfigurationFor(reconciler); final var crdInfo = configuration.getCRDGenerationInfo(); - final var crdName = config.getResourceTypeName(); - // if the CRD just got generated, apply it - if (crdInfo.shouldApplyCRD(crdName)) { - applyCRD(operator.getKubernetesClient(), crdInfo, crdName); - } - // try to register the reconciler, if we get a MissingCRDException, apply the CRD and re-attempt registration - try { - operator.register(reconciler); - } catch (MissingCRDException e) { - applyCRD(operator.getKubernetesClient(), crdInfo, crdName); - operator.register(reconciler); + // if some CRDs just got generated and need to be applied, apply them + if (crdInfo.isApplyCRDs()) { + for (String generatedCrdName : crdInfo.getGenerated()) { + applyCRD(configuration.getClient(), crdInfo, generatedCrdName); + } } + operator.register(reconciler); } } diff --git a/samples/joke/src/main/resources/application.properties b/samples/joke/src/main/resources/application.properties index d00f8a5fb..4e516ed4a 100644 --- a/samples/joke/src/main/resources/application.properties +++ b/samples/joke/src/main/resources/application.properties @@ -3,4 +3,5 @@ quarkus.operator-sdk.crd.apply=true quarkus.container-image.builder=jib quarkus.operator-sdk.bundle.channels=alpha quarkus.operator-sdk.bundle.package-name=joke-operator -quarkus.operator-sdk.crd.generate-all=true \ No newline at end of file +quarkus.operator-sdk.crd.generate-all=true +quarkus.kubernetes-client.devservices.override-kubeconfig=true \ No newline at end of file diff --git a/samples/joke/src/test/java/io/quarkiverse/operatorsdk/samples/joke/JokeRequestReconcilerTest.java b/samples/joke/src/test/java/io/quarkiverse/operatorsdk/samples/joke/JokeRequestReconcilerTest.java index b2345e262..d6624a2bb 100644 --- a/samples/joke/src/test/java/io/quarkiverse/operatorsdk/samples/joke/JokeRequestReconcilerTest.java +++ b/samples/joke/src/test/java/io/quarkiverse/operatorsdk/samples/joke/JokeRequestReconcilerTest.java @@ -1,6 +1,6 @@ package io.quarkiverse.operatorsdk.samples.joke; -import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.awaitility.Awaitility.await; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; @@ -21,16 +21,13 @@ import org.mockito.Mockito; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; -import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.Operator; import io.quarkiverse.operatorsdk.samples.joke.JokeRequestSpec.Category; import io.quarkiverse.operatorsdk.samples.joke.JokeRequestStatus.State; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.mockito.InjectMock; -import io.quarkus.test.kubernetes.client.KubernetesTestServer; -import io.quarkus.test.kubernetes.client.WithKubernetesTestServer; -@WithKubernetesTestServer @QuarkusTest class JokeRequestReconcilerTest { @@ -38,8 +35,8 @@ class JokeRequestReconcilerTest { @RestClient JokeService jokeService; - @KubernetesTestServer - KubernetesServer mockServer; + @Inject + KubernetesClient client; @Inject Operator operator; @@ -59,24 +56,25 @@ void canReconcile() { final JokeRequest testRequest = new JokeRequest(); testRequest.setMetadata(new ObjectMetaBuilder() .withName("myjoke1") - .withNamespace(mockServer.getClient().getNamespace()) + .withNamespace(client.getNamespace()) .build()); testRequest.setSpec(new JokeRequestSpec()); testRequest.getSpec().setCategory(Category.Any); // act - mockServer.getClient().resources(JokeRequest.class).resource(testRequest).create(); - + client.resource(testRequest).create(); + // assert - await().ignoreException(NullPointerException.class).atMost(5, MINUTES).untilAsserted(() -> { - JokeRequest updatedRequest = mockServer.getClient().resources(JokeRequest.class) + await().ignoreException(NullPointerException.class).atMost(60, SECONDS).untilAsserted(() -> { + JokeRequest updatedRequest = client.resources(JokeRequest.class) .inNamespace(testRequest.getMetadata().getNamespace()) - .withName(testRequest.getMetadata().getName()).get(); + .withName(testRequest.getMetadata().getName()) + .get(); assertThat(updatedRequest.getStatus(), is(notNullValue())); assertThat(updatedRequest.getStatus().getState(), equalTo(State.CREATED)); }); - var createdJokes = mockServer.getClient().resources(Joke.class).inNamespace(testRequest.getMetadata().getNamespace()) + var createdJokes = client.resources(Joke.class).inNamespace(testRequest.getMetadata().getNamespace()) .list(); assertThat(createdJokes.getItems(), is(not(empty())));