Skip to content

Commit f71a782

Browse files
author
Pushkar Acharya
committed
Handle the case of missing instances when checking for shutdown instances
1 parent 5c3cadf commit f71a782

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

Diff for: internal/instances/instances.go

+27
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var ErrAssertTimeTypeFailed = errors.New("failed to assert type time.Time for fi
2525

2626
type Instances struct {
2727
nodeFirstSeen sync.Map
28+
nodeShutdown sync.Map
2829
apiClient client.APIClient
2930
}
3031

@@ -100,6 +101,10 @@ func (i *Instances) InstanceShutdownByProviderID(ctx context.Context, providerID
100101
defer responseBody.Body.Close()
101102
}
102103
if err != nil {
104+
if errors.Is(err, client.ErrInstanceNotFound) {
105+
return i.handleInstanceNotFoundErr(providerID, err)
106+
}
107+
103108
return false, fmt.Errorf("failed to get instance by provider ID %s: %w", providerID, err)
104109
}
105110
if currInstance == nil || currInstance.State == "STATE_SHUTOFF" || currInstance.State == "STATE_SHUTDOWN" {
@@ -268,3 +273,25 @@ func getNodeAddress(currInstance *crusoeapi.InstanceV1Alpha5) ([]v1.NodeAddress,
268273

269274
return nodeAddress, nil
270275
}
276+
277+
func (i *Instances) handleInstanceNotFoundErr(providerID string, orignalErr error) (instanceShutdown bool, err error) {
278+
attempt, ok := i.nodeShutdown.Load(providerID)
279+
if !ok {
280+
i.nodeShutdown.Store(providerID, 1)
281+
282+
return false, orignalErr
283+
}
284+
intAttempt, ok := attempt.(int)
285+
if !ok {
286+
// store correct data to avoid conversion issues in next iteration
287+
i.nodeShutdown.Store(providerID, 1)
288+
289+
return false, orignalErr
290+
}
291+
if intAttempt >= 3 {
292+
return true, nil
293+
}
294+
i.nodeShutdown.Store(providerID, (intAttempt + 1))
295+
296+
return false, orignalErr
297+
}

Diff for: internal/instances/instances_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
v1alpha5 "github.com/crusoecloud/client-go/swagger/v1alpha5"
10+
"github.com/crusoecloud/crusoe-cloud-controller-manager/internal/client"
1011
mock_client "github.com/crusoecloud/crusoe-cloud-controller-manager/internal/client/mock"
1112
"github.com/crusoecloud/crusoe-cloud-controller-manager/internal/instances"
1213
"github.com/golang/mock/gomock"
@@ -109,6 +110,38 @@ func TestInstanceShutdownByProviderID(t *testing.T) {
109110
require.True(t, shutdown)
110111
}
111112

113+
func TestInstanceShutdownByProviderIDInstanceMissingFromCloudProvider(t *testing.T) {
114+
t.Parallel()
115+
ctrl := gomock.NewController(t)
116+
defer ctrl.Finish()
117+
118+
mockClient := mock_client.NewMockApiClient(ctrl)
119+
mockClient.EXPECT().GetInstanceByID(gomock.Any(), TESTInstanceID).Return(nil,
120+
nil, client.ErrInstanceNotFound).AnyTimes()
121+
instanceService := instances.NewCrusoeInstances(mockClient)
122+
123+
// Instance shutdown by ID should return true on third attempt
124+
// attempt #1
125+
shutdown, err := instanceService.InstanceShutdownByProviderID(context.Background(), ProviderIDPrefix+TESTInstanceID)
126+
require.ErrorIs(t, err, client.ErrInstanceNotFound)
127+
require.False(t, shutdown)
128+
129+
// attempt #2
130+
shutdown, err = instanceService.InstanceShutdownByProviderID(context.Background(), ProviderIDPrefix+TESTInstanceID)
131+
require.ErrorIs(t, err, client.ErrInstanceNotFound)
132+
require.False(t, shutdown)
133+
134+
// attempt #3
135+
shutdown, err = instanceService.InstanceShutdownByProviderID(context.Background(), ProviderIDPrefix+TESTInstanceID)
136+
require.ErrorIs(t, err, client.ErrInstanceNotFound)
137+
require.False(t, shutdown)
138+
139+
// attempt #4
140+
shutdown, err = instanceService.InstanceShutdownByProviderID(context.Background(), ProviderIDPrefix+TESTInstanceID)
141+
require.NoError(t, err)
142+
require.True(t, shutdown)
143+
}
144+
112145
func TestInstanceMetadata(t *testing.T) {
113146
t.Parallel()
114147
ctrl := gomock.NewController(t)

0 commit comments

Comments
 (0)