-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use retryable http client in Azure authz provider #372
Use retryable http client in Azure authz provider #372
Conversation
68962f3
to
1cbc986
Compare
@weinong @AzureMarker could you please have a review? Thanks! |
1cbc986
to
ad88d63
Compare
authz/providers/azure/azure.go
Outdated
@@ -120,6 +124,8 @@ func (s Authorizer) Check(ctx context.Context, request *authzv1.SubjectAccessRev | |||
return &authzv1.SubjectAccessReviewStatus{Allowed: true, Reason: rbac.AccessAllowedVerdict}, nil | |||
} | |||
|
|||
ctx = azureutils.WithRetryableHttpClient(ctx, s.HttpClientRetryCount) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- why do we save the http client in the context?
- as far as I can tell, it still uses AccessInfo.client, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed the comment of WithRetryableHttpClient
.
// WithRetryableHttpClient sets the oauth2.HTTPClient key of the context to an
// *http.Client made from makeRetryableHttpClient.
// Some of the libraries we use will take the client out of the context via
// oauth2.HTTPClient and use it, so this way we can add retries to external code.
Both RefreshToken
and sendCheckAccessRequest
are using the library "net/http".
@AzureMarker to confirm whether "net/http" respects the http client in the context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
net/http
is a standard library, it doesn't reference third party code so there's no way it uses that context key.
This key is used in go-oidc:
if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok { |
The other HTTP client usages hard-code to go.kubeguard.dev/guard/util/httpclient
's DefaultHTTPClient
, which is just a normal HTTP client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made this change 57e588e. Could you please review it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AzureMarker gentle ping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments
ad88d63
to
bc5f06a
Compare
@@ -74,6 +75,9 @@ func (u *oboTokenProvider) Acquire(ctx context.Context, token string) (AuthRespo | |||
klog.V(10).Infoln(cmd) | |||
} | |||
|
|||
if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok { | |||
u.client = c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't modify the token provider (u.client
). Store a reference to the HTTP client in a variable and modify it there.
The issue is if this is called twice (first with a context that holds an HTTP client, then with a context that has no HTTP client), the second call will use the HTTP client of the first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed this part to make the pr focus on authz.
authz/providers/azure/rbac/rbac.go
Outdated
@@ -374,6 +375,10 @@ func (a *AccessInfo) CheckAccess(request *authzv1.SubjectAccessReviewSpec) (*aut | |||
} | |||
|
|||
func (a *AccessInfo) sendCheckAccessRequest(ctx context.Context, checkAccessURL url.URL, checkAccessBody *CheckAccessRequest, ch chan *authzv1.SubjectAccessReviewStatus) error { | |||
if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok { | |||
a.client = c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here, don't modify a.client
, store it in a local variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed. Could you please check whether the fix meets the requirement? Thanks
57e588e
to
656a1ec
Compare
@AzureMarker Could you please have a review again? Thanks |
@weinong could you please have a review? Thanks |
fd7361f
to
f30b13d
Compare
The PR is rebased. @weinong could you please have a review? Please let me know if anything is missing. Thanks! |
authz/providers/azure/rbac/rbac.go
Outdated
@@ -373,6 +377,11 @@ func (a *AccessInfo) CheckAccess(request *authzv1.SubjectAccessReviewSpec) (*aut | |||
} | |||
|
|||
func (a *AccessInfo) sendCheckAccessRequest(ctx context.Context, checkAccessUsername string, checkAccessURL url.URL, checkAccessBody *CheckAccessRequest, ch chan *authzv1.SubjectAccessReviewStatus) error { | |||
var clientInCtx *http.Client | |||
if c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we move this client loader to util/azure
so we can hide the context key from caller?
@@ -37,7 +37,8 @@ import ( | |||
) | |||
|
|||
const ( | |||
loginResp = `{ "token_type": "Bearer", "expires_in": 8459, "access_token": "%v"}` | |||
loginResp = `{ "token_type": "Bearer", "expires_in": 8459, "access_token": "%v"}` | |||
httpClientRetryCount = 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add a unit test for covering the retry behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
ClientID: "client_id", | ||
ClientSecret: "client_secret", | ||
TenantID: "tenant_id", | ||
HttpClientRetryCount: httpClientRetryCount, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we assert that it try 2 times ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
da82048
to
685ade4
Compare
Signed-off-by: Bin Xia <binxi@microsoft.com>
685ade4
to
3e9b748
Compare
@@ -171,6 +174,7 @@ func TestCheck(t *testing.T) { | |||
assert.Nilf(t, resp, "response should be nil") | |||
assert.NotNilf(t, err, "should get error") | |||
assert.Contains(t, err.Error(), "Error occured during authorization check") | |||
assert.Contains(t, err.Error(), fmt.Sprintf("giving up after %d attempt", httpClientRetryCount+1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bcho @julienstroheker this line can assert that it gives up after 3 attempts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please have another round of review? Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@weinong could you please have another round of review? Thanks |
@julienstroheker PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
approved
We see the timeout error in the checkaccess requrests sometimes.
This PR moves
withRetryableHttpClient
from Azure authn provider toutils
, and leverage it in Azure authz provider'sRefreshToken
andCheckAccess
.