Skip to content

Commit 05d3e66

Browse files
authored
Merge pull request #683 from replicatedhq/danj-multiple-inputs
Danj multiple inputs
2 parents 7403e39 + d70ecf7 commit 05d3e66

File tree

7 files changed

+157
-36
lines changed

7 files changed

+157
-36
lines changed

cmd/troubleshoot/cli/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
3434
v := viper.GetViper()
3535

3636
logger.SetQuiet(v.GetBool("quiet"))
37-
return runTroubleshoot(v, args[0])
37+
return runTroubleshoot(v, args)
3838
},
3939
}
4040

cmd/troubleshoot/cli/run.go

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131
"k8s.io/client-go/rest"
3232
)
3333

34-
func runTroubleshoot(v *viper.Viper, arg string) error {
34+
func runTroubleshoot(v *viper.Viper, arg []string) error {
3535
interactive := v.GetBool("interactive") && isatty.IsTerminal(os.Stdout.Fd())
3636

3737
if interactive {
@@ -68,51 +68,58 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
6868
})
6969
}
7070

71-
collectorContent, err := supportbundle.LoadSupportBundleSpec(arg)
72-
if err != nil {
73-
return errors.Wrap(err, "failed to load collector spec")
74-
}
75-
76-
multidocs := strings.Split(string(collectorContent), "\n---\n")
77-
78-
// we support both raw collector kinds and supportbundle kinds here
79-
supportBundle, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
80-
if err != nil {
81-
return errors.Wrap(err, "failed to parse collector")
82-
}
71+
var mainBundle *troubleshootv1beta2.SupportBundle
8372

8473
troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
8574
decode := scheme.Codecs.UniversalDeserializer().Decode
86-
8775
additionalRedactors := &troubleshootv1beta2.Redactor{}
88-
for idx, redactor := range v.GetStringSlice("redactors") {
89-
redactorObj, err := supportbundle.GetRedactorFromURI(redactor)
76+
for i, v := range arg {
77+
78+
collectorContent, err := supportbundle.LoadSupportBundleSpec(v)
9079
if err != nil {
91-
return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx)
80+
return errors.Wrap(err, "failed to load collector spec")
9281
}
93-
94-
if redactorObj != nil {
95-
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...)
82+
multidocs := strings.Split(string(collectorContent), "\n---\n")
83+
supportBundle, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
84+
if err != nil {
85+
return errors.Wrap(err, "failed to parse collector")
9686
}
97-
}
9887

99-
for i, additionalDoc := range multidocs {
10088
if i == 0 {
101-
continue
89+
mainBundle = supportBundle
90+
} else {
91+
mainBundle = supportbundle.ConcatSpec(mainBundle, supportBundle)
10292
}
103-
additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
104-
if err != nil {
105-
return errors.Wrap(err, "failed to convert to v1beta2")
93+
94+
for i, additionalDoc := range multidocs {
95+
if i == 0 {
96+
continue
97+
}
98+
additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
99+
if err != nil {
100+
return errors.Wrap(err, "failed to convert to v1beta2")
101+
}
102+
obj, _, err := decode(additionalDoc, nil, nil)
103+
if err != nil {
104+
return errors.Wrapf(err, "failed to parse additional doc %d", i)
105+
}
106+
multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
107+
if !ok {
108+
continue
109+
}
110+
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
106111
}
107-
obj, _, err := decode(additionalDoc, nil, nil)
112+
}
113+
114+
for idx, redactor := range v.GetStringSlice("redactors") {
115+
redactorObj, err := supportbundle.GetRedactorFromURI(redactor)
108116
if err != nil {
109-
return errors.Wrapf(err, "failed to parse additional doc %d", i)
117+
return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx)
110118
}
111-
multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
112-
if !ok {
113-
continue
119+
120+
if redactorObj != nil {
121+
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...)
114122
}
115-
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
116123
}
117124

118125
var collectorCB func(chan interface{}, string)
@@ -193,7 +200,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
193200
c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine()))
194201
}
195202

196-
response, err := supportbundle.CollectSupportBundleFromSpec(&supportBundle.Spec, additionalRedactors, createOpts)
203+
response, err := supportbundle.CollectSupportBundleFromSpec(&mainBundle.Spec, additionalRedactors, createOpts)
197204
if err != nil {
198205
return errors.Wrap(err, "failed to run collect and analyze process")
199206
}
@@ -202,7 +209,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
202209
close(finishedCh) // this removes the spinner
203210
isFinishedChClosed = true
204211

205-
if err := showInteractiveResults(supportBundle.Name, response.AnalyzerResults); err != nil {
212+
if err := showInteractiveResults(mainBundle.Name, response.AnalyzerResults); err != nil {
206213
interactive = false
207214
}
208215
} else {
@@ -211,7 +218,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
211218
}
212219

213220
if !response.FileUploaded {
214-
if appName := supportBundle.Labels["applicationName"]; appName != "" {
221+
if appName := mainBundle.Labels["applicationName"]; appName != "" {
215222
f := `A support bundle for %s has been created in this directory
216223
named %s. Please upload it on the Troubleshoot page of
217224
the %s Admin Console to begin analysis.`

pkg/supportbundle/supportbundle.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,14 @@ func AnalyzeSupportBundle(spec *troubleshootv1beta2.SupportBundleSpec, tmpDir st
226226
}
227227
return analyzeResults, nil
228228
}
229+
230+
// the intention with these appends is to swap them out at a later date with more specific handlers for merging the spec fields
231+
func ConcatSpec(target *troubleshootv1beta2.SupportBundle, source *troubleshootv1beta2.SupportBundle) *troubleshootv1beta2.SupportBundle {
232+
newBundle := target.DeepCopy()
233+
newBundle.Spec.Collectors = append(target.Spec.Collectors, source.Spec.Collectors...)
234+
newBundle.Spec.AfterCollection = append(target.Spec.AfterCollection, source.Spec.AfterCollection...)
235+
newBundle.Spec.HostCollectors = append(target.Spec.HostCollectors, source.Spec.HostCollectors...)
236+
newBundle.Spec.HostAnalyzers = append(target.Spec.HostAnalyzers, source.Spec.HostAnalyzers...)
237+
newBundle.Spec.Analyzers = append(target.Spec.Analyzers, source.Spec.Analyzers...)
238+
return newBundle
239+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package supportbundle
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func Test_LoadAndConcatSpec(t *testing.T) {
9+
10+
bundle1doc,err := LoadSupportBundleSpec("test/supportbundle1.yaml")
11+
if err != nil {
12+
t.Error("couldn't load bundle1 from file")
13+
}
14+
15+
bundle2doc,err := LoadSupportBundleSpec("test/supportbundle2.yaml")
16+
if err != nil {
17+
t.Error("couldn't load bundle2 from file")
18+
}
19+
20+
bundle1,err := ParseSupportBundleFromDoc(bundle1doc)
21+
if err != nil {
22+
t.Error("couldn't parse bundle 1")
23+
}
24+
25+
bundle2,err := ParseSupportBundleFromDoc(bundle2doc)
26+
if err != nil {
27+
t.Error("couldn't parse bundle 2")
28+
}
29+
30+
fulldoc,err := LoadSupportBundleSpec("test/completebundle.yaml")
31+
if err != nil {
32+
t.Error("couldn't load full bundle from file")
33+
}
34+
35+
fullbundle,err := ParseSupportBundleFromDoc(fulldoc)
36+
if err != nil {
37+
t.Error("couldn't parse full bundle")
38+
}
39+
40+
bundle3 := ConcatSpec(bundle1,bundle2)
41+
42+
if reflect.DeepEqual(fullbundle, bundle3) == false {
43+
t.Error("Full bundle and concatenated bundle are not the same.")
44+
}
45+
46+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apiVersion: troubleshoot.sh/v1beta2
2+
kind: SupportBundle
3+
metadata:
4+
name: default
5+
spec:
6+
collectors:
7+
- clusterResources: {}
8+
- clusterInfo: {}
9+
analyzers:
10+
- clusterPodStatuses:
11+
outcomes:
12+
- fail:
13+
when: "!= Healthy"
14+
message: "Status: {{ .Status.Reason }}"
15+
- nodeResources:
16+
checkName: Node status check
17+
outcomes:
18+
- fail:
19+
when: "nodeCondition(Ready) == False"
20+
message: "Not all nodes are online."
21+
- fail:
22+
when: "nodeCondition(Ready) == Unknown"
23+
message: "Not all nodes are online."
24+
- pass:
25+
message: "All nodes are online."
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: troubleshoot.sh/v1beta2
2+
kind: SupportBundle
3+
metadata:
4+
name: default
5+
spec:
6+
collectors:
7+
- clusterResources: {}
8+
analyzers:
9+
- clusterPodStatuses:
10+
outcomes:
11+
- fail:
12+
when: "!= Healthy"
13+
message: "Status: {{ .Status.Reason }}"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: troubleshoot.sh/v1beta2
2+
kind: SupportBundle
3+
metadata:
4+
name: default
5+
spec:
6+
collectors:
7+
- clusterInfo: {}
8+
analyzers:
9+
- nodeResources:
10+
checkName: Node status check
11+
outcomes:
12+
- fail:
13+
when: "nodeCondition(Ready) == False"
14+
message: "Not all nodes are online."
15+
- fail:
16+
when: "nodeCondition(Ready) == Unknown"
17+
message: "Not all nodes are online."
18+
- pass:
19+
message: "All nodes are online."

0 commit comments

Comments
 (0)