Skip to content

Commit 3430cfa

Browse files
authored
Add waiters for service enablement EnableService and DisableService (#630)
* Add waiters for service enablement EnableService and DisableService * update changelogs * add sleep before wait
1 parent cad54cd commit 3430cfa

File tree

6 files changed

+281
-1
lines changed

6 files changed

+281
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
- **Feature:** Add new field `AllowSystemComponents` to the `Nodepool` model that configures wether system components are allowed to run on the node pool.
2929
- `loadbalancer`: [v0.XX.X](services/loadbalancer/CHANGELOG.md#v0xxx-2024-xx-xx)
3030
- **Improvement:** Improve default error messages.
31+
- `serviceenablement`: [v0.2.0](services/serviceenablement/CHANGELOG.md#v020-2024-07-12)
32+
- **Feature**: New waiters `EnableServiceWaitHandler` and `DisableServiceWaitHandler` for async operations `EnableService` and `DisableService`, respectively.
3133

3234
## Release (2024-07-01)
3335

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## v0.2.0 (2024-07-12)
2+
3+
- **Feature**: New waiters `EnableServiceWaitHandler` and `DisableServiceWaitHandler` for async operations `EnableService` and `DisableService`, respectively.
4+
15
## v0.1.0 (2024-05-17)
26

37
- **New**: STACKIT Service Enablement module can be used to enable services

services/serviceenablement/go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ module github.com/stackitcloud/stackit-sdk-go/services/serviceenablement
22

33
go 1.18
44

5-
require github.com/stackitcloud/stackit-sdk-go/core v0.12.0
5+
require (
6+
github.com/google/go-cmp v0.6.0
7+
github.com/stackitcloud/stackit-sdk-go/core v0.12.0
8+
)
69

710
require (
811
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect

services/serviceenablement/go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
22
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
33
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
4+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
45
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
56
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
67
github.com/stackitcloud/stackit-sdk-go/core v0.12.0 h1:auIzUUNRuydKOScvpICP4MifGgvOajiDQd+ncGmBL0U=
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package wait
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/stackitcloud/stackit-sdk-go/core/wait"
9+
"github.com/stackitcloud/stackit-sdk-go/services/serviceenablement"
10+
)
11+
12+
const (
13+
ServiceStateEnabled = "ENABLED"
14+
ServiceStateEnabling = "ENABLING"
15+
ServiceStateDisabled = "DISABLED"
16+
ServiceStateDisabling = "DISABLING"
17+
)
18+
19+
// Interface needed for tests
20+
type APIClientInstanceInterface interface {
21+
GetServiceStatusExecute(ctx context.Context, projectId, serviceId string) (*serviceenablement.ServiceStatus, error)
22+
}
23+
24+
func EnableServiceWaitHandler(ctx context.Context, a APIClientInstanceInterface, projectId, serviceId string) *wait.AsyncActionHandler[serviceenablement.ServiceStatus] {
25+
handler := wait.New(func() (waitFinished bool, response *serviceenablement.ServiceStatus, err error) {
26+
s, err := a.GetServiceStatusExecute(ctx, projectId, serviceId)
27+
if err != nil {
28+
return false, nil, err
29+
}
30+
if s == nil || s.State == nil {
31+
return false, nil, nil
32+
}
33+
switch *s.State {
34+
default:
35+
return true, s, fmt.Errorf("service with id %s has unexpected state %s", serviceId, *s.State)
36+
case ServiceStateEnabled:
37+
return true, s, nil
38+
case ServiceStateEnabling:
39+
return false, nil, nil
40+
case ServiceStateDisabled:
41+
return true, s, fmt.Errorf("enabling failed for service with id %s", serviceId)
42+
case ServiceStateDisabling:
43+
return true, s, fmt.Errorf("service with id %s is in state %s", serviceId, *s.State)
44+
}
45+
})
46+
47+
handler.SetTimeout(45 * time.Minute).SetSleepBeforeWait(15 * time.Second)
48+
return handler
49+
}
50+
51+
func DisableServiceWaitHandler(ctx context.Context, a APIClientInstanceInterface, projectId, serviceId string) *wait.AsyncActionHandler[serviceenablement.ServiceStatus] {
52+
handler := wait.New(func() (waitFinished bool, response *serviceenablement.ServiceStatus, err error) {
53+
s, err := a.GetServiceStatusExecute(ctx, projectId, serviceId)
54+
if err != nil {
55+
return false, nil, err
56+
}
57+
if s == nil || s.State == nil {
58+
return false, nil, nil
59+
}
60+
switch *s.State {
61+
default:
62+
return true, s, fmt.Errorf("service with id %s has unexpected state %s", serviceId, *s.State)
63+
case ServiceStateDisabled:
64+
return true, s, nil
65+
case ServiceStateDisabling:
66+
return false, nil, nil
67+
case ServiceStateEnabled:
68+
return true, s, fmt.Errorf("disabling failed for service with id %s", serviceId)
69+
case ServiceStateEnabling:
70+
return true, s, fmt.Errorf("service with id %s is in state %s", serviceId, *s.State)
71+
}
72+
})
73+
handler.SetTimeout(45 * time.Minute).SetSleepBeforeWait(15 * time.Second)
74+
return handler
75+
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package wait
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/google/go-cmp/cmp"
9+
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
10+
"github.com/stackitcloud/stackit-sdk-go/services/serviceenablement"
11+
)
12+
13+
// Used for testing service operations
14+
type apiClientServiceMocked struct {
15+
serviceId string
16+
serviceState string
17+
getServiceFails bool
18+
}
19+
20+
func (a *apiClientServiceMocked) GetServiceStatusExecute(_ context.Context, _, _ string) (*serviceenablement.ServiceStatus, error) {
21+
if a.getServiceFails {
22+
return nil, &oapierror.GenericOpenAPIError{
23+
StatusCode: 500,
24+
}
25+
}
26+
27+
return &serviceenablement.ServiceStatus{
28+
ServiceId: &a.serviceId,
29+
State: &a.serviceState,
30+
}, nil
31+
}
32+
33+
func TestEnableServiceWaitHandler(t *testing.T) {
34+
tests := []struct {
35+
desc string
36+
getServiceFails bool
37+
serviceState string
38+
wantErr bool
39+
wantResp bool
40+
}{
41+
{
42+
desc: "enable_succeeded",
43+
getServiceFails: false,
44+
serviceState: ServiceStateEnabled,
45+
wantErr: false,
46+
wantResp: true,
47+
},
48+
{
49+
desc: "enable_failed",
50+
getServiceFails: false,
51+
serviceState: ServiceStateDisabled,
52+
wantErr: true,
53+
wantResp: false,
54+
},
55+
{
56+
desc: "enable_failed_2",
57+
getServiceFails: false,
58+
serviceState: ServiceStateDisabling,
59+
wantErr: true,
60+
wantResp: false,
61+
},
62+
{
63+
desc: "timeout",
64+
getServiceFails: false,
65+
serviceState: ServiceStateEnabling,
66+
wantErr: true,
67+
wantResp: false,
68+
},
69+
{
70+
desc: "get_service_fails",
71+
getServiceFails: true,
72+
serviceState: ServiceStateEnabling,
73+
wantErr: true,
74+
wantResp: false,
75+
},
76+
}
77+
for _, tt := range tests {
78+
t.Run(tt.desc, func(t *testing.T) {
79+
serviceId := "serviceId"
80+
81+
apiClient := &apiClientServiceMocked{
82+
serviceId: serviceId,
83+
serviceState: tt.serviceState,
84+
getServiceFails: tt.getServiceFails,
85+
}
86+
87+
var wantRes *serviceenablement.ServiceStatus
88+
if tt.wantResp {
89+
wantRes = &serviceenablement.ServiceStatus{
90+
ServiceId: &serviceId,
91+
State: &tt.serviceState,
92+
}
93+
}
94+
95+
ctx := context.Background()
96+
97+
handler := EnableServiceWaitHandler(ctx, apiClient, "projectId", serviceId)
98+
99+
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(ctx)
100+
101+
if err != nil {
102+
if !tt.wantErr {
103+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
104+
}
105+
return
106+
}
107+
if !cmp.Equal(gotRes, wantRes) {
108+
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
109+
}
110+
},
111+
)
112+
}
113+
}
114+
115+
func TestDisableServiceWaitHandler(t *testing.T) {
116+
tests := []struct {
117+
desc string
118+
getServiceFails bool
119+
serviceState string
120+
wantErr bool
121+
wantResp bool
122+
}{
123+
{
124+
desc: "disable_succeeded",
125+
getServiceFails: false,
126+
serviceState: ServiceStateDisabled,
127+
wantErr: false,
128+
wantResp: true,
129+
},
130+
{
131+
desc: "disable_failed",
132+
getServiceFails: false,
133+
serviceState: ServiceStateEnabled,
134+
wantErr: true,
135+
wantResp: false,
136+
},
137+
{
138+
desc: "disable_failed_2",
139+
getServiceFails: false,
140+
serviceState: ServiceStateEnabling,
141+
wantErr: true,
142+
wantResp: false,
143+
},
144+
{
145+
desc: "timeout",
146+
getServiceFails: false,
147+
serviceState: ServiceStateDisabling,
148+
wantErr: true,
149+
wantResp: false,
150+
},
151+
{
152+
desc: "get_service_fails",
153+
getServiceFails: true,
154+
serviceState: ServiceStateDisabling,
155+
wantErr: true,
156+
wantResp: false,
157+
},
158+
}
159+
for _, tt := range tests {
160+
t.Run(tt.desc, func(t *testing.T) {
161+
serviceId := "serviceId"
162+
163+
apiClient := &apiClientServiceMocked{
164+
serviceId: serviceId,
165+
serviceState: tt.serviceState,
166+
getServiceFails: tt.getServiceFails,
167+
}
168+
169+
var wantRes *serviceenablement.ServiceStatus
170+
if tt.wantResp {
171+
wantRes = &serviceenablement.ServiceStatus{
172+
ServiceId: &serviceId,
173+
State: &tt.serviceState,
174+
}
175+
}
176+
177+
ctx := context.Background()
178+
179+
handler := DisableServiceWaitHandler(ctx, apiClient, "projectId", serviceId)
180+
181+
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(ctx)
182+
183+
if err != nil {
184+
if !tt.wantErr {
185+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
186+
}
187+
return
188+
}
189+
if !cmp.Equal(gotRes, wantRes) {
190+
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
191+
}
192+
},
193+
)
194+
}
195+
}

0 commit comments

Comments
 (0)