Skip to content

Commit f0b8de6

Browse files
feat: multiple nodes analyzers (#1667)
* implement refactor for multiple node analyzers --------- Co-authored-by: Diamon Wiggins <[email protected]>
1 parent 544a700 commit f0b8de6

29 files changed

+853
-1130
lines changed

pkg/analyze/collected_contents.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ import (
1010

1111
type collectedContent struct {
1212
NodeName string
13-
Data collectorData
13+
Data []byte
1414
}
1515

16-
type collectorData interface{}
17-
1816
type nodeNames struct {
1917
Nodes []string `json:"nodes"`
2018
}

pkg/analyze/host_analyzer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (c *resultCollector) get(title string) []*AnalyzeResult {
8989
return []*AnalyzeResult{{Title: title, IsWarn: true, Message: "no results"}}
9090
}
9191

92-
func analyzeHostCollectorResults(collectedContent []collectedContent, outcomes []*troubleshootv1beta2.Outcome, checkCondition func(string, collectorData) (bool, error), title string) ([]*AnalyzeResult, error) {
92+
func analyzeHostCollectorResults(collectedContent []collectedContent, outcomes []*troubleshootv1beta2.Outcome, checkCondition func(string, []byte) (bool, error), title string) ([]*AnalyzeResult, error) {
9393
var results []*AnalyzeResult
9494
for _, content := range collectedContent {
9595
currentTitle := title
@@ -108,7 +108,7 @@ func analyzeHostCollectorResults(collectedContent []collectedContent, outcomes [
108108
return results, nil
109109
}
110110

111-
func evaluateOutcomes(outcomes []*troubleshootv1beta2.Outcome, checkCondition func(string, collectorData) (bool, error), data collectorData, title string) ([]*AnalyzeResult, error) {
111+
func evaluateOutcomes(outcomes []*troubleshootv1beta2.Outcome, checkCondition func(string, []byte) (bool, error), data []byte, title string) ([]*AnalyzeResult, error) {
112112
var results []*AnalyzeResult
113113

114114
for _, outcome := range outcomes {

pkg/analyze/host_analyzer_test.go

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package analyzer
22

33
import (
4+
"encoding/json"
45
"testing"
56

67
"github.com/pkg/errors"
@@ -10,25 +11,30 @@ import (
1011
"github.com/stretchr/testify/require"
1112
)
1213

14+
func collectorToBytes(t *testing.T, collector any) []byte {
15+
jsonData, err := json.Marshal(collector)
16+
require.NoError(t, err)
17+
return jsonData
18+
}
19+
1320
func TestAnalyzeHostCollectorResults(t *testing.T) {
1421
tests := []struct {
1522
name string
1623
outcomes []*troubleshootv1beta2.Outcome
1724
collectedContent []collectedContent
18-
checkCondition func(string, collectorData) (bool, error)
1925
expectResult []*AnalyzeResult
2026
}{
2127
{
2228
name: "pass if ubuntu >= 00.1.2",
2329
collectedContent: []collectedContent{
2430
{
2531
NodeName: "node1",
26-
Data: collect.HostOSInfo{
32+
Data: collectorToBytes(t, collect.HostOSInfo{
2733
Name: "myhost",
2834
KernelVersion: "5.4.0-1034-gcp",
2935
PlatformVersion: "00.1.2",
3036
Platform: "ubuntu",
31-
},
37+
}),
3238
},
3339
},
3440
outcomes: []*troubleshootv1beta2.Outcome{
@@ -44,10 +50,6 @@ func TestAnalyzeHostCollectorResults(t *testing.T) {
4450
},
4551
},
4652
},
47-
checkCondition: func(when string, data collectorData) (bool, error) {
48-
osInfo := data.(collect.HostOSInfo)
49-
return osInfo.Platform == "ubuntu" && osInfo.PlatformVersion >= "00.1.2", nil
50-
},
5153
expectResult: []*AnalyzeResult{
5254
{
5355
Title: "Host OS Info - Node node1",
@@ -61,21 +63,21 @@ func TestAnalyzeHostCollectorResults(t *testing.T) {
6163
collectedContent: []collectedContent{
6264
{
6365
NodeName: "node1",
64-
Data: collect.HostOSInfo{
66+
Data: collectorToBytes(t, collect.HostOSInfo{
6567
Name: "myhost",
6668
KernelVersion: "5.4.0-1034-gcp",
6769
PlatformVersion: "11.04",
6870
Platform: "ubuntu",
69-
},
71+
}),
7072
},
7173
{
7274
NodeName: "node2",
73-
Data: collect.HostOSInfo{
75+
Data: collectorToBytes(t, collect.HostOSInfo{
7476
Name: "myhost",
7577
KernelVersion: "5.4.0-1034-gcp",
7678
PlatformVersion: "11.04",
7779
Platform: "ubuntu",
78-
},
80+
}),
7981
},
8082
},
8183
outcomes: []*troubleshootv1beta2.Outcome{
@@ -91,10 +93,6 @@ func TestAnalyzeHostCollectorResults(t *testing.T) {
9193
},
9294
},
9395
},
94-
checkCondition: func(when string, data collectorData) (bool, error) {
95-
osInfo := data.(collect.HostOSInfo)
96-
return osInfo.Platform == "ubuntu" && osInfo.PlatformVersion <= "11.04", nil
97-
},
9896
expectResult: []*AnalyzeResult{
9997
{
10098
Title: "Host OS Info - Node node1",
@@ -113,12 +111,12 @@ func TestAnalyzeHostCollectorResults(t *testing.T) {
113111
collectedContent: []collectedContent{
114112
{
115113
NodeName: "",
116-
Data: collect.HostOSInfo{
114+
Data: collectorToBytes(t, collect.HostOSInfo{
117115
Name: "myhost",
118116
KernelVersion: "5.4.0-1034-gcp",
119117
PlatformVersion: "20.04",
120118
Platform: "ubuntu",
121-
},
119+
}),
122120
},
123121
},
124122
outcomes: []*troubleshootv1beta2.Outcome{
@@ -134,10 +132,6 @@ func TestAnalyzeHostCollectorResults(t *testing.T) {
134132
},
135133
},
136134
},
137-
checkCondition: func(when string, data collectorData) (bool, error) {
138-
osInfo := data.(collect.HostOSInfo)
139-
return osInfo.Platform == "ubuntu" && osInfo.PlatformVersion >= "20.04", nil
140-
},
141135
expectResult: []*AnalyzeResult{
142136
{
143137
Title: "Host OS Info", // Ensuring the title does not include node name if it's empty
@@ -150,8 +144,9 @@ func TestAnalyzeHostCollectorResults(t *testing.T) {
150144

151145
for _, test := range tests {
152146
t.Run(test.name, func(t *testing.T) {
147+
a := AnalyzeHostOS{}
153148
// Call the new analyzeHostCollectorResults function with the test data
154-
result, err := analyzeHostCollectorResults(test.collectedContent, test.outcomes, test.checkCondition, "Host OS Info")
149+
result, err := analyzeHostCollectorResults(test.collectedContent, test.outcomes, a.CheckCondition, "Host OS Info")
155150
require.NoError(t, err)
156151
assert.Equal(t, test.expectResult, result)
157152
})
@@ -162,8 +157,8 @@ func TestEvaluateOutcomes(t *testing.T) {
162157
tests := []struct {
163158
name string
164159
outcomes []*troubleshootv1beta2.Outcome
165-
checkCondition func(string, collectorData) (bool, error)
166-
data collectorData
160+
checkCondition func(string, []byte) (bool, error)
161+
data []byte
167162
expectedResult []*AnalyzeResult
168163
}{
169164
{
@@ -176,11 +171,11 @@ func TestEvaluateOutcomes(t *testing.T) {
176171
},
177172
},
178173
},
179-
checkCondition: func(when string, data collectorData) (bool, error) {
174+
checkCondition: func(when string, data []byte) (bool, error) {
180175
// Return true if the condition being checked matches "failCondition"
181176
return when == "failCondition", nil
182177
},
183-
data: "someData",
178+
data: []byte("someData"),
184179
expectedResult: []*AnalyzeResult{
185180
{
186181
Title: "Test Title",
@@ -199,11 +194,11 @@ func TestEvaluateOutcomes(t *testing.T) {
199194
},
200195
},
201196
},
202-
checkCondition: func(when string, data collectorData) (bool, error) {
197+
checkCondition: func(when string, data []byte) (bool, error) {
203198
// Return true if the condition being checked matches "warnCondition"
204199
return when == "warnCondition", nil
205200
},
206-
data: "someData",
201+
data: []byte("someData"),
207202
expectedResult: []*AnalyzeResult{
208203
{
209204
Title: "Test Title",
@@ -222,11 +217,11 @@ func TestEvaluateOutcomes(t *testing.T) {
222217
},
223218
},
224219
},
225-
checkCondition: func(when string, data collectorData) (bool, error) {
220+
checkCondition: func(when string, data []byte) (bool, error) {
226221
// Return true if the condition being checked matches "passCondition"
227222
return when == "passCondition", nil
228223
},
229-
data: "someData",
224+
data: []byte("someData"),
230225
expectedResult: []*AnalyzeResult{
231226
{
232227
Title: "Test Title",
@@ -253,11 +248,11 @@ func TestEvaluateOutcomes(t *testing.T) {
253248
},
254249
},
255250
},
256-
checkCondition: func(when string, data collectorData) (bool, error) {
251+
checkCondition: func(when string, data []byte) (bool, error) {
257252
// Always return false to simulate no condition matching
258253
return false, nil
259254
},
260-
data: "someData",
255+
data: []byte("someData"),
261256
expectedResult: nil, // No condition matches, so we expect no results
262257
},
263258
{
@@ -270,11 +265,11 @@ func TestEvaluateOutcomes(t *testing.T) {
270265
},
271266
},
272267
},
273-
checkCondition: func(when string, data collectorData) (bool, error) {
268+
checkCondition: func(when string, data []byte) (bool, error) {
274269
// Simulate an error occurring during condition evaluation
275270
return false, errors.New("mock error")
276271
},
277-
data: "someData",
272+
data: []byte("someData"),
278273
expectedResult: []*AnalyzeResult{
279274
{
280275
Title: "Test Title",

pkg/analyze/host_block_devices.go

Lines changed: 24 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -27,90 +27,24 @@ func (a *AnalyzeHostBlockDevices) IsExcluded() (bool, error) {
2727
func (a *AnalyzeHostBlockDevices) Analyze(
2828
getCollectedFileContents func(string) ([]byte, error), findFiles getChildCollectedFileContents,
2929
) ([]*AnalyzeResult, error) {
30-
hostAnalyzer := a.hostAnalyzer
31-
32-
contents, err := getCollectedFileContents(collect.HostBlockDevicesPath)
30+
result := AnalyzeResult{Title: a.Title()}
31+
32+
collectedContents, err := retrieveCollectedContents(
33+
getCollectedFileContents,
34+
collect.HostBlockDevicesPath,
35+
collect.NodeInfoBaseDir,
36+
collect.HostBlockDevicesFileName,
37+
)
3338
if err != nil {
34-
return nil, errors.Wrap(err, "failed to get collected file")
39+
return []*AnalyzeResult{&result}, err
3540
}
3641

37-
var devices []collect.BlockDeviceInfo
38-
if err := json.Unmarshal(contents, &devices); err != nil {
39-
return nil, errors.Wrap(err, "failed to unmarshal block devices info")
40-
}
41-
42-
result := AnalyzeResult{}
43-
44-
result.Title = a.Title()
45-
46-
for _, outcome := range hostAnalyzer.Outcomes {
47-
if outcome.Fail != nil {
48-
if outcome.Fail.When == "" {
49-
result.IsFail = true
50-
result.Message = outcome.Fail.Message
51-
result.URI = outcome.Fail.URI
52-
53-
return []*AnalyzeResult{&result}, nil
54-
}
55-
56-
isMatch, err := compareHostBlockDevicesConditionalToActual(outcome.Fail.When, hostAnalyzer.MinimumAcceptableSize, hostAnalyzer.IncludeUnmountedPartitions, devices)
57-
if err != nil {
58-
return nil, errors.Wrapf(err, "failed to compare %s", outcome.Fail.When)
59-
}
60-
61-
if isMatch {
62-
result.IsFail = true
63-
result.Message = outcome.Fail.Message
64-
result.URI = outcome.Fail.URI
65-
66-
return []*AnalyzeResult{&result}, nil
67-
}
68-
} else if outcome.Warn != nil {
69-
if outcome.Warn.When == "" {
70-
result.IsWarn = true
71-
result.Message = outcome.Warn.Message
72-
result.URI = outcome.Warn.URI
73-
74-
return []*AnalyzeResult{&result}, nil
75-
}
76-
77-
isMatch, err := compareHostBlockDevicesConditionalToActual(outcome.Warn.When, hostAnalyzer.MinimumAcceptableSize, hostAnalyzer.IncludeUnmountedPartitions, devices)
78-
if err != nil {
79-
return nil, errors.Wrapf(err, "failed to compare %s", outcome.Warn.When)
80-
}
81-
82-
if isMatch {
83-
result.IsWarn = true
84-
result.Message = outcome.Warn.Message
85-
result.URI = outcome.Warn.URI
86-
87-
return []*AnalyzeResult{&result}, nil
88-
}
89-
} else if outcome.Pass != nil {
90-
if outcome.Pass.When == "" {
91-
result.IsPass = true
92-
result.Message = outcome.Pass.Message
93-
result.URI = outcome.Pass.URI
94-
95-
return []*AnalyzeResult{&result}, nil
96-
}
97-
98-
isMatch, err := compareHostBlockDevicesConditionalToActual(outcome.Pass.When, hostAnalyzer.MinimumAcceptableSize, hostAnalyzer.IncludeUnmountedPartitions, devices)
99-
if err != nil {
100-
return nil, errors.Wrapf(err, "failed to compare %s", outcome.Pass.When)
101-
}
102-
103-
if isMatch {
104-
result.IsPass = true
105-
result.Message = outcome.Pass.Message
106-
result.URI = outcome.Pass.URI
107-
108-
return []*AnalyzeResult{&result}, nil
109-
}
110-
}
42+
results, err := analyzeHostCollectorResults(collectedContents, a.hostAnalyzer.Outcomes, a.CheckCondition, a.Title())
43+
if err != nil {
44+
return nil, errors.Wrap(err, "failed to analyze block devices")
11145
}
11246

113-
return []*AnalyzeResult{&result}, nil
47+
return results, nil
11448
}
11549

11650
// <regexp> <op> <count>
@@ -205,3 +139,14 @@ func isEligibleBlockDevice(rx *regexp.Regexp, minimumAcceptableSize uint64, incl
205139

206140
return true
207141
}
142+
143+
func (a *AnalyzeHostBlockDevices) CheckCondition(when string, data []byte) (bool, error) {
144+
145+
var devices []collect.BlockDeviceInfo
146+
if err := json.Unmarshal(data, &devices); err != nil {
147+
return false, errors.Wrap(err, "failed to unmarshal block devices info")
148+
}
149+
150+
return compareHostBlockDevicesConditionalToActual(when, a.hostAnalyzer.MinimumAcceptableSize, a.hostAnalyzer.IncludeUnmountedPartitions, devices)
151+
152+
}

0 commit comments

Comments
 (0)