Repository: replicatedhq/troubleshoot (go)

Issue:
ImagePullSecret analyzer panics if pass or fail is nil
The folllowing spec results in a panic when outcome is pass

```yaml
apiVersion: troubleshoot.sh/v1beta2
kind: Preflight
metadata:
  name: preflight-sample
spec:
  analyzers:
    - imagePullSecret:
        checkName: Pull from local registry
        registryName: quay.io
        outcomes:
          - fail:
              message: You won't be able to pull from local registry
```

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x172fcc2]

goroutine 1 [running]:
goroutine 1 [running]:
github.com/replicatedhq/troubleshoot/pkg/analyze.analyzeImagePullSecret(0xc00008d980, 0xc000b61978, 0x0, 0x0, 0x0)
        /home/areed/src/github.com/replicatedhq/troubleshoot/pkg/analyze/image_pull_secret.go:52 +0x322
github.com/replicatedhq/troubleshoot/pkg/analyze.Analyze(0xc000744480, 0xc000b619b0, 0xc000b61978, 0x0, 0x0, 0x0)
        /home/areed/src/github.com/replicatedhq/troubleshoot/pkg/analyze/analyzer.go:102 +0x8c5
github.com/replicatedhq/troubleshoot/pkg/preflight.CollectResult.Analyze(0xc00077db00, 0xc000169890, 0x2, 0x2, 0x0, 0xc000166f20, 0xc00077db00, 0xc000169890, 0x2)
        /home/areed/src/github.com/replicatedhq/troubleshoot/pkg/preflight/analyze.go:33 +0x18f
github.com/replicatedhq/troubleshoot/cmd/preflight/cli.runPreflights(0xc00024c500, 0x7fffa4ec8737, 0x9, 0x0, 0x0)
        /home/areed/src/github.com/replicatedhq/troubleshoot/cmd/preflight/cli/run.go:129 +0x9fc
github.com/replicatedhq/troubleshoot/cmd/preflight/cli.RootCmd.func2(0xc0006c5180, 0xc0006f10b0, 0x1, 0x1, 0x0, 0x0)
        /home/areed/src/github.com/replicatedhq/troubleshoot/cmd/preflight/cli/root.go:29 +0x4d
github.com/spf13/cobra.(*Command).execute(0xc0006c5180, 0xc000128030, 0x1, 0x1, 0xc0006c5180, 0xc000128030)
        /home/areed/pkg/mod/github.com/spf13/cobra@v0.0.5/command.go:826 +0x47c
github.com/spf13/cobra.(*Command).ExecuteC(0xc0006c5180, 0x0, 0x0, 0x0)
        /home/areed/pkg/mod/github.com/spf13/cobra@v0.0.5/command.go:914 +0x30b
github.com/spf13/cobra.(*Command).Execute(...)
        /home/areed/pkg/mod/github.com/spf13/cobra@v0.0.5/command.go:864
github.com/replicatedhq/troubleshoot/cmd/preflight/cli.InitAndExecute()
        /home/areed/src/github.com/replicatedhq/troubleshoot/cmd/preflight/cli/root.go:52 +0x2a
main.main()
        /home/areed/src/github.com/replicatedhq/troubleshoot/cmd/preflight/main.go:9 +0x25
```

Pull request:
ImagePullSecret and TextAnalyzer with regex fixed
Hi @areed @divolgin , I added a default message for the ImagePullSecret Analyzer. Fix #263 

Patch:
diff --git a/pkg/analyze/database_shared.go b/pkg/analyze/database_shared.go
index 55fe8f5d..f0b56f51 100644
--- a/pkg/analyze/database_shared.go
+++ b/pkg/analyze/database_shared.go
@@ -35,18 +35,14 @@ func compareDatabaseConditionalToActual(conditional string, result *collect.Data
 		return false, errors.New("unable to parse postgres connected analyzer")
 
 	case "version":
-		expected, err := semver.ParseTolerant(strings.Replace(parts[2], "x", "0", -1))
+		expectedRange, err := semver.ParseRange(fmt.Sprintf("%s %s", parts[1], parts[2]))
 		if err != nil {
-			return false, errors.Wrap(err, "failed to parse expected version")
-		}
-		actual, err := semver.ParseTolerant(strings.Replace(result.Version, "x", "0", -1))
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse postgres db actual version")
+			return false, errors.Wrap(err, "failed to parse semver range")
 		}
 
-		expectedRange, err := semver.ParseRange(fmt.Sprintf("%s %s", parts[1], expected.String()))
+		actual, err := semver.Parse(result.Version)
 		if err != nil {
-			return false, errors.Wrap(err, "failed to parse semver range")
+			return false, errors.Wrap(err, "failed to parse actual psotgres version")
 		}
 
 		return expectedRange(actual), nil
diff --git a/pkg/analyze/image_pull_secret.go b/pkg/analyze/image_pull_secret.go
index 4fbc5546..264bd78e 100644
--- a/pkg/analyze/image_pull_secret.go
+++ b/pkg/analyze/image_pull_secret.go
@@ -2,6 +2,7 @@ package analyzer
 
 import (
 	"encoding/json"
+	"fmt"
 
 	"github.com/pkg/errors"
 	troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
@@ -13,13 +14,13 @@ func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getCh
 		return nil, errors.Wrap(err, "failed to get file contents for image pull secrets")
 	}
 
-	var failOutcome *troubleshootv1beta2.Outcome
-	var passOutcome *troubleshootv1beta2.Outcome
+	var failOutcome *troubleshootv1beta2.SingleOutcome
+	var passOutcome *troubleshootv1beta2.SingleOutcome
 	for _, outcome := range analyzer.Outcomes {
 		if outcome.Fail != nil {
-			failOutcome = outcome
+			failOutcome = outcome.Fail
 		} else if outcome.Pass != nil {
-			passOutcome = outcome
+			passOutcome = outcome.Pass
 		}
 	}
 	title := analyzer.CheckName
@@ -32,8 +33,10 @@ func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getCh
 		IconKey: "kubernetes_image_pull_secret",
 		IconURI: "https://troubleshoot.sh/images/analyzer-icons/image-pull-secret.svg?w=16&h=14",
 		IsFail:  true,
-		Message: failOutcome.Fail.Message,
-		URI:     failOutcome.Fail.URI,
+	}
+	if failOutcome != nil {
+		result.Message = failOutcome.Message
+		result.URI = failOutcome.URI
 	}
 
 	for _, v := range imagePullSecrets {
@@ -46,11 +49,20 @@ func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getCh
 			if registry == analyzer.RegistryName {
 				result.IsPass = true
 				result.IsFail = false
-				result.Message = passOutcome.Pass.Message
-				result.URI = passOutcome.Pass.URI
+				if passOutcome != nil {
+					result.Message = passOutcome.Message
+					result.URI = passOutcome.URI
+				}
 			}
 		}
 	}
 
+	if result.Message == "" {
+		if result.IsPass {
+			result.Message = fmt.Sprintf("Credentials to pull from: %s found", analyzer.RegistryName)
+		} else {
+			result.Message = fmt.Sprintf("Credentials to pull from: %s not ound", analyzer.RegistryName)
+		}
+	}
 	return &result, nil
 }
diff --git a/pkg/analyze/text_analyze.go b/pkg/analyze/text_analyze.go
index 705f5315..203dd246 100644
--- a/pkg/analyze/text_analyze.go
+++ b/pkg/analyze/text_analyze.go
@@ -82,33 +82,35 @@ func analyzeRegexPattern(pattern string, collected []byte, outcomes []*troublesh
 		return nil, errors.Wrapf(err, "failed to compile regex: %s", pattern)
 	}
 
-	var failOutcome *troubleshootv1beta2.Outcome
-	var passOutcome *troubleshootv1beta2.Outcome
+	var failOutcome *troubleshootv1beta2.SingleOutcome
+	var passOutcome *troubleshootv1beta2.SingleOutcome
 	for _, outcome := range outcomes {
 		if outcome.Fail != nil {
-			failOutcome = outcome
+			failOutcome = outcome.Fail
 		} else if outcome.Pass != nil {
-			passOutcome = outcome
+			passOutcome = outcome.Pass
 		}
 	}
-
-	if re.MatchString(string(collected)) {
-		return &AnalyzeResult{
-			Title:   checkName,
-			IsPass:  true,
-			Message: passOutcome.Pass.Message,
-			URI:     passOutcome.Pass.URI,
-		}, nil
-	}
-
-	return &AnalyzeResult{
+	result := AnalyzeResult{
 		Title:   checkName,
 		IconKey: "kubernetes_text_analyze",
 		IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
-		IsFail:  true,
-		Message: failOutcome.Fail.Message,
-		URI:     failOutcome.Fail.URI,
-	}, nil
+	}
+
+	if re.MatchString(string(collected)) {
+		result.IsPass = true
+		if passOutcome != nil {
+			result.Message = passOutcome.Message
+			result.URI = passOutcome.URI
+		}
+		return &result, nil
+	}
+	result.IsFail = true
+	if failOutcome != nil {
+		result.Message = failOutcome.Message
+		result.URI = failOutcome.URI
+	}
+	return &result, nil
 }
 
 func analyzeRegexGroups(pattern string, collected []byte, outcomes []*troubleshootv1beta2.Outcome, checkName string) (*AnalyzeResult, error) {


Test patch:
diff --git a/pkg/analyze/text_analyze_test.go b/pkg/analyze/text_analyze_test.go
index 2e351240..981dd781 100644
--- a/pkg/analyze/text_analyze_test.go
+++ b/pkg/analyze/text_analyze_test.go
@@ -45,6 +45,8 @@ func Test_textAnalyze(t *testing.T) {
 					IsFail:  false,
 					Title:   "text-collector-1",
 					Message: "pass",
+					IconKey: "kubernetes_text_analyze",
+					IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
 				},
 			},
 			files: map[string][]byte{
@@ -145,6 +147,8 @@ func Test_textAnalyze(t *testing.T) {
 					IsFail:  false,
 					Title:   "text-collector-5",
 					Message: "success",
+					IconKey: "kubernetes_text_analyze",
+					IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
 				},
 			},
 			files: map[string][]byte{
@@ -245,6 +249,8 @@ func Test_textAnalyze(t *testing.T) {
 					IsFail:  false,
 					Title:   "text-collector-1",
 					Message: "pass",
+					IconKey: "kubernetes_text_analyze",
+					IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
 				},
 				{
 					IsPass:  false,