diff --git a/.gitignore b/.gitignore index 36ed54b..5aa4c50 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ target/ # VSCode .factorypath +.vscode diff --git a/pom.xml b/pom.xml index 35b5156..ac31978 100644 --- a/pom.xml +++ b/pom.xml @@ -15,8 +15,8 @@ 11 11 - 1.11.0.Final - 1.6.4-SNAPSHOT + 5.1.1 + 2.16.4.Final 3.8.1 true @@ -24,9 +24,9 @@ - io.quarkus - quarkus-bom - ${quarkus.version} + io.quarkiverse.operatorsdk + quarkus-operator-sdk-bom + ${quarkus-operator-sdk.version} pom import @@ -35,15 +35,23 @@ - io.javaoperatorsdk - operator-framework-quarkus-extension - ${josdk.version} + io.quarkiverse.operatorsdk + quarkus-operator-sdk commons-collections commons-collections 3.2.2 + + io.fabric8 + crd-generator-apt + compile + + + io.fabric8 + kubernetes-model-common + @@ -95,4 +103,4 @@ - \ No newline at end of file + diff --git a/src/main/java/io/javaoperatorsdk/sample/memcached/DeploymentEvent.java b/src/main/java/io/javaoperatorsdk/sample/memcached/DeploymentEvent.java deleted file mode 100644 index d3b4ad9..0000000 --- a/src/main/java/io/javaoperatorsdk/sample/memcached/DeploymentEvent.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.javaoperatorsdk.sample.memcached; - -import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.client.Watcher; -import io.javaoperatorsdk.operator.processing.event.AbstractEvent; - -public class DeploymentEvent extends AbstractEvent { - - private final Watcher.Action action; - private final Deployment deployment; - - public DeploymentEvent( - Watcher.Action action, - Deployment resource, - String ownerUid, - DeploymentEventSource deploymentEventSource) { - super(ownerUid, deploymentEventSource); - this.action = action; - this.deployment = resource; - } - - public Watcher.Action getAction() { - return action; - } - - public String resourceUid() { - return getDeployment().getMetadata().getUid(); - } - - @Override - public String toString() { - return "CustomResourceEvent{" - + "action=" - + action - + ", resource=[ name=" - + getDeployment().getMetadata().getName() - + ", kind=" - + getDeployment().getKind() - + ", apiVersion=" - + getDeployment().getApiVersion() - + " ,resourceVersion=" - + getDeployment().getMetadata().getResourceVersion() - + ", markedForDeletion: " - + (getDeployment().getMetadata().getDeletionTimestamp() != null - && !getDeployment().getMetadata().getDeletionTimestamp().isEmpty()) - + " ]" - + '}'; - } - - public Deployment getDeployment() { - return deployment; - } -} diff --git a/src/main/java/io/javaoperatorsdk/sample/memcached/DeploymentEventSource.java b/src/main/java/io/javaoperatorsdk/sample/memcached/DeploymentEventSource.java deleted file mode 100644 index baaeaf9..0000000 --- a/src/main/java/io/javaoperatorsdk/sample/memcached/DeploymentEventSource.java +++ /dev/null @@ -1,78 +0,0 @@ -package io.javaoperatorsdk.sample.memcached; - -import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID; -import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion; - -import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.Watcher; -import io.fabric8.kubernetes.client.WatcherException; -import io.javaoperatorsdk.operator.processing.event.AbstractEventSource; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DeploymentEventSource extends AbstractEventSource implements Watcher { - private static final Logger log = LoggerFactory.getLogger(DeploymentEventSource.class); - - private final KubernetesClient client; - - private final Map labels; - - public static DeploymentEventSource createAndRegisterWatch( - KubernetesClient client, Map labels) { - DeploymentEventSource deploymentEventSource = new DeploymentEventSource(client, labels); - deploymentEventSource.registerWatch(); - return deploymentEventSource; - } - - private DeploymentEventSource(KubernetesClient client, Map labels) { - this.client = client; - this.labels = labels; - } - - private void registerWatch() { - client.apps().deployments().inAnyNamespace().withLabels(labels).watch(this); - } - - @Override - public void eventReceived(Action action, Deployment deployment) { - log.info( - "Event received for action: {}, Deployment: {} (rr={})", - action.name(), - deployment.getMetadata().getName(), - deployment.getStatus().getReadyReplicas()); - - if (action == Action.ERROR) { - log.warn( - "Skipping {} event for custom resource uid: {}, version: {}", - action, - getUID(deployment), - getVersion(deployment)); - return; - } - - eventHandler.handleEvent( - new DeploymentEvent( - action, - deployment, - deployment.getMetadata().getOwnerReferences().get(0).getUid(), - this)); - } - - @Override - public void onClose(WatcherException e) { - if (e == null) { - return; - } - if (e.isHttpGone()) { - log.warn("Received error for watch, will try to reconnect.", e); - registerWatch(); - } else { - // Note that this should not happen normally, since fabric8 client handles reconnect. - // In case it tries to reconnect this method is not called. - log.error("Unexpected error happened with watch. Will exit.", e); - System.exit(1); - } - } -} diff --git a/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedController.java b/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedController.java index 7b1197d..877aa1a 100644 --- a/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedController.java +++ b/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedController.java @@ -1,13 +1,27 @@ package io.javaoperatorsdk.sample.memcached; -import io.fabric8.kubernetes.api.model.*; +import io.fabric8.kubernetes.api.model.ContainerBuilder; +import io.fabric8.kubernetes.api.model.ContainerPortBuilder; +import io.fabric8.kubernetes.api.model.LabelSelectorBuilder; +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.api.model.OwnerReferenceBuilder; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.PodSpecBuilder; +import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; import io.fabric8.kubernetes.api.model.apps.DeploymentSpecBuilder; import io.fabric8.kubernetes.client.KubernetesClient; -import io.javaoperatorsdk.operator.api.*; -import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.processing.event.EventSourceManager; +import io.javaoperatorsdk.operator.api.config.informer.InformerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.Context; +import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceContext; +import io.javaoperatorsdk.operator.api.reconciler.EventSourceInitializer; +import io.javaoperatorsdk.operator.api.reconciler.Reconciler; +import io.javaoperatorsdk.operator.api.reconciler.UpdateControl; +import io.javaoperatorsdk.operator.processing.event.source.EventSource; +import io.javaoperatorsdk.operator.processing.event.source.informer.InformerEventSource; +import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -16,8 +30,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller -public class MemcachedController implements ResourceController { +@ControllerConfiguration() +public class MemcachedController + implements Reconciler, EventSourceInitializer { private static Logger log = LoggerFactory.getLogger(MemcachedController.class); @@ -28,17 +43,18 @@ public MemcachedController(KubernetesClient client) { } @Override - public void init(EventSourceManager eventSourceManager) { - Map deploymentLabel = new HashMap<>(); - deploymentLabel.put("app", "memcached"); - eventSourceManager.registerEventSource( - "memcached-deployment", - DeploymentEventSource.createAndRegisterWatch(client, deploymentLabel)); + public Map prepareEventSources(EventSourceContext context) { + InformerConfiguration deploymentInformerConfiguration = InformerConfiguration.from(Deployment.class, context) + .withLabelSelector("app.kubernetes.io/managed-by=memcached-operator") + .withSecondaryToPrimaryMapper(Mappers.fromOwnerReference()) + .build(); + + return EventSourceInitializer.nameEventSources(new InformerEventSource<>(deploymentInformerConfiguration, context)); } @Override - public UpdateControl createOrUpdateResource( - Memcached memcached, Context context) { + public UpdateControl reconcile(Memcached memcached, Context context) { + Deployment deployment = client .apps() @@ -76,7 +92,7 @@ public UpdateControl createOrUpdateResource( || !CollectionUtils.isEqualCollection(podNames, memcached.getStatus().getNodes())) { if (memcached.getStatus() == null) memcached.setStatus(new MemcachedStatus()); memcached.getStatus().setNodes(podNames); - return UpdateControl.updateStatusSubResource(memcached); + return UpdateControl.updateStatus(memcached); } return UpdateControl.noUpdate(); @@ -88,10 +104,11 @@ private Deployment createMemcachedDeployment(Memcached m) { new ObjectMetaBuilder() .withName(m.getMetadata().getName()) .withNamespace(m.getMetadata().getNamespace()) + .withLabels(Map.of("app.kubernetes.io/managed-by", "memcached-operator")) .withOwnerReferences( new OwnerReferenceBuilder() - .withApiVersion("v1alpha1") - .withKind("Memcached") + .withApiVersion(m.getApiVersion()) + .withKind(m.getKind()) .withName(m.getMetadata().getName()) .withUid(m.getMetadata().getUid()) .build()) @@ -130,13 +147,4 @@ private Map labelsForMemcached(Memcached m) { labels.put("memcached_cr", m.getMetadata().getName()); return labels; } - - @Override - public DeleteControl deleteResource(Memcached memcached, Context context) { - log.info("Deleting memcached object {}", memcached.getMetadata().getName()); - // nothing to do here... - // framework takes care of deleting the memcached object - // k8s takes care of deleting deployment and pods because of ownerreference set - return DeleteControl.DEFAULT_DELETE; - } } diff --git a/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedOperator.java b/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedOperator.java deleted file mode 100644 index f92cd04..0000000 --- a/src/main/java/io/javaoperatorsdk/sample/memcached/MemcachedOperator.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.javaoperatorsdk.sample.memcached; - -import io.javaoperatorsdk.operator.Operator; -import io.javaoperatorsdk.operator.api.config.ConfigurationService; -import io.quarkus.runtime.Quarkus; -import io.quarkus.runtime.QuarkusApplication; -import io.quarkus.runtime.annotations.QuarkusMain; -import javax.inject.Inject; - -@QuarkusMain -public class MemcachedOperator implements QuarkusApplication { - - @Inject ConfigurationService configuration; - - @Inject MemcachedController controller; - - @Inject Operator operator; - - public static void main(String... args) { - Quarkus.run(MemcachedOperator.class, args); - } - - @Override - public int run(String... args) throws Exception { - configuration.getConfigurationFor(controller); - Quarkus.waitForExit(); - return 0; - } -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..440be28 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +quarkus.operator-sdk.crd.apply=true