-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
x-pack/filebeat/input/entityanalytics/provider/okta: Rate limiting fixes #41583
x-pack/filebeat/input/entityanalytics/provider/okta: Rate limiting fixes #41583
Conversation
Pinging @elastic/security-service-integrations (Team:Security-Service Integrations) |
This pull request does not have a backport label.
To fixup this pull request, you need to add the backport labels for the needed
|
|
368f547
to
b57da7b
Compare
3c56801
to
317c45e
Compare
endpoint = "/api/v1/users/{user}" | ||
path = strings.Replace(endpoint, "{user}", user, 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.
Can we not just use path.Join
here rather than a search/replace?
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.
We do also need endpoint
now, without the ID inserted, for the rate limiter.
I think it's good that the final path
is derived from the endpoint
pattern. If there's a change they're less likely to diverge.
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 don't particularly like it, but 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.
Ok. Leaving it like that.
var endpoint string | ||
var path string |
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.
var endpoint, path string
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.
Done.
u := &url.URL{ | ||
Scheme: "https", | ||
Host: host, | ||
Path: path.Join(endpoint, user, "factors"), | ||
Path: path, |
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 think keeping the use if path.Join
would be better (also below).
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.
As above. Leaving it.
} | ||
if limiter.lim.Burst() != 1 { | ||
t.Errorf("unexpected burst: got:%d want:1", limiter.lim.Burst()) | ||
for _, l := range *limiter { |
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 think this needs a comment, or preferably since we have constructed the system here, use the key that we expect to exist using limiter[<key>]
.
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 went with the comment.
type RateLimiter struct { | ||
lim *rate.Limiter | ||
} | ||
type RateLimiter map[string]*rate.Limiter | ||
|
||
func NewRateLimiter() *RateLimiter { |
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 does not need to be on a pointer.
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.
Changed to:
func NewRateLimiter() RateLimiter
@@ -444,7 +444,7 @@ var nextTests = []struct { | |||
func TestNext(t *testing.T) { | |||
for i, test := range nextTests { | |||
got, err := Next(test.header) | |||
if err != test.wantErr { | |||
if !errors.Is(err, test.wantErr) { |
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 is not right. The two cases are nil
and io.EOF
and the latter is never wrapped.
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.
Reverted.
@@ -478,7 +478,7 @@ func (p *oktaInput) doFetchUsers(ctx context.Context, state *stateStore, fullSyn | |||
|
|||
next, err := okta.Next(h) | |||
if err != nil { | |||
if err == io.EOF { | |||
if errors.Is(err, io.EOF) { |
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 and below.
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.
Reverted 3 cases.
r.Update(endpoint, headers, window, logp.L()) | ||
err := r.Update(endpoint, headers, window, logp.L()) | ||
if err != nil { | ||
t.Errorf("Update returned error: %v", err) |
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.
t.Errorf("unexpected error from Update(): %v", err)
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.
Done.
if _, copyErr := io.Copy(io.Discard, resp.Body); copyErr != nil { | ||
err = errors.Join(err, copyErr) | ||
} |
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.
If I were going to do this, I would have it as
_, cerr := io.Copy(io.Discard, resp.Body)
return nil, nil, errors.Join(err, cerr)
but we are just discarding the the body to recover the conn's usability, so this is really only an optimisation and as such should not change the behaviour qualitatively; I would leave this as it was originally.
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.
Reverted it.
return &r | ||
} | ||
|
||
func (r RateLimiter) get(path string) *rate.Limiter { |
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.
func (r RateLimiter) get(path string) *rate.Limiter { | |
func (r RateLimiter) Limiter(path string) *rate.Limiter { |
with necessary changes elsewhere.
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.
Or unexported? I think this should only be used internally and for testing.
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.
Sure, unexported is fine. If this becomes something we need to share later, we can export it then.
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.
Done.
This pull request is now in conflicts. Could you fix it? 🙏
|
23a565a
to
13a79f3
Compare
…xes (#41583) - Separate rate limits by endpoint. - Stop requests until reset when `x-rate-limit-remaining: 0`. (cherry picked from commit 4e19d09) # Conflicts: # x-pack/filebeat/input/entityanalytics/provider/okta/internal/okta/okta.go # x-pack/filebeat/input/entityanalytics/provider/okta/internal/okta/okta_test.go
…xes (#41583) (#41902) - Separate rate limits by endpoint. - Stop requests until reset when `x-rate-limit-remaining: 0`. (cherry picked from commit 4e19d09) Co-authored-by: Chris Berkhout <[email protected]>
…r/okta: Rate limiting fixes (#41901) x-pack/filebeat/input/entityanalytics/provider/okta: Rate limiting fixes (#41583) - Separate rate limits by endpoint. - Stop requests until reset when `x-rate-limit-remaining: 0`. (cherry picked from commit 4e19d09) - Resolved conflicts by removing changes to `GetUserFactors`, `GetUserRoles` and `GetGroupRoles`, because 8.16 doesn't have #41044.
Proposed commit message
Checklist
CHANGELOG.next.asciidoc
orCHANGELOG-developer.next.asciidoc
.Discussion
Can be reviewed commit-by-commit.
The reason a new
rate.Limiter
needs to be created whenx-rate-limit-remaining: 0
is that whilerate.Limiter
allows updating of the rate and burst, it doesn't allow clearing of existing tokens.Disruptive User Impact
None.
Related issues