Skip to content

Commit 31ee46a

Browse files
authored
feat(ske): add wait handlers for trigger endpoints (#3379)
relates to STACKITCLI-53
1 parent 95413fe commit 31ee46a

File tree

5 files changed

+356
-3
lines changed

5 files changed

+356
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
- `serviceenablement`: [v1.2.2](services/serviceenablement/CHANGELOG.md#v122)
6666
- **Dependencies:** Bump `github.com/golang-jwt/jwt/v5` from `v5.2.2` to `v5.2.3`
6767
- `ske`:
68+
- [v1.3.0](services/ske/CHANGELOG.md#v130)
69+
- **Feature:** Add new wait handlers: `TriggerClusterHibernationWaitHandler`, `TriggerClusterMaintenanceWaitHandler`, `TriggerClusterReconciliationWaitHandler`, `TriggerClusterWakeupWaitHandler`
6870
- [v1.2.0](services/ske/CHANGELOG.md#v120)
6971
- **Feature:** Add new method `TriggerWakeup`
7072
- [v1.1.1](services/ske/CHANGELOG.md#v111)

services/ske/CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
## v1.3.0
2+
- **Feature:** Add new wait handlers: `TriggerClusterHibernationWaitHandler`, `TriggerClusterMaintenanceWaitHandler`, `TriggerClusterReconciliationWaitHandler`, `TriggerClusterWakeupWaitHandler`
3+
14
## v1.2.0
2-
- **Feature:** Add new method `TriggerWakeup`
5+
- **Feature:** Add new method `TriggerWakeup`
36

47
## v1.1.1
5-
- **Dependencies:** Bump `github.com/golang-jwt/jwt/v5` from `v5.2.2` to `v5.2.3`
8+
- **Dependencies:** Bump `github.com/golang-jwt/jwt/v5` from `v5.2.2` to `v5.2.3`
69

710
## v1.1.0
811
- **Breaking Change:** `ClusterError.Code` field is now a string type instead of an enum. The field no longer validates against predefined enum values and accepts any string value.

services/ske/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.2.0
1+
v1.3.0

services/ske/wait/wait.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,78 @@ func DeleteClusterWaitHandler(ctx context.Context, a APIClientClusterInterface,
9090
return handler
9191
}
9292

93+
func TriggerClusterHibernationWaitHandler(ctx context.Context, a APIClientClusterInterface, projectId, region, clusterName string) *wait.AsyncActionHandler[ske.Cluster] {
94+
handler := wait.New(func() (waitFinished bool, response *ske.Cluster, err error) {
95+
cluster, err := a.GetClusterExecute(ctx, projectId, region, clusterName)
96+
if err != nil {
97+
return false, nil, err
98+
}
99+
state := *cluster.Status.Aggregated
100+
101+
if state == ske.CLUSTERSTATUSSTATE_HIBERNATING {
102+
return false, nil, nil
103+
}
104+
105+
return true, cluster, nil
106+
})
107+
handler.SetTimeout(45 * time.Minute)
108+
return handler
109+
}
110+
111+
func TriggerClusterMaintenanceWaitHandler(ctx context.Context, a APIClientClusterInterface, projectId, region, clusterName string) *wait.AsyncActionHandler[ske.Cluster] {
112+
handler := wait.New(func() (waitFinished bool, response *ske.Cluster, err error) {
113+
cluster, err := a.GetClusterExecute(ctx, projectId, region, clusterName)
114+
if err != nil {
115+
return false, nil, err
116+
}
117+
state := *cluster.Status.Aggregated
118+
119+
if state == ske.CLUSTERSTATUSSTATE_RECONCILING {
120+
return false, nil, nil
121+
}
122+
123+
return true, cluster, nil
124+
})
125+
handler.SetTimeout(45 * time.Minute)
126+
return handler
127+
}
128+
129+
func TriggerClusterReconciliationWaitHandler(ctx context.Context, a APIClientClusterInterface, projectId, region, clusterName string) *wait.AsyncActionHandler[ske.Cluster] {
130+
handler := wait.New(func() (waitFinished bool, response *ske.Cluster, err error) {
131+
cluster, err := a.GetClusterExecute(ctx, projectId, region, clusterName)
132+
if err != nil {
133+
return false, nil, err
134+
}
135+
state := *cluster.Status.Aggregated
136+
137+
if state == ske.CLUSTERSTATUSSTATE_RECONCILING {
138+
return false, nil, nil
139+
}
140+
141+
return true, cluster, nil
142+
})
143+
handler.SetTimeout(45 * time.Minute)
144+
return handler
145+
}
146+
147+
func TriggerClusterWakeupWaitHandler(ctx context.Context, a APIClientClusterInterface, projectId, region, clusterName string) *wait.AsyncActionHandler[ske.Cluster] {
148+
handler := wait.New(func() (waitFinished bool, response *ske.Cluster, err error) {
149+
cluster, err := a.GetClusterExecute(ctx, projectId, region, clusterName)
150+
if err != nil {
151+
return false, nil, err
152+
}
153+
state := *cluster.Status.Aggregated
154+
155+
if state == ske.CLUSTERSTATUSSTATE_WAKINGUP {
156+
return false, nil, nil
157+
}
158+
159+
return true, cluster, nil
160+
})
161+
handler.SetTimeout(45 * time.Minute)
162+
return handler
163+
}
164+
93165
// RotateCredentialsWaitHandler will wait for credentials rotation
94166
func RotateCredentialsWaitHandler(ctx context.Context, a APIClientClusterInterface, projectId, region, clusterName string) *wait.AsyncActionHandler[ske.Cluster] {
95167
handler := wait.New(func() (waitFinished bool, response *ske.Cluster, err error) {

services/ske/wait/wait_test.go

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,282 @@ func TestCreateOrUpdateClusterWaitHandler(t *testing.T) {
163163
}
164164
}
165165

166+
func TestTriggerClusterHibernationWaitHandler(t *testing.T) {
167+
tests := []struct {
168+
description string
169+
getFails bool
170+
resourceState ske.ClusterStatusState
171+
wantErr bool
172+
wantResp bool
173+
}{
174+
{
175+
description: "hibernation ongoing (timeout)",
176+
getFails: false,
177+
resourceState: ske.CLUSTERSTATUSSTATE_HIBERNATING,
178+
wantErr: true,
179+
wantResp: false,
180+
},
181+
{
182+
description: "hibernation succeeded",
183+
getFails: false,
184+
resourceState: ske.CLUSTERSTATUSSTATE_HIBERNATED,
185+
wantErr: false,
186+
wantResp: true,
187+
},
188+
{
189+
description: "unexpected status",
190+
getFails: false,
191+
resourceState: ske.CLUSTERSTATUSSTATE_HEALTHY,
192+
wantErr: false,
193+
wantResp: true,
194+
},
195+
{
196+
description: "get_fails",
197+
getFails: true,
198+
wantErr: true,
199+
wantResp: false,
200+
},
201+
}
202+
for _, tt := range tests {
203+
t.Run(tt.description, func(t *testing.T) {
204+
name := "cluster"
205+
206+
apiClient := &apiClientClusterMocked{
207+
getFails: tt.getFails,
208+
name: name,
209+
resourceState: tt.resourceState,
210+
}
211+
var wantRes *ske.Cluster
212+
if tt.wantResp {
213+
wantRes = &ske.Cluster{
214+
Name: &name,
215+
Status: &ske.ClusterStatus{
216+
Aggregated: utils.Ptr(tt.resourceState),
217+
},
218+
}
219+
}
220+
221+
handler := TriggerClusterHibernationWaitHandler(context.Background(), apiClient, "", testRegion, name)
222+
223+
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
224+
225+
if (err != nil) != tt.wantErr {
226+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
227+
}
228+
if !cmp.Equal(gotRes, wantRes) {
229+
t.Fatalf("handler gotRes = %+v, want %+v", gotRes, wantRes)
230+
}
231+
})
232+
}
233+
}
234+
235+
func TestTriggerClusterMaintenanceWaitHandler(t *testing.T) {
236+
tests := []struct {
237+
description string
238+
getFails bool
239+
resourceState ske.ClusterStatusState
240+
wantErr bool
241+
wantResp bool
242+
}{
243+
{
244+
description: "maintenance ongoing (timeout)",
245+
getFails: false,
246+
resourceState: ske.CLUSTERSTATUSSTATE_RECONCILING,
247+
wantErr: true,
248+
wantResp: false,
249+
},
250+
{
251+
description: "maintenance succeeded",
252+
getFails: false,
253+
resourceState: ske.CLUSTERSTATUSSTATE_HEALTHY,
254+
wantErr: false,
255+
wantResp: true,
256+
},
257+
{
258+
description: "unexpected status",
259+
getFails: false,
260+
resourceState: ske.CLUSTERSTATUSSTATE_HIBERNATED,
261+
wantErr: false,
262+
wantResp: true,
263+
},
264+
{
265+
description: "get_fails",
266+
getFails: true,
267+
wantErr: true,
268+
wantResp: false,
269+
},
270+
}
271+
for _, tt := range tests {
272+
t.Run(tt.description, func(t *testing.T) {
273+
name := "cluster"
274+
275+
apiClient := &apiClientClusterMocked{
276+
getFails: tt.getFails,
277+
name: name,
278+
resourceState: tt.resourceState,
279+
}
280+
var wantRes *ske.Cluster
281+
if tt.wantResp {
282+
wantRes = &ske.Cluster{
283+
Name: &name,
284+
Status: &ske.ClusterStatus{
285+
Aggregated: utils.Ptr(tt.resourceState),
286+
},
287+
}
288+
}
289+
290+
handler := TriggerClusterMaintenanceWaitHandler(context.Background(), apiClient, "", testRegion, name)
291+
292+
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
293+
294+
if (err != nil) != tt.wantErr {
295+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
296+
}
297+
if !cmp.Equal(gotRes, wantRes) {
298+
t.Fatalf("handler gotRes = %+v, want %+v", gotRes, wantRes)
299+
}
300+
})
301+
}
302+
}
303+
304+
func TestTriggerClusterWakeupWaitHandler(t *testing.T) {
305+
tests := []struct {
306+
description string
307+
getFails bool
308+
resourceState ske.ClusterStatusState
309+
wantErr bool
310+
wantResp bool
311+
}{
312+
{
313+
description: "wakeup ongoing (timeout)",
314+
getFails: false,
315+
resourceState: ske.CLUSTERSTATUSSTATE_WAKINGUP,
316+
wantErr: true,
317+
wantResp: false,
318+
},
319+
{
320+
description: "wakeup succeeded",
321+
getFails: false,
322+
resourceState: ske.CLUSTERSTATUSSTATE_HEALTHY,
323+
wantErr: false,
324+
wantResp: true,
325+
},
326+
{
327+
description: "unexpected status",
328+
getFails: false,
329+
resourceState: ske.CLUSTERSTATUSSTATE_DELETING,
330+
wantErr: false,
331+
wantResp: true,
332+
},
333+
{
334+
description: "get_fails",
335+
getFails: true,
336+
wantErr: true,
337+
wantResp: false,
338+
},
339+
}
340+
for _, tt := range tests {
341+
t.Run(tt.description, func(t *testing.T) {
342+
name := "cluster"
343+
344+
apiClient := &apiClientClusterMocked{
345+
getFails: tt.getFails,
346+
name: name,
347+
resourceState: tt.resourceState,
348+
}
349+
var wantRes *ske.Cluster
350+
if tt.wantResp {
351+
wantRes = &ske.Cluster{
352+
Name: &name,
353+
Status: &ske.ClusterStatus{
354+
Aggregated: utils.Ptr(tt.resourceState),
355+
},
356+
}
357+
}
358+
359+
handler := TriggerClusterWakeupWaitHandler(context.Background(), apiClient, "", testRegion, name)
360+
361+
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
362+
363+
if (err != nil) != tt.wantErr {
364+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
365+
}
366+
if !cmp.Equal(gotRes, wantRes) {
367+
t.Fatalf("handler gotRes = %+v, want %+v", gotRes, wantRes)
368+
}
369+
})
370+
}
371+
}
372+
373+
func TestTriggerClusterReconciliationWaitHandler(t *testing.T) {
374+
tests := []struct {
375+
description string
376+
getFails bool
377+
resourceState ske.ClusterStatusState
378+
wantErr bool
379+
wantResp bool
380+
}{
381+
{
382+
description: "reconciliation ongoing (timeout)",
383+
getFails: false,
384+
resourceState: ske.CLUSTERSTATUSSTATE_RECONCILING,
385+
wantErr: true,
386+
wantResp: false,
387+
},
388+
{
389+
description: "reconciliation succeeded",
390+
getFails: false,
391+
resourceState: ske.CLUSTERSTATUSSTATE_HEALTHY,
392+
wantErr: false,
393+
wantResp: true,
394+
},
395+
{
396+
description: "unexpected status",
397+
getFails: false,
398+
resourceState: ske.CLUSTERSTATUSSTATE_CREATING,
399+
wantErr: false,
400+
wantResp: true,
401+
},
402+
{
403+
description: "get_fails",
404+
getFails: true,
405+
wantErr: true,
406+
wantResp: false,
407+
},
408+
}
409+
for _, tt := range tests {
410+
t.Run(tt.description, func(t *testing.T) {
411+
name := "cluster"
412+
413+
apiClient := &apiClientClusterMocked{
414+
getFails: tt.getFails,
415+
name: name,
416+
resourceState: tt.resourceState,
417+
}
418+
var wantRes *ske.Cluster
419+
if tt.wantResp {
420+
wantRes = &ske.Cluster{
421+
Name: &name,
422+
Status: &ske.ClusterStatus{
423+
Aggregated: utils.Ptr(tt.resourceState),
424+
},
425+
}
426+
}
427+
428+
handler := TriggerClusterReconciliationWaitHandler(context.Background(), apiClient, "", testRegion, name)
429+
430+
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
431+
432+
if (err != nil) != tt.wantErr {
433+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
434+
}
435+
if !cmp.Equal(gotRes, wantRes) {
436+
t.Fatalf("handler gotRes = %+v, want %+v", gotRes, wantRes)
437+
}
438+
})
439+
}
440+
}
441+
166442
func TestRotateCredentialsWaitHandler(t *testing.T) {
167443
tests := []struct {
168444
desc string

0 commit comments

Comments
 (0)