Skip to content

Commit

Permalink
Analyze from the CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
marccampbell committed Jun 12, 2020
1 parent 8d991e1 commit a22e2e2
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -128,7 +128,7 @@ run-preflight: preflight

.PHONY: run-troubleshoot
run-troubleshoot: support-bundle
./bin/support-bundle ./examples/troubleshoot/sample-troubleshoot.yaml
./bin/support-bundle ./examples/troubleshoot/sample-supportbundle.yaml

.PHONY: run-analyze
run-analyze: analyze
Expand Down
77 changes: 59 additions & 18 deletions cmd/troubleshoot/cli/run.go
Expand Up @@ -21,10 +21,12 @@ import (
"github.com/mholt/archiver"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/cmd/util"
analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
"github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
"github.com/replicatedhq/troubleshoot/pkg/collect"
"github.com/replicatedhq/troubleshoot/pkg/convert"
"github.com/replicatedhq/troubleshoot/pkg/redact"
"github.com/spf13/viper"
spin "github.com/tj/go-spin"
Expand Down Expand Up @@ -132,7 +134,63 @@ func runTroubleshoot(v *viper.Viper, arg string) error {

fmt.Printf("\r%s\r", cursor.ClearEntireLine())

if len(supportBundleSpec.Spec.AfterCollection) == 0 {
// upload if needed
fileUploaded := false
if len(supportBundleSpec.Spec.AfterCollection) > 0 {
for _, ac := range supportBundleSpec.Spec.AfterCollection {
if ac.UploadResultsTo != nil {
if err := uploadSupportBundle(ac.UploadResultsTo, archivePath); err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to upload support bundle: %v\n", cursor.ClearEntireLine(), err)
} else {
fileUploaded = true
}
} else if ac.Callback != nil {
if err := callbackSupportBundleAPI(ac.Callback, archivePath); err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to notify API that support bundle has been uploaded: %v\n", cursor.ClearEntireLine(), err)
}
}
}

}

// perform analysis, if possible
if len(supportBundleSpec.Spec.Analyzers) > 0 {
tmpDir, err := ioutil.TempDir("", "troubleshoot")
if err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to make directory for analysis: %v\n", cursor.ClearEntireLine(), err)
}

f, err := os.Open(archivePath)
if err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to open support bundle for analysis: %v\n", cursor.ClearEntireLine(), err)

}
if err := analyzer.ExtractTroubleshootBundle(f, tmpDir); err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to extract support bundle for analysis: %v\n", cursor.ClearEntireLine(), err)
}

analyzeResults, err := analyzer.AnalyzeLocal(tmpDir, supportBundleSpec.Spec.Analyzers)
if err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to analyze support bundle: %v\n", cursor.ClearEntireLine(), err)
}

data := convert.FromAnalyzerResult(analyzeResults)
formatted, err := json.MarshalIndent(data, "", " ")
if err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to format analysis: %v\n", cursor.ClearEntireLine(), err)
}

fmt.Printf("%s", formatted)
}

if !fileUploaded {
msg := archivePath
if appName := supportBundleSpec.Labels["applicationName"]; appName != "" {
f := `A support bundle for %s has been created in this directory
Expand All @@ -146,23 +204,6 @@ the %s Admin Console to begin analysis.`
return nil
}

fileUploaded := false
for _, ac := range supportBundleSpec.Spec.AfterCollection {
if ac.UploadResultsTo != nil {
if err := uploadSupportBundle(ac.UploadResultsTo, archivePath); err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to upload support bundle: %v\n", cursor.ClearEntireLine(), err)
} else {
fileUploaded = true
}
} else if ac.Callback != nil {
if err := callbackSupportBundleAPI(ac.Callback, archivePath); err != nil {
c := color.New(color.FgHiRed)
c.Printf("%s\r * Failed to notify API that support bundle has been uploaded: %v\n", cursor.ClearEntireLine(), err)
}
}
}

fmt.Printf("\r%s\r", cursor.ClearEntireLine())
if fileUploaded {
fmt.Printf("A support bundle has been created and uploaded to your cluster for analysis. Please visit the Troubleshoot page to continue.\n")
Expand Down
15 changes: 14 additions & 1 deletion examples/troubleshoot/sample-supportbundle.yaml
Expand Up @@ -4,4 +4,17 @@ metadata:
name: supportbundle-sample
spec:
collectors: []
analyzers: []
analyzers:
- clusterVersion:
outcomes:
- fail:
when: "< 1.13.0"
message: The application requires at Kubernetes 1.13.0 or later, and recommends 1.15.0.
uri: https://www.kubernetes.io
- warn:
when: "< 1.15.0"
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.15.0 or later.
uri: https://kubernetes.io
- pass:
when: ">= 1.15.0"
message: Your cluster meets the recommended and required versions of Kubernetes.
45 changes: 25 additions & 20 deletions pkg/analyze/download.go
Expand Up @@ -20,6 +20,26 @@ type fileContentProvider struct {
rootDir string
}

// Analyze local will analyze a locally available (already downloaded) bundle
func AnalyzeLocal(localBundlePath string, analyzers []*troubleshootv1beta1.Analyze) ([]*AnalyzeResult, error) {
fcp := fileContentProvider{rootDir: localBundlePath}

analyzeResults := []*AnalyzeResult{}
for _, analyzer := range analyzers {
analyzeResult, err := Analyze(analyzer, fcp.getFileContents, fcp.getChildFileContents)
if err != nil {
logger.Printf("an analyzer failed to run: %v\n", err)
continue
}

if analyzeResult != nil {
analyzeResults = append(analyzeResults, analyzeResult)
}
}

return analyzeResults, nil
}

func DownloadAndAnalyze(bundleURL string, analyzersSpec string) ([]*AnalyzeResult, error) {
tmpDir, err := ioutil.TempDir("", "troubleshoot-k8s")
if err != nil {
Expand Down Expand Up @@ -52,22 +72,7 @@ func DownloadAndAnalyze(bundleURL string, analyzersSpec string) ([]*AnalyzeResul
analyzers = parsedAnalyzers
}

fcp := fileContentProvider{rootDir: tmpDir}

analyzeResults := []*AnalyzeResult{}
for _, analyzer := range analyzers {
analyzeResult, err := Analyze(analyzer, fcp.getFileContents, fcp.getChildFileContents)
if err != nil {
logger.Printf("an analyzer failed to run: %v\n", err)
continue
}

if analyzeResult != nil {
analyzeResults = append(analyzeResults, analyzeResult)
}
}

return analyzeResults, nil
return AnalyzeLocal(tmpDir, analyzers)
}

func downloadTroubleshootBundle(bundleURL string, destDir string) error {
Expand All @@ -77,15 +82,15 @@ func downloadTroubleshootBundle(bundleURL string, destDir string) error {
return errors.Wrap(err, "failed to open support bundle")
}
defer f.Close()
return extractTroubleshootBundle(f, destDir)
return ExtractTroubleshootBundle(f, destDir)
}

pwd, err := os.Getwd()
if err != nil {
return errors.Wrap(err, "failed to get workdir")
}

tmpDir, err := ioutil.TempDir("", "getter")
tmpDir, err := ioutil.TempDir("", "troubleshoot")
if err != nil {
return errors.Wrap(err, "failed to create tmp dir")
}
Expand All @@ -107,10 +112,10 @@ func downloadTroubleshootBundle(bundleURL string, destDir string) error {
}
defer f.Close()

return extractTroubleshootBundle(f, destDir)
return ExtractTroubleshootBundle(f, destDir)
}

func extractTroubleshootBundle(reader io.Reader, destDir string) error {
func ExtractTroubleshootBundle(reader io.Reader, destDir string) error {
gzReader, err := gzip.NewReader(reader)
if err != nil {
return errors.Wrap(err, "failed to create gzip reader")
Expand Down

0 comments on commit a22e2e2

Please sign in to comment.