Skip to content

Commit 40f1f01

Browse files
authored
Merge branch 'main' into dependabot/go_modules/github.com/hashicorp/go-getter-1.6.2
2 parents a5fceaf + 2de46a1 commit 40f1f01

20 files changed

+1718
-32
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Thank you for your interest in Troubleshoot, we welcome your participation. Plea
1111
To get started we recommend:
1212

1313
1. Go (v1.17 or later)
14-
2. Kubernetes (we recommend https://k3d.io/. requires Docker v20.10.5 or later)
14+
2. A Kubernetes cluster (we recommend https://k3d.io/. This requires Docker v20.10.5 or later)
1515
3. Fork and clone the repo to $GOPATH/src/github.com/replicatedhq/
1616
4. Run `make support-bundle preflight` to generate binaries
1717
5. Run `make run-troubleshoot` to generate a support bundle with the `sample-troubleshoot.yaml` in the root of the repo

examples/preflight/sample-preflight.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ spec:
77
- clusterVersion:
88
outcomes:
99
- fail:
10-
when: "< 1.13.0"
11-
message: This application requires at least Kubernetes 1.13.0 or later, and recommends 1.15.0.
10+
when: "< 1.20.0"
11+
message: This application requires at least Kubernetes 1.20.0, and recommends 1.22.0.
1212
uri: https://www.kubernetes.io
1313
- warn:
14-
when: "< 1.15.0"
15-
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.15.0 or later.
14+
when: "< 1.22.0"
15+
message: Your cluster meets the minimum version of Kubernetes, but we recommend you update to 1.22.0 or later.
1616
uri: https://kubernetes.io
1717
- pass:
18-
when: ">= 1.15.0"
18+
when: ">= 1.22.0"
1919
message: Your cluster meets the recommended and required versions of Kubernetes.
2020
- customResourceDefinition:
2121
checkName: Ingress
@@ -28,10 +28,10 @@ spec:
2828
- containerRuntime:
2929
outcomes:
3030
- pass:
31-
when: "== docker"
32-
message: Docker container runtime was found.
31+
when: "== containerd"
32+
message: containerd container runtime was found.
3333
- fail:
34-
message: Did not find Docker container runtime.
34+
message: Did not find containerd container runtime.
3535
- storageClass:
3636
checkName: Required storage classes
3737
storageClassName: "default"
@@ -121,4 +121,4 @@ spec:
121121
message: All nodes are recommended to have at least 100 GB of ephemeral storage.
122122
uri: https://kurl.sh/docs/install-with-kurl/system-requirements
123123
- pass:
124-
message: All nodes have at least 100 GB of ephemeral storage.
124+
message: All nodes have at least 100 GB of ephemeral storage.

pkg/analyze/analyzer.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package analyzer
22

33
import (
44
"fmt"
5+
"reflect"
56
"strconv"
67

78
"github.com/pkg/errors"
@@ -339,6 +340,36 @@ func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileCont
339340
}
340341
return results, nil
341342
}
343+
if analyzer.YamlCompare != nil {
344+
isExcluded, err := isExcluded(analyzer.YamlCompare.Exclude)
345+
if err != nil {
346+
return nil, err
347+
}
348+
if isExcluded {
349+
return nil, nil
350+
}
351+
result, err := analyzeYamlCompare(analyzer.YamlCompare, getFile)
352+
if err != nil {
353+
return nil, err
354+
}
355+
result.Strict = analyzer.YamlCompare.Strict.BoolOrDefaultFalse()
356+
return []*AnalyzeResult{result}, nil
357+
}
358+
if analyzer.JsonCompare != nil {
359+
isExcluded, err := isExcluded(analyzer.JsonCompare.Exclude)
360+
if err != nil {
361+
return nil, err
362+
}
363+
if isExcluded {
364+
return nil, nil
365+
}
366+
result, err := analyzeJsonCompare(analyzer.JsonCompare, getFile)
367+
if err != nil {
368+
return nil, err
369+
}
370+
result.Strict = analyzer.JsonCompare.Strict.BoolOrDefaultFalse()
371+
return []*AnalyzeResult{result}, nil
372+
}
342373
if analyzer.Postgres != nil {
343374
isExcluded, err := isExcluded(analyzer.Postgres.Exclude)
344375
if err != nil {
@@ -472,3 +503,25 @@ func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileCont
472503

473504
return nil, errors.New("invalid analyzer")
474505
}
506+
507+
func GetExcludeFlag(analyzer *troubleshootv1beta2.Analyze) *multitype.BoolOrString {
508+
if analyzer == nil {
509+
return nil
510+
}
511+
512+
reflected := reflect.ValueOf(analyzer).Elem()
513+
for i := 0; i < reflected.NumField(); i++ {
514+
if reflected.Field(i).IsNil() {
515+
continue
516+
}
517+
518+
field := reflect.Indirect(reflected.Field(i)).FieldByName("Exclude")
519+
exclude, ok := field.Interface().(*multitype.BoolOrString)
520+
if !ok {
521+
continue
522+
}
523+
return exclude
524+
}
525+
526+
return nil
527+
}

pkg/analyze/analyzer_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package analyzer
2+
3+
import (
4+
"testing"
5+
6+
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
7+
"github.com/replicatedhq/troubleshoot/pkg/multitype"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func Test_GetExcludeFlag(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
analyzer *troubleshootv1beta2.Analyze
16+
want bool
17+
}{
18+
{
19+
name: "nil case",
20+
analyzer: nil,
21+
want: false,
22+
},
23+
{
24+
name: "true is set",
25+
analyzer: &troubleshootv1beta2.Analyze{
26+
TextAnalyze: &troubleshootv1beta2.TextAnalyze{
27+
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
28+
Exclude: multitype.FromBool(true),
29+
},
30+
},
31+
},
32+
want: true,
33+
},
34+
{
35+
name: "false is set",
36+
analyzer: &troubleshootv1beta2.Analyze{
37+
ClusterVersion: &troubleshootv1beta2.ClusterVersion{
38+
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
39+
Exclude: multitype.FromBool(false),
40+
},
41+
},
42+
},
43+
want: false,
44+
},
45+
{
46+
name: "nothing is set",
47+
analyzer: &troubleshootv1beta2.Analyze{
48+
Postgres: &troubleshootv1beta2.DatabaseAnalyze{
49+
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{},
50+
},
51+
},
52+
want: false,
53+
},
54+
}
55+
56+
for _, test := range tests {
57+
t.Run(test.name, func(t *testing.T) {
58+
req := require.New(t)
59+
60+
gotWrapped := GetExcludeFlag(test.analyzer)
61+
got, err := gotWrapped.Bool()
62+
req.NoError(err)
63+
64+
assert.Equal(t, test.want, got)
65+
})
66+
}
67+
}

pkg/analyze/ceph_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,14 @@ func Test_cephStatus(t *testing.T) {
219219
}`,
220220
},
221221
{
222-
name: "warn case with multiple health status messages",
222+
name: "warn case with health status message and summary",
223223
analyzer: troubleshootv1beta2.CephStatusAnalyze{},
224224
expectResult: AnalyzeResult{
225225
IsPass: false,
226226
IsWarn: true,
227227
IsFail: false,
228228
Title: "Ceph Status",
229-
Message: "Ceph status is HEALTH_WARN\nPOOL_NO_REDUNDANCY: 11 pool(s) have no replicas configured\nPOOL_PG_NUM_NOT_POWER_OF_TWO: 8 pool(s) have non-power-of-two pg_num",
229+
Message: "Ceph status is HEALTH_WARN\nPOOL_NO_REDUNDANCY: 11 pool(s) have no replicas configured",
230230
URI: "https://rook.io/docs/rook/v1.4/ceph-common-issues.html",
231231
IconKey: "rook",
232232
IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16",
@@ -244,12 +244,6 @@ func Test_cephStatus(t *testing.T) {
244244
"count": 11
245245
},
246246
"muted": false
247-
},
248-
"POOL_PG_NUM_NOT_POWER_OF_TWO": {
249-
"severity": "HEALTH_WARN",
250-
"summary": {
251-
"message": "8 pool(s) have non-power-of-two pg_num"
252-
}
253247
}
254248
}
255249
}

pkg/analyze/json_compare.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package analyzer
2+
3+
import (
4+
"encoding/json"
5+
"path/filepath"
6+
"reflect"
7+
"strconv"
8+
9+
"github.com/pkg/errors"
10+
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
11+
iutils "github.com/replicatedhq/troubleshoot/pkg/interfaceutils"
12+
)
13+
14+
func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
15+
fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName)
16+
collected, err := getCollectedFileContents(fullPath)
17+
if err != nil {
18+
return nil, errors.Wrapf(err, "failed to read collected file name: %s", fullPath)
19+
}
20+
21+
var actual interface{}
22+
err = json.Unmarshal(collected, &actual)
23+
if err != nil {
24+
return nil, errors.Wrap(err, "failed to parse collected data as json")
25+
}
26+
27+
if analyzer.Path != "" {
28+
actual, err = iutils.GetAtPath(actual, analyzer.Path)
29+
if err != nil {
30+
return nil, errors.Wrapf(err, "failed to get object at path: %s", analyzer.Path)
31+
}
32+
}
33+
34+
var expected interface{}
35+
err = json.Unmarshal([]byte(analyzer.Value), &expected)
36+
if err != nil {
37+
return nil, errors.Wrap(err, "failed to parse expected value as json")
38+
}
39+
40+
title := analyzer.CheckName
41+
if title == "" {
42+
title = analyzer.CollectorName
43+
}
44+
45+
result := &AnalyzeResult{
46+
Title: title,
47+
IconKey: "kubernetes_text_analyze",
48+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
49+
}
50+
51+
equal := reflect.DeepEqual(actual, expected)
52+
53+
for _, outcome := range analyzer.Outcomes {
54+
if outcome.Fail != nil {
55+
when := false
56+
if outcome.Fail.When != "" {
57+
when, err = strconv.ParseBool(outcome.Fail.When)
58+
if err != nil {
59+
return nil, errors.Wrapf(err, "failed to process when statement: %s", outcome.Fail.When)
60+
}
61+
}
62+
63+
if when == equal {
64+
result.IsFail = true
65+
result.Message = outcome.Fail.Message
66+
result.URI = outcome.Fail.URI
67+
68+
return result, nil
69+
}
70+
} else if outcome.Warn != nil {
71+
when := false
72+
if outcome.Warn.When != "" {
73+
when, err = strconv.ParseBool(outcome.Warn.When)
74+
if err != nil {
75+
return nil, errors.Wrapf(err, "failed to process when statement: %s", outcome.Warn.When)
76+
}
77+
}
78+
79+
if when == equal {
80+
result.IsWarn = true
81+
result.Message = outcome.Warn.Message
82+
result.URI = outcome.Warn.URI
83+
84+
return result, nil
85+
}
86+
} else if outcome.Pass != nil {
87+
when := true // default to passing when values are equal
88+
if outcome.Pass.When != "" {
89+
when, err = strconv.ParseBool(outcome.Pass.When)
90+
if err != nil {
91+
return nil, errors.Wrapf(err, "failed to process when statement: %s", outcome.Pass.When)
92+
}
93+
}
94+
95+
if when == equal {
96+
result.IsPass = true
97+
result.Message = outcome.Pass.Message
98+
result.URI = outcome.Pass.URI
99+
100+
return result, nil
101+
}
102+
}
103+
}
104+
105+
return &AnalyzeResult{
106+
Title: title,
107+
IconKey: "kubernetes_text_analyze",
108+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
109+
IsFail: true,
110+
Message: "Invalid analyzer",
111+
}, nil
112+
}

0 commit comments

Comments
 (0)