Skip to content

Commit 98f94c3

Browse files
gerrod3mdellweg
authored andcommitted
Add support for rename of S3 storage backend
fixes: #7228 (cherry picked from commit 0d632d4)
1 parent 0143abf commit 98f94c3

File tree

10 files changed

+44
-14
lines changed

10 files changed

+44
-14
lines changed

CHANGES/7228.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed not supporting the new rename of the S3 storage backend.

docs/admin/guides/configure-pulp/configure-storages.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ When creating a `Domain` you can use the following payload:
103103
```json
104104
{
105105
"name": "cloudfront_storage",
106-
"storage_class": "storages.backends.s3boto3.S3Boto3Storage",
106+
"storage_class": "storages.backends.s3.S3Storage",
107107
"storage_settings": {
108108
"access_key": "{aws_access_key}",
109109
"secret_key": "{aws_secret_key}",
@@ -124,14 +124,14 @@ When creating a `Domain` you can use the following payload:
124124
# We need to format our key to a JSON friendly format
125125
export CLOUDFRONT_KEY=$(cat keyfile.pem | jq -sR .)
126126

127-
curl -X POST $BASE_HREF/pulp/default/api/v3/domains/ -d '{"name": "cloudfront_storage", "storage_class": "storages.backends.s3boto3.S3Boto3Storage", "storage_settings": {"access_key": "{aws_access_key}", "secret_key": "{aws_secret_key}", "bucket_name": "{aws_bucket_name}", "region_name": "{aws_region_name}", "default_acl": "private", "cloudfront_key_id": "{aws_cloudfront_key_id}", "cloudfront_key": '"$CLOUDFRONT_KEY"', "custom_domain": "{aws_cloudfront_custom_domain}"}, "redirect_to_object_storage": true, "hide_guarded_distributions": false}' -H 'Content-Type: application/json'
127+
curl -X POST $BASE_HREF/pulp/default/api/v3/domains/ -d '{"name": "cloudfront_storage", "storage_class": "storages.backends.s3.S3Storage", "storage_settings": {"access_key": "{aws_access_key}", "secret_key": "{aws_secret_key}", "bucket_name": "{aws_bucket_name}", "region_name": "{aws_region_name}", "default_acl": "private", "cloudfront_key_id": "{aws_cloudfront_key_id}", "cloudfront_key": '"$CLOUDFRONT_KEY"', "custom_domain": "{aws_cloudfront_custom_domain}"}, "redirect_to_object_storage": true, "hide_guarded_distributions": false}' -H 'Content-Type: application/json'
128128
```
129129

130130
=== Create a new Domain using pulp-cli
131131
```bash
132132
export CLOUDFRONT_KEY=$(cat keyfile.pem | jq -sR .)
133133

134-
pulp domain create --name cloudfront_test --storage-class storages.backends.s3boto3.S3Boto3Storage --storage-settings '{"access_key": "{aws_access_key}", "secret_key": "{aws_secret_key}", "bucket_name": "{aws_bucket_name}", "region_name": "{aws_region_name}", "default_acl": "private", "cloudfront_key_id": "{aws_cloudfront_key_id}", "cloudfront_key": '"$CLOUDFRONT_KEY"', "custom_domain": "{aws_cloudfront_custom_domain}"}'
134+
pulp domain create --name cloudfront_test --storage-class storages.backends.s3.S3Storage --storage-settings '{"access_key": "{aws_access_key}", "secret_key": "{aws_secret_key}", "bucket_name": "{aws_bucket_name}", "region_name": "{aws_region_name}", "default_acl": "private", "cloudfront_key_id": "{aws_cloudfront_key_id}", "cloudfront_key": '"$CLOUDFRONT_KEY"', "custom_domain": "{aws_cloudfront_custom_domain}"}'
135135
```
136136

137137
Create your remotes, repositories, and distributions under this domain and the requests will be redirected to the

pulpcore/app/serializers/domain.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
BACKEND_CHOICES = (
2323
("pulpcore.app.models.storage.FileSystem", "Use local filesystem as storage"),
2424
# ("pulpcore.app.models.storage.PulpSFTPStorage", "Use SFTP server as storage"),
25-
("storages.backends.s3boto3.S3Boto3Storage", "Use Amazon S3 as storage"),
25+
("storages.backends.s3boto3.S3Boto3Storage", "Use Amazon S3 as storage [deprecated]"),
26+
("storages.backends.s3.S3Storage", "Use Amazon S3 as storage"),
2627
("storages.backends.azure_storage.AzureStorage", "Use Azure Blob as storage"),
2728
# ("storages.backends.gcloud.GoogleCloudStorage", "Use Google Cloud as storage"),
2829
)
@@ -159,7 +160,7 @@ def create(self, validated_data):
159160
class AmazonS3SettingsSerializer(BaseSettingsClass):
160161
"""A Serializer for Amazon S3 storage settings."""
161162

162-
STORAGE_CLASS = "storages.backends.s3boto3.S3Boto3Storage"
163+
STORAGE_CLASS = "storages.backends.s3.S3Storage"
163164
SETTING_MAPPING = {
164165
"aws_s3_access_key_id": "access_key",
165166
"aws_access_key_id": "access_key",

pulpcore/app/util.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,10 @@ def get_artifact_url(artifact, headers=None, http_method=None):
516516
or not artifact_domain.redirect_to_object_storage
517517
):
518518
return _artifact_serving_distribution().artifact_url(artifact)
519-
elif artifact_domain.storage_class == "storages.backends.s3boto3.S3Boto3Storage":
519+
elif artifact_domain.storage_class in (
520+
"storages.backends.s3boto3.S3Boto3Storage",
521+
"storages.backends.s3.S3Storage",
522+
):
520523
parameters = {"ResponseContentDisposition": content_disposition}
521524
if headers and headers.get("Content-Type"):
522525
parameters["ResponseContentType"] = headers.get("Content-Type")

pulpcore/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
# Storage-type mapped to storage-response-map
109109
STORAGE_RESPONSE_MAP = {
110110
"storages.backends.s3boto3.S3Boto3Storage": S3_RESPONSE_HEADER_MAP,
111+
"storages.backends.s3.S3Storage": S3_RESPONSE_HEADER_MAP,
111112
"storages.backends.azure_storage.AzureStorage": AZURE_RESPONSE_HEADER_MAP,
112113
"storages.backends.gcloud.GoogleCloudStorage": GCS_RESPONSE_HEADER_MAP,
113114
}

pulpcore/content/handler.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,10 @@ def _build_url(**kwargs):
10211021
return FileResponse(path, headers=headers)
10221022
elif not domain.redirect_to_object_storage:
10231023
return ArtifactResponse(content_artifact.artifact, headers=headers)
1024-
elif domain.storage_class == "storages.backends.s3boto3.S3Boto3Storage":
1024+
elif domain.storage_class in (
1025+
"storages.backends.s3boto3.S3Boto3Storage",
1026+
"storages.backends.s3.S3Storage",
1027+
):
10251028
raise HTTPFound(_build_url(http_method=request.method), headers=headers)
10261029
elif domain.storage_class in (
10271030
"storages.backends.azure_storage.AzureStorage",

pulpcore/pytest_plugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ def _settings_factory(storage_class=None, storage_settings=None):
597597
pytest.skip("Domains not enabled")
598598
keys = dict()
599599
keys["pulpcore.app.models.storage.FileSystem"] = ["MEDIA_ROOT", "MEDIA_URL"]
600-
keys["storages.backends.s3boto3.S3Boto3Storage"] = [
600+
keys["storages.backends.s3.S3Storage"] = [
601601
"access_key",
602602
"secret_key",
603603
"endpoint_url",
@@ -606,6 +606,7 @@ def _settings_factory(storage_class=None, storage_settings=None):
606606
"region_name",
607607
"bucket_name",
608608
]
609+
keys["storages.backends.s3boto3.S3Boto3Storage"] = keys["storages.backends.s3.S3Storage"]
609610
keys["storages.backends.azure_storage.AzureStorage"] = [
610611
"AZURE_ACCOUNT_NAME",
611612
"AZURE_CONTAINER",

pulpcore/tests/functional/api/test_artifact_distribution.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
OBJECT_STORAGES = (
77
"storages.backends.s3boto3.S3Boto3Storage",
8+
"storages.backends.s3.S3Storage",
89
"storages.backends.azure_storage.AzureStorage",
910
"storages.backends.gcloud.GoogleCloudStorage",
1011
)

pulpcore/tests/functional/api/test_crud_domains.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def test_special_domain_creation(pulpcore_bindings, gen_object_with_cleanup, pul
190190
"pulpcore.app.models.storage.FileSystem",
191191
# "pulpcore.app.models.storage.PulpSFTPStorage",
192192
"storages.backends.s3boto3.S3Boto3Storage",
193+
"storages.backends.s3.S3Storage",
193194
"storages.backends.azure_storage.AzureStorage",
194195
# "storages.backends.gcloud.GoogleCloudStorage",
195196
}
@@ -204,7 +205,7 @@ def test_special_domain_creation(pulpcore_bindings, gen_object_with_cleanup, pul
204205
"key_filename": "/etc/pulp/certs/storage_id_ed25519",
205206
},
206207
},
207-
"storages.backends.s3boto3.S3Boto3Storage": {
208+
"storages.backends.s3.S3Storage": {
208209
"AWS_ACCESS_KEY_ID": "random",
209210
"AWS_SECRET_ACCESS_KEY": "random",
210211
"AWS_STORAGE_BUCKET_NAME": "pulp3",
@@ -227,6 +228,9 @@ def test_special_domain_creation(pulpcore_bindings, gen_object_with_cleanup, pul
227228
"GS_CUSTOM_ENDPOINT": "http://custom-endpoint",
228229
},
229230
}
231+
storage_settings["storages.backends.s3boto3.S3Boto3Storage"] = storage_settings[
232+
"storages.backends.s3.S3Storage"
233+
]
230234

231235
installed_backends = []
232236
domain_names = set()
@@ -244,7 +248,8 @@ def test_special_domain_creation(pulpcore_bindings, gen_object_with_cleanup, pul
244248
assert e.status == 400
245249
assert "Backend is not installed on Pulp." in e.body
246250
else:
247-
installed_backends.append(backend)
251+
if backend != "storages.backends.s3boto3.S3Boto3Storage":
252+
installed_backends.append(backend)
248253
domain_names.add(domain.name)
249254
# Try creating domains with correct settings
250255
for backend in installed_backends:
@@ -257,6 +262,7 @@ def test_special_domain_creation(pulpcore_bindings, gen_object_with_cleanup, pul
257262
domain_names.add(domain.name)
258263

259264
# Try creating domains with incorrect settings
265+
storage_types.remove("storages.backends.s3boto3.S3Boto3Storage")
260266
for backend in installed_backends:
261267
random_backend = random.choice(tuple(storage_types - {backend}))
262268
body = {

pulpcore/tests/unit/serializers/test_domain.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def _no_validate_storage_backend(monkeypatch):
3030
params=[
3131
"pulpcore.app.models.storage.FileSystem",
3232
"storages.backends.s3boto3.S3Boto3Storage",
33+
"storages.backends.s3.S3Storage",
3334
"storages.backends.azure_storage.AzureStorage",
3435
]
3536
)
@@ -41,7 +42,10 @@ def storage_class(request):
4142
def serializer_class(storage_class):
4243
if storage_class == "pulpcore.app.models.storage.FileSystem":
4344
return FileSystemSettingsSerializer
44-
elif storage_class == "storages.backends.s3boto3.S3Boto3Storage":
45+
elif storage_class in (
46+
"storages.backends.s3boto3.S3Boto3Storage",
47+
"storages.backends.s3.S3Storage",
48+
):
4549
return AmazonS3SettingsSerializer
4650
elif storage_class == "storages.backends.azure_storage.AzureStorage":
4751
return AzureSettingsSerializer
@@ -51,7 +55,10 @@ def serializer_class(storage_class):
5155
def required_settings(storage_class):
5256
if storage_class == "pulpcore.app.models.storage.FileSystem":
5357
return {"location": "/var/lib/pulp/media/"}
54-
elif storage_class == "storages.backends.s3boto3.S3Boto3Storage":
58+
elif storage_class in (
59+
"storages.backends.s3boto3.S3Boto3Storage",
60+
"storages.backends.s3.S3Storage",
61+
):
5562
return {"access_key": "testing", "bucket_name": "test"}
5663
elif storage_class == "storages.backends.azure_storage.AzureStorage":
5764
return {"account_name": "test", "account_key": "secret", "azure_container": "test"}
@@ -60,7 +67,10 @@ def required_settings(storage_class):
6067
@pytest.fixture
6168
def extra_required_settings(storage_class):
6269
"""For fields required in the serializer's validate, but not on the field itself."""
63-
if storage_class == "storages.backends.s3boto3.S3Boto3Storage":
70+
if storage_class in (
71+
"storages.backends.s3boto3.S3Boto3Storage",
72+
"storages.backends.s3.S3Storage",
73+
):
6474
return {"secret_key": "secret"}
6575
return {}
6676

@@ -129,7 +139,10 @@ def test_using_setting_names(storage_class, serializer_class, all_settings):
129139

130140
@pytest.mark.django_db
131141
def test_cloudfront_s3_storage_settings(storage_class, required_settings):
132-
if storage_class != "storages.backends.s3boto3.S3Boto3Storage":
142+
if storage_class not in (
143+
"storages.backends.s3boto3.S3Boto3Storage",
144+
"storages.backends.s3.S3Storage",
145+
):
133146
pytest.skip("This test only make sense when using S3 as storage backend.")
134147

135148
domain = SimpleNamespace(storage_class=storage_class, **MIN_DOMAIN_SETTINGS)

0 commit comments

Comments
 (0)