@@ -19,6 +19,8 @@ type Discoverer struct {
1919 client kubernetes.Interface
2020 rbacChecker * RBACChecker
2121 expander * ResourceExpander
22+ kotsDetector * KotsDetector
23+ rbacReporter * RBACReporter
2224}
2325
2426// NewDiscoverer creates a new autodiscovery discoverer
@@ -36,12 +38,16 @@ func NewDiscoverer(clientConfig *rest.Config, client kubernetes.Interface) (*Dis
3638 }
3739
3840 expander := NewResourceExpander ()
41+ kotsDetector := NewKotsDetector (client )
42+ rbacReporter := NewRBACReporter ()
3943
4044 return & Discoverer {
4145 clientConfig : clientConfig ,
4246 client : client ,
4347 rbacChecker : rbacChecker ,
4448 expander : expander ,
49+ kotsDetector : kotsDetector ,
50+ rbacReporter : rbacReporter ,
4551 }, nil
4652}
4753
@@ -77,6 +83,13 @@ func (d *Discoverer) DiscoverFoundational(ctx context.Context, opts DiscoveryOpt
7783 }
7884 }
7985
86+ // Generate RBAC remediation report if there were permission issues
87+ if d .rbacReporter .HasWarnings () {
88+ d .rbacReporter .GeneratePermissionSummary ()
89+ d .rbacReporter .GenerateRemediationReport ()
90+ d .rbacReporter .SummarizeCollectionResults (len (foundationalCollectors ) + d .rbacReporter .GetFilteredCollectorCount ())
91+ }
92+
8093 klog .V (2 ).Infof ("Discovered %d foundational collectors" , len (foundationalCollectors ))
8194 return foundationalCollectors , nil
8295}
@@ -145,6 +158,35 @@ func (d *Discoverer) generateFoundationalCollectors(namespaces []string, opts Di
145158 // Always include cluster-level info
146159 collectors = append (collectors , d .generateClusterInfoCollectors ()... )
147160
161+ // KOTS-aware discovery: Detect and add KOTS-specific collectors
162+ ctx := context .Background ()
163+ if kotsApps , err := d .kotsDetector .DetectKotsApplications (ctx ); err == nil && len (kotsApps ) > 0 {
164+ klog .Infof ("Found %d KOTS applications, generating KOTS-specific collectors" , len (kotsApps ))
165+ kotsCollectors := d .kotsDetector .GenerateKotsCollectors (kotsApps )
166+ collectors = append (collectors , kotsCollectors ... )
167+
168+ // Log the KOTS collectors for debugging
169+ for _ , kotsCollector := range kotsCollectors {
170+ klog .V (2 ).Infof ("Added KOTS collector: %s (type: %s, namespace: %s)" ,
171+ kotsCollector .Name , kotsCollector .Type , kotsCollector .Namespace )
172+ }
173+ } else if err != nil {
174+ klog .V (2 ).Infof ("KOTS detection failed (non-fatal): %v" , err )
175+ } else {
176+ klog .V (2 ).Info ("No KOTS applications detected in cluster" )
177+ }
178+
179+ // ALWAYS generate standard KOTS diagnostic collectors for troubleshooting
180+ // These attempt to collect expected KOTS resources even if no apps are detected
181+ // This creates valuable error files when resources are missing (important for support)
182+ standardKotsCollectors := d .kotsDetector .GenerateStandardKotsCollectors (ctx )
183+ collectors = append (collectors , standardKotsCollectors ... )
184+
185+ klog .V (2 ).Infof ("Added %d standard KOTS diagnostic collectors" , len (standardKotsCollectors ))
186+ for _ , stdCollector := range standardKotsCollectors {
187+ klog .V (2 ).Infof ("Added standard KOTS collector: %s (creates error file if missing)" , stdCollector .Name )
188+ }
189+
148190 // Add namespace-scoped collectors for each target namespace
149191 for _ , namespace := range namespaces {
150192 collectors = append (collectors , d .generateNamespacedCollectors (namespace , opts )... )
@@ -287,7 +329,9 @@ func (d *Discoverer) applyRBACFiltering(ctx context.Context, collectors []Collec
287329 if allowedKeys [key ] {
288330 filteredCollectors = append (filteredCollectors , collector )
289331 } else {
290- klog .V (3 ).Infof ("Filtered out collector %s due to RBAC permissions" , collector .Name )
332+ // FIXED: Replace silent filtering with user-visible warnings
333+ d .rbacReporter .ReportFilteredCollector (collector , "insufficient RBAC permissions" )
334+ d .rbacReporter .ReportMissingPermission (resource .Kind , resource .Namespace , "get,list" , collector .Name )
291335 }
292336 }
293337
0 commit comments