зеркало из https://github.com/Azure/ARO-RP.git
pkg/util/steps: Remove AuthorizationRefreshingAction
No longer used.
This commit is contained in:
Родитель
eca54c1101
Коммит
025f0e5cbc
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/compute"
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/network"
|
||||
"github.com/Azure/ARO-RP/pkg/util/permissions"
|
||||
"github.com/Azure/ARO-RP/pkg/util/steps"
|
||||
"github.com/Azure/ARO-RP/pkg/util/subnet"
|
||||
)
|
||||
|
||||
|
@ -292,11 +291,6 @@ func (dv *dynamic) validateActions(ctx context.Context, r *azure.Resource, actio
|
|||
return wait.PollImmediateUntil(20*time.Second, func() (bool, error) {
|
||||
dv.log.Debug("retry validateActions")
|
||||
perms, err := dv.permissions.ListForResource(ctx, r.ResourceGroup, r.Provider, "", r.ResourceType, r.ResourceName)
|
||||
|
||||
if detailedErr, ok := err.(autorest.DetailedError); ok &&
|
||||
detailedErr.StatusCode == http.StatusForbidden {
|
||||
return false, steps.ErrWantRefresh
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -258,13 +258,12 @@ func TestInstallationTimeMetrics(t *testing.T) {
|
|||
steps: []steps.Step{
|
||||
steps.Action(successfulActionStep),
|
||||
steps.Condition(successfulConditionStep, 30*time.Minute, true),
|
||||
steps.AuthorizationRefreshingAction(nil, steps.Action(successfulActionStep)),
|
||||
steps.Action(successfulActionStep),
|
||||
},
|
||||
wantedMetrics: map[string]int64{
|
||||
"backend.openshiftcluster.install.duration.total.seconds": 6,
|
||||
"backend.openshiftcluster.install.duration.total.seconds": 4,
|
||||
"backend.openshiftcluster.install.action.successfulActionStep.duration.seconds": 2,
|
||||
"backend.openshiftcluster.install.condition.successfulConditionStep.duration.seconds": 2,
|
||||
"backend.openshiftcluster.install.refreshing.successfulActionStep.duration.seconds": 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -274,13 +273,12 @@ func TestInstallationTimeMetrics(t *testing.T) {
|
|||
steps: []steps.Step{
|
||||
steps.Action(successfulActionStep),
|
||||
steps.Condition(successfulConditionStep, 30*time.Minute, true),
|
||||
steps.AuthorizationRefreshingAction(nil, steps.Action(successfulActionStep)),
|
||||
steps.Action(successfulActionStep),
|
||||
},
|
||||
wantedMetrics: map[string]int64{
|
||||
"backend.openshiftcluster.update.duration.total.seconds": 9,
|
||||
"backend.openshiftcluster.update.duration.total.seconds": 6,
|
||||
"backend.openshiftcluster.update.action.successfulActionStep.duration.seconds": 3,
|
||||
"backend.openshiftcluster.update.condition.successfulConditionStep.duration.seconds": 3,
|
||||
"backend.openshiftcluster.update.refreshing.successfulActionStep.duration.seconds": 3,
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
package steps
|
||||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the Apache License 2.0.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"github.com/Azure/ARO-RP/pkg/util/azureerrors"
|
||||
"github.com/Azure/ARO-RP/pkg/util/refreshable"
|
||||
)
|
||||
|
||||
var ErrWantRefresh = errors.New("want refresh")
|
||||
|
||||
// AuthorizationRefreshingAction returns a wrapper Step which will refresh
|
||||
// `authorizer` if the step returns an Azure AuthenticationError and rerun it.
|
||||
// The step will be retried until `retryTimeout` is hit. Any other error will be
|
||||
// returned directly.
|
||||
func AuthorizationRefreshingAction(authorizer refreshable.Authorizer, step Step) Step {
|
||||
return authorizationRefreshingActionStep{
|
||||
step: step,
|
||||
authorizer: authorizer,
|
||||
}
|
||||
}
|
||||
|
||||
type authorizationRefreshingActionStep struct {
|
||||
step Step
|
||||
authorizer refreshable.Authorizer
|
||||
retryTimeout time.Duration
|
||||
pollInterval time.Duration
|
||||
}
|
||||
|
||||
func (s authorizationRefreshingActionStep) run(ctx context.Context, log *logrus.Entry) error {
|
||||
var pollInterval time.Duration
|
||||
var retryTimeout time.Duration
|
||||
|
||||
// If no pollInterval has been set, use a default
|
||||
if s.retryTimeout == time.Duration(0) {
|
||||
retryTimeout = 10 * time.Minute
|
||||
} else {
|
||||
retryTimeout = s.retryTimeout
|
||||
}
|
||||
|
||||
// If no pollInterval has been set, use a default
|
||||
if s.pollInterval == time.Duration(0) {
|
||||
pollInterval = 10 * time.Second
|
||||
} else {
|
||||
pollInterval = s.pollInterval
|
||||
}
|
||||
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, retryTimeout)
|
||||
defer cancel()
|
||||
|
||||
// Run the step immediately. If an Azure authorization error is returned and
|
||||
// we have not hit the retry timeout, the authorizer is refreshed and the
|
||||
// step is called again after runner.pollInterval. If we have timed out or
|
||||
// any other error is returned, the error from the step is returned
|
||||
// directly.
|
||||
return wait.PollImmediateUntil(pollInterval, func() (bool, error) {
|
||||
// We use the outer context, not the timeout context, as we do not want
|
||||
// to time out the condition function itself, only stop retrying once
|
||||
// timeoutCtx's timeout has fired.
|
||||
err := s.step.run(ctx, log)
|
||||
|
||||
// Don't refresh if we have timed out
|
||||
if timeoutCtx.Err() == nil &&
|
||||
(azureerrors.HasAuthorizationFailedError(err) ||
|
||||
azureerrors.HasLinkedAuthorizationFailedError(err) ||
|
||||
err == ErrWantRefresh) {
|
||||
log.Print(err)
|
||||
// Try refreshing auth.
|
||||
if s.authorizer == nil {
|
||||
return false, nil // retry step
|
||||
}
|
||||
_, err = s.authorizer.RefreshWithContext(ctx, log)
|
||||
return false, err // retry step
|
||||
}
|
||||
return true, err
|
||||
}, timeoutCtx.Done())
|
||||
}
|
||||
|
||||
func (s authorizationRefreshingActionStep) String() string {
|
||||
return fmt.Sprintf("[AuthorizationRefreshingAction %s]", s.step)
|
||||
}
|
||||
|
||||
func (s authorizationRefreshingActionStep) metricsName() string {
|
||||
trimedName := strings.ReplaceAll(strings.ReplaceAll(s.step.String(), "[", ""), "]", "")
|
||||
return fmt.Sprintf("refreshing.%s", shortName(trimedName))
|
||||
}
|
|
@ -9,32 +9,17 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
mock_refreshable "github.com/Azure/ARO-RP/pkg/util/mocks/refreshable"
|
||||
utilerror "github.com/Azure/ARO-RP/test/util/error"
|
||||
testlog "github.com/Azure/ARO-RP/test/util/log"
|
||||
)
|
||||
|
||||
func successfulFunc(context.Context) error { return nil }
|
||||
func failingFunc(context.Context) error { return errors.New("oh no!") }
|
||||
func failsWithAzureError(ctx context.Context) error {
|
||||
return autorest.DetailedError{
|
||||
Method: "GET",
|
||||
PackageType: "TEST",
|
||||
Message: "oops",
|
||||
StatusCode: 403,
|
||||
Original: &azure.ServiceError{
|
||||
Code: "AuthorizationFailed",
|
||||
Message: "failed",
|
||||
},
|
||||
}
|
||||
}
|
||||
func successfulFunc(context.Context) error { return nil }
|
||||
func failingFunc(context.Context) error { return errors.New("oh no!") }
|
||||
func alwaysFalseCondition(context.Context) (bool, error) { return false, nil }
|
||||
func alwaysTrueCondition(context.Context) (bool, error) { return true, nil }
|
||||
func timingOutCondition(ctx context.Context) (bool, error) {
|
||||
|
@ -102,64 +87,6 @@ func TestStepRunner(t *testing.T) {
|
|||
},
|
||||
wantErr: `oh no!`,
|
||||
},
|
||||
{
|
||||
name: "An AuthorizationRefreshingAction that fails but is retried successfully will allow a successful run",
|
||||
steps: func(controller *gomock.Controller) []Step {
|
||||
refreshable := mock_refreshable.NewMockAuthorizer(controller)
|
||||
refreshable.EXPECT().
|
||||
RefreshWithContext(gomock.Any(), gomock.Any()).
|
||||
Return(true, nil)
|
||||
|
||||
errsRemaining := 1
|
||||
action := Action(func(context.Context) error {
|
||||
if errsRemaining > 0 {
|
||||
errsRemaining--
|
||||
return autorest.DetailedError{
|
||||
Method: "GET",
|
||||
PackageType: "TEST",
|
||||
Message: "oops",
|
||||
StatusCode: 403,
|
||||
Original: &azure.ServiceError{
|
||||
Code: "AuthorizationFailed",
|
||||
Message: "failed",
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
errorsOnce := &authorizationRefreshingActionStep{
|
||||
step: action,
|
||||
authorizer: refreshable,
|
||||
retryTimeout: 50 * time.Millisecond,
|
||||
pollInterval: 25 * time.Millisecond,
|
||||
}
|
||||
|
||||
return []Step{
|
||||
Action(successfulFunc),
|
||||
errorsOnce,
|
||||
Action(successfulFunc),
|
||||
}
|
||||
},
|
||||
wantEntries: []map[string]types.GomegaMatcher{
|
||||
{
|
||||
"msg": gomega.Equal("running step [Action github.com/Azure/ARO-RP/pkg/util/steps.successfulFunc]"),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.MatchRegexp(`running step \[AuthorizationRefreshingAction \[Action github.com/Azure/ARO-RP/pkg/util/steps\.TestStepRunner\..*.\.1]]`),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.Equal(`TEST#GET: oops: StatusCode=403 -- Original Error: Code="AuthorizationFailed" Message="failed"`),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.Equal("running step [Action github.com/Azure/ARO-RP/pkg/util/steps.successfulFunc]"),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "A successful condition will allow steps to continue",
|
||||
steps: func(controller *gomock.Controller) []Step {
|
||||
|
@ -212,63 +139,6 @@ func TestStepRunner(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AuthorizationRefreshingAction will not refresh once it is timed out",
|
||||
steps: func(controller *gomock.Controller) []Step {
|
||||
// We time out immediately, so we won't actually try and refresh
|
||||
refreshable := mock_refreshable.NewMockAuthorizer(controller)
|
||||
return []Step{
|
||||
Action(successfulFunc),
|
||||
&authorizationRefreshingActionStep{
|
||||
step: Action(failsWithAzureError),
|
||||
authorizer: refreshable,
|
||||
retryTimeout: 1 * time.Nanosecond,
|
||||
},
|
||||
Action(successfulFunc),
|
||||
}
|
||||
},
|
||||
wantEntries: []map[string]types.GomegaMatcher{
|
||||
{
|
||||
"msg": gomega.Equal("running step [Action github.com/Azure/ARO-RP/pkg/util/steps.successfulFunc]"),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.Equal("running step [AuthorizationRefreshingAction [Action github.com/Azure/ARO-RP/pkg/util/steps.failsWithAzureError]]"),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.Equal(`step [AuthorizationRefreshingAction [Action github.com/Azure/ARO-RP/pkg/util/steps.failsWithAzureError]] encountered error: TEST#GET: oops: StatusCode=403 -- Original Error: Code="AuthorizationFailed" Message="failed"`),
|
||||
"level": gomega.Equal(logrus.ErrorLevel),
|
||||
},
|
||||
},
|
||||
wantErr: `TEST#GET: oops: StatusCode=403 -- Original Error: Code="AuthorizationFailed" Message="failed"`,
|
||||
},
|
||||
{
|
||||
name: "AuthorizationRefreshingAction will not refresh on a real failure",
|
||||
steps: func(controller *gomock.Controller) []Step {
|
||||
refreshable := mock_refreshable.NewMockAuthorizer(controller)
|
||||
return []Step{
|
||||
Action(successfulFunc),
|
||||
AuthorizationRefreshingAction(refreshable, Action(failingFunc)),
|
||||
Action(successfulFunc),
|
||||
}
|
||||
},
|
||||
wantEntries: []map[string]types.GomegaMatcher{
|
||||
{
|
||||
"msg": gomega.Equal("running step [Action github.com/Azure/ARO-RP/pkg/util/steps.successfulFunc]"),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.Equal("running step [AuthorizationRefreshingAction [Action github.com/Azure/ARO-RP/pkg/util/steps.failingFunc]]"),
|
||||
"level": gomega.Equal(logrus.InfoLevel),
|
||||
},
|
||||
{
|
||||
"msg": gomega.Equal(`step [AuthorizationRefreshingAction [Action github.com/Azure/ARO-RP/pkg/util/steps.failingFunc]] encountered error: oh no!`),
|
||||
"level": gomega.Equal(logrus.ErrorLevel),
|
||||
},
|
||||
},
|
||||
wantErr: `oh no!`,
|
||||
},
|
||||
{
|
||||
name: "A timed out Condition causes a failure",
|
||||
steps: func(controller *gomock.Controller) []Step {
|
||||
|
@ -360,21 +230,11 @@ func TestStepMetricsNameFormatting(t *testing.T) {
|
|||
step: Condition(alwaysTrueCondition, 1*time.Millisecond, true),
|
||||
want: "condition.alwaysTrueCondition",
|
||||
},
|
||||
{
|
||||
desc: "test refreshing step naming",
|
||||
step: AuthorizationRefreshingAction(nil, Action(successfulFunc)),
|
||||
want: "refreshing.successfulFunc",
|
||||
},
|
||||
{
|
||||
desc: "test anonymous action step naming",
|
||||
step: Action(func(context.Context) error { return nil }),
|
||||
want: "action.func1",
|
||||
},
|
||||
{
|
||||
desc: "test anonymous action step naming",
|
||||
step: AuthorizationRefreshingAction(nil, Action(func(context.Context) error { return nil })),
|
||||
want: "refreshing.func2",
|
||||
},
|
||||
} {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
if got := tt.step.metricsName(); got != tt.want {
|
||||
|
|
Загрузка…
Ссылка в новой задаче