@@ -3,6 +3,7 @@ package supportbundle
33import (
44 "bytes"
55 "context"
6+ "encoding/json"
67 "fmt"
78 "net/http"
89 "os"
@@ -22,6 +23,8 @@ import (
2223 "github.com/replicatedhq/troubleshoot/pkg/convert"
2324 "github.com/replicatedhq/troubleshoot/pkg/version"
2425 "go.opentelemetry.io/otel"
26+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+ "k8s.io/client-go/kubernetes"
2528 "k8s.io/client-go/rest"
2629 "k8s.io/klog/v2"
2730)
@@ -46,6 +49,11 @@ type SupportBundleResponse struct {
4649 FileUploaded bool
4750}
4851
52+ // NodeList is a list of remote nodes to collect data from in a support bundle
53+ type NodeList struct {
54+ Nodes []string `json:"nodes"`
55+ }
56+
4957// CollectSupportBundleFromSpec collects support bundle from start to finish, including running
5058// collectors, analyzers and after collection steps. Input arguments are specifications.
5159// if FromCLI option is set to true, the output is the name of the archive on disk in the cwd.
@@ -98,7 +106,7 @@ func CollectSupportBundleFromSpec(
98106 return nil , errors .Wrap (err , "create bundle dir" )
99107 }
100108
101- var result , files , hostFiles collect.CollectorResult
109+ result := make ( collect.CollectorResult )
102110
103111 ctx , root := otel .Tracer (constants .LIB_TRACER_NAME ).Start (
104112 context .Background (), constants .TROUBLESHOOT_ROOT_SPAN_NAME ,
@@ -110,10 +118,32 @@ func CollectSupportBundleFromSpec(
110118 root .End ()
111119 }()
112120
121+ // only create a node list if we are running host collectors in a pod
122+ if opts .RunHostCollectorsInPod {
123+ clientset , err := kubernetes .NewForConfig (opts .KubernetesRestConfig )
124+ if err != nil {
125+ return nil , errors .Wrap (err , "failed to create kubernetes clientset to run host collectors in pod" )
126+ }
127+ nodeList , err := getNodeList (clientset , opts )
128+ if err != nil {
129+ return nil , errors .Wrap (err , "failed to get remote node list" )
130+ }
131+ nodeListBytes , err := json .MarshalIndent (nodeList , "" , " " )
132+ if err != nil {
133+ return nil , errors .Wrap (err , "failed to marshal remote node list" )
134+ }
135+ err = result .SaveResult (bundlePath , constants .NODE_LIST_FILE , bytes .NewBuffer (nodeListBytes ))
136+ if err != nil {
137+ return nil , errors .Wrap (err , "failed to write remote node list" )
138+ }
139+ }
140+
113141 // Cache error returned by collectors and return it at the end of the function
114142 // so as to have a chance to run analyzers and archive the support bundle after.
115143 // If both host and in cluster collectors fail, the errors will be wrapped
116144 collectorsErrs := []string {}
145+ var files , hostFiles collect.CollectorResult
146+
117147 if spec .HostCollectors != nil {
118148 // Run host collectors
119149 hostFiles , err = runHostCollectors (ctx , spec .HostCollectors , additionalRedactors , bundlePath , opts )
@@ -130,16 +160,16 @@ func CollectSupportBundleFromSpec(
130160 }
131161 }
132162
133- if files != nil && hostFiles != nil {
134- result = files
135- for k , v := range hostFiles {
136- result [ k ] = v
137- }
138- } else if files != nil {
139- result = files
140- } else if hostFiles != nil {
141- result = hostFiles
142- } else {
163+ // merge in-cluster and host collectors results
164+ for k , v := range files {
165+ result [ k ] = v
166+ }
167+
168+ for k , v := range hostFiles {
169+ result [ k ] = v
170+ }
171+
172+ if len ( result ) == 0 {
143173 if len (collectorsErrs ) > 0 {
144174 return nil , fmt .Errorf ("failed to generate support bundle: %s" , strings .Join (collectorsErrs , "\n " ))
145175 }
@@ -288,3 +318,18 @@ func ConcatSpec(target *troubleshootv1beta2.SupportBundle, source *troubleshootv
288318 }
289319 return newBundle
290320}
321+
322+ func getNodeList (clientset kubernetes.Interface , opts SupportBundleCreateOpts ) (* NodeList , error ) {
323+ // todo: any node filtering on opts?
324+ nodes , err := clientset .CoreV1 ().Nodes ().List (context .Background (), metav1.ListOptions {})
325+ if err != nil {
326+ return nil , errors .Wrap (err , "failed to list nodes" )
327+ }
328+
329+ nodeList := NodeList {}
330+ for _ , node := range nodes .Items {
331+ nodeList .Nodes = append (nodeList .Nodes , node .Name )
332+ }
333+
334+ return & nodeList , nil
335+ }
0 commit comments