Skip to content
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

S3 vhost customisation #832

Merged
merged 9 commits into from Nov 1, 2022
Merged

Conversation

endgame
Copy link
Collaborator

@endgame endgame commented Oct 27, 2022

Implement S3 vhost rewriting customisation using the design proposed by @basvandijk. The basic design is the same:

  • request :: AWSRequest a => Service -> a -> Request a in class AWSRequest is now accepts the service to send the request to, instead of generators hardcoding defaultService. This allows the Request to be computed from the overriden Service instead of defaultService.
  • We need to be able to determine the default service for a request type when doing initial signing, so we need a typeclass method service :: AWSRequest a => Proxy a -> Service somewhere. We apply overrides to it before passing it to request.
  • It might be possible to avoid the additional typeclass method by making request :: AWSRequest a => (Service -> Service) -> a -> Request a, but every option I could think of seemed worse than a new typeclass method.

There are some differences to the original design (which I cherry-picked from @ivb-supercede's branch with generator fixes):

  • The service function is a method of class AWSRequest a instead of a separate class AWSService a and making class AWSService a => AWSRequest a; I couldn't see much benefit in a separate typeclass. Am I wrong?
  • Instead of a Bool, I added a sum type to match the S3 addressing style options

Because we're going to have to regenerate everything, I updated botocore as well. A full regeneration is available at endgame:s3-vhost-customisation-generation and will be merged once this branch lands. I have rebuilt the entire repo locally and it at least compiles.

Ping @basvandijk @ivb-supercede @kfigiela @akshaymankar @periodic who might be interested — please test the branch above.

@basvandijk / @ivb-supercede: Is it OK that I've cherry-picked your commits here?

Fixes #760
Closes #797

This implements a change suggested by this comment:
brendanhay#797 (comment)
as part of a fix to the following issue:
brendanhay#760

This modifies the code generation for AWS endpoints so that requests
which make other requests all share the same (passed-in) `Service`. This
is done by making `request` take an extra `Service` argument. This also
adds a new parent class of `AWSRequest`, called `AWSService`, which
defines the default service used for each request (this being
`defaultService`.)

These are some breaking changes, but they are required to allow modified
`Service`s to be used in complex requests. This is necessary to allow
VHost rewriting to be turned off for local mocking and other use cases
at the `Service` level.

Co-authored-by: Bas van Dijk <v.dijk.bas@gmail.com>
endgame and others added 2 commits October 27, 2022 14:02
We have no need for types which associate a `Service` but are not
`Request`s.
Originally "Non-working attempt to fix the test failure in PR brendanhay#797"

This adds a new field to `Service` which controls if requests to the
service should have their URLs rewritten using `s3vhost`. This is
particularly relevant for mocks of S3 which don't support having the
bucket name in the hostname (e.g. because they are bound to `localhost`,
which isn't a domain and can't have a subdomain.)

This field is defaulted to `True` to preserve the current behaviour for
all services.

Co-authored-by: Isaac van Bakel <isaac@supercede.com>
@endgame endgame force-pushed the s3-vhost-customisation branch 2 times, most recently from d785589 to 71c5da2 Compare October 27, 2022 04:11
This makes our S3-vhost-rewriting rules configurable in the same way
as boto3.
We need to regenerate everything anyway, so we may as well keep up
with service definitions.
@ivb-supercede
Copy link
Contributor

The service function is a method of class AWSRequest a instead of a separate class AWSService a and making class AWSService a => AWSRequest a; I couldn't see much benefit in a separate typeclass. Am I wrong?

I don't know enough to comment on this in general, since I just cribbed this from Bas' code. But in the case where AWSService is a superclass of AWSRequest, then this is design doesn't really make a difference - without any typeclass laws, what meaningful code can be written with only a AWSService instance?

Ping @basvandijk @ivb-supercede @kfigiela @akshaymankar @periodic who might be interested — please test the branch above.

Will do.

@basvandijk / @ivb-supercede: Is it OK that I've cherry-picked your commits here?

All good with me 👍.

@kfigiela
Copy link

I will test this soon. If anyone needs a version with all services regenerated, it's available on my fork with the same branch name.

@kfigiela
Copy link

kfigiela commented Oct 27, 2022

I can confirm that our integration tests work just fine with aws mocked with localstack and endpoint override configured not to use vhosts.

@ivb-supercede
Copy link
Contributor

Looks like these changes work fine for us, for both real AWS usage and for local mocking with Moto.

@endgame endgame merged commit 5d9fd87 into brendanhay:main Nov 1, 2022
akshaymankar added a commit to wireapp/wire-server that referenced this pull request Dec 28, 2022
brendanhay/amazonka#832 should have solved our problems,
so we shouldn't need the fork.
akshaymankar added a commit to wireapp/wire-server that referenced this pull request Dec 29, 2022
Path style is not supported for newer buckets, more info:
https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/

All object storage providers (like MinIO, ScalityRing, etc) might not work with
vhost style addressing, so this change introduces a new configuration option in
cargohold as aws.s3AddressingStyle to choose the addressing style.

Other changes:

* Move wire-server from using forked version of amazonka to upstream HEAD.

The option to choose S3 Addressing Style has been implemented in
brendanhay/amazonka#832

* Makefile: Skip schema migrations for packages without DB

This allows running something like `make ci package=cargohold` even if cargohold
doesn't produce a cargohold-schema executable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

S3: Setting endpoint interferes with vhost style URLs
4 participants