Skip to content

Dependent resource desired() is called twice during reconcile for update #1758

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
amitmun opened this issue Feb 6, 2023 · 0 comments · Fixed by #1759
Closed

Dependent resource desired() is called twice during reconcile for update #1758

amitmun opened this issue Feb 6, 2023 · 0 comments · Fixed by #1759

Comments

@amitmun
Copy link

amitmun commented Feb 6, 2023

Bug Report

What did you do?

I'm reconciling a standalone dependent resource of type Secret that needs to be updated (it exists in k8s but I need to update it with new data).
I believe this also affects managed dependent resources, and any type of resource.

What did you expect to see?

During the reconcile() method, the desired() method should have been called only once.

What did you see instead? Under which circumstances?

During the reconcile() method, the desired() method is called twice.

Environment

Kubernetes cluster type:

OpenShift

$ Mention java-operator-sdk version from pom.xml file

4.2.2

$ java -version

openjdk version "11.0.16.1" 2022-08-12
OpenJDK Runtime Environment Temurin-11.0.16.1+1 (build 11.0.16.1+1)
OpenJDK 64-Bit Server VM Temurin-11.0.16.1+1 (build 11.0.16.1+1, mixed mode)

$ kubectl version

Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.0", GitCommit:"b46a3f887ca979b1a5d14fd39cb1af43e7e5d12d", GitTreeState:"clean", BuildDate:"2022-12-08T19:58:30Z", GoVersion:"go1.19.4", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v4.5.7
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5+70fb84c", GitCommit:"3c28e7a79b58e78b4c1dc1ab7e5f6c6c2d3aedd3", GitTreeState:"clean", BuildDate:"2022-04-25T15:58:12Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}

Possible Solution

In the reconcile() method of AbstractDependentResource, at line 67, the match() method calls desired() and stores the computed actual resources in the Matcher.Result object (which is good).
https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java#L67
But then, in line 69, desired() is called AGAIN (even though it's in orElse part):
https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractDependentResource.java#L69
Line 69 should change and only invoke desired() if the Optional match.computedDesired() is empty.
Simple change :)

Here's the current code:

67        final Matcher.Result<R> match = match(actualResource, primary, context);
68        if (!match.matched()) {
69          final var desired = match.computedDesired().orElse(desired(primary, context));
            throwIfNull(desired, primary, "Desired");
            logForOperation("Updating", primary, desired);
            var updatedResource = handleUpdate(actualResource, desired, primary, context);
            return ReconcileResult.resourceUpdated(updatedResource);
          }

Additional context

In my case, we're generating some random data, including passwords, that are stored in the secret. I've implemented a custom check to determine if the reconciliation of the secret is required (basically, if it does not exist or it is empty), and only in such a case generate the passwords and create/update the secret with the random passwords. I observed that when the secret exists but is empty, passwords were actually generated twice before being applied to the secret. The first set of passwords were actually used, and the second was generated for nothing (since it's in the orElse part that is not used since the desired state was already computed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant