forked from argoproj/argo-workflows
-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
339 lines (293 loc) · 15.5 KB
/
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
package v1alpha1
import (
"encoding/json"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/rest"
)
// SyncOperation contains sync operation details.
type SyncOperation struct {
Revision string `json:"revision" protobuf:"bytes,1,opt,name=revision"`
Prune bool `json:"prune" protobuf:"bytes,2,opt,name=prune"`
DryRun bool `json:"dryRun" protobuf:"bytes,3,opt,name=dryRun"`
}
type RollbackOperation struct {
ID int64 `json:"id" protobuf:"bytes,1,opt,name=id"`
Prune bool `json:"prune" protobuf:"bytes,2,opt,name=prune"`
DryRun bool `json:"dryRun" protobuf:"bytes,3,opt,name=dryRun"`
}
// Operation contains requested operation parameters.
type Operation struct {
Sync *SyncOperation `json:"sync" protobuf:"bytes,1,opt,name=sync"`
Rollback *RollbackOperation `json:"rollback" protobuf:"bytes,2,opt,name=rollback"`
}
type OperationStatus = string
const (
OperationStatusInProgress = "InProgress"
OperationStatusFailed = "Failed"
OperationStatusSucceeded = "Succeeded"
)
// OperationState contains information about state of currently performing operation on application.
type OperationState struct {
Status OperationStatus `json:"status" protobuf:"bytes,1,opt,name=status"`
ErrorDetails string `json:"errorDetails" protobuf:"bytes,2,opt,name=errorDetails"`
SyncResult *SyncOperationResult `json:"syncResult" protobuf:"bytes,3,opt,name=syncResult"`
RollbackResult *SyncOperationResult `json:"rollbackResult" protobuf:"bytes,4,opt,name=rollbackResult"`
}
// SyncOperationResult represent result of sync operation
type SyncOperationResult struct {
Message string `json:"message" protobuf:"bytes,1,opt,name=message"`
Resources []*ResourceDetails `json:"resources" protobuf:"bytes,2,opt,name=resources"`
}
type ResourceDetails struct {
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"`
Namespace string `json:"namespace" protobuf:"bytes,3,opt,name=namespace"`
Message string `json:"message" protobuf:"bytes,4,opt,name=message"`
}
// DeploymentInfo contains information relevant to an application deployment
type DeploymentInfo struct {
Params []ComponentParameter `json:"params" protobuf:"bytes,1,name=params"`
Revision string `json:"revision" protobuf:"bytes,2,opt,name=revision"`
ComponentParameterOverrides []ComponentParameter `json:"componentParameterOverrides,omitempty" protobuf:"bytes,3,opt,name=componentParameterOverrides"`
DeployedAt metav1.Time `json:"deployedAt" protobuf:"bytes,4,opt,name=deployedAt"`
ID int64 `json:"id" protobuf:"bytes,5,opt,name=id"`
}
// Application is a definition of Application resource.
// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Application struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"`
Spec ApplicationSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
Status ApplicationStatus `json:"status" protobuf:"bytes,3,opt,name=status"`
Operation *Operation `json:"operation,omitempty" protobuf:"bytes,4,opt,name=operation"`
}
// ApplicationWatchEvent contains information about application change.
type ApplicationWatchEvent struct {
Type watch.EventType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=k8s.io/apimachinery/pkg/watch.EventType"`
// Application is:
// * If Type is Added or Modified: the new state of the object.
// * If Type is Deleted: the state of the object immediately before deletion.
// * If Type is Error: *api.Status is recommended; other types may make sense
// depending on context.
Application Application `json:"application" protobuf:"bytes,2,opt,name=application"`
}
// ApplicationList is list of Application resources
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ApplicationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata" protobuf:"bytes,1,opt,name=metadata"`
Items []Application `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.
type ApplicationSpec struct {
// Source is a reference to the location ksonnet application definition
Source ApplicationSource `json:"source" protobuf:"bytes,1,opt,name=source"`
// Destination overrides the kubernetes server and namespace defined in the environment ksonnet app.yaml
Destination ApplicationDestination `json:"destination" protobuf:"bytes,2,name=destination"`
// SyncPolicy dictates whether we auto-sync based on the delta between the tracked branch and live state
SyncPolicy string `json:"syncPolicy,omitempty" protobuf:"bytes,3,opt,name=syncPolicy"`
}
// ComponentParameter contains information about component parameter value
type ComponentParameter struct {
Component string `json:"component" protobuf:"bytes,1,opt,name=component"`
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
Value string `json:"value" protobuf:"bytes,3,opt,name=value"`
}
// ApplicationSource contains information about github repository, path within repository and target application environment.
type ApplicationSource struct {
// RepoURL is the repository URL containing the ksonnet application.
RepoURL string `json:"repoURL" protobuf:"bytes,1,opt,name=repoURL"`
// Path is a directory path within repository which contains ksonnet application.
Path string `json:"path" protobuf:"bytes,2,opt,name=path"`
// Environment is a ksonnet application environment name.
Environment string `json:"environment" protobuf:"bytes,3,opt,name=environment"`
// TargetRevision defines the commit, tag, or branch in which to sync the application to.
// If omitted, will sync to HEAD
TargetRevision string `json:"targetRevision,omitempty" protobuf:"bytes,4,opt,name=targetRevision"`
// Environment parameter override values
ComponentParameterOverrides []ComponentParameter `json:"componentParameterOverrides,omitempty" protobuf:"bytes,5,opt,name=componentParameterOverrides"`
}
// ApplicationDestination contains deployment destination information
type ApplicationDestination struct {
// Server overrides the environment server value in the ksonnet app.yaml
Server string `json:"server,omitempty" protobuf:"bytes,1,opt,name=server"`
// Namespace overrides the environment namespace value in the ksonnet app.yaml
Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,opt,name=namespace"`
}
// ComparisonStatus is a type which represents possible comparison results
type ComparisonStatus string
// Possible comparison results
const (
ComparisonStatusUnknown ComparisonStatus = ""
ComparisonStatusError ComparisonStatus = "Error"
ComparisonStatusSynced ComparisonStatus = "Synced"
ComparisonStatusOutOfSync ComparisonStatus = "OutOfSync"
)
// ApplicationStatus contains information about application status in target environment.
type ApplicationStatus struct {
ComparisonResult ComparisonResult `json:"comparisonResult" protobuf:"bytes,1,opt,name=comparisonResult"`
RecentDeployments []DeploymentInfo `json:"recentDeployments" protobuf:"bytes,2,opt,name=recentDeployment"`
Parameters []ComponentParameter `json:"parameters,omitempty" protobuf:"bytes,3,opt,name=parameters"`
Health HealthStatus `json:"health,omitempty" protobuf:"bytes,4,opt,name=health"`
OperationState *OperationState `json:"operationState,omitempty" protobuf:"bytes,5,opt,name=operationState"`
}
// ComparisonResult is a comparison result of application spec and deployed application.
type ComparisonResult struct {
ComparedAt metav1.Time `json:"comparedAt" protobuf:"bytes,1,opt,name=comparedAt"`
ComparedTo ApplicationSource `json:"comparedTo" protobuf:"bytes,2,opt,name=comparedTo"`
Server string `json:"server" protobuf:"bytes,3,opt,name=server"`
Namespace string `json:"namespace" protobuf:"bytes,4,opt,name=namespace"`
Status ComparisonStatus `json:"status" protobuf:"bytes,5,opt,name=status,casttype=ComparisonStatus"`
Resources []ResourceState `json:"resources" protobuf:"bytes,6,opt,name=resources"`
Error string `json:"error" protobuf:"bytes,7,opt,name=error"`
}
type HealthStatus struct {
Status HealthStatusCode `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"`
StatusDetails string `json:"statusDetails,omitempty" protobuf:"bytes,2,opt,name=statusDetails"`
}
type HealthStatusCode = string
const (
HealthStatusUnknown = ""
HealthStatusProgressing = "Progressing"
HealthStatusHealthy = "Healthy"
HealthStatusDegraded = "Degraded"
)
// ResourceNode contains information about live resource and its children
type ResourceNode struct {
State string `json:"state,omitempty" protobuf:"bytes,1,opt,name=state"`
Children []ResourceNode `json:"children,omitempty" protobuf:"bytes,2,opt,name=children"`
}
// ResourceState holds the target state of a resource and live state of a resource
type ResourceState struct {
TargetState string `json:"targetState,omitempty" protobuf:"bytes,1,opt,name=targetState"`
LiveState string `json:"liveState,omitempty" protobuf:"bytes,2,opt,name=liveState"`
Status ComparisonStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
ChildLiveResources []ResourceNode `json:"childLiveResources,omitempty" protobuf:"bytes,4,opt,name=childLiveResources"`
Health HealthStatus `json:"health,omitempty" protobuf:"bytes,5,opt,name=health"`
}
// Cluster is the definition of a cluster resource
type Cluster struct {
// Server is the API server URL of the Kubernetes cluster
Server string `json:"server" protobuf:"bytes,1,opt,name=server"`
// Name of the cluster. If omitted, will use the server address
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
// Config holds cluster information for connecting to a cluster
Config ClusterConfig `json:"config" protobuf:"bytes,3,opt,name=config"`
}
// ClusterList is a collection of Clusters.
type ClusterList struct {
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []Cluster `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// ClusterConfig is the configuration attributes. This structure is subset of the go-client
// rest.Config with annotations added for marshalling.
type ClusterConfig struct {
// Server requires Basic authentication
Username string `json:"username,omitempty" protobuf:"bytes,1,opt,name=username"`
Password string `json:"password,omitempty" protobuf:"bytes,2,opt,name=password"`
// Server requires Bearer authentication. This client will not attempt to use
// refresh tokens for an OAuth2 flow.
// TODO: demonstrate an OAuth2 compatible client.
BearerToken string `json:"bearerToken,omitempty" protobuf:"bytes,3,opt,name=bearerToken"`
// TLSClientConfig contains settings to enable transport layer security
TLSClientConfig `json:"tlsClientConfig" protobuf:"bytes,4,opt,name=tlsClientConfig"`
}
// TLSClientConfig contains settings to enable transport layer security
type TLSClientConfig struct {
// Server should be accessed without verifying the TLS certificate. For testing only.
Insecure bool `json:"insecure" protobuf:"bytes,1,opt,name=insecure"`
// ServerName is passed to the server for SNI and is used in the client to check server
// ceritificates against. If ServerName is empty, the hostname used to contact the
// server is used.
ServerName string `json:"serverName,omitempty" protobuf:"bytes,2,opt,name=serverName"`
// CertData holds PEM-encoded bytes (typically read from a client certificate file).
// CertData takes precedence over CertFile
CertData []byte `json:"certData,omitempty" protobuf:"bytes,3,opt,name=certData"`
// KeyData holds PEM-encoded bytes (typically read from a client certificate key file).
// KeyData takes precedence over KeyFile
KeyData []byte `json:"keyData,omitempty" protobuf:"bytes,4,opt,name=keyData"`
// CAData holds PEM-encoded bytes (typically read from a root certificates bundle).
// CAData takes precedence over CAFile
CAData []byte `json:"caData,omitempty" protobuf:"bytes,5,opt,name=caData"`
}
// Repository is a Git repository holding application configurations
type Repository struct {
Repo string `json:"repo" protobuf:"bytes,1,opt,name=repo"`
Username string `json:"username,omitempty" protobuf:"bytes,2,opt,name=username"`
Password string `json:"password,omitempty" protobuf:"bytes,3,opt,name=password"`
SSHPrivateKey string `json:"sshPrivateKey,omitempty" protobuf:"bytes,4,opt,name=sshPrivateKey"`
}
// RepositoryList is a collection of Repositories.
type RepositoryList struct {
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Items []Repository `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// NeedRefreshAppStatus answers if application status needs to be refreshed. Returns true if application never been compared, has changed or comparison result has expired.
func (app *Application) NeedRefreshAppStatus(statusRefreshTimeout time.Duration) bool {
return app.Status.ComparisonResult.Status == ComparisonStatusUnknown ||
!app.Spec.Source.Equals(app.Status.ComparisonResult.ComparedTo) ||
app.Status.ComparisonResult.ComparedAt.Add(statusRefreshTimeout).Before(time.Now())
}
// Equals compares two instances of ApplicationSource and return true if instances are equal.
func (source ApplicationSource) Equals(other ApplicationSource) bool {
return source.TargetRevision == other.TargetRevision &&
source.RepoURL == other.RepoURL &&
source.Path == other.Path &&
source.Environment == other.Environment
}
// RESTConfig returns a go-client REST config from cluster
func (c *Cluster) RESTConfig() *rest.Config {
return &rest.Config{
Host: c.Server,
Username: c.Config.Username,
Password: c.Config.Password,
BearerToken: c.Config.BearerToken,
TLSClientConfig: rest.TLSClientConfig{
Insecure: c.Config.TLSClientConfig.Insecure,
ServerName: c.Config.TLSClientConfig.ServerName,
CertData: c.Config.TLSClientConfig.CertData,
KeyData: c.Config.TLSClientConfig.KeyData,
CAData: c.Config.TLSClientConfig.CAData,
},
}
}
// TargetObjects deserializes the list of target states into unstructured objects
func (cr *ComparisonResult) TargetObjects() ([]*unstructured.Unstructured, error) {
objs := make([]*unstructured.Unstructured, len(cr.Resources))
for i, resState := range cr.Resources {
obj, err := UnmarshalToUnstructured(resState.TargetState)
if err != nil {
return nil, err
}
objs[i] = obj
}
return objs, nil
}
// LiveObjects deserializes the list of live states into unstructured objects
func (cr *ComparisonResult) LiveObjects() ([]*unstructured.Unstructured, error) {
objs := make([]*unstructured.Unstructured, len(cr.Resources))
for i, resState := range cr.Resources {
obj, err := UnmarshalToUnstructured(resState.LiveState)
if err != nil {
return nil, err
}
objs[i] = obj
}
return objs, nil
}
func UnmarshalToUnstructured(resource string) (*unstructured.Unstructured, error) {
if resource == "" || resource == "null" {
return nil, nil
}
var obj unstructured.Unstructured
err := json.Unmarshal([]byte(resource), &obj)
if err != nil {
return nil, err
}
return &obj, nil
}