Skip to content

Commit 4fca6af

Browse files
Deduplication for In-Cluster Collectors (#972)
* adding dedup for in cluster collectors * add tests * return collector as is whenever marshalling to json fails --------- Co-authored-by: Evans Mungai <[email protected]>
1 parent f27c64c commit 4fca6af

File tree

6 files changed

+136
-29
lines changed

6 files changed

+136
-29
lines changed

cmd/troubleshoot/cli/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ the %s Admin Console to begin analysis.`
328328
return nil
329329
}
330330

331-
fmt.Printf("%s\n", response.ArchivePath)
331+
fmt.Printf("\n%s\n", response.ArchivePath)
332332
return nil
333333
}
334334

pkg/collect/collect.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -190,31 +190,3 @@ func CollectRemote(c *troubleshootv1beta2.RemoteCollector, additionalRedactors *
190190
collectResult.AllCollectedData = allCollectedData
191191
return collectResult, nil
192192
}
193-
194-
// Ensure that the specified collector is in the list of collectors
195-
func EnsureCollectorInList(list []*troubleshootv1beta2.Collect, collector troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect {
196-
for _, inList := range list {
197-
if collector.ClusterResources != nil && inList.ClusterResources != nil {
198-
return list
199-
}
200-
if collector.ClusterInfo != nil && inList.ClusterInfo != nil {
201-
return list
202-
}
203-
}
204-
205-
return append(list, &collector)
206-
}
207-
208-
// collect ClusterResources earliest in the list so the pod list does not include pods started by collectors
209-
func EnsureClusterResourcesFirst(list []*troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect {
210-
sliceOfClusterResources := []*troubleshootv1beta2.Collect{}
211-
sliceOfOtherCollectors := []*troubleshootv1beta2.Collect{}
212-
for _, collector := range list {
213-
if collector.ClusterResources != nil {
214-
sliceOfClusterResources = append(sliceOfClusterResources, []*troubleshootv1beta2.Collect{collector}...)
215-
} else {
216-
sliceOfOtherCollectors = append(sliceOfOtherCollectors, []*troubleshootv1beta2.Collect{collector}...)
217-
}
218-
}
219-
return append(sliceOfClusterResources, sliceOfOtherCollectors...)
220-
}

pkg/collect/collector.go

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

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"strconv"
78
"strings"
@@ -189,3 +190,54 @@ func getCollectorName(c interface{}) string {
189190
}
190191
return collector
191192
}
193+
194+
// Ensure that the specified collector is in the list of collectors
195+
func EnsureCollectorInList(list []*troubleshootv1beta2.Collect, collector troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect {
196+
for _, inList := range list {
197+
if collector.ClusterResources != nil && inList.ClusterResources != nil {
198+
return list
199+
}
200+
if collector.ClusterInfo != nil && inList.ClusterInfo != nil {
201+
return list
202+
}
203+
}
204+
205+
return append(list, &collector)
206+
}
207+
208+
// collect ClusterResources earliest in the list so the pod list does not include pods started by collectors
209+
func EnsureClusterResourcesFirst(list []*troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect {
210+
sliceOfClusterResources := []*troubleshootv1beta2.Collect{}
211+
sliceOfOtherCollectors := []*troubleshootv1beta2.Collect{}
212+
for _, collector := range list {
213+
if collector.ClusterResources != nil {
214+
sliceOfClusterResources = append(sliceOfClusterResources, []*troubleshootv1beta2.Collect{collector}...)
215+
} else {
216+
sliceOfOtherCollectors = append(sliceOfOtherCollectors, []*troubleshootv1beta2.Collect{collector}...)
217+
}
218+
}
219+
return append(sliceOfClusterResources, sliceOfOtherCollectors...)
220+
}
221+
222+
// deduplicates a list of troubleshootv1beta2.Collect objects
223+
// marshals object to json and then uses its string value to check for uniqueness
224+
// there is no sorting of the keys in the collect object's spec so if the spec isn't an exact match line for line as written, no dedup will occur
225+
func DedupCollectors(allCollectors []*troubleshootv1beta2.Collect) []*troubleshootv1beta2.Collect {
226+
uniqueCollectors := make(map[string]bool)
227+
finalCollectors := []*troubleshootv1beta2.Collect{}
228+
229+
for _, collector := range allCollectors {
230+
data, err := json.Marshal(collector)
231+
if err != nil {
232+
// return collector as is if for whatever reason it can't be marshalled into json
233+
finalCollectors = append(finalCollectors, collector)
234+
} else {
235+
stringData := string(data)
236+
if _, value := uniqueCollectors[stringData]; !value {
237+
uniqueCollectors[stringData] = true
238+
finalCollectors = append(finalCollectors, collector)
239+
}
240+
}
241+
}
242+
return finalCollectors
243+
}

pkg/collect/collector_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
77
"github.com/replicatedhq/troubleshoot/pkg/multitype"
8+
"github.com/stretchr/testify/assert"
89
"github.com/stretchr/testify/require"
910
)
1011

@@ -364,3 +365,83 @@ pwd=somethinggoeshere;`,
364365
})
365366
}
366367
}
368+
369+
func TestCollector_DedupCollectors(t *testing.T) {
370+
tests := []struct {
371+
name string
372+
Collectors []*troubleshootv1beta2.Collect
373+
want []*troubleshootv1beta2.Collect
374+
}{
375+
{
376+
name: "multiple cluster info",
377+
Collectors: []*troubleshootv1beta2.Collect{
378+
{
379+
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
380+
},
381+
{
382+
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
383+
},
384+
},
385+
want: []*troubleshootv1beta2.Collect{
386+
{
387+
ClusterInfo: &troubleshootv1beta2.ClusterInfo{},
388+
},
389+
},
390+
},
391+
{
392+
name: "multiple cluster resources with matching namespace lists",
393+
Collectors: []*troubleshootv1beta2.Collect{
394+
{
395+
ClusterResources: &troubleshootv1beta2.ClusterResources{
396+
Namespaces: []string{"namespace1", "namespace2"},
397+
},
398+
},
399+
{
400+
ClusterResources: &troubleshootv1beta2.ClusterResources{
401+
Namespaces: []string{"namespace1", "namespace2"},
402+
},
403+
},
404+
},
405+
want: []*troubleshootv1beta2.Collect{
406+
{
407+
ClusterResources: &troubleshootv1beta2.ClusterResources{
408+
Namespaces: []string{"namespace1", "namespace2"},
409+
},
410+
},
411+
},
412+
},
413+
{
414+
name: "multiple cluster resources with unnique namespace lists",
415+
Collectors: []*troubleshootv1beta2.Collect{
416+
{
417+
ClusterResources: &troubleshootv1beta2.ClusterResources{
418+
Namespaces: []string{"namespace1", "namespace2"},
419+
},
420+
},
421+
{
422+
ClusterResources: &troubleshootv1beta2.ClusterResources{
423+
Namespaces: []string{"namespace1000", "namespace2000"},
424+
},
425+
},
426+
},
427+
want: []*troubleshootv1beta2.Collect{
428+
{
429+
ClusterResources: &troubleshootv1beta2.ClusterResources{
430+
Namespaces: []string{"namespace1", "namespace2"},
431+
},
432+
},
433+
{
434+
ClusterResources: &troubleshootv1beta2.ClusterResources{
435+
Namespaces: []string{"namespace1000", "namespace2000"},
436+
},
437+
},
438+
},
439+
},
440+
}
441+
for _, tc := range tests {
442+
t.Run(tc.name, func(t *testing.T) {
443+
got := DedupCollectors(tc.Collectors)
444+
assert.Equal(t, tc.want, got)
445+
})
446+
}
447+
}

pkg/preflight/collect.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func Collect(opts CollectOpts, p *troubleshootv1beta2.Preflight) (CollectResult,
135135
}
136136
collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}})
137137
collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}})
138+
collectSpecs = collect.DedupCollectors(collectSpecs)
138139
collectSpecs = collect.EnsureClusterResourcesFirst(collectSpecs)
139140

140141
opts.KubernetesRestConfig.QPS = constants.DEFAULT_CLIENT_QPS

pkg/supportbundle/collect.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func runCollectors(collectors []*troubleshootv1beta2.Collect, additionalRedactor
7676
collectSpecs = append(collectSpecs, collectors...)
7777
collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}})
7878
collectSpecs = collect.EnsureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}})
79+
collectSpecs = collect.DedupCollectors(collectSpecs)
7980
collectSpecs = collect.EnsureClusterResourcesFirst(collectSpecs)
8081

8182
opts.KubernetesRestConfig.QPS = constants.DEFAULT_CLIENT_QPS

0 commit comments

Comments
 (0)