Skip to content

Commit

Permalink
s3_object_info - add support for prefix when listing objects
Browse files Browse the repository at this point in the history
  • Loading branch information
abikouo committed Jan 23, 2025
1 parent a894ae8 commit 334b49e
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- s3_object_info - add support to list objects under a specific prefix (https://github.com/ansible-collections/amazon.aws/issues/2477).
15 changes: 15 additions & 0 deletions plugins/modules/s3_object_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
description:
- The name of the object.
- If not specified, a list of all objects in the specified bucket will be returned.
- Mutually exclusive with O(prefix).
required: false
type: str
endpoint_url:
Expand Down Expand Up @@ -108,6 +109,12 @@
- Max number of results to return. Set this if you want to retrieve only partial results.
type: int
version_added: 9.0.0
prefix:
description:
- Limits the response to keys that begin with the specified prefix.
- Mutually exclusive with O(object_name).
type: str
version_added: 9.2.0
notes:
- Support for the E(S3_URL) environment variable has been
deprecated and will be removed in a release after 2024-12-01, please use the O(endpoint_url) parameter
Expand Down Expand Up @@ -159,6 +166,11 @@
attributes_list:
- ETag
- ObjectSize
- name: Retrieve keys that begin with the prefix /my/desired/
amazon.aws.s3_object_info:
bucket: mybucket
prefix: /my/desired/
"""

RETURN = r"""
Expand Down Expand Up @@ -641,6 +653,7 @@ def list_bucket_objects(connection, module, bucket_name):
bucket=bucket_name,
max_keys=module.params["max_keys"],
start_after=module.params["marker"],
prefix=module.params["prefix"],
)
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, msg="Failed to list bucket objects.")
Expand Down Expand Up @@ -692,6 +705,7 @@ def main():
ceph=dict(default=False, type="bool", aliases=["rgw"]),
marker=dict(),
max_keys=dict(type="int", no_log=False),
prefix=dict(type="str", required=False),
)

required_if = [
Expand All @@ -702,6 +716,7 @@ def main():
argument_spec=argument_spec,
supports_check_mode=True,
required_if=required_if,
mutually_exclusive=[["object_name", "prefix"]],
)

bucket_name = module.params.get("bucket_name")
Expand Down
3 changes: 3 additions & 0 deletions tests/integration/targets/s3_object_info_prefix/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cloud/aws
s3_object_info
time=1m
90 changes: 90 additions & 0 deletions tests/integration/targets/s3_object_info_prefix/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
# Integration tests for s3_object_info with prefix
- module_defaults:
group/aws:
access_key: "{{ aws_access_key }}"
secret_key: "{{ aws_secret_key }}"
session_token: "{{ security_token | default(omit) }}"
region: "{{ aws_region }}"

vars:
bucket_name: '{{ resource_prefix | hash("md5") }}'
src_objects:
- ansible/hello.txt
- ansible/world.txt
- ansible-core.yaml
- ansible-builder.yaml

block:
# Ensure module fails when both object_name and prefix parameters are provided
- name: Retrieve a list of objects in Ceph RGW S3
amazon.aws.s3_object_info:
prefix: test_
bucket_name: "{{ bucket_name }}"
object_name: test
register: error_m
ignore_errors: true

- name: Ensure module fails when both object_name and prefix are passed
ansible.builtin.assert:
that:
- error_m is failed
- error_m.msg == "parameters are mutually exclusive: object_name|prefix"

- name: Create bucket
amazon.aws.s3_bucket:
name: "{{ bucket_name }}"
state: present

- name: Put object into bucket
amazon.aws.s3_object:
bucket: "{{ bucket_name }}"
mode: put
object: "{{ item }}"
content: "some bucket content for testing amazon.aws.s3_object_info module"
with_items: "{{ src_objects }}"

- name: Retrieve objects using prefix 'ansible/'
amazon.aws.s3_object_info:
prefix: 'ansible/'
bucket_name: "{{ bucket_name }}"
register: objects

- name: Ensure all objects retrieved have a 'ansible/' prefix
ansible.builtin.assert:
that:
- (objects.s3_keys | map('regex_search', '^ansible/(\w+)\.txt$') | length) == (objects.s3_keys | length)

- name: Retrieve objects using prefix 'ansible-'
amazon.aws.s3_object_info:
prefix: 'ansible-'
bucket_name: "{{ bucket_name }}"
register: objects

- name: Ensure all objects retrieved have a 'ansible-' prefix
ansible.builtin.assert:
that:
- (objects.s3_keys | map('regex_search', '^ansible\-(\w+)\.yaml$') | length) == (objects.s3_keys | length)

always:
# Delete bucket
- name: List bucket object
amazon.aws.s3_object_info:
bucket_name: "{{ bucket_name }}"
register: objects
ignore_errors: true

- name: Remove objects from bucket
amazon.aws.s3_object:
bucket: "{{ bucket_name }}"
mode: delobj
object: "{{ item }}"
with_items: "{{ objects.s3_keys }}"
when: "'s3_keys' in objects"
ignore_errors: true

- name: Delete the bucket
amazon.aws.s3_bucket:
name: "{{ bucket_name }}"
state: absent
ignore_errors: true

0 comments on commit 334b49e

Please sign in to comment.