diff --git a/sample-operators/leader-election/README.md b/sample-operators/leader-election/README.md index 2a9a369a45..d74bad0b35 100644 --- a/sample-operators/leader-election/README.md +++ b/sample-operators/leader-election/README.md @@ -1,6 +1,10 @@ # Leader Election E2E Test -The purpose of this module is to e2e test leader election feature. +The purpose of this module is to e2e test leader election feature and to demonstrate contract-first CRDs. The deployment is using directly pods in order to better control some aspects in test. -In real life this would be a Deployment. \ No newline at end of file +In real life this would be a Deployment. + +The custom resource definition (CRD) is defined in YAML in the folder `src/main/resources/kubernetes`. +Upon build, the [java-generator-maven-plugin](https://github.com/fabric8io/kubernetes-client/blob/master/doc/java-generation-from-CRD.md) +generates the Java code under `target/generated-sources/java`. diff --git a/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml b/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml index 68e00d81ad..13724a911a 100644 --- a/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml +++ b/sample-operators/leader-election/k8s/namespace-inferred-operator.yaml @@ -48,8 +48,8 @@ rules: - apiGroups: - "sample.javaoperatorsdk" resources: - - leaderelectiontestcustomresources - - leaderelectiontestcustomresources/status + - leaderelections + - leaderelections/status verbs: - '*' - apiGroups: diff --git a/sample-operators/leader-election/k8s/operator.yaml b/sample-operators/leader-election/k8s/operator.yaml index 00ed3e7273..9d289a2d6c 100644 --- a/sample-operators/leader-election/k8s/operator.yaml +++ b/sample-operators/leader-election/k8s/operator.yaml @@ -52,8 +52,8 @@ rules: - apiGroups: - "sample.javaoperatorsdk" resources: - - leaderelectiontestcustomresources - - leaderelectiontestcustomresources/status + - leaderelections + - leaderelections/status verbs: - '*' - apiGroups: diff --git a/sample-operators/leader-election/pom.xml b/sample-operators/leader-election/pom.xml index 87b346a818..bb417df67e 100644 --- a/sample-operators/leader-election/pom.xml +++ b/sample-operators/leader-election/pom.xml @@ -47,11 +47,6 @@ takes 1.21.1 - - io.fabric8 - crd-generator-apt - provided - org.awaitility awaitility @@ -88,6 +83,22 @@ maven-compiler-plugin 3.10.0 + + + io.fabric8 + java-generator-maven-plugin + ${fabric8-client.version} + + + + generate + + + + + src/main/resources/kubernetes + + diff --git a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestCustomResource.java b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestCustomResource.java deleted file mode 100644 index b440be4d18..0000000000 --- a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestCustomResource.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.javaoperatorsdk.operator.sample; - -import io.fabric8.kubernetes.api.model.Namespaced; -import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.model.annotation.Group; -import io.fabric8.kubernetes.model.annotation.ShortNames; -import io.fabric8.kubernetes.model.annotation.Version; - -@Group("sample.javaoperatorsdk") -@Version("v1") -@ShortNames("le") -public class LeaderElectionTestCustomResource - extends CustomResource - implements Namespaced { -} diff --git a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java index f6231d0a52..4cd8627328 100644 --- a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java +++ b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestReconciler.java @@ -1,15 +1,19 @@ package io.javaoperatorsdk.operator.sample; import java.time.Duration; +import java.util.ArrayList; import io.javaoperatorsdk.operator.api.reconciler.Context; import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; import io.javaoperatorsdk.operator.api.reconciler.Reconciler; import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import javaoperatorsdk.sample.v1.LeaderElection; +import javaoperatorsdk.sample.v1.LeaderElectionStatus; + @ControllerConfiguration() public class LeaderElectionTestReconciler - implements Reconciler { + implements Reconciler { private final String reconcilerName; @@ -18,12 +22,15 @@ public LeaderElectionTestReconciler(String reconcilerName) { } @Override - public UpdateControl reconcile( - LeaderElectionTestCustomResource resource, - Context context) { + public UpdateControl reconcile( + LeaderElection resource, + Context context) { if (resource.getStatus() == null) { - resource.setStatus(new LeaderElectionTestStatus()); + resource.setStatus(new LeaderElectionStatus()); + } + if (resource.getStatus().getReconciledBy() == null) { + resource.getStatus().setReconciledBy(new ArrayList<>()); } resource.getStatus().getReconciledBy().add(reconcilerName); diff --git a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestStatus.java b/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestStatus.java deleted file mode 100644 index 5a9e66e270..0000000000 --- a/sample-operators/leader-election/src/main/java/io/javaoperatorsdk/operator/sample/LeaderElectionTestStatus.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.javaoperatorsdk.operator.sample; - -import java.util.ArrayList; -import java.util.List; - -public class LeaderElectionTestStatus { - - private List reconciledBy; - - public List getReconciledBy() { - if (reconciledBy == null) { - reconciledBy = new ArrayList<>(); - } - return reconciledBy; - } - - public LeaderElectionTestStatus setReconciledBy(List reconciledBy) { - this.reconciledBy = reconciledBy; - return this; - } -} diff --git a/sample-operators/leader-election/src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml b/sample-operators/leader-election/src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml new file mode 100644 index 0000000000..cc9d8c3fc6 --- /dev/null +++ b/sample-operators/leader-election/src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml @@ -0,0 +1,34 @@ +# Custom Resource Definition that will be used to generate the Java classes in target/generated-sources/java +# See https://github.com/fabric8io/kubernetes-client/blob/master/doc/java-generation-from-CRD.md +# The Java classes will then be used to recreate this CR in target/classes/META-INF/fabric8 +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: leaderelections.sample.javaoperatorsdk +spec: + group: sample.javaoperatorsdk + names: + kind: LeaderElection + singular: leaderelection + plural: leaderelections + shortNames: + - le + - les + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + status: + properties: + reconciledBy: + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java b/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java index 9b4eb736db..5512f54fc1 100644 --- a/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java +++ b/sample-operators/leader-election/src/test/java/io/javaoperatorsdk/operator/sample/LeaderElectionE2E.java @@ -27,6 +27,8 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientBuilder; +import javaoperatorsdk.sample.v1.LeaderElection; + import static io.javaoperatorsdk.operator.junit.AbstractOperatorExtension.CRD_READY_WAIT; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -61,7 +63,7 @@ void otherInstancesTakesOverWhenSteppingDown(String yamlFilePrefix) { await().pollDelay(Duration.ofSeconds(MINIMAL_SECONDS_FOR_RENEWAL)) .atMost(Duration.ofSeconds(MAX_WAIT_SECONDS)) .untilAsserted(() -> { - var actualStatus = client.resources(LeaderElectionTestCustomResource.class) + var actualStatus = client.resources(LeaderElection.class) .inNamespace(namespace).withName(TEST_RESOURCE_NAME).get().getStatus(); assertThat(actualStatus).isNotNull(); @@ -71,14 +73,14 @@ void otherInstancesTakesOverWhenSteppingDown(String yamlFilePrefix) { client.pods().inNamespace(namespace).withName(OPERATOR_1_POD_NAME).delete(); - var actualListSize = client.resources(LeaderElectionTestCustomResource.class) + var actualListSize = client.resources(LeaderElection.class) .inNamespace(namespace).withName(TEST_RESOURCE_NAME).get().getStatus().getReconciledBy() .size(); await().pollDelay(Duration.ofSeconds(MINIMAL_SECONDS_FOR_RENEWAL)) .atMost(Duration.ofSeconds(240)) .untilAsserted(() -> { - var actualStatus = client.resources(LeaderElectionTestCustomResource.class) + var actualStatus = client.resources(LeaderElection.class) .inNamespace(namespace).withName(TEST_RESOURCE_NAME).get().getStatus(); assertThat(actualStatus).isNotNull(); @@ -87,7 +89,7 @@ void otherInstancesTakesOverWhenSteppingDown(String yamlFilePrefix) { }); assertReconciliations( - client.resources(LeaderElectionTestCustomResource.class).inNamespace(namespace) + client.resources(LeaderElection.class).inNamespace(namespace) .withName(TEST_RESOURCE_NAME).get().getStatus().getReconciledBy()); } @@ -104,7 +106,7 @@ private void assertReconciliations(List reconciledBy) { } private void applyCustomResource() { - var res = new LeaderElectionTestCustomResource(); + var res = new LeaderElection(); res.setMetadata(new ObjectMetaBuilder() .withName(TEST_RESOURCE_NAME) .withNamespace(namespace) @@ -150,7 +152,7 @@ private void deployOperatorsInOrder(String yamlFilePrefix) { void applyCRD() { String path = - "./target/classes/META-INF/fabric8/leaderelectiontestcustomresources.sample.javaoperatorsdk-v1.yml"; + "./src/main/resources/kubernetes/leaderelections.sample.javaoperatorsdk-v1.yml"; try (InputStream is = new FileInputStream(path)) { final var crd = client.load(is); crd.createOrReplace();