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

Allow to filter which CRDs are generated #674

Closed Obirah closed 1 year ago

Obirah commented 1 year ago

Currently (as far as I'm aware of), the quarkus-operator-sdk only allows users to either enable or disable CRD generation. In my opinion, it should be possible to filter which CustomResource implementations are used to generate CRDs (e.g. only generate CRDs for certain groups).

My use-case is the following: I want to implement a reconciler for a CustomResource that belongs to another operator. The reconciler's only job is to watch the status of the CustomResource and modify the CustomResources that belong to my operator depending on the watched status. As the CRD already exists on the cluster and belongs to another operator, I don't need that CRD to be generated even though I'm implementing CustomResource and using it in an reconciler.

metacosm commented 1 year ago

This makes sense. How would you want to configure this, though?

Obirah commented 1 year ago

I would love to see a mechanism, where I can configure the following two things:

Either opt-in to CRD generation for specific groups:

quarkus.operator-sdk.crd.generator.include-groups=com.mygroup.myoperator

Or opt-out from CRD generation for specific groups:

quarkus.operator-sdk.crd.generator.exclude-groups=com.mygroup.otheroperator

Alternatively, I could also imagine the same mechanism with CustomResource class names:

Include: quarkus.operator-sdk.crd.generator.include-resources=MyOperatorResource

Exclude: quarkus.operator-sdk.crd.generator.exclude-resources=OtherOperatorResource

Of course, the best way would be to have all of those options as I can imagine all of them might be useful in certain operator use-cases.

csviri commented 1 year ago

Wonder if it makes sense to filter also on Kind.

Obirah commented 1 year ago

Wonder if it makes sense to filter also on Kind.

Basically, the second part of the suggestion in my previous comment is a filtering on Kind as the Name of the CustomResource class translates to Kind when the CRD is generated.

csviri commented 1 year ago

Ahh, yes sorry :) That makes sense imo. Since we are generating from classes.

csviri commented 1 year ago

On the other hand it can be a little fuzzy, if on class not on kind, since a kind can have multiple classes. If there are multiple versions for a CR. But this is not that big issue.

metacosm commented 1 year ago

I settled for quarkus.operator-sdk.crd.exclude-resources passing the resources' FQNs for now. I believe this should cover most of the cases, especially considering that using quarkus.operator-sdk.crd.generate-all, you can already include non-reconciler associated resources for CRD generation, the ones associated with reconcilers being already automatically generated on demand (unless quarkus.operator-sdk.crd.generate is set to false, in which case CRD generation is completely disabled).

Obirah commented 1 year ago

Thank you for implementing this feature, @metacosm. :) I have a follow-up question: I tried to use quarkus.operator-sdk.crd.exclude-resources but my external CRD is tied to a reconciler and it seems like because of that the yaml file is generated anyway. I don't want to set quarkus.operator-sdk.crd.generate to false because I have three other CRDs that are supposed to be generated, but I don't want to have the external one generated even though it is tied to a reconciler. Is it currently possible to achieve this with a combination of config options?

metacosm commented 1 year ago

Thank you for implementing this feature, @metacosm. :) I have a follow-up question: I tried to use quarkus.operator-sdk.crd.exclude-resources but my external CRD is tied to a reconciler and it seems like because of that the yaml file is generated anyway. I don't want to set quarkus.operator-sdk.crd.generate to false because I have three other CRDs that are supposed to be generated, but I don't want to have the external one generated even though it is tied to a reconciler. Is it currently possible to achieve this with a combination of config options?

So, if I understand correctly, you'd like to exclude a reconciler's primary resource from triggering the generation of the associated CRD, right? If that's indeed the case, it might not indeed not be possible at this point. Let me look into it.

Obirah commented 1 year ago

Thank you for implementing this feature, @metacosm. :) I have a follow-up question: I tried to use quarkus.operator-sdk.crd.exclude-resources but my external CRD is tied to a reconciler and it seems like because of that the yaml file is generated anyway. I don't want to set quarkus.operator-sdk.crd.generate to false because I have three other CRDs that are supposed to be generated, but I don't want to have the external one generated even though it is tied to a reconciler. Is it currently possible to achieve this with a combination of config options?

So, if I understand correctly, you'd like to exclude a reconciler's primary resource from triggering the generation of the associated CRD, right? If that's indeed the case, it might not indeed not be possible at this point. Let me look into it.

Yes, exactly. My operator provisions a resource that is handled by another operator and has a reconciler that is analyzing the status the other operator writes into that dependent resource and will perform further tasks based on that.

metacosm commented 1 year ago

Actually, did you try excluding your CR in your operator's application.properties file using quarkus.operator-sdk.crd.exclude-resources=<fully qualified class name of your primary resource>? This seems to prevent the CRD from being generated in my case (though this might have consequences on other downstream processes such as automatically applying the CRD to the cluster or OLM bundle generation).

Obirah commented 1 year ago

Oh yes, I'm sorry I didn't describe the problem correctly, you are right. It is possible to exclude the CR, the yaml file is not generated but then a downstream error occurs (quarkusDev task with generate=true and apply=false):

java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkiverse.operatorsdk.bundle.deployment.BundleProcessor#generateBundle threw an exception: java.lang.IllegalStateException: Missing owned CRD data for resources: [my.crd.package] for bundle: my-operator
metacosm commented 1 year ago

Yes, that's expected: the OLM generator needs the CRD to work properly. So either you disable bundle generation or you need to provide the CRD to the generator. Then again from what you describe, it looks like for your reconciler the CRD is more like a required one than an owned one and this particular case is not currently supported…