-
Notifications
You must be signed in to change notification settings - Fork 88
/
preflight.go
135 lines (121 loc) · 4.18 KB
/
preflight.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package reporting
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/pkg/errors"
kotsv1beta1 "github.com/replicatedhq/kots/kotskinds/apis/kots/v1beta1"
appstatustypes "github.com/replicatedhq/kots/pkg/api/appstatus/types"
"github.com/replicatedhq/kots/pkg/buildversion"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/store"
troubleshootpreflight "github.com/replicatedhq/troubleshoot/pkg/preflight"
)
func SendPreflightsReportToReplicatedApp(license *kotsv1beta1.License, appID string, clusterID string, sequence int, skipPreflights bool, installStatus string, isCLI bool, preflightStatus string, appStatus string) error {
endpoint := license.Spec.Endpoint
if !canReport(endpoint) {
return nil
}
urlValues := url.Values{}
urlValues.Set("sequence", fmt.Sprintf("%d", sequence))
urlValues.Set("skipPreflights", fmt.Sprintf("%t", skipPreflights))
urlValues.Set("installStatus", installStatus)
urlValues.Set("isCLI", fmt.Sprintf("%t", isCLI))
urlValues.Set("preflightStatus", preflightStatus)
urlValues.Set("appStatus", appStatus)
urlValues.Set("kotsVersion", buildversion.Version())
url := fmt.Sprintf("%s/kots_metrics/preflights/%s/%s?%s", endpoint, appID, clusterID, urlValues.Encode())
var buf bytes.Buffer
postReq, err := http.NewRequest("POST", url, &buf)
if err != nil {
return errors.Wrap(err, "failed to call newrequest")
}
postReq.Header.Add("Authorization", license.Spec.LicenseID)
postReq.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(postReq)
if err != nil {
return errors.Wrap(err, "failed to send preflights reports")
}
defer resp.Body.Close()
if resp.StatusCode != 201 {
return errors.Errorf("Unexpected status code %d", resp.StatusCode)
}
return nil
}
func SendPreflightInfo(appID string, sequence int, isSkipPreflights bool, isCLI bool) error {
license, err := store.GetStore().GetLatestLicenseForApp(appID)
if err != nil {
return errors.Wrap(err, "failed to find license for app")
}
downstreams, err := store.GetStore().ListDownstreamsForApp(appID)
if err != nil {
return errors.Wrap(err, "failed to list downstreams for app")
} else if len(downstreams) == 0 {
err = errors.New("no downstreams for app")
return err
}
clusterID := downstreams[0].ClusterID
go func() {
appStatus := appstatustypes.StateMissing
for start := time.Now(); time.Since(start) < 20*time.Minute; {
s, err := store.GetStore().GetAppStatus(appID)
if err != nil {
logger.Debugf("failed to get app status: %v", err.Error())
return
}
if s.Sequence == int64(sequence) && s.State == appstatustypes.StateReady {
appStatus = s.State
break
}
time.Sleep(time.Second * 10)
}
preflightState := ""
var preflightResults *troubleshootpreflight.UploadPreflightResults
for start := time.Now(); time.Since(start) < 5*time.Minute; {
p, err := store.GetStore().GetPreflightResults(appID, int64(sequence))
if err != nil {
logger.Debugf("failed to get preflight results: %v", err.Error())
return
}
if p.Result != "" {
if err := json.Unmarshal([]byte(p.Result), &preflightResults); err != nil {
logger.Debugf("failed to unmarshal preflight results: %v", err.Error())
return
}
preflightState = getPreflightState(preflightResults)
break
}
time.Sleep(time.Second * 10)
}
currentVersionStatus, err := store.GetStore().GetStatusForVersion(appID, clusterID, int64(sequence))
if err != nil {
logger.Debugf("failed to get status for version: %v", err)
return
}
if err := SendPreflightsReportToReplicatedApp(license, appID, clusterID, sequence, isSkipPreflights, currentVersionStatus, isCLI, preflightState, string(appStatus)); err != nil {
logger.Debugf("failed to send preflights data to replicated app: %v", err)
return
}
}()
return nil
}
func getPreflightState(preflightResults *troubleshootpreflight.UploadPreflightResults) string {
if len(preflightResults.Errors) > 0 {
return "fail"
}
if len(preflightResults.Results) == 0 {
return "pass"
}
state := "pass"
for _, result := range preflightResults.Results {
if result.IsFail {
return "fail"
} else if result.IsWarn {
state = "warn"
}
}
return state
}