Description
Bug Report
What did you do?
I created a basic reconciler for a cluster-scoped custom resource:
class ProjectReconciler : Reconciler<Project> {
override fun reconcile(
resource: Project,
context: Context<Project>,
): UpdateControl<Project> {
println("Reconciling ${resource.metadata.name}")
if (resource.status == null) {
resource.status = ProjectStatus()
}
return UpdateControl.patchStatus(resource)
}
}
I've then started the operator, created the custom resource and then deleted it.
What did you expect to see?
It doesn't throw an exception when I delete it.
What did you see instead? Under which circumstances?
When I delete the custom resource, the operator throws the following exception:
java.lang.IllegalStateException: Should not be called with DELETED
at io.javaoperatorsdk.operator.processing.event.source.controller.ControllerResourceEventSource.isAcceptedByFilters(ControllerResourceEventSource.java:98)
at io.javaoperatorsdk.operator.processing.event.source.controller.ControllerResourceEventSource.eventReceived(ControllerResourceEventSource.java:75)
at io.javaoperatorsdk.operator.processing.event.source.controller.ControllerResourceEventSource.onDelete(ControllerResourceEventSource.java:118)
at io.javaoperatorsdk.operator.processing.event.source.controller.ControllerResourceEventSource.onDelete(ControllerResourceEventSource.java:28)
at io.fabric8.kubernetes.client.informers.impl.cache.ProcessorListener$DeleteNotification.handle(ProcessorListener.java:122)
at io.fabric8.kubernetes.client.informers.impl.cache.ProcessorListener.add(ProcessorListener.java:50)
at io.fabric8.kubernetes.client.informers.impl.cache.SharedProcessor.lambda$distribute$0(SharedProcessor.java:87)
at io.fabric8.kubernetes.client.informers.impl.cache.SharedProcessor.lambda$distribute$1(SharedProcessor.java:110)
at io.fabric8.kubernetes.client.utils.internal.SerialExecutor.lambda$execute$0(SerialExecutor.java:58)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Environment
Kubernetes cluster type: minikube
$ Mention java-operator-sdk version from pom.xml file
java-operator-sdk version: 4.2.0
$ java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.4", GitCommit:"95ee5ab382d64cfe6c28967f36b53970b8374491", GitTreeState:"clean", BuildDate:"2022-08-17T18:54:23Z", GoVersion:"go1.18.5", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v4.5.4
Server Version: version.Info{Major:"1", Minor:"25", GitVersion:"v1.25.3", GitCommit:"434bfd82814af038ad94d62ebe59b133fcb50506", GitTreeState:"clean", BuildDate:"2022-10-12T10:49:09Z", GoVersion:"go1.19.2", Compiler:"gc", Platform:"linux/amd64"}
Possible Solution
ControllerResourceEventSource
contains a method isAcceptedByFilters()
:
private boolean isAcceptedByFilters(ResourceAction action, T resource, T oldResource) {
// delete event is filtered for generic filter only.
if (genericFilter != null && !genericFilter.accept(resource)) {
return false;
}
switch (action) {
case ADDED:
return onAddFilter == null || onAddFilter.accept(resource);
case UPDATED:
return onUpdateFilter.accept(resource, oldResource);
case DELETED:
throw new IllegalStateException("Should not be called with " + action);
}
return true;
}
For some reason, it throws an exception if it's called for deletions, even though there is a comment that says it only uses the generic filters for deletions. This was changed in commit 952a26b. It just returned true
before.
A possible fix would be removing the DELETE
case and adding a default
case which returns true
.
Additional context
I'm using the Quarkiverse Operator SDK extension for Quarkus.