/
analysis_types.go
350 lines (296 loc) · 17.9 KB
/
analysis_types.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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
package v1alpha1
import (
"encoding/json"
"time"
batchv1 "k8s.io/api/batch/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
intstrutil "k8s.io/apimachinery/pkg/util/intstr"
)
//+kubebuilder:object:root=true
type AnalysisTemplate struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Spec AnalysisTemplateSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
}
//+kubebuilder:object:root=true
type AnalysisTemplateList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"`
Items []AnalysisTemplate `json:"items" protobuf:"bytes,2,rep,name=items"`
}
type AnalysisTemplateSpec struct {
Metrics []Metric `json:"metrics" protobuf:"bytes,1,rep,name=metrics"`
Args []Argument `json:"args,omitempty" protobuf:"bytes,2,rep,name=args"`
DryRun []DryRun `json:"dryRun,omitempty" protobuf:"bytes,3,rep,name=dryRun"`
MeasurementRetention []MeasurementRetention `json:"measurementRetention,omitempty" protobuf:"bytes,4,rep,name=measurementRetention"`
}
type DurationString string
func (d DurationString) Duration() (time.Duration, error) {
return time.ParseDuration(string(d))
}
type Metric struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Interval DurationString `json:"interval,omitempty" protobuf:"bytes,2,opt,name=interval,casttype=DurationString"`
InitialDelay DurationString `json:"initialDelay,omitempty" protobuf:"bytes,3,opt,name=initialDelay,casttype=DurationString"`
Count *intstrutil.IntOrString `json:"count,omitempty" protobuf:"bytes,4,opt,name=count"`
SuccessCondition string `json:"successCondition,omitempty" protobuf:"bytes,5,opt,name=successCondition"`
FailureCondition string `json:"failureCondition,omitempty" protobuf:"bytes,6,opt,name=failureCondition"`
FailureLimit *intstrutil.IntOrString `json:"failureLimit,omitempty" protobuf:"bytes,7,opt,name=failureLimit"`
InconclusiveLimit *intstrutil.IntOrString `json:"inconclusiveLimit,omitempty" protobuf:"bytes,8,opt,name=inconclusiveLimit"`
ConsecutiveErrorLimit *intstrutil.IntOrString `json:"consecutiveErrorLimit,omitempty" protobuf:"bytes,9,opt,name=consecutiveErrorLimit"`
Provider MetricProvider `json:"provider" protobuf:"bytes,10,opt,name=provider"`
}
type DryRun struct {
MetricName string `json:"metricName" protobuf:"bytes,1,opt,name=metricName"`
}
type MeasurementRetention struct {
MetricName string `json:"metricName" protobuf:"bytes,1,opt,name=metricName"`
Limit int32 `json:"limit" protobuf:"varint,2,opt,name=limit"`
}
type MetricProvider struct {
Prometheus *PrometheusMetric `json:"prometheus,omitempty" protobuf:"bytes,1,opt,name=prometheus"`
Kayenta *KayentaMetric `json:"kayenta,omitempty" protobuf:"bytes,2,opt,name=kayenta"`
Web *WebMetric `json:"web,omitempty" protobuf:"bytes,3,opt,name=web"`
Datadog *DatadogMetric `json:"datadog,omitempty" protobuf:"bytes,4,opt,name=datadog"`
Wavefront *WavefrontMetric `json:"wavefront,omitempty" protobuf:"bytes,5,opt,name=wavefront"`
NewRelic *NewRelicMetric `json:"newRelic,omitempty" protobuf:"bytes,6,opt,name=newRelic"`
Job *JobMetric `json:"job,omitempty" protobuf:"bytes,7,opt,name=job"`
CloudWatch *CloudWatchMetric `json:"cloudWatch,omitempty" protobuf:"bytes,8,opt,name=cloudWatch"`
Graphite *GraphiteMetric `json:"graphite,omitempty" protobuf:"bytes,9,opt,name=graphite"`
Influxdb *InfluxdbMetric `json:"influxdb,omitempty" protobuf:"bytes,10,opt,name=influxdb"`
SkyWalking *SkyWalkingMetric `json:"skywalking,omitempty" protobuf:"bytes,11,opt,name=skywalking"`
Plugin map[string]json.RawMessage `json:"plugin,omitempty" protobuf:"bytes,12,rep,name=plugin,castvalue=encoding/json.RawMessage"`
}
type AnalysisPhase string
const (
AnalysisPhasePending AnalysisPhase = "Pending"
AnalysisPhaseRunning AnalysisPhase = "Running"
AnalysisPhaseSuccessful AnalysisPhase = "Successful"
AnalysisPhaseFailed AnalysisPhase = "Failed"
AnalysisPhaseError AnalysisPhase = "Error"
AnalysisPhaseInconclusive AnalysisPhase = "Inconclusive"
)
// Completed returns whether or not the analysis status is considered completed
func (as AnalysisPhase) Completed() bool {
switch as {
case AnalysisPhaseSuccessful, AnalysisPhaseFailed, AnalysisPhaseError, AnalysisPhaseInconclusive:
return true
}
return false
}
type PrometheusMetric struct {
Address string `json:"address,omitempty" protobuf:"bytes,1,opt,name=address"`
Query string `json:"query,omitempty" protobuf:"bytes,2,opt,name=query"`
Authentication Authentication `json:"authentication,omitempty" protobuf:"bytes,3,opt,name=authentication"`
Timeout *int64 `json:"timeout,omitempty" protobuf:"varint,4,opt,name=timeout"`
Insecure bool `json:"insecure,omitempty" protobuf:"varint,5,opt,name=insecure"`
Headers []WebMetricHeader `json:"headers,omitempty" protobuf:"bytes,6,rep,name=headers"`
}
type Authentication struct {
Sigv4 Sigv4Config `json:"sigv4,omitempty" protobuf:"bytes,1,opt,name=sigv4"`
OAuth2 OAuth2Config `json:"oauth2,omitempty" protobuf:"bytes,2,opt,name=oauth2"`
}
type OAuth2Config struct {
TokenURL string `json:"tokenUrl,omitempty" protobuf:"bytes,1,opt,name=tokenUrl"`
ClientID string `json:"clientId,omitempty" protobuf:"bytes,2,opt,name=clientId"`
ClientSecret string `json:"clientSecret,omitempty" protobuf:"bytes,3,opt,name=clientSecret"`
Scopes []string `json:"scopes,omitempty" protobuf:"bytes,4,rep,name=scopes"`
}
type Sigv4Config struct {
Region string `json:"region,omitempty" protobuf:"bytes,1,opt,name=region"`
Profile string `json:"profile,omitempty" protobuf:"bytes,2,opt,name=profile"`
RoleARN string `json:"roleArn,omitempty" protobuf:"bytes,3,opt,name=roleArn"`
}
type WavefrontMetric struct {
Address string `json:"address,omitempty" protobuf:"bytes,1,opt,name=address"`
Query string `json:"query,omitempty" protobuf:"bytes,2,opt,name=query"`
}
type NewRelicMetric struct {
Profile string `json:"profile,omitempty" protobuf:"bytes,1,opt,name=profile"`
Query string `json:"query" protobuf:"bytes,2,opt,name=query"`
}
type JobMetric struct {
Metadata metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Spec batchv1.JobSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
}
type GraphiteMetric struct {
Address string `json:"address,omitempty" protobuf:"bytes,1,opt,name=address"`
Query string `json:"query,omitempty" protobuf:"bytes,2,opt,name=query"`
}
type InfluxdbMetric struct {
Profile string `json:"profile,omitempty" protobuf:"bytes,1,opt,name=profile"`
Query string `json:"query,omitempty" protobuf:"bytes,2,opt,name=query"`
}
type CloudWatchMetric struct {
Interval DurationString `json:"interval,omitempty" protobuf:"bytes,1,opt,name=interval,casttype=DurationString"`
MetricDataQueries []CloudWatchMetricDataQuery `json:"metricDataQueries" protobuf:"bytes,2,rep,name=metricDataQueries"`
}
type CloudWatchMetricDataQuery struct {
Id string `json:"id,omitempty" protobuf:"bytes,1,opt,name=id"`
Expression *string `json:"expression,omitempty" protobuf:"bytes,2,opt,name=expression"`
Label *string `json:"label,omitempty" protobuf:"bytes,3,opt,name=label"`
MetricStat *CloudWatchMetricStat `json:"metricStat,omitempty" protobuf:"bytes,4,opt,name=metricStat"`
Period *intstrutil.IntOrString `json:"period,omitempty" protobuf:"bytes,5,opt,name=period"`
ReturnData *bool `json:"returnData,omitempty" protobuf:"varint,6,opt,name=returnData"`
}
type CloudWatchMetricStat struct {
Metric CloudWatchMetricStatMetric `json:"metric,omitempty" protobuf:"bytes,1,opt,name=metric"`
Period intstrutil.IntOrString `json:"period,omitempty" protobuf:"bytes,2,opt,name=period"`
Stat string `json:"stat,omitempty" protobuf:"bytes,3,opt,name=stat"`
Unit string `json:"unit,omitempty" protobuf:"bytes,4,opt,name=unit"`
}
type CloudWatchMetricStatMetric struct {
Dimensions []CloudWatchMetricStatMetricDimension `json:"dimensions,omitempty" protobuf:"bytes,1,rep,name=dimensions"`
MetricName string `json:"metricName,omitempty" protobuf:"bytes,2,opt,name=metricName"`
Namespace *string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`
}
type CloudWatchMetricStatMetricDimension struct {
Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
type AnalysisRun struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Spec AnalysisRunSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
Status AnalysisRunStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
//+kubebuilder:object:root=true
type AnalysisRunList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"`
Items []AnalysisRun `json:"items" protobuf:"bytes,2,rep,name=items"`
}
type SkyWalkingMetric struct {
Address string `json:"address,omitempty" protobuf:"bytes,1,opt,name=address"`
Query string `json:"query,omitempty" protobuf:"bytes,2,opt,name=query"`
Interval DurationString `json:"interval,omitempty" protobuf:"bytes,3,opt,name=interval,casttype=DurationString"`
}
type AnalysisRunSpec struct {
Metrics []Metric `json:"metrics" protobuf:"bytes,1,rep,name=metrics"`
Args []Argument `json:"args,omitempty" protobuf:"bytes,2,rep,name=args"`
Terminate bool `json:"terminate,omitempty" protobuf:"varint,3,opt,name=terminate"`
DryRun []DryRun `json:"dryRun,omitempty" protobuf:"bytes,4,rep,name=dryRun"`
MeasurementRetention []MeasurementRetention `json:"measurementRetention,omitempty" protobuf:"bytes,5,rep,name=measurementRetention"`
}
type Argument struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Value *string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
ValueFrom *ValueFrom `json:"valueFrom,omitempty" protobuf:"bytes,3,opt,name=valueFrom"`
}
type ValueFrom struct {
SecretKeyRef *SecretKeyRef `json:"secretKeyRef,omitempty" protobuf:"bytes,1,opt,name=secretKeyRef"`
FieldRef *FieldRef `json:"fieldRef,omitempty" protobuf:"bytes,2,opt,name=fieldRef"`
}
type SecretKeyRef struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Key string `json:"key" protobuf:"bytes,2,opt,name=key"`
}
type AnalysisRunStatus struct {
Phase AnalysisPhase `json:"phase" protobuf:"bytes,1,opt,name=phase,casttype=AnalysisPhase"`
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
MetricResults []MetricResult `json:"metricResults,omitempty" protobuf:"bytes,3,rep,name=metricResults"`
StartedAt *metav1.Time `json:"startedAt,omitempty" protobuf:"bytes,4,opt,name=startedAt"`
RunSummary RunSummary `json:"runSummary,omitempty" protobuf:"bytes,5,opt,name=runSummary"`
DryRunSummary *RunSummary `json:"dryRunSummary,omitempty" protobuf:"bytes,6,opt,name=dryRunSummary"`
}
func (s *AnalysisRunStatus) CompletedAt() *metav1.Time {
if !s.Phase.Completed() {
return nil
}
// FIXME: Use `CompletedAt` (which will be introduced in rollouts v1.7.0) as a default value
var completedAt *metav1.Time
// TODO: Remove after we bump up minimum rollouts version to v1.7.0
for _, mr := range s.MetricResults {
for _, m := range mr.Measurements {
if m.FinishedAt == nil {
continue
}
if completedAt == nil || m.FinishedAt.After(completedAt.Time) {
completedAt = m.FinishedAt.DeepCopy()
}
}
}
return completedAt
}
type RunSummary struct {
Count int32 `json:"count,omitempty" protobuf:"varint,1,opt,name=count"`
Successful int32 `json:"successful,omitempty" protobuf:"varint,2,opt,name=successful"`
Failed int32 `json:"failed,omitempty" protobuf:"varint,3,opt,name=failed"`
Inconclusive int32 `json:"inconclusive,omitempty" protobuf:"varint,4,opt,name=inconclusive"`
Error int32 `json:"error,omitempty" protobuf:"varint,5,opt,name=error"`
}
type MetricResult struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Phase AnalysisPhase `json:"phase" protobuf:"bytes,2,opt,name=phase,casttype=AnalysisPhase"`
Measurements []Measurement `json:"measurements,omitempty" protobuf:"bytes,3,rep,name=measurements"`
Message string `json:"message,omitempty" protobuf:"bytes,4,opt,name=message"`
Count int32 `json:"count,omitempty" protobuf:"varint,5,opt,name=count"`
Successful int32 `json:"successful,omitempty" protobuf:"varint,6,opt,name=successful"`
Failed int32 `json:"failed,omitempty" protobuf:"varint,7,opt,name=failed"`
Inconclusive int32 `json:"inconclusive,omitempty" protobuf:"varint,8,opt,name=inconclusive"`
Error int32 `json:"error,omitempty" protobuf:"varint,9,opt,name=error"`
ConsecutiveError int32 `json:"consecutiveError,omitempty" protobuf:"varint,10,opt,name=consecutiveError"`
DryRun bool `json:"dryRun,omitempty" protobuf:"varint,11,opt,name=dryRun"`
Metadata map[string]string `json:"metadata,omitempty" protobuf:"bytes,12,rep,name=metadata"`
}
type Measurement struct {
Phase AnalysisPhase `json:"phase" protobuf:"bytes,1,opt,name=phase,casttype=AnalysisPhase"`
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
StartedAt *metav1.Time `json:"startedAt,omitempty" protobuf:"bytes,3,opt,name=startedAt"`
FinishedAt *metav1.Time `json:"finishedAt,omitempty" protobuf:"bytes,4,opt,name=finishedAt"`
Value string `json:"value,omitempty" protobuf:"bytes,5,opt,name=value"`
Metadata map[string]string `json:"metadata,omitempty" protobuf:"bytes,6,rep,name=metadata"`
ResumeAt *metav1.Time `json:"resumeAt,omitempty" protobuf:"bytes,7,opt,name=resumeAt"`
}
type KayentaMetric struct {
Address string `json:"address" protobuf:"bytes,1,opt,name=address"`
Application string `json:"application" protobuf:"bytes,2,opt,name=application"`
CanaryConfigName string `json:"canaryConfigName" protobuf:"bytes,3,opt,name=canaryConfigName"`
MetricsAccountName string `json:"metricsAccountName" protobuf:"bytes,4,opt,name=metricsAccountName"`
ConfigurationAccountName string `json:"configurationAccountName" protobuf:"bytes,5,opt,name=configurationAccountName"`
StorageAccountName string `json:"storageAccountName" protobuf:"bytes,6,opt,name=storageAccountName"`
Threshold KayentaThreshold `json:"threshold" protobuf:"bytes,7,opt,name=threshold"`
Scopes []KayentaScope `json:"scopes" protobuf:"bytes,8,rep,name=scopes"`
}
type KayentaThreshold struct {
Pass int64 `json:"pass" protobuf:"varint,1,opt,name=pass"`
Marginal int64 `json:"marginal" protobuf:"varint,2,opt,name=marginal"`
}
type KayentaScope struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
ControlScope ScopeDetail `json:"controlScope" protobuf:"bytes,2,opt,name=controlScope"`
ExperimentScope ScopeDetail `json:"experimentScope" protobuf:"bytes,3,opt,name=experimentScope"`
}
type ScopeDetail struct {
Scope string `json:"scope" protobuf:"bytes,1,opt,name=scope"`
Region string `json:"region" protobuf:"bytes,2,opt,name=region"`
Step int64 `json:"step" protobuf:"varint,3,opt,name=step"`
Start string `json:"start" protobuf:"bytes,4,opt,name=start"`
End string `json:"end" protobuf:"bytes,5,opt,name=end"`
}
type WebMetric struct {
Method WebMetricMethod `json:"method,omitempty" protobuf:"bytes,1,opt,name=method,casttype=WebMetricMethod"`
// URL is the address of the web metric
URL string `json:"url" protobuf:"bytes,2,opt,name=url"`
Headers []WebMetricHeader `json:"headers,omitempty" protobuf:"bytes,3,rep,name=headers"`
Body string `json:"body,omitempty" protobuf:"bytes,4,opt,name=body"`
TimeoutSeconds int64 `json:"timeoutSeconds,omitempty" protobuf:"varint,5,opt,name=timeoutSeconds"`
JSONPath string `json:"jsonPath,omitempty" protobuf:"bytes,6,opt,name=jsonPath"`
Insecure bool `json:"insecure,omitempty" protobuf:"varint,7,opt,name=insecure"`
JSONBody json.RawMessage `json:"jsonBody,omitempty" protobuf:"bytes,8,opt,name=jsonBody,casttype=encoding/json.RawMessage"`
Authentication Authentication `json:"authentication,omitempty" protobuf:"bytes,9,opt,name=authentication"`
}
type WebMetricMethod string
type WebMetricHeader struct {
Key string `json:"key" protobuf:"bytes,1,opt,name=key"`
Value string `json:"value" protobuf:"bytes,2,opt,name=value"`
}
type DatadogMetric struct {
Interval DurationString `json:"interval,omitempty" protobuf:"bytes,1,opt,name=interval,casttype=DurationString"`
Query string `json:"query,omitempty" protobuf:"bytes,2,opt,name=query"`
Queries map[string]string `json:"queries,omitempty" protobuf:"bytes,3,rep,name=queries"`
Formula string `json:"formula,omitempty" protobuf:"bytes,4,opt,name=formula"`
ApiVersion string `json:"apiVersion,omitempty" protobuf:"bytes,5,opt,name=apiVersion"`
}