fix: s3 update and find fail with short bucket names#250
Conversation
|
Task linked: DUPLO-41903 s3: update fails |
Review Summary by QodoFix S3 update and find operations with short bucket names
WalkthroughsDescription• Fixed s3 find to resolve short bucket names via list-and-match • Fixed s3 update to use full bucket name and lowercase endpoint • Added error handling with proper exception types • Enables apply to work correctly with short bucket names Diagramflowchart LR
A["Short bucket name<br/>e.g. mybucket"] -->|find method| B["List all buckets"]
B -->|match prefix| C["Resolve full name<br/>e.g. duploservices-tenant-mybucket-123456"]
C -->|update method| D["PUT to lowercase<br/>aws/s3bucket endpoint"]
D -->|with full name| E["Updated bucket"]
File Changes1. src/duplo_resource/s3.py
|
Code Review by Qodo
1. update() assumes dict body
|
☂️ Python Coverage
Overall Coverage
New FilesNo new covered files... Modified Files
|
| DuploNotFound: If the bucket could not be found. | ||
| """ | ||
| prefix = self.prefixed_name(name) | ||
| for bucket in self.list(): |
There was a problem hiding this comment.
I am usually against using list for GET purposes as it does not scale well.
For this case, however, I think its actually fine because of the lower default bucket quota per AWS account (I think the limit is 100?)
There was a problem hiding this comment.
I'm also not sure that using the LIST to GET is a good idea.
There is an endpoint to get a single bucket and this change removes that. Now we would never be able to use this cli to hit that endpoint.
I think we can think about this a bit more and come up with a better solution even if it means sacrificing some bells and whistles to make the logic more "dumb."
kferrone
left a comment
There was a problem hiding this comment.
I have an idea, instead of making a call to the list to guarantee some name exists. There is some way we can determine if something is using a prefixed name or not.
Like we could always try twice, first find takes the name as is, if we get a not found then we try one more time with the prefix. I have done this logic before and it worked well.
I see what you mean. The problem is that prefixed_name alone isn't enough to reconstruct the full bucket name. AWS buckets come back as duploservices--- (e.g. duploservices-amaechi-test-bucket-182680712604). So trying the short name, and then trying the prefix would still miss because we don't know the account-ID suffix without listing. Maybe we could first attempt GET {name} as-is for the case where the user passes in the full name, and only fall back to list-and-match on DuploNotFound (handles short names). That way the direct endpoint is still exercised whenever the caller already knows the full name, and we only pay the list cost when resolving a short name. |
kferrone
left a comment
There was a problem hiding this comment.
We can use the System resource to get the Account id.
Something like this in the constructor:
sys_svc = self.duplo.load("system")
Then when you need to:
sys_info = sys_svc.info()
Then you can find the account id on sys_info.
kferrone
left a comment
There was a problem hiding this comment.
So the logic would be like this:
- try to find with the name given as is.
- if the name is found as is, then return that
- if the name given was not found, then build the generated "fullname" with account id and tenant prefix, try and find that
- if long name found return it
- if not even the long name is found, then truly raise a DuploNotFound error
Co-authored-by: Copilot <copilot@github.com>
Describe Changes
The S3 backend API's GET endpoint passes the raw bucket name directly to AWS SDK via
LocateBucket(), which cannot resolve short names (e.g.test-bucket) to full AWS names (e.g.duploservices-amaechi-test-bucket-182680712604). The PUT endpoint additionally requires the lowercases3bucketroute and the full bucket name in both the URL and request body.find: Replaced direct GET lookup with list-and-match that resolves short names by checking if the full bucket name starts withprefixed_name(short_name)update: New override that resolves the full name viafind, sets it in the body, and PUTs to the lowercaseaws/s3bucket/{full_name}endpointPreviously,
applyonly worked becausefindfailed with a short name and fell through to thecreatepath. Nowfind,update, andapplyall work correctly with short names.Link to Issues
https://app.clickup.com/t/8655600/DUPLO-41903
PR Review Checklist