@@ -24,10 +24,11 @@ import (
2424 appsv1 "k8s.io/api/apps/v1"
2525 corev1 "k8s.io/api/core/v1"
2626 rbacv1 "k8s.io/api/rbac/v1"
27- crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2827 apierrors "k8s.io/apimachinery/pkg/api/errors"
2928 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3029 "k8s.io/apimachinery/pkg/runtime"
30+ "k8s.io/client-go/discovery"
31+ "k8s.io/client-go/rest"
3132 ctrl "sigs.k8s.io/controller-runtime"
3233 "sigs.k8s.io/controller-runtime/pkg/client"
3334 logr "sigs.k8s.io/controller-runtime/pkg/log"
@@ -168,7 +169,7 @@ func (r *RolloutManagerReconciler) SetupWithManager(mgr ctrl.Manager) error {
168169 // Watch for changes to ClusterRoleBinding sub-resources owned by RolloutManager.
169170 bld .Owns (& rbacv1.ClusterRoleBinding {})
170171
171- if crdExists , err := r .doesCRDExist (mgr .GetClient (), serviceMonitorsCRDName ); err != nil {
172+ if crdExists , err := r .doesCRDExist (mgr .GetConfig (), serviceMonitorsCRDName ); err != nil {
172173 return err
173174 } else if crdExists {
174175 // We only attempt to own ServiceMonitor if it exists on the cluster on startup
@@ -178,29 +179,25 @@ func (r *RolloutManagerReconciler) SetupWithManager(mgr ctrl.Manager) error {
178179 return bld .Complete (r )
179180}
180181
181- // doesCRDExist checks if a CRD with the given name is present on the cluster.
182- func (r * RolloutManagerReconciler ) doesCRDExist (k8sClient client.Client , crdName string ) (bool , error ) {
183-
184- // As per the docs, the name of a CRD MUST always be in the format <.spec.name>.<.spec.group>
185- crd := crdv1.CustomResourceDefinition {
186- ObjectMeta : metav1.ObjectMeta {
187- Name : crdName ,
188- },
189- }
190-
191- if err := k8sClient .Get (context .Background (), client .ObjectKeyFromObject (& crd ), & crd ); err != nil {
182+ // doesCRDExist checks if a CRD is present in the cluster, by using the discovery client.
183+ //
184+ // NOTE: this function should only be called from SetupWithManager. There are more efficient methods to determine this, elsewhere.
185+ func (r * RolloutManagerReconciler ) doesCRDExist (cfg * rest.Config , crdName string ) (bool , error ) {
192186
193- if apierrors .IsNotFound (err ) {
194- // Not found, so CRD doesn't exist; return
195- return false , nil
196- }
187+ // Idealy we would use client.Client to retrieve the CRD, here, but since the manager has not yet started, we don't have access to the client from the manager. We would need to convert the rest.Config into a client.Client, and it's easier to use
197188
198- // Some other error occurred: log it, and return it
199- log . Error ( err , "an unexpected error occurred when retrieving CRD" , "crdName" , crdName )
189+ discoveryClient , err := discovery . NewDiscoveryClientForConfig ( cfg )
190+ if err != nil {
200191 return false , err
201192 }
202-
203- // CRD exists
204- return true , nil
205-
193+ apiResources , err := discoveryClient .ServerResourcesForGroupVersion ("monitoring.coreos.com/v1" )
194+ if err != nil {
195+ return false , err
196+ }
197+ for _ , resource := range apiResources .APIResources {
198+ if resource .Name == crdName {
199+ return true , nil
200+ }
201+ }
202+ return false , nil
206203}
0 commit comments