Skip to content

Commit

Permalink
add namespace filter to direct download responses
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcusk19 committed Oct 25, 2024
1 parent 9f72e2e commit 2f1b938
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 5 deletions.
4 changes: 4 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,3 +901,7 @@ def create_transaction(db):
# Disable pushes while allowing other registry operations.
# Defaults to "False".
DISABLE_PUSHES = False

# Specific namespaces that be exceptions to the s3-cloudflare optimization
# used for registry-proxy namespaces
CDN_SPECIFIC_NAMESPACES: Optional[List[str]] = []
8 changes: 8 additions & 0 deletions endpoints/v2/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def download_blob(namespace_name, repo_name, digest, registry_model):
username=username,
namespace=namespace_name,
repo_name=repo_name,
cdn_specific=_is_cdn_specific(namespace_name),
)
if direct_download_url:
logger.debug("Returning direct download URL")
Expand All @@ -151,6 +152,13 @@ def download_blob(namespace_name, repo_name, digest, registry_model):
)


def _is_cdn_specific(namespace):
# Checks if blob belongs to namespace that should have cdn url returned
logger.debug("Checking for namespace %s", namespace)
namespaces = app.config.get("CDN_SPECIFIC_NAMESPACES")
return namespace in namespaces


def _try_to_mount_blob(repository_ref, mount_blob_digest):
"""
Attempts to mount a blob requested by the user from another repository.
Expand Down
11 changes: 7 additions & 4 deletions storage/cloudflarestorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ def get_direct_download_url(
if self.cloudflare_privatekey is None or request_ip is None:
return s3_presigned_url

logger.debug('Got direct download request for path "%s" with IP "%s"', path, request_ip)

if is_in_network_request(self._context, request_ip, self.region):
logger.debug("Request is from within the network, returning S3 URL")
return s3_presigned_url
if kwargs.get("cdn_specific", False):
logger.debug(
"Request came from within network but namespace is protected: %s", path
)
else:
logger.debug("Request is from within the network, returning S3 URL")
return s3_presigned_url

s3_url_parsed = urllib.parse.urlparse(s3_presigned_url)

Expand Down
26 changes: 25 additions & 1 deletion storage/test/test_cloudfront.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from moto import mock_s3

from app import config_provider
from storage import CloudFrontedS3Storage, StorageContext
from storage import CloudFlareS3Storage, CloudFrontedS3Storage, StorageContext
from test.fixtures import *
from util.ipresolver import IPResolver
from util.ipresolver.test.test_ipresolver import (
Expand Down Expand Up @@ -222,3 +222,27 @@ def test_direct_download_with_repo_name(test_aws_ip, aws_ip_range_data, ipranges
assert engine.exists(_TEST_PATH)
url = engine.get_direct_download_url(_TEST_PATH, request_ip="1.2.3.4", repo_name=_TEST_REPO)
assert f"repo_name={_TEST_REPO}" in url


@mock_s3
def test_direct_download_cdn_specific(test_aws_ip, aws_ip_range_data, ipranges_populated, app):
ipresolver = IPResolver(app)
context = StorageContext("nyc", None, config_provider, ipresolver)

# Create a test bucket and put some test content.
boto3.client("s3").create_bucket(Bucket=_TEST_BUCKET)

engine = CloudFlareS3Storage(
context,
"cloudflare-domain",
"test/data/test.pem",
"some/path",
_TEST_BUCKET,
_TEST_REGION,
None,
)

engine.put_content(_TEST_PATH, _TEST_CONTENT)
assert engine.exists(_TEST_PATH)
url = engine.get_direct_download_url(_TEST_PATH, request_ip="4.0.0.2", cdn_specific=True)
assert "cloudflare-domain" in url
2 changes: 2 additions & 0 deletions test/testconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ def create_transaction(db):
AUTOPRUNE_FETCH_TAGS_PAGE_LIMIT = 2
AUTOPRUNE_FETCH_REPOSITORIES_PAGE_LIMIT = 2
FEATURE_IMAGE_EXPIRY_TRIGGER = True

CDN_SPECIFIC_NAMESPACES = ["redhat"]
1 change: 1 addition & 0 deletions util/config/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"RESET_CHILD_MANIFEST_EXPIRATION",
"PERMANENTLY_DELETE_TAGS",
"FEATURE_RH_MARKETPLACE",
"CDN_SPECIFIC_NAMESPACES",
}

CONFIG_SCHEMA = {
Expand Down

0 comments on commit 2f1b938

Please sign in to comment.