From 1dc290cce079e254cef579c8ca25dda915b68165 Mon Sep 17 00:00:00 2001 From: Laure-di <62625835+Laure-di@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:11:28 +0200 Subject: [PATCH] feat(dedibox): add waiter support for Service and Server (#2157) --- api/dedibox/v1/dedibox_utils.go | 100 ++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 api/dedibox/v1/dedibox_utils.go diff --git a/api/dedibox/v1/dedibox_utils.go b/api/dedibox/v1/dedibox_utils.go new file mode 100644 index 00000000..16d8e4fa --- /dev/null +++ b/api/dedibox/v1/dedibox_utils.go @@ -0,0 +1,100 @@ +package dedibox + +import ( + "github.com/scaleway/scaleway-sdk-go/internal/async" + "github.com/scaleway/scaleway-sdk-go/internal/errors" + "github.com/scaleway/scaleway-sdk-go/scw" + "time" +) + +const ( + defaultRetryInterval = time.Second * 15 + defaultTimeout = time.Minute * 30 +) + +type WaitForServiceRequest struct { + ServiceID uint64 + Zone scw.Zone + Timeout *time.Duration + RetryInterval *time.Duration +} + +func (s *API) WaitForService(req *WaitForServiceRequest, opts ...scw.RequestOption) (*Service, error) { + timeout := defaultTimeout + if req.Timeout != nil { + timeout = *req.Timeout + } + retryInterval := defaultRetryInterval + if req.RetryInterval != nil { + retryInterval = *req.RetryInterval + } + terminalStatus := map[ServiceProvisioningStatus]struct{}{ + ServiceProvisioningStatusReady: {}, + ServiceProvisioningStatusError: {}, + ServiceProvisioningStatusExpired: {}, + } + service, err := async.WaitSync(&async.WaitSyncConfig{ + Get: func() (interface{}, bool, error) { + service, err := s.GetService(&GetServiceRequest{ + Zone: req.Zone, + ServiceID: req.ServiceID, + }, opts...) + if err != nil { + return nil, false, err + } + _, isTerminal := terminalStatus[service.ProvisioningStatus] + return service, isTerminal, nil + }, + IntervalStrategy: async.LinearIntervalStrategy(retryInterval), + Timeout: timeout, + }) + if err != nil { + return nil, errors.Wrap(err, "waiting for service failed") + } + return service.(*Service), nil +} + +type WaitForServerRequest struct { + ServerID uint64 + Zone scw.Zone + Timeout *time.Duration + RetryInterval *time.Duration +} + +func (s *API) WaitForServer(req *WaitForServerRequest, opts ...scw.RequestOption) (*Server, error) { + timeout := defaultTimeout + if req.Timeout != nil { + timeout = *req.Timeout + } + retryInterval := defaultRetryInterval + if req.RetryInterval != nil { + retryInterval = *req.RetryInterval + } + terminalStatus := map[ServerStatus]struct{}{ + ServerStatusReady: {}, + ServerStatusError: {}, + ServerStatusLocked: {}, + ServerStatusStopped: {}, + ServerStatusBusy: {}, + ServerStatusRescue: {}, + } + server, err := async.WaitSync(&async.WaitSyncConfig{ + Get: func() (interface{}, bool, error) { + server, err := s.GetServer(&GetServerRequest{ + Zone: req.Zone, + ServerID: req.ServerID, + }, opts...) + if err != nil { + return nil, false, err + } + _, isTerminal := terminalStatus[server.Status] + return server, isTerminal, nil + }, + IntervalStrategy: async.LinearIntervalStrategy(retryInterval), + Timeout: timeout, + }) + if err != nil { + return nil, errors.Wrap(err, "waiting for server failed") + } + return server.(*Server), nil +}