-
Notifications
You must be signed in to change notification settings - Fork 330
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Allow s3 to use subfolders as the root folder of a files addon * use colon delineation for s3 buckets, remove bucket_name query_param * fix issue with over mocking Gitlab messing with serializer method * revert serializer for correct id * de-ordinaryize the s3 calling format this allows non us-east-1 regions to work for s3 * add migration for s3 folder_ids and names * change migration to management command * fix tests for management command * flake8 fixes * reintroduce OrdinaryCallingFormat and remove from get_bucket * make migration allow for already converted folder_ids and folder_names * make get bucket names use the correct calling format * clean-up and revert old changes * use boto3 to access bucket regions using V4 s3 auth * move add delim command to management command dir for s3 improvment --------- Co-authored-by: John Tordoff <> Co-authored-by: John Tordoff <[email protected]>
- Loading branch information
Showing
10 changed files
with
222 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
boto==2.38.0 | ||
boto3==1.4.7 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# -*- coding: utf-8 -*- | ||
import logging | ||
|
||
from django.core.management.base import BaseCommand | ||
from django.apps import apps | ||
from django.db.models import F, Value | ||
from django.db.models.functions import Concat, Replace | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Adds Colon (':') delineators to s3 buckets to separate them from them from their subfolder, so `<bucket_name>` | ||
becomes `<bucket_name>:/` , the root path. Folder names will also be updated to maintain consistency. | ||
""" | ||
|
||
def add_arguments(self, parser): | ||
super().add_arguments(parser) | ||
parser.add_argument( | ||
'--reverse', | ||
action='store_true', | ||
dest='reverse', | ||
help='Unsets date_retraction' | ||
) | ||
|
||
def handle(self, *args, **options): | ||
reverse = options.get('reverse', False) | ||
if reverse: | ||
reverse_update_folder_names() | ||
else: | ||
update_folder_names() | ||
|
||
|
||
def update_folder_names(): | ||
NodeSettings = apps.get_model('addons_s3', 'NodeSettings') | ||
|
||
# Update folder_id for all records | ||
NodeSettings.objects.exclude( | ||
folder_name__contains=':/' | ||
).update( | ||
folder_id=Concat(F('folder_id'), Value(':/')) | ||
) | ||
|
||
# Update folder_name for records containing '(' | ||
NodeSettings.objects.filter( | ||
folder_name__contains=' (' | ||
).exclude( | ||
folder_name__contains=':/' | ||
).update( | ||
folder_name=Replace(F('folder_name'), Value(' ('), Value(':/ (')) | ||
) | ||
NodeSettings.objects.exclude( | ||
folder_name__contains=':/' | ||
).exclude( | ||
folder_name__contains=' (' | ||
).update( | ||
folder_name=Concat(F('folder_name'), Value(':/')) | ||
) | ||
logger.info('Update Folder Names/IDs complete') | ||
|
||
|
||
def reverse_update_folder_names(): | ||
NodeSettings = apps.get_model('addons_s3', 'NodeSettings') | ||
|
||
# Reverse update folder_id for all records | ||
NodeSettings.objects.update(folder_id=Replace(F('folder_id'), Value(':/'), Value(''))) | ||
|
||
# Reverse update folder_name for records containing ':/ (' | ||
NodeSettings.objects.filter(folder_name__contains=':/ (').update( | ||
folder_name=Replace(F('folder_name'), Value(':/ ('), Value(' (')) | ||
) | ||
NodeSettings.objects.filter(folder_name__contains=':/').update( | ||
folder_name=Replace(F('folder_name'), Value(':/'), Value('')) | ||
) | ||
logger.info('Reverse Update Folder Names/IDs complete') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import pytest | ||
from osf.management.commands.add_colon_delim_to_s3_buckets import update_folder_names, reverse_update_folder_names | ||
|
||
@pytest.mark.django_db | ||
class TestUpdateFolderNamesMigration: | ||
|
||
def test_update_folder_names_migration(self): | ||
from addons.s3.models import NodeSettings | ||
from addons.s3.tests.factories import S3NodeSettingsFactory | ||
# Create sample folder names and IDs | ||
S3NodeSettingsFactory(folder_name='Folder 1 (Location 1)', folder_id='folder1') | ||
S3NodeSettingsFactory(folder_name='Folder 2', folder_id='folder2') | ||
S3NodeSettingsFactory(folder_name='Folder 3 (Location 3)', folder_id='folder3') | ||
S3NodeSettingsFactory(folder_name='Folder 4:/ (Location 4)', folder_id='folder4:/') | ||
|
||
update_folder_names() | ||
|
||
# Verify updated folder names and IDs | ||
updated_folder_names_ids = NodeSettings.objects.values_list('folder_name', 'folder_id') | ||
expected_updated_folder_names_ids = { | ||
('Folder 1:/ (Location 1)', 'folder1:/'), | ||
('Folder 2:/', 'folder2:/'), | ||
('Folder 3:/ (Location 3)', 'folder3:/'), | ||
('Folder 3:/ (Location 3)', 'folder3:/'), | ||
('Folder 4:/ (Location 4)', 'folder4:/'), | ||
|
||
} | ||
assert set(updated_folder_names_ids) == expected_updated_folder_names_ids | ||
|
||
# Reverse the migration | ||
reverse_update_folder_names() | ||
|
||
# Verify the folder names and IDs after the reverse migration | ||
reverted_folder_names_ids = NodeSettings.objects.values_list('folder_name', 'folder_id') | ||
expected_reverted_folder_names_ids = { | ||
('Folder 1 (Location 1)', 'folder1'), | ||
('Folder 2', 'folder2'), | ||
('Folder 3 (Location 3)', 'folder3'), | ||
('Folder 4 (Location 4)', 'folder4'), | ||
} | ||
assert set(reverted_folder_names_ids) == expected_reverted_folder_names_ids |