1#!/usr/local/bin/python3.8 2# Copyright (c) 2017 Ansible Project 3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 5from __future__ import (absolute_import, division, print_function) 6__metaclass__ = type 7 8 9DOCUMENTATION = ''' 10module: elasticache_info 11short_description: Retrieve information for AWS ElastiCache clusters 12version_added: 1.0.0 13description: 14 - Retrieve information from AWS ElastiCache clusters 15 - This module was called C(elasticache_facts) before Ansible 2.9. The usage did not change. 16options: 17 name: 18 description: 19 - The name of an ElastiCache cluster. 20 type: str 21 22author: 23 - Will Thames (@willthames) 24extends_documentation_fragment: 25- amazon.aws.aws 26- amazon.aws.ec2 27 28''' 29 30EXAMPLES = ''' 31- name: obtain all ElastiCache information 32 community.aws.elasticache_info: 33 34- name: obtain all information for a single ElastiCache cluster 35 community.aws.elasticache_info: 36 name: test_elasticache 37''' 38 39RETURN = ''' 40elasticache_clusters: 41 description: List of ElastiCache clusters 42 returned: always 43 type: complex 44 contains: 45 auto_minor_version_upgrade: 46 description: Whether to automatically upgrade to minor versions 47 returned: always 48 type: bool 49 sample: true 50 cache_cluster_create_time: 51 description: Date and time cluster was created 52 returned: always 53 type: str 54 sample: '2017-09-15T05:43:46.038000+00:00' 55 cache_cluster_id: 56 description: ID of the cache cluster 57 returned: always 58 type: str 59 sample: abcd-1234-001 60 cache_cluster_status: 61 description: Status of ElastiCache cluster 62 returned: always 63 type: str 64 sample: available 65 cache_node_type: 66 description: Instance type of ElastiCache nodes 67 returned: always 68 type: str 69 sample: cache.t2.micro 70 cache_nodes: 71 description: List of ElastiCache nodes in the cluster 72 returned: always 73 type: complex 74 contains: 75 cache_node_create_time: 76 description: Date and time node was created 77 returned: always 78 type: str 79 sample: '2017-09-15T05:43:46.038000+00:00' 80 cache_node_id: 81 description: ID of the cache node 82 returned: always 83 type: str 84 sample: '0001' 85 cache_node_status: 86 description: Status of the cache node 87 returned: always 88 type: str 89 sample: available 90 customer_availability_zone: 91 description: Availability Zone in which the cache node was created 92 returned: always 93 type: str 94 sample: ap-southeast-2b 95 endpoint: 96 description: Connection details for the cache node 97 returned: always 98 type: complex 99 contains: 100 address: 101 description: URL of the cache node endpoint 102 returned: always 103 type: str 104 sample: abcd-1234-001.bgiz2p.0001.apse2.cache.amazonaws.com 105 port: 106 description: Port of the cache node endpoint 107 returned: always 108 type: int 109 sample: 6379 110 parameter_group_status: 111 description: Status of the Cache Parameter Group 112 returned: always 113 type: str 114 sample: in-sync 115 cache_parameter_group: 116 description: Contents of the Cache Parameter Group 117 returned: always 118 type: complex 119 contains: 120 cache_node_ids_to_reboot: 121 description: Cache nodes which need to be rebooted for parameter changes to be applied 122 returned: always 123 type: list 124 sample: [] 125 cache_parameter_group_name: 126 description: Name of the cache parameter group 127 returned: always 128 type: str 129 sample: default.redis3.2 130 parameter_apply_status: 131 description: Status of parameter updates 132 returned: always 133 type: str 134 sample: in-sync 135 cache_security_groups: 136 description: Security Groups used by the cache 137 returned: always 138 type: list 139 sample: 140 - 'sg-abcd1234' 141 cache_subnet_group_name: 142 description: ElastiCache Subnet Group used by the cache 143 returned: always 144 type: str 145 sample: abcd-subnet-group 146 client_download_landing_page: 147 description: URL of client download web page 148 returned: always 149 type: str 150 sample: 'https://console.aws.amazon.com/elasticache/home#client-download:' 151 engine: 152 description: Engine used by ElastiCache 153 returned: always 154 type: str 155 sample: redis 156 engine_version: 157 description: Version of ElastiCache engine 158 returned: always 159 type: str 160 sample: 3.2.4 161 notification_configuration: 162 description: Configuration of notifications 163 returned: if notifications are enabled 164 type: complex 165 contains: 166 topic_arn: 167 description: ARN of notification destination topic 168 returned: if notifications are enabled 169 type: str 170 sample: arn:aws:sns:*:123456789012:my_topic 171 topic_name: 172 description: Name of notification destination topic 173 returned: if notifications are enabled 174 type: str 175 sample: MyTopic 176 num_cache_nodes: 177 description: Number of Cache Nodes 178 returned: always 179 type: int 180 sample: 1 181 pending_modified_values: 182 description: Values that are pending modification 183 returned: always 184 type: complex 185 contains: {} 186 preferred_availability_zone: 187 description: Preferred Availability Zone 188 returned: always 189 type: str 190 sample: ap-southeast-2b 191 preferred_maintenance_window: 192 description: Time slot for preferred maintenance window 193 returned: always 194 type: str 195 sample: sat:12:00-sat:13:00 196 replication_group_id: 197 description: Replication Group Id 198 returned: always 199 type: str 200 sample: replication-001 201 security_groups: 202 description: List of Security Groups associated with ElastiCache 203 returned: always 204 type: complex 205 contains: 206 security_group_id: 207 description: Security Group ID 208 returned: always 209 type: str 210 sample: sg-abcd1234 211 status: 212 description: Status of Security Group 213 returned: always 214 type: str 215 sample: active 216 tags: 217 description: Tags applied to the ElastiCache cluster 218 returned: always 219 type: complex 220 contains: {} 221 sample: 222 Application: web 223 Environment: test 224''' 225 226from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict 227from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule 228from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code 229from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry 230from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict 231 232 233try: 234 import botocore 235except ImportError: 236 pass # caught by AnsibleAWSModule 237 238 239@AWSRetry.exponential_backoff() 240def describe_cache_clusters_with_backoff(client, cluster_id=None): 241 paginator = client.get_paginator('describe_cache_clusters') 242 params = dict(ShowCacheNodeInfo=True) 243 if cluster_id: 244 params['CacheClusterId'] = cluster_id 245 try: 246 response = paginator.paginate(**params).build_full_result() 247 except is_boto3_error_code('CacheClusterNotFound'): 248 return [] 249 return response['CacheClusters'] 250 251 252@AWSRetry.exponential_backoff() 253def get_elasticache_tags_with_backoff(client, cluster_id): 254 return client.list_tags_for_resource(ResourceName=cluster_id)['TagList'] 255 256 257def get_aws_account_id(module): 258 try: 259 client = module.client('sts') 260 except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: 261 module.fail_json_aws(e, msg="Can't authorize connection") 262 263 try: 264 return client.get_caller_identity()['Account'] 265 except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: 266 module.fail_json_aws(e, msg="Couldn't obtain AWS account id") 267 268 269def get_elasticache_clusters(client, module): 270 region = module.region 271 try: 272 clusters = describe_cache_clusters_with_backoff(client, cluster_id=module.params.get('name')) 273 except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: 274 module.fail_json_aws(e, msg="Couldn't obtain cache cluster info") 275 276 account_id = get_aws_account_id(module) 277 results = [] 278 for cluster in clusters: 279 280 cluster = camel_dict_to_snake_dict(cluster) 281 arn = "arn:aws:elasticache:%s:%s:cluster:%s" % (region, account_id, cluster['cache_cluster_id']) 282 try: 283 tags = get_elasticache_tags_with_backoff(client, arn) 284 except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: 285 module.fail_json_aws(e, msg="Couldn't get tags for cluster %s") 286 287 cluster['tags'] = boto3_tag_list_to_ansible_dict(tags) 288 results.append(cluster) 289 return results 290 291 292def main(): 293 argument_spec = dict( 294 name=dict(required=False), 295 ) 296 module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) 297 if module._name == 'elasticache_facts': 298 module.deprecate("The 'elasticache_facts' module has been renamed to 'elasticache_info'", date='2021-12-01', collection_name='community.aws') 299 300 client = module.client('elasticache') 301 302 module.exit_json(elasticache_clusters=get_elasticache_clusters(client, module)) 303 304 305if __name__ == '__main__': 306 main() 307