@@ -407,20 +407,8 @@ func getDefaultContainerDisks() []DataSourceInfo {
407407
408408// searchDataSources searches for DataSource resources in the cluster
409409func searchDataSources (params api.ToolHandlerParams , query string ) ([]DataSourceInfo , error ) {
410- // Try to get dynamic client to query for DataSources
411- // Handle nil or invalid clients gracefully (e.g., in test environments)
412- if params .Kubernetes == nil {
413- // Return just the built-in containerdisk images
414- return getDefaultContainerDisks (), nil
415- }
416-
417- restConfig := params .RESTConfig ()
418- if restConfig == nil {
419- // Return just the built-in containerdisk images
420- return getDefaultContainerDisks (), nil
421- }
422-
423- dynamicClient , err := dynamic .NewForConfig (restConfig )
410+ // Get dynamic client for querying DataSources
411+ dynamicClient , err := getDynamicClient (params )
424412 if err != nil {
425413 // Return just the built-in containerdisk images
426414 return getDefaultContainerDisks (), nil
@@ -433,6 +421,43 @@ func searchDataSources(params api.ToolHandlerParams, query string) ([]DataSource
433421 Resource : "datasources" ,
434422 }
435423
424+ // Collect DataSources from well-known namespaces and all namespaces
425+ results := collectDataSources (params , dynamicClient , dataSourceGVR )
426+
427+ // Add common containerdisk images
428+ results = append (results , getDefaultContainerDisks ()... )
429+
430+ // Return helpful message if no sources found
431+ if len (results ) == 0 {
432+ return []DataSourceInfo {
433+ {
434+ Name : "No sources available" ,
435+ Namespace : "" ,
436+ Source : "No DataSources or containerdisks found" ,
437+ },
438+ }, nil
439+ }
440+
441+ return results , nil
442+ }
443+
444+ // getDynamicClient creates a dynamic Kubernetes client from the provided parameters
445+ func getDynamicClient (params api.ToolHandlerParams ) (dynamic.Interface , error ) {
446+ // Handle nil or invalid clients gracefully (e.g., in test environments)
447+ if params .Kubernetes == nil {
448+ return nil , fmt .Errorf ("kubernetes client is nil" )
449+ }
450+
451+ restConfig := params .RESTConfig ()
452+ if restConfig == nil {
453+ return nil , fmt .Errorf ("REST config is nil" )
454+ }
455+
456+ return dynamic .NewForConfig (restConfig )
457+ }
458+
459+ // collectDataSources collects DataSources from well-known namespaces and all namespaces
460+ func collectDataSources (params api.ToolHandlerParams , dynamicClient dynamic.Interface , gvr schema.GroupVersionResource ) []DataSourceInfo {
436461 var results []DataSourceInfo
437462
438463 // Try to list DataSources from well-known namespaces first
@@ -442,20 +467,18 @@ func searchDataSources(params api.ToolHandlerParams, query string) ([]DataSource
442467 }
443468
444469 for _ , ns := range wellKnownNamespaces {
445- dsInfos , err := listDataSourcesFromNamespace (params , dynamicClient , dataSourceGVR , ns )
470+ dsInfos , err := listDataSourcesFromNamespace (params , dynamicClient , gvr , ns )
446471 if err == nil {
447472 results = append (results , dsInfos ... )
448473 }
449474 }
450475
451476 // List DataSources from all namespaces
452- list , err := dynamicClient .Resource (dataSourceGVR ).List (params .Context , metav1.ListOptions {})
477+ list , err := dynamicClient .Resource (gvr ).List (params .Context , metav1.ListOptions {})
453478 if err != nil {
454- // If we found DataSources from well-known namespaces but couldn't list all, continue
479+ // If we found DataSources from well-known namespaces but couldn't list all, return what we have
455480 if len (results ) > 0 {
456- // Add common containerdisk images as well
457- results = append (results , getDefaultContainerDisks ()... )
458- return results , nil
481+ return results
459482 }
460483 // DataSources might not be available, return helpful message
461484 return []DataSourceInfo {
@@ -464,18 +487,26 @@ func searchDataSources(params api.ToolHandlerParams, query string) ([]DataSource
464487 Namespace : "" ,
465488 Source : "CDI may not be installed or DataSources are not available in this cluster" ,
466489 },
467- }, nil
490+ }
468491 }
469492
470- // Parse the results from all namespaces (this will include well-known namespaces again, but we'll deduplicate)
493+ // Deduplicate and add DataSources from all namespaces
494+ results = deduplicateAndMergeDataSources (results , list .Items )
495+
496+ return results
497+ }
498+
499+ // deduplicateAndMergeDataSources merges new DataSources with existing ones, avoiding duplicates
500+ func deduplicateAndMergeDataSources (existing []DataSourceInfo , items []unstructured.Unstructured ) []DataSourceInfo {
501+ // Create a map to track already seen DataSources
471502 seen := make (map [string ]bool )
472- // Mark DataSources from well-known namespaces as already seen
473- for _ , ds := range results {
503+ for _ , ds := range existing {
474504 key := ds .Namespace + "/" + ds .Name
475505 seen [key ] = true
476506 }
477507
478- for _ , item := range list .Items {
508+ // Add new DataSources that haven't been seen
509+ for _ , item := range items {
479510 name := item .GetName ()
480511 namespace := item .GetNamespace ()
481512 key := namespace + "/" + name
@@ -486,8 +517,6 @@ func searchDataSources(params api.ToolHandlerParams, query string) ([]DataSource
486517 }
487518
488519 labels := item .GetLabels ()
489-
490- // Extract source information from the DataSource spec
491520 source := extractDataSourceInfo (& item )
492521
493522 // Extract default instancetype and preference from labels
@@ -498,28 +527,16 @@ func searchDataSources(params api.ToolHandlerParams, query string) ([]DataSource
498527 defaultPreference = labels [defaultPreferenceLabel ]
499528 }
500529
501- results = append (results , DataSourceInfo {
530+ existing = append (existing , DataSourceInfo {
502531 Name : name ,
503532 Namespace : namespace ,
504533 Source : source ,
505534 DefaultInstancetype : defaultInstancetype ,
506535 DefaultPreference : defaultPreference ,
507536 })
508537 }
509- // Add common containerdisk images as well
510- results = append (results , getDefaultContainerDisks ()... )
511538
512- if len (results ) == 0 {
513- return []DataSourceInfo {
514- {
515- Name : "No sources available" ,
516- Namespace : "" ,
517- Source : "No DataSources or containerdisks found" ,
518- },
519- }, nil
520- }
521-
522- return results , nil
539+ return existing
523540}
524541
525542// listDataSourcesFromNamespace lists DataSources from a specific namespace
0 commit comments