generated from kyma-project/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #480 from Disper/retryable_improvements
Improves gardener errors handling for those which can be retried
- Loading branch information
Showing
8 changed files
with
232 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package gardener | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
|
||
gardener "github.com/gardener/gardener/pkg/apis/core/v1beta1" | ||
gardenerhelper "github.com/gardener/gardener/pkg/apis/core/v1beta1/helper" | ||
) | ||
|
||
type ErrReason string | ||
|
||
func IsRetryable(lastErrors []gardener.LastError) bool { | ||
if len(lastErrors) > 0 && | ||
!gardenerhelper.HasNonRetryableErrorCode(lastErrors...) { | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
func ToErrReason(lastErrors ...gardener.LastError) ErrReason { | ||
var codes []gardener.ErrorCode | ||
var vals []string | ||
|
||
for _, e := range lastErrors { | ||
if len(e.Codes) > 0 { | ||
codes = append(codes, e.Codes...) | ||
} | ||
} | ||
|
||
for _, code := range codes { | ||
vals = append(vals, string(code)) | ||
} | ||
|
||
return ErrReason(strings.Join(vals, ", ")) | ||
} | ||
|
||
func CombineErrorDescriptions(lastErrors []gardener.LastError) string { | ||
var descriptions string | ||
for i, lastError := range lastErrors { | ||
descriptions += fmt.Sprint(strconv.Itoa(i+1), ") ", lastError.Description, " ") | ||
} | ||
return descriptions | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package gardener | ||
|
||
import ( | ||
"testing" | ||
|
||
gardener "github.com/gardener/gardener/pkg/apis/core/v1beta1" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGardenerErrorHandler(t *testing.T) { | ||
t.Run("Should combine error descriptions", func(t *testing.T) { | ||
// given | ||
lastErrors := []gardener.LastError{ | ||
{ | ||
Description: "First description", | ||
}, | ||
{ | ||
Description: "Second description", | ||
}, | ||
} | ||
|
||
// when | ||
combinedDescritpion := CombineErrorDescriptions(lastErrors) | ||
|
||
// then | ||
assert.Equal(t, "1) First description 2) Second description ", combinedDescritpion) | ||
}) | ||
|
||
for _, testCase := range []struct { | ||
name string | ||
lastErrors []gardener.LastError | ||
expectedRetryable bool | ||
}{ | ||
{ | ||
name: "Should return true for retryable gardener errors", | ||
lastErrors: fixRetryableErrors(), | ||
expectedRetryable: true, | ||
}, | ||
{ | ||
name: "Should return false for retryable gardener errors", | ||
lastErrors: fixNonRetryableErrors(), | ||
expectedRetryable: false, | ||
}, | ||
{ | ||
name: "Should return false for mixture of retryable and non-retryable gardener errors", | ||
lastErrors: fixMixtureOfErrors(), | ||
expectedRetryable: false, | ||
}, | ||
{ | ||
name: "Should return false empty list", | ||
lastErrors: []gardener.LastError{}, | ||
expectedRetryable: false, | ||
}, | ||
} { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
// given | ||
|
||
// when | ||
retryable := IsRetryable(testCase.lastErrors) | ||
|
||
// then | ||
assert.Equal(t, testCase.expectedRetryable, retryable) | ||
}) | ||
} | ||
} | ||
|
||
func fixRetryableErrors() []gardener.LastError { | ||
return []gardener.LastError{ | ||
{ | ||
Description: "First description - retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorRetryableConfigurationProblem, | ||
}, | ||
}, | ||
{ | ||
Description: "Second description - retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorRetryableInfraDependencies, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func fixNonRetryableErrors() []gardener.LastError { | ||
return []gardener.LastError{ | ||
{ | ||
Description: "First description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraDependencies, | ||
}, | ||
}, | ||
{ | ||
Description: "Second description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraQuotaExceeded, | ||
}, | ||
}, | ||
{ | ||
Description: "Third description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraUnauthenticated, | ||
}, | ||
}, | ||
{ | ||
Description: "Fourth description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraUnauthorized, | ||
}, | ||
}, | ||
{ | ||
Description: "Fifth description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraRateLimitsExceeded, | ||
}, | ||
}, | ||
{ | ||
Description: "Sixth description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorConfigurationProblem, | ||
}, | ||
}, | ||
{ | ||
Description: "Seventh description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorProblematicWebhook, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func fixMixtureOfErrors() []gardener.LastError { | ||
return []gardener.LastError{ | ||
{ | ||
Description: "First description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraDependencies, | ||
}, | ||
}, | ||
{ | ||
Description: "Second description - retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorRetryableConfigurationProblem, | ||
}, | ||
}, | ||
{ | ||
Description: "Third description - non-retryable", | ||
Codes: []gardener.ErrorCode{ | ||
gardener.ErrorInfraQuotaExceeded, | ||
}, | ||
}, | ||
} | ||
} |