Skip to content

Commit 5d03273

Browse files
authored
Merge branch 'main' into linodedns.updates.bug
2 parents 7de2c85 + 27f5949 commit 5d03273

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

controller/linodemachine_controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ func (r *LinodeMachineReconciler) reconcileCreate(
300300
createOpts, err := r.newCreateConfig(ctx, machineScope, tags, logger)
301301
if err != nil {
302302
logger.Error(err, "Failed to create Linode machine InstanceCreateOptions")
303+
if util.IsTransientError(err) {
304+
return ctrl.Result{RequeueAfter: reconciler.DefaultMachineControllerRetryDelay}, nil
305+
}
303306

304307
return ctrl.Result{}, err
305308
}

util/helpers.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package util
22

33
import (
44
"errors"
5+
"io"
6+
"net/http"
7+
"os"
58

69
"github.com/linode/linodego"
710
)
@@ -30,3 +33,23 @@ func UnwrapError(err error) error {
3033

3134
return err
3235
}
36+
37+
// IsTransientError determines if the error is transient, meaning a controller that
38+
// encounters this error should requeue reconciliation to try again later
39+
func IsTransientError(err error) bool {
40+
if linodego.ErrHasStatus(
41+
err,
42+
http.StatusTooManyRequests,
43+
http.StatusInternalServerError,
44+
http.StatusBadGateway,
45+
http.StatusGatewayTimeout,
46+
http.StatusServiceUnavailable) {
47+
return true
48+
}
49+
50+
if errors.Is(err, http.ErrHandlerTimeout) || errors.Is(err, os.ErrDeadlineExceeded) || errors.Is(err, io.ErrUnexpectedEOF) {
51+
return true
52+
}
53+
54+
return false
55+
}

util/helpers_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package util
22

33
import (
44
"errors"
5+
"io"
6+
"net/http"
57
"testing"
68

79
"github.com/linode/linodego"
@@ -49,3 +51,41 @@ func TestIgnoreLinodeAPIError(t *testing.T) {
4951
})
5052
}
5153
}
54+
55+
func TestIsTransientError(t *testing.T) {
56+
t.Parallel()
57+
tests := []struct {
58+
name string
59+
err error
60+
shouldRetry bool
61+
}{{
62+
name: "unexpected EOF",
63+
err: io.ErrUnexpectedEOF,
64+
shouldRetry: true,
65+
}, {
66+
name: "not found Linode API error",
67+
err: &linodego.Error{
68+
Response: nil,
69+
Code: http.StatusNotFound,
70+
Message: "not found",
71+
},
72+
shouldRetry: false,
73+
}, {
74+
name: "Rate limiting Linode API error",
75+
err: &linodego.Error{
76+
Response: nil,
77+
Code: http.StatusTooManyRequests,
78+
Message: "rate limited",
79+
},
80+
shouldRetry: true,
81+
}}
82+
for _, tt := range tests {
83+
testcase := tt
84+
t.Run(testcase.name, func(t *testing.T) {
85+
t.Parallel()
86+
if testcase.shouldRetry != IsTransientError(testcase.err) {
87+
t.Errorf("wanted %v, got %v", testcase.shouldRetry, IsTransientError(testcase.err))
88+
}
89+
})
90+
}
91+
}

0 commit comments

Comments
 (0)