Skip to content

Commit

Permalink
initial attempt
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Jones <danj@replicated.com>
  • Loading branch information
danj-replicated committed Aug 22, 2022
1 parent 414bf84 commit 3b3ae4e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 36 deletions.
2 changes: 1 addition & 1 deletion cmd/troubleshoot/cli/root.go
Expand Up @@ -34,7 +34,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
v := viper.GetViper()

logger.SetQuiet(v.GetBool("quiet"))
return runTroubleshoot(v, args[0])
return runTroubleshoot(v, args)
},
}

Expand Down
109 changes: 74 additions & 35 deletions cmd/troubleshoot/cli/run.go
Expand Up @@ -31,7 +31,7 @@ import (
"k8s.io/client-go/rest"
)

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

if interactive {
Expand Down Expand Up @@ -68,53 +68,92 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
})
}

collectorContent, err := supportbundle.LoadSupportBundleSpec(arg)
if err != nil {
return errors.Wrap(err, "failed to load collector spec")
}

multidocs := strings.Split(string(collectorContent), "\n---\n")

// we support both raw collector kinds and supportbundle kinds here
supportBundle, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
if err != nil {
return errors.Wrap(err, "failed to parse collector")
}
// collectorContent, err := supportbundle.LoadSupportBundleSpec(arg)
// if err != nil {
// return errors.Wrap(err, "failed to load collector spec")
// }
//
// multidocs := strings.Split(string(collectorContent), "\n---\n")
//
// // we support both raw collector kinds and supportbundle kinds here
// supportBundle, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
// if err != nil {
// return errors.Wrap(err, "failed to parse collector")
// }

var mainBundle *troubleshootv1beta2.SupportBundle

troubleshootclientsetscheme.AddToScheme(scheme.Scheme)
decode := scheme.Codecs.UniversalDeserializer().Decode

additionalRedactors := &troubleshootv1beta2.Redactor{}
for idx, redactor := range v.GetStringSlice("redactors") {
redactorObj, err := supportbundle.GetRedactorFromURI(redactor)
for i, v := range arg {

collectorContent, err := supportbundle.LoadSupportBundleSpec(v)
if err != nil {
return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx)
return errors.Wrap(err, "failed to load collector spec")
}

if redactorObj != nil {
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...)
multidocs := strings.Split(string(collectorContent), "\n---\n")
supportBundle, err := supportbundle.ParseSupportBundleFromDoc([]byte(multidocs[0]))
if err != nil {
return errors.Wrap(err, "failed to parse collector")
}
}

for i, additionalDoc := range multidocs {
if i == 0 {
continue
mainBundle = supportBundle
} else {
mainBundle.concatSpec(supportBundle)
}
additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
if err != nil {
return errors.Wrap(err, "failed to convert to v1beta2")

for i, additionalDoc := range multidocs {
if i == 0 {
continue
}
additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
if err != nil {
return errors.Wrap(err, "failed to convert to v1beta2")
}
obj, _, err := decode(additionalDoc, nil, nil)
if err != nil {
return errors.Wrapf(err, "failed to parse additional doc %d", i)
}
multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
if !ok {
continue
}
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
}
obj, _, err := decode(additionalDoc, nil, nil)
}

for idx, redactor := range v.GetStringSlice("redactors") {
redactorObj, err := supportbundle.GetRedactorFromURI(redactor)
if err != nil {
return errors.Wrapf(err, "failed to parse additional doc %d", i)
return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx)
}
multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
if !ok {
continue

if redactorObj != nil {
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...)
}
additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
}

// for i, additionalDoc := range multidocs {
// if i == 0 {
// continue
// }
// additionalDoc, err := docrewrite.ConvertToV1Beta2([]byte(additionalDoc))
// if err != nil {
// return errors.Wrap(err, "failed to convert to v1beta2")
// }
// obj, _, err := decode(additionalDoc, nil, nil)
// if err != nil {
// return errors.Wrapf(err, "failed to parse additional doc %d", i)
// }
// multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor)
// if !ok {
// continue
// }
// additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, multidocRedactors.Spec.Redactors...)
// }

var collectorCB func(chan interface{}, string)
progressChan := make(chan interface{}) // non-zero buffer can result in missed messages
finishedCh := make(chan bool, 1)
Expand Down Expand Up @@ -193,7 +232,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
c.Println(fmt.Sprintf("\r%s\r", cursor.ClearEntireLine()))
}

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

if err := showInteractiveResults(supportBundle.Name, response.AnalyzerResults); err != nil {
if err := showInteractiveResults(mainBundle.Name, response.AnalyzerResults); err != nil {
interactive = false
}
} else {
Expand All @@ -211,7 +250,7 @@ func runTroubleshoot(v *viper.Viper, arg string) error {
}

if !response.FileUploaded {
if appName := supportBundle.Labels["applicationName"]; appName != "" {
if appName := mainBundle.Labels["applicationName"]; appName != "" {
f := `A support bundle for %s has been created in this directory
named %s. Please upload it on the Troubleshoot page of
the %s Admin Console to begin analysis.`
Expand Down
18 changes: 18 additions & 0 deletions pkg/apis/troubleshoot/v1beta2/supportbundle_types.go
Expand Up @@ -48,6 +48,24 @@ type SupportBundle struct {
Status SupportBundleStatus `json:"status,omitempty"`
}

func (s *SupportBundle) concatSpec(bundle *SupportBundle) {
for _, v := range bundle.Spec.Collectors {
s.Spec.Collectors = append(bundle.Spec.Collectors, v)
}
for _, v := range bundle.Spec.AfterCollection {
s.Spec.AfterCollection = append(bundle.Spec.AfterCollection, v)
}
for _, v := range bundle.Spec.HostCollectors {
s.Spec.HostCollectors = append(bundle.Spec.HostCollectors, v)
}
for _, v := range bundle.Spec.HostAnalyzers {
s.Spec.HostAnalyzers = append(bundle.Spec.HostAnalyzers, v)
}
for _, v := range bundle.Spec.Analyzers {
s.Spec.Analyzers = append(bundle.Spec.Analyzers, v)
}
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// SupportBundleList contains a list of SupportBundle
Expand Down

0 comments on commit 3b3ae4e

Please sign in to comment.