From b9382d9546e4c020d82e8eba5f50be2d9fe99aed Mon Sep 17 00:00:00 2001 From: Tim Diggins Date: Wed, 29 Nov 2023 18:16:26 +0000 Subject: [PATCH] allow s3_object put to specify metadata again (#1882) allow s3_object put to specify metadata again fix erroneous change to meaning fixes #1881 optional extra refactorings as separate commits (happy to drop these if unwanted) Reviewed-by: Mark Chappell (cherry picked from commit 3333b658c0040b2f7f07f30f11a9241a4042c1a7) --- ...ct-to-specify-content-type-in-metadata.yml | 3 ++ plugins/modules/s3_object.py | 20 ++++++------- .../targets/s3_object/tasks/main.yml | 28 +++++++++++++++++++ 3 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml diff --git a/changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml b/changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml new file mode 100644 index 00000000000..6051a344d5e --- /dev/null +++ b/changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml @@ -0,0 +1,3 @@ +bugfixes: + - s3_object - when doing a put and specifying ``Content-Type`` in metadata, this module (since 6.0.0) erroneously set the ``Content-Type`` to ``None`` causing the put to fail. + Fix now correctly honours the specified ``Content-Type`` (https://github.com/ansible-collections/amazon.aws/issues/1881). diff --git a/plugins/modules/s3_object.py b/plugins/modules/s3_object.py index 73eae84df84..e22aa2578a8 100644 --- a/plugins/modules/s3_object.py +++ b/plugins/modules/s3_object.py @@ -639,15 +639,14 @@ def path_check(path): return False -def get_content_type(src, present=True): - if not present: - content_type = None - if src: - content_type = mimetypes.guess_type(src)[0] - if content_type is None: - # s3 default content type - content_type = "binary/octet-stream" - return content_type +def guess_content_type(src): + if src: + content_type = mimetypes.guess_type(src)[0] + if content_type: + return content_type + + # S3 default content type + return "binary/octet-stream" def get_extra_params( @@ -732,7 +731,8 @@ def upload_s3file( elif isinstance(permissions, list): extra["ACL"] = permissions[0] - extra["ContentType"] = get_content_type(src, present=extra.get("ContentType")) + if "ContentType" not in extra: + extra["ContentType"] = guess_content_type(src) if src: s3.upload_file(aws_retry=True, Filename=src, Bucket=bucket, Key=obj, ExtraArgs=extra) diff --git a/tests/integration/targets/s3_object/tasks/main.yml b/tests/integration/targets/s3_object/tasks/main.yml index d00bd196d0a..21a20a4c1af 100644 --- a/tests/integration/targets/s3_object/tasks/main.yml +++ b/tests/integration/targets/s3_object/tasks/main.yml @@ -458,6 +458,34 @@ - "'Object deleted from bucket' in result.msg" - result is changed + - name: test putting an object in the bucket with metadata set + s3_object: + bucket: "{{ bucket_name }}" + mode: put + src: "{{ remote_tmp_dir }}/upload.txt" + metadata: "Content-Type=text/plain" + object: delete_meta.txt + tags: + "lowercase spaced": "hello cruel world" + "Title Case": "Hello Cruel World" + retries: 3 + delay: 3 + register: result + + - assert: + that: + - result is changed + - result.msg == "PUT operation complete" + + - name: test delobj to just delete an object in the bucket + s3_object: + bucket: "{{ bucket_name }}" + mode: delobj + object: delete_meta.txt + retries: 3 + delay: 3 + register: result + - name: test putting an encrypted object in the bucket s3_object: bucket: "{{ bucket_name }}"