@@ -24,7 +24,9 @@ import (
2424 corev1 "k8s.io/api/core/v1"
2525 v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2626 "k8s.io/apimachinery/pkg/runtime"
27+ "k8s.io/apimachinery/pkg/runtime/schema"
2728 "k8s.io/apimachinery/pkg/types"
29+ "k8s.io/apimachinery/pkg/util/sets"
2830 "k8s.io/client-go/kubernetes"
2931 clientgocorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
3032 "k8s.io/client-go/tools/record"
@@ -161,11 +163,44 @@ func Run(cmd *cobra.Command, args []string) (returnErr error) {
161163 if err != nil {
162164 return fmt .Errorf ("failed to create event recorder: %v" , err )
163165 }
166+ // Data gatherers are loaded depending on what the Kubernetes API supports.
167+ // First, let's do a /api discovery to see what the API supports.
168+ discoveryClient , err := k8s .NewDiscoveryClient ("" )
169+ if err != nil {
170+ return fmt .Errorf ("failed to create a discovery client: %v" , err )
171+ }
164172
173+ _ , resources , err := discoveryClient .ServerGroupsAndResources ()
174+ if err != nil {
175+ return fmt .Errorf ("failed to get server resources: %v" , err )
176+ }
177+ supported := sets .NewString ()
178+ for _ , r := range resources {
179+ gv , err := schema .ParseGroupVersion (r .GroupVersion )
180+ if err != nil {
181+ log .Error (err , "Failed to parse group version" )
182+ }
183+ for _ , r2 := range r .APIResources {
184+ supported .Insert (gv .WithResource (r2 .Name ).String ())
185+ }
186+ }
187+ log .V (logs .Debug ).Info ("Supported" , "resources" , supported .List ())
165188 dataGatherers := map [string ]datagatherer.DataGatherer {}
166189
167190 // load datagatherer config and boot each one
168191 for _ , dgConfig := range config .DataGatherers {
192+ if c , ok := dgConfig .Config .(* k8s.ConfigDynamic ); ok {
193+ gvr := c .GroupVersionResource
194+ if ! supported .Has (gvr .String ()) {
195+ log .Info (
196+ "Skipping DataGatherer" ,
197+ "name" , dgConfig .Name ,
198+ "reason" , "GroupVersionResource not installed" ,
199+ "groupVersionResource" , gvr ,
200+ )
201+ continue
202+ }
203+ }
169204 kind := dgConfig .Kind
170205 if dgConfig .DataPath != "" {
171206 kind = "local"
@@ -213,17 +248,16 @@ func Run(cmd *cobra.Command, args []string) (returnErr error) {
213248 // too, it will backoff and retry of its own accord. Initial boot
214249 // will only be delayed by a max of 5 seconds.
215250 bootCtx , bootCancel := context .WithTimeout (gctx , 5 * time .Second )
216- defer bootCancel ()
217- for _ , dgConfig := range config .DataGatherers {
218- dg := dataGatherers [dgConfig .Name ]
251+ for dgName , dg := range dataGatherers {
219252 // wait for the informer to complete an initial sync, we do this to
220253 // attempt to have an initial set of data for the first upload of
221254 // the run.
222255 if err := dg .WaitForCacheSync (bootCtx .Done ()); err != nil {
223256 // log sync failure, this might recover in future
224- log .Error (err , "Failed to complete initial sync of DataGatherer" , "kind" , dgConfig . Kind , " name" , dgConfig . Name )
257+ log .Error (err , "Failed to complete initial sync of DataGatherer" , "name" , dgName )
225258 }
226259 }
260+ bootCancel ()
227261
228262 // begin the datagathering loop, periodically sending data to the
229263 // configured output using data in datagatherer caches or refreshing from
0 commit comments