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 a content parameter to aws_s3 put operation #20

Merged
merged 35 commits into from
Nov 16, 2020
Merged

Add a content parameter to aws_s3 put operation #20

merged 35 commits into from
Nov 16, 2020

Conversation

onitake
Copy link
Contributor

@onitake onitake commented Mar 30, 2020

SUMMARY

This is a port of the original pull request at ansible/ansible#67091 to collections. There might still be compatibility issues due to renamed packages.

Add support for uploading S3 objects from in-memory content in addition to on-disk files.

Fixes ansible/ansible#67086

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME

aws_s3

ADDITIONAL INFORMATION

Example usage:

- name: PUT operation from a rendered template
  aws_s3:
    bucket: mybucket
    object: /object.yaml
    content: "{{ lookup('template', 'templates/object.yaml.j2') }}"
    mode: put

@onitake onitake changed the title S3 put content v2 Add a content parameter to aws_s3 put operation Mar 30, 2020
@onitake
Copy link
Contributor Author

onitake commented Mar 31, 2020

Comment from original PR:

Hmm... Looks like strings aren't autocast into byte strings.
If possible, I'd like to keep the possibility to pass a binary data into the content parameter. Is this possible at all? Should I change the content parameter type to string?

@onitake
Copy link
Contributor Author

onitake commented Mar 31, 2020

Another comment:

So, I added a unit test for the content parameter and it looks like the feature's working as expected. Shippable had a timeout in a completely unrelated test, perhaps a retry is in order.

I changed the content parameter type to string, as I don't see a way to pass byte strings into Ansible modules. If there's a way to do this, please tell me. The string is converted to UTF-8 before sending it to S3.

What the unit tests don't cover yet is a multi-part put. This is probably crucial, as the the new calculate_etag_content utility function will not have full test coverage otherwise. I'll try to address this.

Copy link
Contributor

@tremble tremble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for migrating this over. I've not tested this locally, but some some minor comments

plugins/modules/aws_s3.py Outdated Show resolved Hide resolved
plugins/modules/aws_s3.py Outdated Show resolved Hide resolved
plugins/modules/aws_s3.py Outdated Show resolved Hide resolved
@onitake
Copy link
Contributor Author

onitake commented May 8, 2020

I also noticed that there a ton of % formats in the module.
Since Python 2 is now EOL, wouldn't it also be good to change them into f-strings or at least str.format()?

@onitake
Copy link
Contributor Author

onitake commented May 8, 2020

I addressed your comments and also fixed a bug with etag calculation that popped up thanks to the idempotency test.

My other two comments regarding dest checking and refactoring % into format() have nothing to do with this PR, so please disregard them.

@tremble
Copy link
Contributor

tremble commented May 8, 2020

Short verison on % : Yes we probably should (although I don't always remember)

The only trouble with testing that dest exists is that you need to check that the parent folder exists since you may be creating the target. (but it would be worth tweaking that to type=path too)

- This parameter will be treated as a string and converted to UTF-8 before sending it to S3.
To send binary data, use the I(src) parameter instead.
- Either I(content) or I(src) must be specified for a PUT operation. Ignored otherwise.
version_added: "2.10"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jillr What are we supposed to be using for 'version_added' at the minute?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tremble the collection version the patch will land in, using semver. We should be targeting version_added: 1.1.0 right now.

@jillr jillr changed the base branch from master to main July 2, 2020 19:22
@jillr
Copy link
Collaborator

jillr commented Jul 6, 2020

Regarding python2, Ansible will support 2.7 as long as we have supported platforms that ship with 2.7 (like RHEL). So it would be good to update these but it's not urgent.

@jillr
Copy link
Collaborator

jillr commented Jul 9, 2020

@onitake following up on your question:

If possible, I'd like to keep the possibility to pass a binary data into the content parameter. Is this possible at all? Should I change the content parameter type to string?

Unfortunately there's not any good ways to take multiple types of content in the same parameter. The best way to handle this would be to have a content parameter that is for str data, and another option such as base64_content for bytes data.

@abadger
Copy link

abadger commented Jul 9, 2020

And the base64_content parameter would take a base64 encoded byte string (not a raw byte string). There's no way in ansible to pass a raw byte string through all the layers.

@onitake
Copy link
Contributor Author

onitake commented Jul 10, 2020

Thanks for the suggestions, I will add such a parameter.

@onitake
Copy link
Contributor Author

onitake commented Jul 10, 2020

I implemented the mentioned content_base64 parameter, but now we we have a bit of asymmetry:
There is no getbin mode to obtain binary object contents without writing to disk.
I think this is an acceptable tradeoff, but if you want it added as well, I'd rather submit a separate PR for that feature.

@ansibullbot
Copy link

@ansibullbot ansibullbot added affects_2.10 community_review feature This issue/PR relates to a feature request integration tests/integration module module module_utils module_utils new_contributor Help guide this first time contributor stale_ci CI is older than 7 days, rerun before merging tests tests labels Aug 18, 2020
@ansibullbot ansibullbot added the plugins plugin (any type) label Aug 27, 2020
plugins/modules/aws_s3.py Outdated Show resolved Hide resolved
plugins/modules/aws_s3.py Outdated Show resolved Hide resolved
@tremble tremble merged commit 615577b into ansible-collections:main Nov 16, 2020
@tremble
Copy link
Contributor

tremble commented Nov 16, 2020

Many thanks for your efforts on this. I'm sorry it's taken so long.

Given how long you've been waiting on us for this I've added a changelog fragment and tweaked the 'added_in' value.

@onitake
Copy link
Contributor Author

onitake commented Nov 16, 2020

Thanks for taking time to review this & merging it!

@onitake onitake deleted the s3-put-content-v2 branch November 16, 2020 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects_2.10 community_review feature This issue/PR relates to a feature request integration tests/integration module_utils module_utils module module new_contributor Help guide this first time contributor plugins plugin (any type) stale_ci CI is older than 7 days, rerun before merging tests tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aws_s3 should support putting content without filesystem access
6 participants