-
Notifications
You must be signed in to change notification settings - Fork 223
Open
Description
Hi,
I have an operator that uses a standalone dependent resource. The dependent resource is of type CRUDKubernetesDependentResource<ConfigMap, T>
and only overrides method protected ConfigMap desired(T primary, Context<T> context)
. When the dependent resource does not exist yet, desired
is called once. However, when the dependent resource exists, desired
is called twice in a row. Why is that? According to the flowchart in the docs, I would have expected only one call.
Minimal reproducible example based on the WebPage Example Operator
Full source code can be found here: https://github.com/michaelkoepf/dependent-resource-test. Most important classes can be found below.
@ControllerConfiguration
public class WebPageStandaloneDependentsReconciler implements Reconciler<WebPage> {
private static final Logger LOG = LoggerFactory.getLogger(WebPageStandaloneDependentsReconciler.class);
private final Workflow<WebPage> workflow;
public WebPageStandaloneDependentsReconciler() {
workflow = createDependentResourcesAndWorkflow();
}
@Override
public List<EventSource<?, WebPage>> prepareEventSources(EventSourceContext<WebPage> context) {
return EventSourceUtils.eventSourcesFromWorkflow(context, workflow);
}
@Override
public UpdateControl<WebPage> reconcile(WebPage webPage, Context<WebPage> context)
throws Exception {
LOG.info("Starting reconciliation at {}", System.currentTimeMillis());
workflow.reconcile(webPage, context);
return UpdateControl.noUpdate();
}
@SuppressWarnings({"unchecked", "rawtypes"})
private Workflow<WebPage> createDependentResourcesAndWorkflow() {
// create the dependent resources
var configMapDR = new ConfigMapDependentResource();
// configure them with our label selector
Arrays.asList(configMapDR)
.forEach(
dr ->
dr.configureWith(
new KubernetesDependentResourceConfigBuilder()
.withKubernetesDependentInformerConfig(
InformerConfiguration.builder(dr.resourceType())
.withLabelSelector("managed=true")
.build())
.build()));
return new WorkflowBuilder<WebPage>()
.addDependentResource(configMapDR)
.build();
}
}
public class ConfigMapDependentResource
extends CRUDKubernetesDependentResource<ConfigMap, WebPage> {
private static final Logger LOG = LoggerFactory.getLogger(ConfigMapDependentResource.class);
@Override
protected ConfigMap desired(WebPage webPage, Context<WebPage> context) {
LOG.info("Evaluating desired state at {}", System.currentTimeMillis());
Map<String, String> data = new HashMap<>();
data.put("index.html", webPage.getSpec().getHtml());
Map<String, String> labels = new HashMap<>();
labels.put("managed", "true");
return new ConfigMapBuilder()
.withMetadata(
new ObjectMetaBuilder()
.withName("webpage-configmap")
.withNamespace(webPage.getMetadata().getNamespace())
.withLabels(labels)
.build())
.withData(data)
.build();
}
}
Example
- Trigger reconciliation by
kubectl apply -f k8s/webpage-v1.yaml
. Dependent resource does not exist yet. Log:
2025-08-11 13:32:02,237 INFO [com.exa.WebPageStandaloneDependentsReconciler] (ReconcilerExecutor-webpagestandalonedependentsreconciler-185) Starting reconciliation at 1754911922237
2025-08-11 13:32:02,240 INFO [com.exa.ConfigMapDependentResource] (pool-16-thread-1) Evaluating desired state at 1754911922240
- Dependent resource now exists. Trigger reconciliation again by
kubectl apply -f k8s/webpage-v2.yaml
. Log:
2025-08-11 13:32:04,816 INFO [com.exa.WebPageStandaloneDependentsReconciler] (ReconcilerExecutor-webpagestandalonedependentsreconciler-188) Starting reconciliation at 1754911924816
2025-08-11 13:32:04,817 INFO [com.exa.ConfigMapDependentResource] (pool-16-thread-2) Evaluating desired state at 1754911924817
2025-08-11 13:32:04,818 INFO [com.exa.ConfigMapDependentResource] (pool-16-thread-2) Evaluating desired state at 1754911924818
- Trigger reconciliation again by
kubectl apply -f k8s/webpage-v3.yaml
. Log:
2025-08-11 13:32:06,888 INFO [com.exa.WebPageStandaloneDependentsReconciler] (ReconcilerExecutor-webpagestandalonedependentsreconciler-191) Starting reconciliation at 1754911926888
2025-08-11 13:32:06,889 INFO [com.exa.ConfigMapDependentResource] (pool-16-thread-3) Evaluating desired state at 1754911926889
2025-08-11 13:32:06,889 INFO [com.exa.ConfigMapDependentResource] (pool-16-thread-3) Evaluating desired state at 1754911926889
Metadata
Metadata
Assignees
Labels
No labels