Files
troubleshoot/pkg/preflight/collect.go
Andrew Lavery d016e3269c add global and per-collector redactors
add redact type, and begin wiring global redactors

use per-collector redactors

add a test of the 'data' collector and redaction

handle literal string replacements

remove redundant types and redact calls

add proper redactor type, foundations of global redactors

accept global redactors from the CLI, include sample redaction spec
2020-04-16 14:03:00 -04:00

108 lines
3.1 KiB
Go

package preflight
import (
"fmt"
"github.com/pkg/errors"
troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
"github.com/replicatedhq/troubleshoot/pkg/collect"
"k8s.io/client-go/rest"
)
type CollectOpts struct {
Namespace string
IgnorePermissionErrors bool
KubernetesRestConfig *rest.Config
ProgressChan chan interface{}
}
type CollectResult struct {
AllCollectedData map[string][]byte
Collectors collect.Collectors
IsRBACAllowed bool
Spec *troubleshootv1beta1.Preflight
}
// Collect runs the collection phase of preflight checks
func Collect(opts CollectOpts, p *troubleshootv1beta1.Preflight) (CollectResult, error) {
collectSpecs := make([]*troubleshootv1beta1.Collect, 0, 0)
collectSpecs = append(collectSpecs, p.Spec.Collectors...)
collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta1.Collect{ClusterInfo: &troubleshootv1beta1.ClusterInfo{}})
collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta1.Collect{ClusterResources: &troubleshootv1beta1.ClusterResources{}})
allCollectedData := make(map[string][]byte)
var collectors collect.Collectors
for _, desiredCollector := range collectSpecs {
collector := collect.Collector{
Redact: true,
Collect: desiredCollector,
ClientConfig: opts.KubernetesRestConfig,
Namespace: opts.Namespace,
}
collectors = append(collectors, &collector)
}
collectResult := CollectResult{
Collectors: collectors,
Spec: p,
}
if err := collectors.CheckRBAC(); err != nil {
return collectResult, errors.Wrap(err, "failed to check RBAC for collectors")
}
foundForbidden := false
for _, c := range collectors {
for _, e := range c.RBACErrors {
foundForbidden = true
opts.ProgressChan <- e
}
}
if foundForbidden && !opts.IgnorePermissionErrors {
collectResult.IsRBACAllowed = false
return collectResult, errors.New("insufficient permissions to run all collectors")
}
// Run preflights collectors synchronously
for _, collector := range collectors {
if len(collector.RBACErrors) > 0 {
// don't skip clusterResources collector due to RBAC issues
if collector.Collect.ClusterResources == nil {
collectResult.IsRBACAllowed = false // not failing, but going to report this
opts.ProgressChan <- fmt.Sprintf("skipping collector %s with insufficient RBAC permissions", collector.GetDisplayName())
continue
}
}
result, err := collector.RunCollectorSync(nil)
if err != nil {
opts.ProgressChan <- errors.Errorf("failed to run collector %s: %v\n", collector.GetDisplayName(), err)
continue
}
if result != nil {
for k, v := range result {
allCollectedData[k] = v
}
}
}
collectResult.AllCollectedData = allCollectedData
return collectResult, nil
}
func ensureCollectorInList(list []*troubleshootv1beta1.Collect, collector troubleshootv1beta1.Collect) []*troubleshootv1beta1.Collect {
for _, inList := range list {
if collector.ClusterResources != nil && inList.ClusterResources != nil {
return list
}
if collector.ClusterInfo != nil && inList.ClusterInfo != nil {
return list
}
}
return append(list, &collector)
}