Skip to content

Commit

Permalink
Quay: Cloudfront multi domain (PROJQUAY-4506) (#1598)
Browse files Browse the repository at this point in the history
Multi domain support for Quay. CLOUDFRONT ONLY
  • Loading branch information
kwestpharedhat authored Nov 2, 2022
1 parent 434c193 commit dcf5a37
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
6 changes: 5 additions & 1 deletion endpoints/v1/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ def get_image_layer(namespace, repository, image_id, headers):
user = get_authenticated_user()
username = user.username if user else None
direct_download_url = store.get_direct_download_url(
legacy_image.blob.placements, path, get_request_ip(), username=username
legacy_image.blob.placements,
path,
get_request_ip(),
username=username,
namespace=namespace,
)
if direct_download_url:
logger.debug("Returning direct download URL")
Expand Down
2 changes: 1 addition & 1 deletion endpoints/v2/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def download_blob(namespace_name, repo_name, digest, registry_model):
user = get_authenticated_user()
username = user.username if user else None
direct_download_url = storage.get_direct_download_url(
blob.placements, path, get_request_ip(), username=username
blob.placements, path, get_request_ip(), username=username, namespace=namespace_name
)
if direct_download_url:
logger.debug("Returning direct download URL")
Expand Down
11 changes: 10 additions & 1 deletion storage/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,7 @@ def __init__(
self,
context,
cloudfront_distribution_domain,
cloudfront_distribution_org_overrides,
cloudfront_key_id,
cloudfront_privatekey_filename,
storage_path,
Expand All @@ -1000,6 +1001,7 @@ def __init__(
context, storage_path, s3_bucket, *args, **kwargs
)

self.cloudfront_distribution_org_overrides = cloudfront_distribution_org_overrides
self.s3_region = s3_region
self.cloudfront_distribution_domain = cloudfront_distribution_domain
self.cloudfront_key_id = cloudfront_key_id
Expand All @@ -1008,6 +1010,7 @@ def __init__(
def get_direct_download_url(
self, path, request_ip=None, expires_in=60, requires_cors=False, head=False, **kwargs
):

# If CloudFront could not be loaded, fall back to normal S3.
if self.cloudfront_privatekey is None or request_ip is None:
return super(CloudFrontedS3Storage, self).get_direct_download_url(
Expand All @@ -1032,7 +1035,13 @@ def get_direct_download_url(
path, request_ip, expires_in, requires_cors, head, **kwargs
)

url = "https://%s/%s" % (self.cloudfront_distribution_domain, path)
domain = self.cloudfront_distribution_domain
if kwargs:
namespace = kwargs.get("namespace")
if namespace in self.cloudfront_distribution_org_overrides:
domain = self.cloudfront_distribution_org_overrides.get(namespace)

url = "https://%s/%s" % (domain, path)
if kwargs:
url += f"?{urllib.parse.urlencode(kwargs)}"

Expand Down
45 changes: 45 additions & 0 deletions storage/test/test_cloudfront.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def test_direct_download(
engine = CloudFrontedS3Storage(
context,
"cloudfrontdomain",
{},
"keyid",
"test/data/test.pem",
"some/path",
Expand All @@ -98,6 +99,48 @@ def test_direct_download(
# get back an S3 URL.
assert "s3.amazonaws.com" in engine.get_direct_download_url(_TEST_PATH, "1.2.3.4")

engine = CloudFrontedS3Storage(
context,
"defaultdomain",
{"testnamespace": "overridedomain"},
"keyid",
"test/data/test.pem",
"some/path",
_TEST_BUCKET,
_TEST_REGION,
_TEST_USER,
_TEST_PASSWORD,
)

engine.put_content(_TEST_PATH, _TEST_CONTENT)
assert engine.exists(_TEST_PATH)

# Request a direct download URL for a request from a known AWS IP but not in the same region, returned CloudFront URL.
assert "overridedomain" in engine.get_direct_download_url(
_TEST_PATH, test_aws_ip, namespace="testnamespace"
)

assert "defaultdomain" in engine.get_direct_download_url(
_TEST_PATH, test_aws_ip, namespace="defaultnamespace"
)

# Request a direct download URL for a request from a known AWS IP and in the same region, returned S3 URL.
assert "s3.amazonaws.com" in engine.get_direct_download_url(
_TEST_PATH, "4.0.0.2", namespace="testnamespace"
)

if ipranges_populated:
# Request a direct download URL for a request from a non-AWS IP, and ensure we are returned a CloudFront URL.
assert "overridedomain" in engine.get_direct_download_url(
_TEST_PATH, "1.2.3.4", namespace="testnamespace"
)
else:
# Request a direct download URL for a request from a non-AWS IP, but since IP Ranges isn't populated, we still
# get back an S3 URL.
assert "s3.amazonaws.com" in engine.get_direct_download_url(
_TEST_PATH, "1.2.3.4", namespace="testnamespace"
)


@mock_s3
def test_direct_download_no_ip(test_aws_ip, aws_ip_range_data, ipranges_populated, app):
Expand All @@ -110,6 +153,7 @@ def test_direct_download_no_ip(test_aws_ip, aws_ip_range_data, ipranges_populate
engine = CloudFrontedS3Storage(
context,
"cloudfrontdomain",
{},
"keyid",
"test/data/test.pem",
"some/path",
Expand All @@ -134,6 +178,7 @@ def test_direct_download_with_username(test_aws_ip, aws_ip_range_data, ipranges_
engine = CloudFrontedS3Storage(
context,
"cloudfrontdomain",
{},
"keyid",
"test/data/test.pem",
"some/path",
Expand Down

0 comments on commit dcf5a37

Please sign in to comment.