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

add bucket name delimiter #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
5.0.9 (unreleased)
5.0.9
------------------

- Nothing changed yet.
- Allow bucket name delimiter config


5.0.8 (2021-05-06)
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Example config.json:
"aws_client_id": "<client id>",
"aws_client_secret": "<client secret>",
"bucket": "<bucket name suffix>",
"bucket_name_format": "{container}{delimiter}{base}",
"endpoint_url": null,
"ssl": true,
"verify_ssl": null,
Expand Down
9 changes: 3 additions & 6 deletions guillotina_s3storage/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@


class IS3FileField(IFileField):
"""Field marked as S3FileField
"""
"""Field marked as S3FileField"""


# Configuration Utility


class IS3BlobStore(Interface):
"""Configuration utility.
"""
"""Configuration utility."""


class IS3File(IFile):
"""Marker for a S3File
"""
"""Marker for a S3File"""
20 changes: 17 additions & 3 deletions guillotina_s3storage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import logging
from typing import AsyncIterator

import aiobotocore
import aiohttp
import backoff
import botocore
from guillotina import configure
from guillotina import task_vars
from guillotina.component import get_utility
Expand All @@ -19,8 +21,6 @@
from guillotina.schema import Object
from zope.interface import implementer

import aiobotocore
import botocore
from guillotina_s3storage.interfaces import IS3BlobStore
from guillotina_s3storage.interfaces import IS3File
from guillotina_s3storage.interfaces import IS3FileField
Expand Down Expand Up @@ -315,9 +315,23 @@ def __init__(self, settings, loop=None):

self._bucket_name = settings["bucket"]

self._bucket_name_format = settings.get(
"bucket_name_format", "{container}{delimiter}{base}"
)

async def get_bucket_name(self):
container = task_vars.container.get()
bucket_name = container.id.lower() + "." + self._bucket_name

if "." in self._bucket_name:
char_delimiter = "."
else:
char_delimiter = "-"

bucket_name = self._bucket_name_format.format(
container=container.id.lower(),
delimiter=char_delimiter,
base=self._bucket_name,
)

bucket_name = bucket_name.replace("_", "-")

Expand Down
1 change: 1 addition & 0 deletions guillotina_s3storage/tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def settings_configurator(settings):
"factory": "guillotina_s3storage.storage.S3BlobStore",
"settings": {
"bucket": os.environ.get("S3CLOUD_BUCKET", "testbucket"),
"bucket_name_format": "{container}{delimiter}{base}",
"aws_client_id": os.environ.get("S3CLOUD_ID", "x" * 10),
"aws_client_secret": os.environ.get("S3CLOUD_SECRET", "x" * 10), # noqa
},
Expand Down
19 changes: 18 additions & 1 deletion guillotina_s3storage/tests/test_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from hashlib import md5

import backoff
import botocore.exceptions
import pytest
from guillotina import task_vars
from guillotina.component import get_utility
Expand All @@ -16,7 +17,6 @@
from guillotina.tests.utils import login
from zope.interface import Interface

import botocore.exceptions
from guillotina_s3storage.interfaces import IS3BlobStore
from guillotina_s3storage.storage import CHUNK_SIZE
from guillotina_s3storage.storage import RETRIABLE_EXCEPTIONS
Expand Down Expand Up @@ -775,3 +775,20 @@ async def test_read_range(own_dummy_request, mock_txn):
async for chunk in s3mng.read_range(100, 200):
assert len(chunk) == 100
assert chunk == _test_gif[100:200]


async def test_custom_bucket_name(dummy_request):
util = get_utility(IS3BlobStore)
request = dummy_request # noqa
login()
container = create_content(Container, id="test-container")
task_vars.container.set(container)

# No dots in the name, delimiter is -
bucket_name = await util.get_bucket_name()
assert bucket_name.startswith("test-container-testbucket")

# Dots in the name, delimiter is .
util._bucket_name = "testbucket.com"
bucket_name = await util.get_bucket_name()
assert bucket_name.startswith("test-container.testbucket.com")