@@ -35,6 +35,7 @@ import (
35
35
rbacv1 "k8s.io/api/rbac/v1"
36
36
"k8s.io/apimachinery/pkg/labels"
37
37
"k8s.io/apimachinery/pkg/runtime/schema"
38
+ "k8s.io/apimachinery/pkg/types"
38
39
"sigs.k8s.io/controller-runtime/pkg/client"
39
40
40
41
otelv1alpha1 "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
@@ -43,13 +44,16 @@ import (
43
44
)
44
45
45
46
type Cluster struct {
46
- config * config.Config
47
+ config * config.Config
48
+ apiAvailabilityCache map [schema.GroupVersionResource ]bool
47
49
}
48
50
49
51
func NewCluster (cfg * config.Config ) Cluster {
50
- return Cluster {config : cfg }
52
+ return Cluster {
53
+ config : cfg ,
54
+ apiAvailabilityCache : make (map [schema.GroupVersionResource ]bool ),
55
+ }
51
56
}
52
-
53
57
func (c * Cluster ) getOperatorNamespace () (string , error ) {
54
58
if c .config .OperatorNamespace != "" {
55
59
return c .config .OperatorNamespace , nil
@@ -295,207 +299,42 @@ func (c *Cluster) processOTELCollector(otelCol *otelv1beta1.OpenTelemetryCollect
295
299
return nil
296
300
}
297
301
298
- func (c * Cluster ) processOwnedResources (otelCol * otelv1beta1.OpenTelemetryCollector , folder string ) error {
299
- errorDetected := false
300
-
301
- ////////////////////////////////////////////////////////////////// apps/v1
302
- // DaemonSets
303
- daemonsets , err := c .getOwnerResources (& appsv1.DaemonSetList {}, otelCol )
304
- if err != nil {
305
- errorDetected = true
306
- log .Fatalln (err )
307
- }
308
- for _ , d := range daemonsets {
309
- writeToFile (folder , d )
310
- }
311
-
312
- // Deployments
313
- deployments , err := c .getOwnerResources (& appsv1.DeploymentList {}, otelCol )
314
- if err != nil {
315
- errorDetected = true
316
- log .Fatalln (err )
317
- }
318
- for _ , d := range deployments {
319
- writeToFile (folder , d )
320
- }
321
-
322
- // StatefulSets
323
- statefulsets , err := c .getOwnerResources (& appsv1.StatefulSetList {}, otelCol )
324
- if err != nil {
325
- errorDetected = true
326
- log .Fatalln (err )
327
- }
328
- for _ , s := range statefulsets {
329
- writeToFile (folder , s )
330
- }
331
-
332
- ////////////////////////////////////////////////////////////////// rbac/v1
333
- // ClusterRole
334
- crs , err := c .getOwnerResources (& rbacv1.ClusterRoleList {}, otelCol )
335
- if err != nil {
336
- errorDetected = true
337
- log .Fatalln (err )
338
- }
339
- for _ , cr := range crs {
340
- writeToFile (folder , cr )
341
- }
342
-
343
- // ClusterRoleBindings
344
- crbs , err := c .getOwnerResources (& rbacv1.ClusterRoleBindingList {}, otelCol )
345
- if err != nil {
346
- errorDetected = true
347
- log .Fatalln (err )
348
- }
349
- for _ , crb := range crbs {
350
- writeToFile (folder , crb )
351
- }
352
-
353
- ////////////////////////////////////////////////////////////////// core/v1
354
- // ConfigMaps
355
- cms , err := c .getOwnerResources (& corev1.ConfigMapList {}, otelCol )
356
- if err != nil {
357
- errorDetected = true
358
- log .Fatalln (err )
359
- }
360
- for _ , c := range cms {
361
- writeToFile (folder , c )
362
- }
363
-
364
- // PersistentVolumes
365
- pvs , err := c .getOwnerResources (& corev1.PersistentVolumeList {}, otelCol )
366
- if err != nil {
367
- errorDetected = true
368
- log .Fatalln (err )
369
- }
370
- for _ , p := range pvs {
371
- writeToFile (folder , p )
372
- }
373
-
374
- // PersistentVolumeClaims
375
- pvcs , err := c .getOwnerResources (& corev1.PersistentVolumeClaimList {}, otelCol )
376
- if err != nil {
377
- errorDetected = true
378
- log .Fatalln (err )
379
- }
380
- for _ , p := range pvcs {
381
- writeToFile (folder , p )
382
- }
383
-
384
- // Pods
385
- pods , err := c .getOwnerResources (& corev1.PodList {}, otelCol )
386
- if err != nil {
387
- errorDetected = true
388
- log .Fatalln (err )
389
- }
390
- for _ , p := range pods {
391
- writeToFile (folder , p )
392
- }
393
-
394
- // Services
395
- services , err := c .getOwnerResources (& corev1.ServiceList {}, otelCol )
396
- if err != nil {
397
- errorDetected = true
398
- log .Fatalln (err )
399
- }
400
- for _ , s := range services {
401
- writeToFile (folder , s )
402
- }
403
-
404
- // ServiceAccounts
405
- sas , err := c .getOwnerResources (& corev1.ServiceAccountList {}, otelCol )
406
- if err != nil {
407
- errorDetected = true
408
- log .Fatalln (err )
409
- }
410
- for _ , s := range sas {
411
- writeToFile (folder , s )
412
- }
413
-
414
- ////////////////////////////////////////////////////////////////// autoscaling/v2
415
- // HPAs
416
- hpas , err := c .getOwnerResources (& autoscalingv2.HorizontalPodAutoscalerList {}, otelCol )
417
- if err != nil {
418
- errorDetected = true
419
- log .Fatalln (err )
420
- }
421
- for _ , h := range hpas {
422
- writeToFile (folder , h )
423
- }
424
-
425
- ////////////////////////////////////////////////////////////////// networking/v1
426
- // Ingresses
427
- ingresses , err := c .getOwnerResources (& networkingv1.IngressList {}, otelCol )
428
- if err != nil {
429
- errorDetected = true
430
- log .Fatalln (err )
431
- }
432
- for _ , i := range ingresses {
433
- writeToFile (folder , i )
434
- }
435
-
436
- ////////////////////////////////////////////////////////////////// policy/v1
437
- // PodDisruptionBudge
438
- pdbs , err := c .getOwnerResources (& policy1.PodDisruptionBudgetList {}, otelCol )
439
- if err != nil {
440
- errorDetected = true
441
- log .Fatalln (err )
442
- }
443
- for _ , pdb := range pdbs {
444
- writeToFile (folder , pdb )
445
- }
446
-
447
- ////////////////////////////////////////////////////////////////// monitoring/v1
448
- if c .isAPIAvailable (schema.GroupVersionResource {
449
- Group : monitoringv1 .SchemeGroupVersion .Group ,
450
- Version : monitoringv1 .SchemeGroupVersion .Version ,
451
- Resource : "ServiceMonitor" ,
452
- }) {
453
- // PodMonitors
454
- pms , err := c .getOwnerResources (& monitoringv1.PodMonitorList {}, otelCol )
455
- if err != nil {
456
- errorDetected = true
457
- log .Fatalln (err )
458
- }
459
- for _ , pm := range pms {
460
- writeToFile (folder , pm )
461
- }
462
-
463
- // ServiceMonitors
464
- sms , err := c .getOwnerResources (& monitoringv1.ServiceMonitorList {}, otelCol )
465
- if err != nil {
466
- errorDetected = true
467
- log .Fatalln (err )
468
- }
469
- for _ , s := range sms {
470
- writeToFile (folder , s )
471
- }
472
- }
473
-
474
- ////////////////////////////////////////////////////////////////// route/v1
475
- // Routes
476
- if c .isAPIAvailable (schema.GroupVersionResource {
477
- Group : routev1 .GroupName ,
478
- Version : routev1 .GroupVersion .Version ,
479
- Resource : "Route" ,
480
- }) {
481
- rs , err := c .getOwnerResources (& routev1.RouteList {}, otelCol )
482
- if err != nil {
483
- errorDetected = true
484
- log .Fatalln (err )
485
- }
486
- for _ , r := range rs {
487
- writeToFile (folder , r )
302
+ func (c * Cluster ) processOwnedResources (owner interface {}, folder string ) error {
303
+ resourceTypes := []struct {
304
+ list client.ObjectList
305
+ apiCheck func () bool
306
+ }{
307
+ {& appsv1.DaemonSetList {}, func () bool { return true }},
308
+ {& appsv1.DeploymentList {}, func () bool { return true }},
309
+ {& appsv1.StatefulSetList {}, func () bool { return true }},
310
+ {& rbacv1.ClusterRoleList {}, func () bool { return true }},
311
+ {& rbacv1.ClusterRoleBindingList {}, func () bool { return true }},
312
+ {& corev1.ConfigMapList {}, func () bool { return true }},
313
+ {& corev1.PersistentVolumeList {}, func () bool { return true }},
314
+ {& corev1.PersistentVolumeClaimList {}, func () bool { return true }},
315
+ {& corev1.PodList {}, func () bool { return true }},
316
+ {& corev1.ServiceList {}, func () bool { return true }},
317
+ {& corev1.ServiceAccountList {}, func () bool { return true }},
318
+ {& autoscalingv2.HorizontalPodAutoscalerList {}, func () bool { return true }},
319
+ {& networkingv1.IngressList {}, func () bool { return true }},
320
+ {& policy1.PodDisruptionBudgetList {}, func () bool { return true }},
321
+ {& monitoringv1.PodMonitorList {}, c .isMonitoringAPIAvailable },
322
+ {& monitoringv1.ServiceMonitorList {}, c .isMonitoringAPIAvailable },
323
+ {& routev1.RouteList {}, c .isRouteAPIAvailable },
324
+ }
325
+
326
+ for _ , rt := range resourceTypes {
327
+ if rt .apiCheck () {
328
+ if err := c .processResourceType (rt .list , owner , folder ); err != nil {
329
+ return err
330
+ }
488
331
}
489
332
}
490
333
491
- if errorDetected {
492
- return fmt .Errorf ("something failed while getting the associated resources" )
493
- }
494
-
495
334
return nil
496
335
}
497
336
498
- func (c * Cluster ) getOwnerResources (objList client.ObjectList , otelCol * otelv1beta1. OpenTelemetryCollector ) ([]client.Object , error ) {
337
+ func (c * Cluster ) getOwnerResources (objList client.ObjectList , owner interface {} ) ([]client.Object , error ) {
499
338
err := c .config .KubernetesClient .List (context .TODO (), objList , & client.ListOptions {
500
339
LabelSelector : labels .SelectorFromSet (labels.Set {
501
340
"app.kubernetes.io/managed-by" : "opentelemetry-operator" ,
@@ -510,28 +349,69 @@ func (c *Cluster) getOwnerResources(objList client.ObjectList, otelCol *otelv1be
510
349
items := reflect .ValueOf (objList ).Elem ().FieldByName ("Items" )
511
350
for i := 0 ; i < items .Len (); i ++ {
512
351
item := items .Index (i ).Addr ().Interface ().(client.Object )
513
- if hasOwnerReference (item , otelCol ) {
352
+ if hasOwnerReference (item , owner ) {
514
353
resources = append (resources , item )
515
354
}
516
355
}
517
356
return resources , nil
518
357
519
358
}
520
359
360
+ func (c * Cluster ) processResourceType (list client.ObjectList , owner interface {}, folder string ) error {
361
+ resources , err := c .getOwnerResources (list , owner )
362
+ if err != nil {
363
+ return fmt .Errorf ("failed to get resources: %w" , err )
364
+ }
365
+ for _ , resource := range resources {
366
+ writeToFile (folder , resource )
367
+ }
368
+ return nil
369
+ }
370
+
371
+ func (c * Cluster ) isMonitoringAPIAvailable () bool {
372
+ return c .isAPIAvailable (schema.GroupVersionResource {
373
+ Group : monitoringv1 .SchemeGroupVersion .Group ,
374
+ Version : monitoringv1 .SchemeGroupVersion .Version ,
375
+ Resource : "ServiceMonitor" ,
376
+ })
377
+ }
378
+
379
+ func (c * Cluster ) isRouteAPIAvailable () bool {
380
+ return c .isAPIAvailable (schema.GroupVersionResource {
381
+ Group : routev1 .GroupName ,
382
+ Version : routev1 .GroupVersion .Version ,
383
+ Resource : "Route" ,
384
+ })
385
+ }
386
+
521
387
func (c * Cluster ) isAPIAvailable (gvr schema.GroupVersionResource ) bool {
388
+ if result , ok := c .apiAvailabilityCache [gvr ]; ok {
389
+ return result
390
+ }
391
+
522
392
rm := c .config .KubernetesClient .RESTMapper ()
523
393
524
394
gvk , err := rm .KindFor (gvr )
525
- if err != nil {
526
- return false
527
- }
395
+ result := err == nil && ! gvk .Empty ()
396
+ c .apiAvailabilityCache [gvr ] = result
528
397
529
- return ! gvk . Empty ()
398
+ return result
530
399
}
531
400
532
- func hasOwnerReference (obj client.Object , otelCol * otelv1beta1.OpenTelemetryCollector ) bool {
401
+ func hasOwnerReference (obj client.Object , owner interface {}) bool {
402
+ var ownerKind string
403
+ var ownerUID types.UID
404
+
405
+ switch o := owner .(type ) {
406
+ case * otelv1beta1.OpenTelemetryCollector :
407
+ ownerKind = o .Kind
408
+ ownerUID = o .UID
409
+ default :
410
+ return false
411
+ }
412
+
533
413
for _ , ownerRef := range obj .GetOwnerReferences () {
534
- if ownerRef .Kind == otelCol . Kind && ownerRef .UID == otelCol . UID {
414
+ if ownerRef .Kind == ownerKind && ownerRef .UID == ownerUID {
535
415
return true
536
416
}
537
417
}
0 commit comments