-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Token store deleted parent #4193
Merged
Merged
Changes from 9 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
7e33191
Handle removal of parent index on revoke-orphan and tidy operations
calvn 420373d
Refactor handleTidy to use same for loop children deletion of invalid…
calvn 2533791
Update comments
calvn b027c2f
Add logic for revoke-orphan and tidy to turn no-parent tokens into or…
calvn 73f8040
Add orphan check to test
calvn d531227
Update test comments
calvn 6f2baf5
Fix TestTokenStore_Revoke_Orphan test
calvn 6e60ccb
Address feedback, add explicit delete when parent prefix is empty
calvn 5648624
Revert explicit delete, add comment on why it's not done
calvn 564de0d
Update comment to indicate ok on marking token as orphan
calvn 33340a3
Merge branch 'master' into token-store-deleted-parent
calvn fbba0c3
Fix test
calvn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1169,6 +1169,33 @@ func (ts *TokenStore) revokeSalted(ctx context.Context, saltedId string) (ret er | |
} | ||
} | ||
|
||
// Mark all children token as orphan by removing | ||
// their parent index, and clear the parent entry | ||
parentPath := parentPrefix + saltedId + "/" | ||
children, err := ts.view.List(ctx, parentPath) | ||
if err != nil { | ||
return fmt.Errorf("failed to scan for children: %v", err) | ||
} | ||
for _, child := range children { | ||
entry, err := ts.lookupSalted(ctx, child, true) | ||
if err != nil { | ||
return fmt.Errorf("failed to get child token: %v", err) | ||
} | ||
lock := locksutil.LockForKey(ts.tokenLocks, entry.ID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this lock happens to be the same lock that is being used outside of this loop, acquiring this will deadlock. No? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind. |
||
lock.Lock() | ||
|
||
entry.Parent = "" | ||
err = ts.store(ctx, entry) | ||
if err != nil { | ||
lock.Unlock() | ||
return fmt.Errorf("failed to update child token: %v", err) | ||
} | ||
lock.Unlock() | ||
} | ||
if err = logical.ClearView(ctx, ts.view.SubView(parentPath)); err != nil { | ||
return fmt.Errorf("failed to delete entry: %v", err) | ||
} | ||
|
||
// Now that the entry is not usable for any revocation tasks, nuke it | ||
path := lookupPrefix + saltedId | ||
if err = ts.view.Delete(ctx, path); err != nil { | ||
|
@@ -1322,17 +1349,30 @@ func (ts *TokenStore) handleTidy(ctx context.Context, req *logical.Request, data | |
return nil, fmt.Errorf("failed to fetch secondary index entries: %v", err) | ||
} | ||
|
||
var countParentList, deletedCountParentList int64 | ||
var countParentEntries, deletedCountParentEntries, countParentList, deletedCountParentList int64 | ||
|
||
// Scan through the secondary index entries; if there is an entry | ||
// with the token's salt ID at the end, remove it | ||
for _, parent := range parentList { | ||
countParentEntries++ | ||
|
||
// Get the children | ||
children, err := ts.view.List(ctx, parentPrefix+parent) | ||
if err != nil { | ||
tidyErrors = multierror.Append(tidyErrors, fmt.Errorf("failed to read secondary index: %v", err)) | ||
continue | ||
} | ||
|
||
// First check if the salt ID of the parent exists, and if not mark this so | ||
// that deletion of children later with this loop below applies to all | ||
// children | ||
originalChildrenCount := int64(len(children)) | ||
exists, _ := ts.lookupSalted(ctx, strings.TrimSuffix(parent, "/"), true) | ||
if exists == nil { | ||
ts.logger.Trace("token: deleting invalid parent prefix entry", "index", parentPrefix+parent) | ||
} | ||
|
||
var deletedChildrenCount int64 | ||
for _, child := range children { | ||
countParentList++ | ||
if countParentList%500 == 0 { | ||
|
@@ -1342,17 +1382,43 @@ func (ts *TokenStore) handleTidy(ctx context.Context, req *logical.Request, data | |
// Look up tainted entries so we can be sure that if this isn't | ||
// found, it doesn't exist. Doing the following without locking | ||
// since appropriate locks cannot be held with salted token IDs. | ||
// Also perform deletion if the parent doesn't exist any more. | ||
te, _ := ts.lookupSalted(ctx, child, true) | ||
if te == nil { | ||
// If the child entry is not nil, but the parent doesn't exist, then turn | ||
// that child token into an orphan token. Theres no deletion in this case. | ||
if te != nil && exists == nil { | ||
lock := locksutil.LockForKey(ts.tokenLocks, te.ID) | ||
lock.Lock() | ||
|
||
te.Parent = "" | ||
err = ts.store(ctx, te) | ||
if err != nil { | ||
tidyErrors = multierror.Append(tidyErrors, fmt.Errorf("failed to convert child token into an orphan token: %v", err)) | ||
} | ||
lock.Unlock() | ||
continue | ||
} | ||
// Otherwise, if the entry doesn't exist, or if the parent doesn't exist go | ||
// on with the delete on the secondary index | ||
if te == nil || exists == nil { | ||
index := parentPrefix + parent + child | ||
ts.logger.Trace("token: deleting invalid secondary index", "index", index) | ||
err = ts.view.Delete(ctx, index) | ||
if err != nil { | ||
tidyErrors = multierror.Append(tidyErrors, fmt.Errorf("failed to delete secondary index: %v", err)) | ||
continue | ||
} | ||
deletedCountParentList++ | ||
deletedChildrenCount++ | ||
} | ||
} | ||
// Add current children deleted count to the total count | ||
deletedCountParentList += deletedChildrenCount | ||
// N.B.: We don't call delete on the parent prefix since physical.Backend.Delete | ||
// implementations should be in charge of deleting empty prefixes. | ||
// If we deleted all the children, then add that to our deleted parent entries count. | ||
if originalChildrenCount == deletedChildrenCount { | ||
deletedCountParentEntries++ | ||
} | ||
} | ||
|
||
var countAccessorList, | ||
|
@@ -1447,6 +1513,8 @@ func (ts *TokenStore) handleTidy(ctx context.Context, req *logical.Request, data | |
} | ||
} | ||
|
||
ts.logger.Debug("token: number of entries scanned in parent prefix", "count", countParentEntries) | ||
ts.logger.Debug("token: number of entries deleted in parent prefix", "count", deletedCountParentEntries) | ||
ts.logger.Debug("token: number of tokens scanned in parent index list", "count", countParentList) | ||
ts.logger.Debug("token: number of tokens revoked in parent index list", "count", deletedCountParentList) | ||
ts.logger.Debug("token: number of accessors scanned", "count", countAccessorList) | ||
|
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Maybe add to this comment explaining that marking orphan is correct since revokeTree will ensure that any are deleted anyways if it is not an explicit call to orphan the child tokens.