HDDS-15137. [STS] Ensure each S3 API has an associated S3 Action#10197
Conversation
cfd028f to
7b59609
Compare
|
hi @ChenSammi @sodonnel - this PR has been rebased and is ready for review. Thanks! |
| final OzoneKeyDetails destKeyDetails = getClientProtocol().getKeyDetails( | ||
| volume.getName(), destBucket, destkey); |
There was a problem hiding this comment.
yes, the concern is correct, the suggested fix is incorrect. It is fixed in the follow-on PR https://github.com/apache/ozone/pull/10203/changes by removing the extra destKeyDetails call (which will help performance as well).
| final S3Authentication s3Authentication = OzoneManager.getS3Auth(); | ||
| if (s3Authentication == null || !s3Authentication.hasS3Action()) { | ||
| return context; | ||
| } | ||
| return context.toBuilder() | ||
| .setS3Action(s3Authentication.getS3Action()) | ||
| .build(); |
| } | ||
|
|
||
| protected OzoneVolume getVolume() throws IOException { |
| } | ||
|
|
||
| message CommitKeyResponse { | ||
|
|
There was a problem hiding this comment.
This change is irrelevant, better reverted.
| } | ||
| } | ||
| ] | ||
| } |
There was a problem hiding this comment.
This change is irrelevant, better reverted.
| * @param context the original RequestContext | ||
| * @return RequestContext as before or with s3 action embedded | ||
| */ | ||
| private RequestContext maybeAttachS3ActionFromThreadLocal(RequestContext context) { |
There was a problem hiding this comment.
Can maybeAttachS3ActionFromThreadLocal and maybeAttachSessionPolicyFromThreadLocal merge into one function?
There was a problem hiding this comment.
BTW, can we move setS3Action and setSessionPolicy to where context is created?
There was a problem hiding this comment.
Cannot found where context.getS3Action() is used. Is this a complete patch, or there will be following patch which requires this get function?
There was a problem hiding this comment.
updated to combine the maybeAttach methods and move the setters to where the context is created: a223e5c
There was a problem hiding this comment.
Cannot found where context.getS3Action() is used. Is this a complete patch, or there will be following patch which requires this get function?
This is used in theRangerOzoneAuthorizer to help authorize against the specific action. See apache/ranger#995 and in particular https://github.com/fmorg-git/ranger/blob/e6327b6bd039ef52d8c82e203be4d8c034214f09/plugin-ozone/src/main/java/org/apache/ranger/authorization/ozone/authorizer/RangerOzoneAuthorizer.java#L168-L173
There was a problem hiding this comment.
BTW, can we move setS3Action and setSessionPolicy to where context is created?
originally, I implemented this suggestion but this broke some of my unit tests in TestOMMetadataReader. Now I remember why I did it the way I did, is because there are many sites where the RequestContext is created but they all funnel down to this method in OmMetadataReader:
public boolean checkAcls(OzoneObj obj, RequestContext context,
boolean throwIfPermissionDenied)
So it's safer to have it in the one central location that everyone uses, because if we try to rely on adding to all the sites where RequestContext is created, if a new overloaded call site is added in future, someone would need to remember to update that one as well or else there would be a bug until it is realized, which is brittle. The second issue is that someone might call this method directly like the unit test does, and if we don't set the values here, it would break, just like the unit test. So if we need to set the values in this method anyway, we might as well just set it once. I understand it is an extra object allocation, but at least now the two maybeAttach* methods are combined into one, so it's one less allocation and the code is more maintainable with the one central location.
| long putLength; | ||
| try (OzoneOutputStream ozoneOutputStream = getClientProtocol() | ||
| final long putLength; | ||
| final OzoneOutputStream ozoneOutputStream = getClientProtocol() |
There was a problem hiding this comment.
runWithS3ActionString("PutObject" is missed here. ozoneOutputStream is not closed
There was a problem hiding this comment.
Actually, here is the reason "PutObject" is not missed here. In this else branch of the code, the request action is set to S3GAction.CREATE_MULTIPART_KEY and this has a mapping in S3GActionIamMapper to "PutObject", so it's covered. In the if branch of the code, the request action is set to S3GAction.CREATE_MULTIPART_KEY_BY_COPY which is mapped to null in S3GActionIamMapper (by design, since it needs "GetObject" on the source and "PutObject" on the destination.)
Also, the ozoneOutputStream is closed on line 920 in the try-with-resources block.
There was a problem hiding this comment.
I added a clarification comment about the runWithS3ActionString - e344aae
| final long finalLength = length; | ||
| final long bytesToCopy = length; | ||
| omMultipartCommitUploadPartInfo = runWithS3ActionString("PutObject", () -> { | ||
| final OzoneOutputStream ozoneOutputStream = getClientProtocol().createMultipartKey( |
There was a problem hiding this comment.
ozoneOutputStream is not closed.
There was a problem hiding this comment.
the ozoneOutputStream is closed on line 898 in the try-with-resources block
…icy and s3Action and set them at the call sites Generated-By: Claude Code with manual updates by me
| @@ -628,8 +628,12 @@ public boolean checkAcls(ResourceType resType, StoreType storeType, | |||
| public boolean checkAcls(OzoneObj obj, RequestContext context, | |||
There was a problem hiding this comment.
You can pass RequestContext.Builder in instead of RequestContext here.
There was a problem hiding this comment.
yep, that's a much better idea. Updated - 77cfc5e
|
Thanks for the review and merge. |
Please describe your PR in detail:
HeadObjectandGetObjectS3 apis are associated with "s3:GetObject" action. The actions will not have the s3: prefix when used internally in Ozone and Ranger.Most apis have a 1-1 mapping with api and action like the
HeadObjectandGetObjectapis mentioned previously. In order to avoid having to update multiple call sites, anS3GActionIamMapperis introduced to leverage the already existing api audit functionality and map api names to actions in a thread local (S3Authentication.getS3Action()). Then inOmMetadataReader.checkAcls(), themaybeAttachS3ActionFromThreadLocalfunction is used to read the thread local and set the s3Action in the RequestContext if it exists.However,
CopyObjectandUploadPartCopyare special cases. There is no "s3:CopyObject" nor "s3:UploadPartCopy" action, but rather they both require "s3:GetObject" action on the source object and "s3:PutObject" action on the destination object. For these special cases, a helper methodrunWithS3ActionStringis introduced inEndpointBase.javaso the proper permissions can be checked on the source and on the destination by temporarily overriding the value in the thread local while the operation is invoked, then setting it back to the previous value when done.Additionally, this ticket contains additional fixes found after testing with these new changes. For example, since we now have fine-grained actions, we no longer need to distinguish listing files permission vs download files permission with LIST acl vs READ acl. Both apis can use READ acl.
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-15137
How was this patch tested?
unit tests, smoke tests