11package cli
22
33import (
4- "encoding/base64"
5- "encoding/json"
64 "fmt"
75 "io/ioutil"
86 "net/http"
97 "os"
10- "path/filepath"
11- "strings"
128 "time"
139
1410 cursor "github.com/ahmetalpbalkan/go-cursor"
1511 "github.com/fatih/color"
1612 "github.com/pkg/errors"
17- analyzerunner "github.com/replicatedhq/troubleshoot/pkg/analyze"
1813 troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
1914 troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
20- "github.com/replicatedhq/troubleshoot/pkg/collect "
15+ "github.com/replicatedhq/troubleshoot/pkg/preflight "
2116 "github.com/spf13/viper"
2217 spin "github.com/tj/go-spin"
2318 "k8s.io/client-go/kubernetes/scheme"
@@ -66,7 +61,7 @@ func runPreflights(v *viper.Viper, arg string) error {
6661 return errors .Wrapf (err , "failed to parse %s" , arg )
6762 }
6863
69- preflight := obj .(* troubleshootv1beta1.Preflight )
64+ preflightSpec := obj .(* troubleshootv1beta1.Preflight )
7065
7166 s := spin .New ()
7267 finishedCh := make (chan bool , 1 )
@@ -98,48 +93,34 @@ func runPreflights(v *viper.Viper, arg string) error {
9893 close (finishedCh )
9994 }()
10095
101- allCollectedData , err := RunCollectors ( v , * preflight , progressChan )
96+ restConfig , err := KubernetesConfigFlags . ToRESTConfig ( )
10297 if err != nil {
103- return err
104- }
105-
106- getCollectedFileContents := func (fileName string ) ([]byte , error ) {
107- contents , ok := allCollectedData [fileName ]
108- if ! ok {
109- return nil , fmt .Errorf ("file %s was not collected" , fileName )
110- }
111-
112- return contents , nil
98+ return errors .Wrap (err , "failed to convert kube flags to rest config" )
11399 }
114- getChildCollectedFileContents := func (prefix string ) (map [string ][]byte , error ) {
115- matching := make (map [string ][]byte )
116- for k , v := range allCollectedData {
117- if strings .HasPrefix (k , prefix ) {
118- matching [k ] = v
119- }
120- }
121100
122- return matching , nil
101+ collectOpts := preflight.CollectOpts {
102+ Namespace : v .GetString ("namespace" ),
103+ IgnorePermissionErrors : v .GetBool ("collect-without-permissions" ),
104+ ProgressChan : progressChan ,
105+ KubernetesRestConfig : restConfig ,
123106 }
124107
125- analyzeResults := [] * analyzerunner. AnalyzeResult {}
126- for _ , analyzer := range preflight . Spec . Analyzers {
127- analyzeResult , err := analyzerunner . Analyze ( analyzer , getCollectedFileContents , getChildCollectedFileContents )
128- if err != nil {
129- analyzeResult = & analyzerunner. AnalyzeResult {
130- IsFail : true ,
131- Title : "Analyzer Failed" ,
132- Message : err . Error (),
108+ collectResults , err := preflight . Collect ( collectOpts , preflightSpec )
109+ if err != nil {
110+ if ! collectResults . IsRBACAllowed {
111+ if preflightSpec . Spec . UploadResultsTo != "" {
112+ err := uploadErrors ( preflightSpec . Spec . UploadResultsTo , collectResults . Collectors )
113+ if err != nil {
114+ progressChan <- err
115+ }
133116 }
134117 }
135-
136- if analyzeResult != nil {
137- analyzeResults = append (analyzeResults , analyzeResult )
138- }
118+ return err
139119 }
140120
141- if preflight .Spec .UploadResultsTo != "" {
142- err := uploadResults (preflight .Spec .UploadResultsTo , analyzeResults )
121+ analyzeResults := collectResults .Analyze ()
122+ if preflightSpec .Spec .UploadResultsTo != "" {
123+ err := uploadResults (preflightSpec .Spec .UploadResultsTo , analyzeResults )
143124 if err != nil {
144125 progressChan <- err
145126 }
@@ -151,117 +132,8 @@ func runPreflights(v *viper.Viper, arg string) error {
151132 if len (analyzeResults ) == 0 {
152133 return errors .New ("no data has been collected" )
153134 }
154- return showInteractiveResults (preflight .Name , analyzeResults )
155- }
156-
157- return showStdoutResults (v .GetString ("format" ), preflight .Name , analyzeResults )
158- }
159-
160- func RunCollectors (v * viper.Viper , preflight troubleshootv1beta1.Preflight , progressChan chan interface {}) (map [string ][]byte , error ) {
161- collectSpecs := make ([]* troubleshootv1beta1.Collect , 0 , 0 )
162- collectSpecs = append (collectSpecs , preflight .Spec .Collectors ... )
163- collectSpecs = ensureCollectorInList (collectSpecs , troubleshootv1beta1.Collect {ClusterInfo : & troubleshootv1beta1.ClusterInfo {}})
164- collectSpecs = ensureCollectorInList (collectSpecs , troubleshootv1beta1.Collect {ClusterResources : & troubleshootv1beta1.ClusterResources {}})
165-
166- allCollectedData := make (map [string ][]byte )
167-
168- config , err := KubernetesConfigFlags .ToRESTConfig ()
169- if err != nil {
170- return nil , errors .Wrap (err , "failed to convert kube flags to rest config" )
171- }
172-
173- var collectors collect.Collectors
174- for _ , desiredCollector := range collectSpecs {
175- collector := collect.Collector {
176- Redact : true ,
177- Collect : desiredCollector ,
178- ClientConfig : config ,
179- Namespace : v .GetString ("namespace" ),
180- }
181- collectors = append (collectors , & collector )
182- }
183-
184- if err := collectors .CheckRBAC (); err != nil {
185- return nil , errors .Wrap (err , "failed to check RBAC for collectors" )
186- }
187-
188- foundForbidden := false
189- for _ , c := range collectors {
190- for _ , e := range c .RBACErrors {
191- foundForbidden = true
192- progressChan <- e
193- }
194- }
195-
196- if foundForbidden && ! v .GetBool ("collect-without-permissions" ) {
197- if preflight .Spec .UploadResultsTo != "" {
198- err := uploadErrors (preflight .Spec .UploadResultsTo , collectors )
199- if err != nil {
200- progressChan <- err
201- }
202- }
203- return nil , errors .New ("insufficient permissions to run all collectors" )
204- }
205-
206- // Run preflights collectors synchronously
207- for _ , collector := range collectors {
208- if len (collector .RBACErrors ) > 0 {
209- // don't skip clusterResources collector due to RBAC issues
210- if collector .Collect .ClusterResources == nil {
211- progressChan <- fmt .Sprintf ("skipping collector %s with insufficient RBAC permissions" , collector .GetDisplayName ())
212- continue
213- }
214- }
215-
216- result , err := collector .RunCollectorSync ()
217- if err != nil {
218- progressChan <- errors .Errorf ("failed to run collector %s: %v\n " , collector .GetDisplayName (), err )
219- continue
220- }
221-
222- if result != nil {
223- output , err := parseCollectorOutput (string (result ))
224- if err != nil {
225- progressChan <- errors .Errorf ("failed to parse collector output %s: %v\n " , collector .GetDisplayName (), err )
226- continue
227- }
228- for k , v := range output {
229- allCollectedData [k ] = v
230- }
231- }
232- }
233-
234- return allCollectedData , nil
235- }
236-
237- func parseCollectorOutput (output string ) (map [string ][]byte , error ) {
238- input := make (map [string ]interface {})
239- files := make (map [string ][]byte )
240- if err := json .Unmarshal ([]byte (output ), & input ); err != nil {
241- return nil , err
242- }
243-
244- for filename , maybeContents := range input {
245- fileDir , fileName := filepath .Split (filename )
246-
247- switch maybeContents .(type ) {
248- case string :
249- decoded , err := base64 .StdEncoding .DecodeString (maybeContents .(string ))
250- if err != nil {
251- return nil , err
252- }
253- files [filepath .Join (fileDir , fileName )] = decoded
254-
255- case map [string ]interface {}:
256- for k , v := range maybeContents .(map [string ]interface {}) {
257- decoded , err := base64 .StdEncoding .DecodeString (v .(string ))
258- if err != nil {
259- return nil , err
260- }
261- files [filepath .Join (fileDir , fileName , k )] = decoded
262- }
263- }
135+ return showInteractiveResults (preflightSpec .Name , analyzeResults )
264136 }
265137
266- return files , nil
138+ return showStdoutResults ( v . GetString ( "format" ), preflightSpec . Name , analyzeResults )
267139}
0 commit comments