Repository URL to install this package:
Version:
6.0.0 ▾
|
#!/usr/bin/python
# Copyright: Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
---
module: s3_metrics_configuration
version_added: 1.3.0
short_description: Manage s3 bucket metrics configuration in AWS
description:
- Manage s3 bucket metrics configuration in AWS which allows to get the CloudWatch request metrics for the objects in a bucket
author: Dmytro Vorotyntsev (@vorotech)
notes:
- This modules manages single metrics configuration, the s3 bucket might have up to 1,000 metrics configurations
- To request metrics for the entire bucket, create a metrics configuration without a filter
- Metrics configurations are necessary only to enable request metric, bucket-level daily storage metrics are always turned on
options:
bucket_name:
description:
- "Name of the s3 bucket"
required: true
type: str
id:
description:
- "The ID used to identify the metrics configuration"
required: true
type: str
filter_prefix:
description:
- "A prefix used when evaluating a metrics filter"
required: false
type: str
filter_tags:
description:
- "A dictionary of one or more tags used when evaluating a metrics filter"
required: false
aliases: ['filter_tag']
type: dict
state:
description:
- "Create or delete metrics configuration"
default: present
choices: ['present', 'absent']
type: str
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
'''
EXAMPLES = r'''
# Note: These examples do not set authentication details, see the AWS Guide for details.
- name: Create a metrics configuration that enables metrics for an entire bucket
community.aws.s3_metrics_configuration:
bucket_name: my-bucket
id: EntireBucket
state: present
- name: Put a metrics configuration that enables metrics for objects starting with a prefix
community.aws.s3_metrics_configuration:
bucket_name: my-bucket
id: Assets
filter_prefix: assets
state: present
- name: Put a metrics configuration that enables metrics for objects with specific tag
community.aws.s3_metrics_configuration:
bucket_name: my-bucket
id: Assets
filter_tag:
kind: asset
state: present
- name: Put a metrics configuration that enables metrics for objects that start with a particular prefix and have specific tags applied
community.aws.s3_metrics_configuration:
bucket_name: my-bucket
id: ImportantBlueDocuments
filter_prefix: documents
filter_tags:
priority: high
class: blue
state: present
- name: Delete metrics configuration
community.aws.s3_metrics_configuration:
bucket_name: my-bucket
id: EntireBucket
state: absent
'''
try:
from botocore.exceptions import ClientError, BotoCoreError
except ImportError:
pass # Handled by AnsibleAWSModule
from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_tag_list
def _create_metrics_configuration(mc_id, filter_prefix, filter_tags):
payload = {
'Id': mc_id
}
# Just a filter_prefix or just a single tag filter is a special case
if filter_prefix and not filter_tags:
payload['Filter'] = {
'Prefix': filter_prefix
}
elif not filter_prefix and len(filter_tags) == 1:
payload['Filter'] = {
'Tag': ansible_dict_to_boto3_tag_list(filter_tags)[0]
}
# Otherwise we need to use 'And'
elif filter_tags:
payload['Filter'] = {
'And': {
'Tags': ansible_dict_to_boto3_tag_list(filter_tags)
}
}
if filter_prefix:
payload['Filter']['And']['Prefix'] = filter_prefix
return payload
def create_or_update_metrics_configuration(client, module):
bucket_name = module.params.get('bucket_name')
mc_id = module.params.get('id')
filter_prefix = module.params.get('filter_prefix')
filter_tags = module.params.get('filter_tags')
try:
response = client.get_bucket_metrics_configuration(aws_retry=True, Bucket=bucket_name, Id=mc_id)
metrics_configuration = response['MetricsConfiguration']
except is_boto3_error_code('NoSuchConfiguration'):
metrics_configuration = None
except (BotoCoreError, ClientError) as e: # pylint: disable=duplicate-except
module.fail_json_aws(e, msg="Failed to get bucket metrics configuration")
new_configuration = _create_metrics_configuration(mc_id, filter_prefix, filter_tags)
if metrics_configuration:
if metrics_configuration == new_configuration:
module.exit_json(changed=False)
if module.check_mode:
module.exit_json(changed=True)
try:
client.put_bucket_metrics_configuration(
aws_retry=True,
Bucket=bucket_name,
Id=mc_id,
MetricsConfiguration=new_configuration
)
except (BotoCoreError, ClientError) as e: # pylint: disable=duplicate-except
module.fail_json_aws(e, msg="Failed to put bucket metrics configuration '%s'" % mc_id)
module.exit_json(changed=True)
def delete_metrics_configuration(client, module):
bucket_name = module.params.get('bucket_name')
mc_id = module.params.get('id')
try:
client.get_bucket_metrics_configuration(aws_retry=True, Bucket=bucket_name, Id=mc_id)
except is_boto3_error_code('NoSuchConfiguration'):
module.exit_json(changed=False)
except (BotoCoreError, ClientError) as e: # pylint: disable=duplicate-except
module.fail_json_aws(e, msg="Failed to get bucket metrics configuration")
if module.check_mode:
module.exit_json(changed=True)
try:
client.delete_bucket_metrics_configuration(aws_retry=True, Bucket=bucket_name, Id=mc_id)
except is_boto3_error_code('NoSuchConfiguration'):
module.exit_json(changed=False)
except (BotoCoreError, ClientError) as e: # pylint: disable=duplicate-except
module.fail_json_aws(e, msg="Failed to delete bucket metrics configuration '%s'" % mc_id)
module.exit_json(changed=True)
def main():
argument_spec = dict(
bucket_name=dict(type='str', required=True),
id=dict(type='str', required=True),
filter_prefix=dict(type='str', required=False),
filter_tags=dict(default={}, type='dict', required=False, aliases=['filter_tag']),
state=dict(default='present', type='str', choices=['present', 'absent']),
)
module = AnsibleAWSModule(
argument_spec=argument_spec,
supports_check_mode=True
)
state = module.params.get('state')
try:
client = module.client('s3', retry_decorator=AWSRetry.exponential_backoff(retries=10, delay=3))
except (BotoCoreError, ClientError) as e:
module.fail_json_aws(e, msg='Failed to connect to AWS')
if state == 'present':
create_or_update_metrics_configuration(client, module)
elif state == 'absent':
delete_metrics_configuration(client, module)
if __name__ == '__main__':
main()