operator-framework / java-operator-sdk

Java SDK for building Kubernetes Operators
https://javaoperatorsdk.io/
Apache License 2.0
799 stars 215 forks source link

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

Open nevenr opened 1 year ago

nevenr commented 1 year 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

csviri commented 1 year ago

This seems to me as a Quarkus releated issue, if no objections, will me moved to Quarkus Operator SDK repo. cc @metacosm

nevenr commented 1 year ago

Hi, Yes, please do move this issue to "Quarkus Operator SDK" repo. Thanks. Regards, N.

nevenr commented 1 year ago

Hi,

I open issue in quarkiverse/quarkus-operator-sdk (issues 746) so i will close this one.

Regards, N.

metacosm commented 1 year ago

Sorry for the ping-pong game but this indeed regards JOSDK and is not specific to the Quarkus extension. The problem is that, defining a namespace for your controller, means that JOSDK switches the informer configuration to only watch resources in that namespace. However namespaces themselves are not namespaced resources meaning that an informer watching only a namespace cannot access the namespace itself. To be able to retrieve a namespace itself, you need cluster-wide access since namespaces are clustered-resources.

In this particular case, maybe we should check if the target resources are namespaced or not to properly configure the related informer but I'm not even sure that's a good idea. With Kubernetes, at least as far as I'm aware, you cannot restrict access to only some clustered resources: either you can access all of them or none of them, so the use case of only being able to retrieve the current namespace resource when the controller is configured to only watch one namespace is not really feasible at the Kubernetes level. I might be wrong but I think your only option is to always configure your controller to watch all namespaces.

See quarkiverse/quarkus-operator-sdk#746

github-actions[bot] commented 10 months ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

github-actions[bot] commented 8 months ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.