
    Vh>~                     4   d Z dZdZddlZ	 ddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ  e	j                  d	d	
      d        Z e	j                  d	d	
      d        Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zedk(  r e        yy# e$ r Y w xY w)aU$  
---
module: msk_cluster
short_description: Manage Amazon MSK clusters
version_added: "2.0.0"
description:
    - Create, delete and modify Amazon MSK (Managed Streaming for Apache Kafka) clusters.
    - Prior to release 5.0.0 this module was called C(community.aws.aws_msk_cluster).
      The usage did not change.
author:
    - Daniil Kupchenko (@oukooveu)
options:
    state:
        description: Create (C(present)) or delete (C(absent)) cluster.
        choices: ['present', 'absent']
        type: str
        default: 'present'
    name:
        description: The name of the cluster.
        required: true
        type: str
    version:
        description:
            - The version of Apache Kafka.
            - This version should exist in given configuration.
            - This parameter is required when I(state=present).
        type: str
    configuration_arn:
        description:
            - ARN of the configuration to use.
            - This parameter is required when I(state=present).
        type: str
    configuration_revision:
        description:
            - The revision of the configuration to use.
            - This parameter is required when I(state=present).
        type: int
    nodes:
        description: The number of broker nodes in the cluster. Should be greater or equal to two.
        type: int
        default: 3
    instance_type:
        description:
            - The type of Amazon EC2 instances to use for Kafka brokers.
        choices:
            - kafka.t3.small
            - kafka.m5.large
            - kafka.m5.xlarge
            - kafka.m5.2xlarge
            - kafka.m5.4xlarge
            - kafka.m5.8xlarge
            - kafka.m5.12xlarge
            - kafka.m5.16xlarge
            - kafka.m5.24xlarge
            - kafka.m7g.large
            - kafka.m7g.xlarge
            - kafka.m7g.2xlarge
            - kafka.m7g.4xlarge
            - kafka.m7g.8xlarge
            - kafka.m7g.12xlarge
            - kafka.m7g.16xlarge
        default: kafka.t3.small
        type: str
    ebs_volume_size:
        description: The size in GiB of the EBS volume for the data drive on each broker node.
        type: int
        default: 100
    subnets:
        description:
            - The list of subnets to connect to in the client virtual private cloud (VPC).
              AWS creates elastic network interfaces inside these subnets. Client applications use
              elastic network interfaces to produce and consume data.
            - Client subnets can't be in Availability Zone us-east-1e.
            - This parameter is required when I(state=present).
        type: list
        elements: str
    security_groups:
        description:
            - The AWS security groups to associate with the elastic network interfaces in order to specify
              who can connect to and communicate with the Amazon MSK cluster.
              If you don't specify a security group, Amazon MSK uses the default security group associated with the VPC.
        type: list
        elements: str
    encryption:
        description:
            - Includes all encryption-related information.
            - Effective only for new cluster and can not be updated.
        type: dict
        suboptions:
            kms_key_id:
                description:
                    - The ARN of the AWS KMS key for encrypting data at rest. If you don't specify a KMS key, MSK creates one for you and uses it.
                default: Null
                type: str
            in_transit:
                description: The details for encryption in transit.
                type: dict
                suboptions:
                    in_cluster:
                        description:
                            - When set to true, it indicates that data communication among the broker nodes of the cluster is encrypted.
                              When set to false, the communication happens in plaintext.
                        type: bool
                        default: True
                    client_broker:
                        description:
                            - Indicates the encryption setting for data in transit between clients and brokers. The following are the possible values.
                              TLS means that client-broker communication is enabled with TLS only.
                              TLS_PLAINTEXT means that client-broker communication is enabled for both TLS-encrypted, as well as plaintext data.
                              PLAINTEXT means that client-broker communication is enabled in plaintext only.
                        choices:
                            - TLS
                            - TLS_PLAINTEXT
                            - PLAINTEXT
                        type: str
                        default: TLS
    authentication:
        description:
            - Includes all client authentication related information.
            - Effective only for new cluster and can not be updated.
        type: dict
        suboptions:
            tls_ca_arn:
                description: List of ACM Certificate Authority ARNs.
                type: list
                elements: str
            sasl_scram:
                description: SASL/SCRAM authentication is enabled or not.
                type: bool
            sasl_iam:
                version_added: 5.5.0
                description: IAM authentication is enabled or not.
                type: bool
            unauthenticated:
                version_added: 5.5.0
                description: Option to explicitly turn on or off authentication
                type: bool
                default: True
    enhanced_monitoring:
        description: Specifies the level of monitoring for the MSK cluster.
        choices:
            - DEFAULT
            - PER_BROKER
            - PER_TOPIC_PER_BROKER
            - PER_TOPIC_PER_PARTITION
        default: DEFAULT
        type: str
    open_monitoring:
        description: The settings for open monitoring.
        type: dict
        suboptions:
            jmx_exporter:
                description: Indicates whether you want to enable or disable the JMX Exporter.
                type: bool
                default: False
            node_exporter:
                description: Indicates whether you want to enable or disable the Node Exporter.
                type: bool
                default: False
    logging:
        description: Logging configuration.
        type: dict
        suboptions:
            cloudwatch:
                description: Details of the CloudWatch Logs destination for broker logs.
                type: dict
                suboptions:
                    enabled:
                        description: Specifies whether broker logs get sent to the specified CloudWatch Logs destination.
                        type: bool
                        default: False
                    log_group:
                        description: The CloudWatch log group that is the destination for broker logs.
                        type: str
                        required: False
            firehose:
                description: Details of the Kinesis Data Firehose delivery stream that is the destination for broker logs.
                type: dict
                suboptions:
                    enabled:
                        description: Specifies whether broker logs get send to the specified Kinesis Data Firehose delivery stream.
                        type: bool
                        default: False
                    delivery_stream:
                        description: The Kinesis Data Firehose delivery stream that is the destination for broker logs.
                        type: str
                        required: False
            s3:
                description: Details of the Amazon S3 destination for broker logs.
                type: dict
                suboptions:
                    enabled:
                        description: Specifies whether broker logs get sent to the specified Amazon S3 destination.
                        type: bool
                        default: False
                    bucket:
                        description: The name of the S3 bucket that is the destination for broker logs.
                        type: str
                        required: False
                    prefix:
                        description: The S3 prefix that is the destination for broker logs.
                        type: str
                        required: False
    wait:
        description: Whether to wait for the cluster to be available or deleted.
        type: bool
        default: false
    wait_timeout:
        description: How many seconds to wait. Cluster creation can take up to 20-30 minutes.
        type: int
        default: 3600
notes:
    - All operations are time consuming, for example create takes 20-30 minutes,
      update kafka version -- more than one hour, update configuration -- 10-15 minutes;
    - Cluster's brokers get evenly distributed over a number of availability zones
      that's equal to the number of subnets.
extends_documentation_fragment:
    - amazon.aws.common.modules
    - amazon.aws.region.modules
    - amazon.aws.boto3
    - amazon.aws.tags
a  
# Note: These examples do not set authentication details, see the AWS Guide for details.

- community.aws.msk_cluster:
    name: kafka-cluster
    state: present
    version: 2.6.1
    nodes: 6
    ebs_volume_size: "{{ aws_msk_options.ebs_volume_size }}"
    subnets:
      - subnet-e3b48ce7c25861eeb
      - subnet-2990c8b25b07ddd43
      - subnet-d9fbeaf46c54bfab6
    wait: true
    wait_timeout: 1800
    configuration_arn: arn:aws:kafka:us-east-1:123456789012:configuration/kafka-cluster-configuration/aaaaaaaa-bbbb-4444-3333-ccccccccc-1
    configuration_revision: 1

- community.aws.msk_cluster:
    name: kafka-cluster
    state: absent
a  
# These are examples of possible return values, and in general should use other names for return values.

bootstrap_broker_string:
    description: A list of brokers that a client application can use to bootstrap.
    type: complex
    contains:
        plain:
            description: A string containing one or more hostname:port pairs.
            type: str
        tls:
            description: A string containing one or more DNS names (or IP) and TLS port pairs.
            type: str
    returned: I(state=present) and cluster state is I(ACTIVE)
cluster_info:
    description: Description of the MSK cluster.
    type: dict
    returned: I(state=present)
response:
    description: The response from actual API call.
    type: dict
    returned: always
    sample: {}
    N)camel_dict_to_snake_dict)AWSRetry)compare_aws_tags)AnsibleCommunityAWSModule   )retriesdelayc                 d    | j                  d      }|j                  |      j                         S )Nlist_clusters)ClusterNameFilterget_paginatorpaginatebuild_full_result)clientcluster_name	paginators      m/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/aws/plugins/modules/msk_cluster.pylist_clusters_with_backoffr   %  s/    $$_5I=OOQQ    c                 d    | j                  d      }|j                  |      j                         S )N
list_nodes)
ClusterArnr   )r   cluster_arnr   s      r   list_nodes_with_backoffr   +  s/    $$\2I5GGIIr   c                 B   	 t        | |      j                  dg       }r)t        |      dk7  r|j                  d| d       |d   S i S # t        j                  j                  t        j                  j
                  f$ r}|j                  |d       Y d }~{d }~ww xY w)NClusterInfoListz$Failed to find kafka cluster by name   z'Found more than one cluster with name ''msgr   )	r   getbotocore
exceptionsBotoCoreErrorClientErrorfail_json_awslen	fail_json)r   moduler   cluster_listes        r   find_cluster_by_namer-   1  s    H1&,GKKL]_ab |!#J<.XY!Z[AI 	))'' H 	Q FGG	Hs   A 7BBBc                    	 | j                  |d      }d   d   S # | j                  j                  $ r Y yt        j                  j                  t        j                  j
                  f$ r}|j                  |d       Y d }~pd }~ww xY w)NTr   	aws_retryDELETEDz!Failed to get kafka cluster stateClusterInfoState)describe_clusterr$   NotFoundExceptionr#   r%   r&   r'   r   r*   arnresponser,   s        r   get_cluster_stater9   @  s    E**cT*J M"7++ .. ))'' E 	Q CDD	Es    B
6B
.BB
c                     	 | j                  |d      }d   d   S # t        j                  j                  t        j                  j                  f$ r}|j                  |d       Y d }~Vd }~ww xY w)NTr/   z#Failed to get kafka cluster versionr2   CurrentVersion)r4   r#   r$   r%   r&   r'   r6   s        r   get_cluster_versionr<   M  sz    G**cT*J M"#344	 	))'' G 	Q EFF	Gs    7A0A++A0c                 0   t        j                          }t        |j                  j                  d            }d}	 t	        | ||      }||k(  ry t        j                          |z
  |kD  r|j                  d| d| d       t        j                  |       \)Nwait_timeout<   zTimeout waiting for cluster z (desired state is 'z')r    )timeintparamsr"   r9   r)   sleep)r   r*   r7   statestarttimeoutcheck_intervalcurrent_states           r   wait_for_cluster_staterI   X  s    IIKE&--##N34GN
)&&#>E!99;(#?Nbchbiik!lm

>" r   c                    | j                   d   | j                   d   | j                   d   | j                   d   d| j                   d   | j                   d   | j                   d   d	d
}| j                   d   r<t        | j                   d         dk7  r!| j                   j                  d      |d   d<   | j                   d   r%dd| j                   j                  d      ii|d   d<   | j                   d   ri |d<   | j                   d   j                  d      rd| j                   d   d   i|d   d<   | j                   d   d   j                  dd      | j                   d   d   j                  dd      d|d   d<   | j                   d   ri |d <   | j                   d   j                  d!      s| j                   d   j                  d"      rTi }| j                   d   j                  d!      rd#di|d$<   | j                   d   j                  d"      rd#di|d%<   ||d    d&<   | j                   d   j                  d'      r| j                   d   d'   dd(|d    d)<   | j                   d   j                  d*      r	d+d#dii|d <   |j                  t	        |              |j                  t        |              |j                  t        |              |S ),z<
    Return data structure for cluster create operation
    nameversionconfiguration_arnconfiguration_revisionArnRevisionnodessubnetsinstance_type)ClientSubnetsInstanceType)ClusterNameKafkaVersionConfigurationInfoNumberOfBrokerNodesBrokerNodeGroupInfosecurity_groupsr   r[   SecurityGroupsebs_volume_sizeEbsStorageInfo
VolumeSizeStorageInfo
encryptionEncryptionInfo
kms_key_idDataVolumeKMSKeyIdEncryptionAtRest
in_transitclient_brokerTLS
in_clusterT)ClientBroker	InClusterEncryptionInTransitauthenticationClientAuthentication
sasl_scramsasl_iamEnabledScramIamSasl
tls_ca_arn)CertificateAuthorityArnListrr   TlsunauthenticatedUnauthenticated)rB   r(   r"   update#prepare_enhanced_monitoring_optionsprepare_open_monitoring_optionsprepare_logging_options)r*   c_paramssasls      r   prepare_create_optionsr   f  s    }}V,i0==!45&>?
  &}}W5#]]95"MM/: 
H }}&'C>O0P,QUV,V<BMM<M<MN_<`&'(89}}&'|V]]->->?P-QR:
&'6 }}\"%'!"==&**<8$fmmL&A,&O>H%&'9: #MM,7EII/[`a|4\BFF|UYZ=
!"#89
 }}%&+-'(==)*..|<N^@_@c@cdn@oD}}-.22<@!*D 1W}}-.22:>($/U7;H+,V4==)*..|</5}}=M/N|/\7H+,U3 ==)*../@A!It#40H+, OO7?@OO3F;<OO+F34Or   c                 6    i }| j                   d   xs d|d<   |S )Nenhanced_monitoringDEFAULTEnhancedMonitoring)rB   )r*   m_paramss     r   r|   r|     s&    H%+]]3H%I%VYH!"Or   c                     i }| j                   d   xs i }dd|j                  dd      id|j                  dd      idi|d<   |S )	Nopen_monitoring
PrometheusEnabledInBrokerjmx_exporterFnode_exporter)JmxExporterNodeExporterOpenMonitoringrB   r"   )r*   r   r   s      r   r}   r}     sc    Hmm$56<"O-/B/B>SX/YZ.0C0COUZ0[\
"H Or   c                    i }| j                   d   xs i }|j                  d      rG| j                   d   d   j                  d      | j                   d   d   j                  d      d|d<   nddi|d<   |j                  d	      rG| j                   d   d	   j                  d      | j                   d   d	   j                  d
      d|d<   nddi|d<   |j                  d      rg| j                   d   d   j                  d      | j                   d   d   j                  d      | j                   d   d   j                  d      d|d<   nddi|d<   dd|iiS )Nlogging
cloudwatchenabled	log_group)rr   LogGroupCloudWatchLogsrr   Ffirehosedelivery_stream)rr   DeliveryStreamFirehoses3bucketprefix)rr   BucketPrefixS3LoggingInfo
BrokerLogsr   )r*   l_paramsr   s      r   r~   r~     sj   HmmI&,"G{{< }}Y/=AA)Li0>BB;O&
!"
 '0%7!"{{:}}Y/
;??	J$mmI6zBFFGXY 

 !*51{{4}}Y/599)DmmI.t488BmmI.t488B
 $U+L(344r   c                    d}i }t        | ||j                  d         }|sbd}|j                  rdi fS t        |      }	  | j                  d:ddi|}|j                  j                  d      rt        | ||d   d	
       n |d   |d<   i |d<   |d   |j                  j                  d      d|j                  j                  d      id|d   d   d   d   |j                  j                  d      dd|j                  j                  d      dgid|d   d   |j                  j                  d      d|j                  j                  d      id|d   d   |d   d   d|j                  j                  d      |j                  j                  d       dd!|j                  j                  d      |j                  j                  d       d"id|d   d#   |j                  j                  d$      d%|j                  j                  d$      id|d&   |j                  j                  d'      d(t        |      d)d*|d*   it        |      d(t        |      d)d+|d+   it        |      d(t        |      d)d,}|j                         D ]  \  }}	d-|	v r|j!                  |	d-         s	 t#        | |	j                  d.d/|z               }
|	d2   |	d3   k7  sKd}|j                  rdi fc S t'        | ||d         }t)        | ||d         }|d	k7  r8|j                  d   rt        | ||d   d	
       n|j+                  d4| d56       	  
d:|d   |d7|	d8   |d   |<   |j                  d   st        | ||d   d	
        |t-        | ||d         z  }||fS # t
        j                  j                  t
        j                  j                  f$ r}|j                  |d       Y d}~d}~ww xY w# t$        $ r!}|j                  |d0| d1       Y d}~Ld}~ww xY w# t
        j                  j                  t
        j                  j                  f$ r!}|j                  |d9| d1       Y d}~d}~ww xY w);z/
    Create new or update existing cluster
    FrK   Tr0   zFailed to create kafka clusterNwaitr   ACTIVEr7   rD   changesrZ   rR   TargetNumberOfBrokerNodes)current_valuetarget_valueupdate_paramsr[   ra   r_   r`   r^   TargetBrokerEBSVolumeInfoAll)KafkaBrokerNodeIdVolumeSizeGBrV   rT   TargetInstanceTypeCurrentBrokerSoftwareInfoConfigurationArnConfigurationRevision)r7   revisionrM   rN   rY   rO   rX   rL   TargetKafkaVersionr   r   update_monitoring)r   r   update_methodr   r   r   )broker_countbroker_storagebroker_typecluster_configurationcluster_kafka_versionr   r   r   botocore_versionr   update_z"There is no update method 'update_r   r   r   z?Cluster can be updated only in active state, current state is 'z)'. check cluster state or use wait optionr    r   r;   r   z%Failed to update cluster via 'update_ )r-   rB   
check_moder   create_clusterr#   r$   r%   r&   r'   r"   rI   r|   r}   r~   itemsbotocore_at_leastgetattrAttributeErrorr<   r9   r)   update_cluster_tags)r   r*   changedr8   clustercreate_paramsr,   msk_cluster_changesmethodoptionsr   rL   rD   s                r   create_or_update_clusterr     s'   
 GH"666==3HIG8O.v6	F,v,,MtM}MH ==V$"66x7MU]^ ")!6 
 "))>!? & 1 1' :"=v}}?P?PQX?Y!Z "))>!?!NO_!`am!n & 1 12C D/.3V]]EVEVWhEij2" "))>!?!O & 1 1/ B"68I8I/8Z![ ##>?@RS '(C DE\ ]"
 "==,,-@A & 1 12J K!
 (%}}001DE$*MM$5$56N$O*"&" "))D!En!U & 1 1) <"68I8I)8T!U& "))=!> & 1 12G H!4!DV!L	$ #3G<L4M!N ? G!4!@!H	  #01G!H 7 ?!4!8!@	k;
z  388: %	fOFG!W,//8J0KLX 'OYY_M_0` a '7>+BB$$8O .ffgl>ST)&&',:OPH$}}V,.vv7<CX`hi(("abgah  iR  !S ) _2? 3#*<#83T[\kTl3HY'/ ==(*66w|?T\deK%	fN "668L3IJJGHg --++
 	F   $DEE		Fd " X$$Q*LVHTU(VWWX0 ''55''33 _ ((.STZS[[\,]^^	_sG   N +O1P7O.O))O.1	P:PP7Q6Q11Q6c                    |j                   j                  d      }|y|j                   j                  d      }	 | j                  |d      d   }t        ||
      \  }}|j                  s-	 |r| j                  ||d       |r| j                  ||d       t        |      xs t        |      }	|	S # t        j                  j
                  t        j                  j                  f$ r!}|j                  |d| d	       Y d }~d }~ww xY w# t        j                  j
                  t        j                  j                  f$ r!}|j                  |d| d	       Y d }~d }~ww xY w)NtagsF
purge_tagsT)ResourceArnr0   Tagsz%Unable to retrieve tags for cluster 'r   r    )r   )r   TagKeysr0   )r   r   r0   z Unable to set tags for cluster ')rB   r"   list_tags_for_resourcer#   r$   r&   r%   r'   r   r   untag_resourcetag_resourcebool)
r   r*   r7   new_tagsr   existing_tagsr,   tags_to_addtags_to_remover   s
             r   r   r   _  si   }}  (H""<0JT55#QU5VW]^ #3=(Wa"bK	S%%#~Y]%^##+QU#V ;74#7GN ++X-@-@-N-NO TQ&KC5PQ$RSST ##//1D1D1R1RS 	S  *J3%q(Q RR	Ss/   B5 /,D 57D,DD7E(E##E(c                    t        | ||j                  d         }|j                  r
|rd|fS di fS |sdi fS 	 | j                  |d   |d         }|j                  d   rt        | ||d   d	
       i d<   d|fS # t        j
                  j                  t        j
                  j                  f$ r}|j                  |d       Y d }~xd }~ww xY w)NrK   TFr   r;   r   zFailed to delete kafka clusterr   r1   r   bootstrap_broker_string)
r-   rB   r   delete_clusterr#   r$   r%   r&   r'   rI   )r   r*   r   r8   r,   s        r   r   r   y  s    "666==3HIG= "9byB((|,"#34 ) 
 }}Vvv7<3HPYZ*,H&'> --x/B/B/N/NO BQ @AABs   A; ;7C2C		Cc                  z	   t        dQi dt        dd      dt        dddgd      d	t        d
      dt        d
      dt        d
      dt        dd      dt        g dd      dt        dd      dt        dd      dt        ddd      dt        dt        t        dd      t        dt        t        dd      t        g d d!      "      #      $      #      d%t        dt        t        ddd      t        dd      t        dd      t        ddd&      '      #      d(t        g d)d*d+      d,t        dt        t        dd      t        dd      -      #      d.t        dt        t        dt        t        dd      t        dd      /      #      t        dt        t        dd      t        dd      0      #      t        dt        t        dd      t        dd      t        dd      1      #      2      #      d3t        dd      d4t        dd5      d6t        dd7g8      d9t        dd      } t        | ddg d:ggd;      }|j                  d<t        j                         =      }|j
                  d   dk(  rt        |j
                  d         d>k  r|j                  d?@       t        |j
                  d         t        t        |j
                  d               z  dAk7  r|j                  dB@       t        |j
                  d         dCkD  r2|j                  |j                  dD|j
                  d    dE@             t        ||      \  }}n!|j
                  d   dk(  rt        ||      \  }}i }i }j                  dF      r|j
                  d   dk(  rv	 |j                  |dF   dG      dH   }|j                  dI      dJk(  rH|j                  |dF   dG      }|j                  dK      r|dK   |dL<   |j                  dM      r|dM   |dN<   |j'                  |t)        |      t)        |      P       y # t        j                  j                   t        j                  j"                  f$ r"}|j%                  |dO|dF           Y d }~|d }~ww xY w)RNrK   strT)typerequiredrD   presentabsent)r   choicesdefaultrL   )r   rM   rN   rA   rR      )r   r   rT   )kafka.t3.smallzkafka.m5.largezkafka.m5.xlargezkafka.m5.2xlargezkafka.m5.4xlargezkafka.m5.8xlargezkafka.m5.12xlargezkafka.m5.16xlargezkafka.m5.24xlargezkafka.m7g.largezkafka.m7g.xlargezkafka.m7g.2xlargezkafka.m7g.4xlargezkafka.m7g.8xlargezkafka.m7g.12xlargezkafka.m7g.16xlarger   )r   r   r^   d   rS   list)r   elementsr\   F)r   r   r   rb   dictr   )ri   TLS_PLAINTEXT	PLAINTEXTri   )rj   rh   )r   r   )rd   rg   rn   )r   r   r   )rv   rp   rq   ry   r   )r   
PER_BROKERPER_TOPIC_PER_BROKERPER_TOPIC_PER_PARTITIONr   )r   r   r   r   )r   r   r   )r   r   )r   r   )r   r   r   )r   r   r   r   r>   i  r   resource_tags)r   aliasesr   )rL   rM   rN   rS   )argument_specrequired_ifsupports_check_modekafka)retry_decorator   z.At least two client subnets should be providedr    r   z\The number of broker nodes must be a multiple of availability zones in the subnets parameter@   zCluster name "z" exceeds 64 character limitr   r/   r2   r3   r   BootstrapBrokerStringplainBootstrapBrokerStringTlstlsz)Can not obtain information about cluster )r   r   cluster_infor8   r   )r   AnsibleAWSModuler   r   jittered_backoffrB   r(   r)   rA   r   r   r"   r4   get_bootstrap_brokersr#   r$   r%   r&   r'   	exit_jsonr   )	module_argsr*   r   r   r8   r  r   brokersr,   s	            r   mainr	    s    eut,e	8'<iPe % e E*	e
  $/e q)e $ %'
e8 %59e: &51;e< &55I=e> UU; #'VT#B&*3Xbg&h	
?eX VeeLVe<6E: $&$ O	
Yej ! 	
ke~ !vu=">
eL   $&% @"&EE"B   $&% @(,%%(H   $&% @#?#?
MeB vu-CeD ud3EeF v'89GeH VT2IeKN !y*opq F ]]7H4M4M4O]PF}}W*v}}Y'(1,!QRv}}W%&Sy1I-J)KKqPr   v}}V$%*V--N6==QWCXBYYu2v-wx4VVD	w	8	+*66:L ||L!fmmG&<	&I	!22h|>T`d2efstL(H4 66(<BXdh6i;;677>?V7W+G4;;9:5<=W5X+E2  7-l;)(3	   --++
 	   ;H\<R;ST 		s   A5Q! !7R:R55R:__main__)r   )DOCUMENTATIONEXAMPLESRETURNr@   r#   ImportError0ansible.module_utils.common.dict_transformationsr   ;ansible_collections.amazon.aws.plugins.module_utils.retriesr   ;ansible_collections.amazon.aws.plugins.module_utils.taggingr   >ansible_collections.community.aws.plugins.module_utils.modulesr   r  r  r   r   r-   r9   r<   rI   r   r|   r}   r~   r   r   r   r	  __name__r   r   r   <module>r     s   ]~.
2 	 V P X x 1A.R /R
 1A.J /J

,5#=@	58HV48Vr zF i  		s   B BB