-
Notifications
You must be signed in to change notification settings - Fork 88
/
execute.go
110 lines (95 loc) · 3.43 KB
/
execute.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package preflight
import (
"encoding/json"
"strings"
"github.com/pkg/errors"
"github.com/replicatedhq/kots/kotsadm/pkg/store"
"github.com/replicatedhq/kots/pkg/logger"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/preflight"
troubleshootpreflight "github.com/replicatedhq/troubleshoot/pkg/preflight"
"go.uber.org/zap"
"k8s.io/client-go/rest"
)
// execute will execute the preflights using spec in preflightSpec.
// This spec should be rendered, no template functions remaining
func execute(appID string, sequence int64, preflightSpec *troubleshootv1beta2.Preflight, ignorePermissionErrors bool) (*troubleshootpreflight.UploadPreflightResults, error) {
logger.Debug("executing preflight checks",
zap.String("appID", appID),
zap.Int64("sequence", sequence))
progressChan := make(chan interface{}, 0) // non-zero buffer will result in missed messages
defer close(progressChan)
go func() {
for {
msg, ok := <-progressChan
if ok {
logger.Debugf("%v", msg)
} else {
return
}
}
}()
restConfig, err := rest.InClusterConfig()
if err != nil {
return nil, errors.Wrap(err, "failed to read in cluster config")
}
collectOpts := troubleshootpreflight.CollectOpts{
Namespace: "",
IgnorePermissionErrors: ignorePermissionErrors,
ProgressChan: progressChan,
KubernetesRestConfig: restConfig,
}
logger.Debug("preflight collect phase")
collectResults, err := troubleshootpreflight.Collect(collectOpts, preflightSpec)
if err != nil && !isPermissionsError(err) {
return nil, errors.Wrap(err, "failed to collect")
}
uploadPreflightResults := &troubleshootpreflight.UploadPreflightResults{}
if isPermissionsError(err) {
logger.Debug("skipping analyze due to RBAC errors")
rbacErrors := []*troubleshootpreflight.UploadPreflightError{}
for _, collector := range collectResults.Collectors {
for _, e := range collector.RBACErrors {
rbacErrors = append(rbacErrors, &preflight.UploadPreflightError{
Error: e.Error(),
})
}
}
uploadPreflightResults.Errors = rbacErrors
} else {
logger.Debug("preflight analyze phase")
analyzeResults := collectResults.Analyze()
// the typescript api added some flair to this result
// so let's keep it for compatibility
// MORE TYPES!
results := []*troubleshootpreflight.UploadPreflightResult{}
for _, analyzeResult := range analyzeResults {
uploadPreflightResult := &troubleshootpreflight.UploadPreflightResult{
IsFail: analyzeResult.IsFail,
IsWarn: analyzeResult.IsWarn,
IsPass: analyzeResult.IsPass,
Title: analyzeResult.Title,
Message: analyzeResult.Message,
URI: analyzeResult.URI,
}
results = append(results, uploadPreflightResult)
}
uploadPreflightResults.Results = results
}
logger.Debug("preflight marshalling")
b, err := json.Marshal(uploadPreflightResults)
if err != nil {
return uploadPreflightResults, errors.Wrap(err, "failed to marshal results")
}
if err := store.GetStore().SetPreflightResults(appID, sequence, b); err != nil {
return uploadPreflightResults, errors.Wrap(err, "failed to set preflight results")
}
return uploadPreflightResults, nil
}
func isPermissionsError(err error) bool {
// TODO: make an error type in troubleshoot for this instead of hardcoding the message
if err == nil {
return false
}
return strings.Contains(err.Error(), "insufficient permissions to run all collectors")
}