Skip to content

Commit 34c73e3

Browse files
committed
Only start datagatherer if its API resource is available
Signed-off-by: Richard Wall <[email protected]>
1 parent 1a567ef commit 34c73e3

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

pkg/agent/run.go

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)