quarkiverse / quarkus-operator-sdk

Quarkus Extension to create Kubernetes Operators in Java using the Java Operator SDK (https://github.com/java-operator-sdk/java-operator-sdk) project
Apache License 2.0
119 stars 50 forks source link

context.getSecondaryResource does not return related namespace when quarkus.operator-sdk.namespaces is used #746

Closed nevenr closed 8 months ago

nevenr commented 10 months ago

Bug Report

What did you do?

We create controller for cert-manager CertificateRequest CRD. Controller logic is based on CertificateRequest and namespace metadata in which CertificateRequest reside. That is why we declared namespace as secondary resource.

public class ApproverReconciler implements Reconciler<CertificateRequest>, EventSourceInitializer<CertificateRequest> {

    @Override
    public UpdateControl<CertificateRequest> reconcile(CertificateRequest certRequest, Context<CertificateRequest> context) {
        // (1)
        Namespace namespace = context.getSecondaryResource(Namespace.class).orElseThrow();
        return handle(certRequest, namespace);
    }

    @Override
    public Map<String, EventSource> prepareEventSources(EventSourceContext<CertificateRequest> context) {
        var namespaceEventSource =
                new InformerEventSource<>(InformerConfiguration.from(Namespace.class, context)
                        .withPrimaryToSecondaryMapper((CertificateRequest certificateRequest) -> Collections.singleton(new ResourceID(certificateRequest.getMetadata().getNamespace())))
                        .build(), context
                );
        return EventSourceInitializer.nameEventSources(namespaceEventSource);
    }

    private UpdateControl<CertificateRequest> handle(CertificateRequest certRequest, Namespace namespace) {
        // Some business logic 
        return output;
    }

}

For production deployment controller observe all namespaces and for dev/test deployment only one dedicated namespace. That is why in:

we placed:

but in application.properties we did not.

What did you expect to see?

We expect that in both cases (production and dev/test)

context.getSecondaryResource(Namespace.class)

(in code snippet marked as (1) ) always return related namespace.

What did you see instead? Under which circumstances?

In production case it works, but in dev/test it does not returning related namespace, instead empty optional.

Environment

Kubernetes cluster type:

OpenShift v4.12

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

The same behaviour for io.javaoperatorsdk:operator-framework-core:

$ java -version

JDK 17

$ kubectl version

$ oc version Client Version: 4.12.0-202308291001.p0.gac58b18.assembly.stream-ac58b18 Kustomize Version: v4.5.7 Server Version: 4.12.34 Kubernetes Version: v1.25.12+26bab08

metacosm commented 10 months ago

Which version of the Quarkus extension are you using? Do you see any error in the logs of your operator? That said, the problem is most likely that your controller needs cluster-wide access to be able to return namespaces. If your controller is set to only watch a given namespace, then it only has access to that one namespace and therefore cannot access other namespaces (which would lead to getSecondaryResources returning an empty Optional, though you probably should see some logging of an access error).

nevenr commented 10 months ago

Hi,

I have similar behavior on:

In app logs I do not see any exceptions/error except my app business exception because namespace is undefined.

In dev/test use case operator should monitor only one dedicated namespace for CertificateRequest and as secondary resources it should return exactly (and only) that dedicated namespace not others (in withPrimaryToSecondaryMapper new ResourceID(certificateRequest.getMetadata().getNamespace()) ).

Thanks.

Regards, N.

metacosm commented 10 months ago

The problem, as mentioned before, if you set your controller to watch only one namespace, it doesn't have cluster-wide access, which means it cannot retrieve namespaces, which are clustered resources. I will take a look to see what, if anything, we can do.

metacosm commented 10 months ago

Closing this and re-opened the associated JOSDK issue. See https://github.com/operator-framework/java-operator-sdk/issues/2114#issuecomment-1803479724 for more details. However, I'm afraid that what you're trying to do is not feasible at the Kubernetes level.