-
Notifications
You must be signed in to change notification settings - Fork 88
/
preflight_store.go
203 lines (174 loc) · 6.64 KB
/
preflight_store.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package kotsstore
import (
"encoding/json"
"fmt"
"time"
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/persistence"
preflighttypes "github.com/replicatedhq/kots/pkg/preflight/types"
troubleshootpreflight "github.com/replicatedhq/troubleshoot/pkg/preflight"
"github.com/rqlite/gorqlite"
)
func (s *KOTSStore) SetPreflightProgress(appID string, sequence int64, progress string) error {
db := persistence.MustGetDBSession()
query := `update app_downstream_version set preflight_progress = ? where app_id = ? and parent_sequence = ?`
wr, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{progress, appID, sequence},
})
if err != nil {
return fmt.Errorf("failed to write: %v: %v", err, wr.Err)
}
return nil
}
func (s *KOTSStore) GetPreflightProgress(appID string, sequence int64) (string, error) {
db := persistence.MustGetDBSession()
query := `
SELECT preflight_progress
FROM app_downstream_version
WHERE app_id = ? AND sequence = ?`
rows, err := db.QueryOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{appID, sequence},
})
if err != nil {
return "", fmt.Errorf("failed to query: %v: %v", err, rows.Err)
}
if !rows.Next() {
return "", ErrNotFound
}
var progress gorqlite.NullString
if err := rows.Scan(&progress); err != nil {
return "", errors.Wrap(err, "failed to scan")
}
return progress.String, nil
}
func (s *KOTSStore) SetPreflightResults(appID string, sequence int64, results []byte) error {
db := persistence.MustGetDBSession()
query := `update app_downstream_version set preflight_result = ?, preflight_result_created_at = ?,
status = (case when status = 'deployed' then 'deployed' when status = 'deploying' then 'deploying' else 'pending' end),
preflight_progress = NULL, preflight_skipped = false
where app_id = ? and parent_sequence = ?`
wr, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{string(results), time.Now().Unix(), appID, sequence},
})
if err != nil {
return fmt.Errorf("failed to write: %v: %v", err, wr.Err)
}
return nil
}
func (s *KOTSStore) GetPreflightResults(appID string, sequence int64) (*preflighttypes.PreflightResult, error) {
db := persistence.MustGetDBSession()
query := `
SELECT
app_downstream_version.preflight_result,
app_downstream_version.preflight_result_created_at,
app_downstream_version.preflight_skipped,
app.slug as app_slug,
cluster.slug as cluster_slug,
app_version.preflight_spec
FROM app_downstream_version
INNER JOIN app ON app_downstream_version.app_id = app.id
INNER JOIN cluster ON app_downstream_version.cluster_id = cluster.id
INNER JOIN app_version ON app_downstream_version.app_id = app_version.app_id AND app_downstream_version.parent_sequence = app_version.sequence
WHERE
app_downstream_version.app_id = ? AND
app_downstream_version.sequence = ?`
rows, err := db.QueryOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{appID, sequence},
})
if err != nil {
return nil, fmt.Errorf("failed to query: %v: %v", err, rows.Err)
}
if !rows.Next() {
return nil, ErrNotFound
}
r, err := s.preflightResultFromRow(rows)
if err != nil {
return nil, errors.Wrap(err, "failed to get preflight result from row")
}
return r, nil
}
func (s *KOTSStore) ResetPreflightResults(appID string, sequence int64) error {
db := persistence.MustGetDBSession()
query := `update app_downstream_version set preflight_result=null, preflight_result_created_at=null, preflight_skipped=false where app_id = ? and parent_sequence = ?`
wr, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{appID, sequence},
})
if err != nil {
return fmt.Errorf("failed to write: %v: %v", err, wr.Err)
}
return nil
}
func (s *KOTSStore) SetIgnorePreflightPermissionErrors(appID string, sequence int64) error {
db := persistence.MustGetDBSession()
query := `UPDATE app_downstream_version
SET status = 'pending_preflight', preflight_ignore_permissions = true, preflight_result = null, preflight_skipped = false
WHERE app_id = ? AND sequence = ?`
wr, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{appID, sequence},
})
if err != nil {
return fmt.Errorf("failed to set downstream version ignore rbac errors: %v: %v", err, wr.Err)
}
return nil
}
func (s *KOTSStore) preflightResultFromRow(row gorqlite.QueryResult) (*preflighttypes.PreflightResult, error) {
r := &preflighttypes.PreflightResult{}
var preflightResult gorqlite.NullString
var preflightResultCreatedAt gorqlite.NullTime
var preflightSpec gorqlite.NullString
if err := row.Scan(
&preflightResult,
&preflightResultCreatedAt,
&r.Skipped,
&r.AppSlug,
&r.ClusterSlug,
&preflightSpec,
); err != nil {
return nil, errors.Wrap(err, "failed to scan")
}
r.Result = preflightResult.String
if preflightResultCreatedAt.Valid {
r.CreatedAt = &preflightResultCreatedAt.Time
}
var err error
r.HasFailingStrictPreflights, err = s.hasFailingStrictPreflights(preflightSpec, preflightResult)
if err != nil {
return nil, errors.Wrap(err, "failed to check for failing strict preflight")
}
return r, nil
}
func (s *KOTSStore) hasFailingStrictPreflights(preflightSpecStr gorqlite.NullString, preflightResultStr gorqlite.NullString) (bool, error) {
hasFailingStrictPreflights, err := s.hasStrictPreflights(preflightSpecStr)
if err != nil {
return false, errors.Wrap(err, "failed to check for strict preflight")
}
if preflightResultStr.Valid && preflightResultStr.String != "" {
preflightResult := troubleshootpreflight.UploadPreflightResults{}
if err := json.Unmarshal([]byte(preflightResultStr.String), &preflightResult); err != nil {
return false, errors.Wrap(err, "failed to unmarshal preflightResults")
}
hasFailingStrictPreflights = hasFailingStrictPreflights && troubleshootpreflight.HasStrictAnalyzersFailed(&preflightResult)
}
return hasFailingStrictPreflights, nil
}
func (s *KOTSStore) hasStrictPreflights(preflightSpecStr gorqlite.NullString) (bool, error) {
hasStrictPreflights := false
if preflightSpecStr.Valid && preflightSpecStr.String != "" {
preflight, err := kotsutil.LoadPreflightFromContents([]byte(preflightSpecStr.String))
if err != nil {
return false, errors.Wrap(err, "failed to load preflights from spec")
}
hasStrictPreflights, err = troubleshootpreflight.HasStrictAnalyzers(preflight)
if err != nil {
return false, errors.Wrap(err, "failed to check strict preflights from spec")
}
}
return hasStrictPreflights, nil
}