
    Vh_                        d dl mZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 	 d dl
mZ d d	l
mZ d d
l
mZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm Z  d dlm!Z! d dlm"Z" d dl#m$Z$  edg d      Z%g dZ&g dZ'g dZ(g dZ) G d de      Z* G d  d!e      Z+e+jY                  d"g        ejZ                         d#ed$eee.ef      fd%              Z/e+jY                  d&g        ejZ                         d#ed$eee.ef      fd'              Z0e+jY                  d(g        ejZ                         d#ed$ee   fd)              Z1e+jY                  d*g        ejZ                         d+e.d$eee.e.f      fd,              Z2d-e.d.ed$e%fd/Z3d-e.d.ed$e.fd0Z4d.ed1ed-e.d2ee.ef   d$e5f
d3Z6d.ed-e.d2ee.ef   d$e	ee5f   fd4Z7d.ed5e.d6e.d$d7fd8Z8d.ed9e.d6e.d$d7fd:Z9d.ed;e.d6e.d$d7fd<Z:d.ed;e.d6e.d$d7fd=Z;d.ed>e.d-e.d$d7fd?Z<d\d@e.dAe.dBe5d$ee.ef   fdCZ=d.ed+e.d$ee.e.f   fdDZ>dEee.ef   d$ee.ef   fdFZ?d.ed2ee.ef   d-e.dGe5d$ee.ef   f
dHZ@d.ed+e.dIee.e.f   dJeee.e.f      dKe5d$e5fdLZAdMeee.e.f      dNeee.e.f      dOe5d$e	eee.e.f      eee.e.f      f   fdPZBd.edQe.dReee.e.f      dSeee.e.f      d$e5f
dTZC ejZ                         d.edUedVee.   d$eee.ef      fdW       ZD ejZ                         	 d]dUed.edXe.d$eeE   fdY       ZF ejZ                         	 d^d.edUedVe.dZe.d$eee.ef      f
d[       ZGy7# e$ r Y w xY w)_    )
namedtuple)sleep)Any)Dict)List)Optional)Tuple)BotoCoreError)ClientError)WaiterError)to_text)camel_dict_to_snake_dict)snake_dict_to_camel_dict)"get_boto3_client_method_parametersis_boto3_error_code)AnsibleAWSModule)AWSErrorHandler)AnsibleAWSError)AWSRetry)ansible_dict_to_boto3_tag_list)boto3_tag_list_to_ansible_dict)compare_aws_tags)
get_waiterBoto3ClientMethodnamewaiteroperation_descriptionresourceretry_codes)create_db_cluster restore_db_cluster_from_snapshotrestore_db_cluster_from_s3#restore_db_cluster_to_point_in_timemodify_db_clusterdelete_db_clusteradd_tags_to_resourceremove_tags_from_resourcelist_tags_for_resourcepromote_read_replica_db_clusterstop_db_clusterstart_db_cluster)create_db_instance$restore_db_instance_to_point_in_timerestore_db_instance_from_s3$restore_db_instance_from_db_snapshotcreate_db_instance_read_replicamodify_db_instancedelete_db_instancer(   r)   r*   promote_read_replicastop_db_instancestart_db_instancereboot_db_instanceadd_role_to_db_instanceremove_role_from_db_instance)create_db_cluster_snapshotdelete_db_cluster_snapshotr(   r)   r*   copy_db_cluster_snapshot)create_db_snapshotdelete_db_snapshotr(   r)   copy_db_snapshotr*   c                       e Zd Zy)AnsibleRDSErrorN)__name__
__module____qualname__     g/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/amazon/aws/plugins/module_utils/rds.pyrB   rB   \   s    rG   rB   c                        e Zd ZeZed        Zy)RDSErrorHandlerc                     t        g d      S )N)DBInstanceNotFoundDBSnapshotNotFoundDBClusterNotFoundDBClusterSnapshotNotFoundFaultr   )clss    rH   _is_missingzRDSErrorHandler._is_missingc   s    "o
 	
rG   N)rC   rD   rE   rB   _CUSTOM_EXCEPTIONclassmethodrQ   rF   rG   rH   rJ   rJ   `   s    '
 
rG   rJ   zdescribe db cluster snapshotsparamsreturnc                 j    | j                  d      } |j                  di |j                         d   S )Ndescribe_db_cluster_snapshotsDBClusterSnapshotsrF   get_paginatorpaginatebuild_full_resultclientrT   	paginators      rH   rW   rW   j   s:     $$%DEI9''99;<PQQrG   zdescribe db instancesc                 j    | j                  d      } |j                  di |j                         d   S )Ndescribe_db_instancesDBInstancesrF   rY   r]   s      rH   ra   ra   q   9     $$%<=I9''99;MJJrG   zdescribe db snapshotsc                 j    | j                  d      } |j                  di |j                         d   S )Ndescribe_db_snapshotsDBSnapshotsrF   rY   r]   s      rH   re   re   x   rc   rG   zlist tags for resourceresource_arnc                 ,    | j                  |      d   S )NResourceNameTagList)r*   )r^   rg   s     rH   r*   r*      s     ((l(CINNrG   method_namemodulec                    d}| j                  dd      j                  dd      }d}g }| t        v r'd|j                  v rd}| dk(  rd	}nd
}| dk(  rdg}ndg}n| t        v rPd|j                  v rBd}| dk(  rd}n*| dk(  rd}n"| dk(  rd}n| dk(  rd}n| dk(  rd}n
| dk(  rd}nd}| dk(  rdg}nddg}n| t        v r,d |j                  v rd!}| d"k(  rd#}dg}no| d$k(  rd%}dg}ndd%}dg}n^| t
        v r,d&|j                  v rd'}| d(k(  rd)}dg}n;| d*k(  rd+}dg}n0d+}dg}n*|j                  j                  d,      rt        d-|  d.      t        | ||||/      S )0a   
    Returns rds attributes of the specified method.

        Parameters:
            method_name (str): RDS method to call
            module: AnsibleAWSModule

        Returns:
            Boto3ClientMethod (dict):
                name (str): Name of method
                waiter (str): Name of waiter associated with given method
                operation_description (str): Description of method
                resource (str): Type of resource this method applies to
                                One of ['instance', 'cluster', 'instance_snapshot', 'cluster_snapshot']
                retry_codes (list): List of extra error codes to retry on

        Raises:
            NotImplementedError if wait is True but no waiter can be found for specified method
     _ dbDBnew_db_cluster_identifierclusterr'   cluster_deletedcluster_availabler#   InvalidDBClusterSnapshotStateInvalidDBClusterStatenew_db_instance_identifierinstancer4   db_instance_deletedr6   db_instance_stoppedr9   role_associatedr:   role_disassociatedr5   read_replica_promoteddb_cluster_promotingdb_instance_availabler1   InvalidDBSnapshotStateInvalidDBInstanceStateInvalidDBSecurityGroupStatedb_cluster_snapshot_identifiercluster_snapshotr<   db_cluster_snapshot_deletedr;   db_cluster_snapshot_availabledb_snapshot_identifierinstance_snapshotr?   db_snapshot_deletedr>   db_snapshot_availablewaitmethod zY hasn't been added to the list of accepted methods to use a waiter in module_utils/rds.pyr   )	replacecluster_method_namesrT   instance_method_namescluster_snapshot_method_namesinstance_snapshot_method_namesgetNotImplementedErrorr   )rl   rm   r   readable_opr    r!   s         rH   get_rds_method_attributer      s   ( F%%c3/77dCKHK**/Jfmm/[--&F(F<<:;K23K	-	-2NRXR_R_2_..*F..*F55&F::)F22,F22+F,F@@34K35RSK	5	5:Z^d^k^k:k%662F:;K884F23K 5F:;K	6	6;SW]WdWd;d&..*F34K00,F34K -F34K==V$%+&  A  {U]kv rG   c                    d}|j                   j                  d      }t        | |      j                  }|dk(  r|j                   d   }|j                   d   }n]|dk(  r|j                   d   }|j                   d   }n9|d	k(  r|j                   d
   }n$|dk(  r|j                   d   }nt	        d|  d      |j
                  s|r|r|}|S )al  
    Returns the final identifier for the resource to which the specified method applies.

        Parameters:
            method_name (str): RDS method whose target resource final identifier is returned
            module: AnsibleAWSModule

        Returns:
            updated_identifier (str): The new resource identifier from module params if not in check mode, there is a new identifier in module params, and
                apply_immediately is True; otherwise returns the original resource identifier from module params

        Raises:
            NotImplementedError if the provided method is not supported
    Napply_immediatelyru   db_cluster_identifierrt   r{   db_instance_identifierrz   r   r   r   r   r   zI hasn't been added to the list of accepted methods in module_utils/rds.py)rT   r   r   r    r   
check_mode)rl   rm   updated_identifierr   r    
identifiers         rH   get_final_identifierr      s     ))*=>'V<EEH9]]#:;
#]]+FG	Z	]]#;<
#]]+GH	(	(]]#;<
	'	']]#CD
!k]"kl
 	
 !38I'
rG   	exception
parametersc                    t        |t              s| j                  |d| d|        d}|j                  d   d   }|dv rd|dk(  r_d	t	        |      v rd
}|S dt	        |      v r| j                  |d       |S | j                  |dt        ||       j                          |S |dk(  rB|dk(  r=dt	        |      v rd
}|S | j                  |dt        ||       j                          |S |dk(  rB|dk(  r=dt	        |      v rd
}|S | j                  |dt        ||       j                          |S |dk(  rr|dk(  rmg d}|j                  d      |vr*| j                  |d|j                  d       d|        |S | j                  |dt        ||       j                          |S | j                  |dt        ||       j                          |S )a}  
    Fails the module with an appropriate error message given the provided exception.

        Parameters:
            module: AnsibleAWSModule
            exception: Botocore exception to be handled
            method_name (str): Name of boto3 rds client method
            parameters (dict): Parameters provided to boto3 client method

        Returns:
            changed (bool): False if provided exception indicates that no modifications were requested or a read replica promotion was attempted on an
                instance/cluseter that is not a read replica; should never return True (the module should always fail instead)
    zUnexpected failure for method z with parameters msgTErrorCode)r3   r&   InvalidParameterCombinationzNo modifications were requestedFzModifyDbCluster APIzlIt appears you are trying to modify attributes that are managed at the cluster level. Please see rds_clusterz
Unable to r5   r   z!DB Instance is not a read replicar+   InvalidDBClusterStateFaultz%DB Cluster that is not a read replicar"   InvalidParameterValue)aurorazaurora-mysqlzaurora-postgresqlmysqlpostgresEnginez
DB engine z should be one of )
isinstancer   fail_json_awsresponser   r   r   r   )rm   r   rl   r   changed
error_codeaccepted_enginess          rH   handle_errorsr     s    i-Y.L[MYjkujv,wxG##G,V4JAAjTqFq,	0BBGX NW #gi&88   C ! T NK    !9+v!N!d!d ef ! J NC 
.	.:AY3Y.')2DDG> N;    !9+v!N!d!d ef ! : N3 
9	9jLh>h2gi6HHG. N+    !9+v!N!d!d ef ! * N# 
+	+
>U0U_>>(#+;;  JNN8,D+EEWXhWij !  N    !9+v!N!d!d ef !  N 	5k6J``ab 	 	

 NrG   c                 z   i }d}|j                   s~|j                  j                  d      }t        ||      j                  }t        | |      }	   t        j                  |      |      di |}|r|rt        ||      }
t        | ||
|       ||fS # t        t        f$ r}	t        ||	||      }Y d}	~	Dd}	~	ww xY w)a7  Calls the provided boto3 rds client method with the provided parameters.

    Handles check mode determination, whether or not to wait for resource status, and method-specific retry codes.

        Parameters:
            client: boto3 rds client
            module: Ansible AWS module
            method_name (str): Name of the boto3 rds client method to call
            parameters (dict): Parameters to pass to the boto3 client method; these must already match expected parameters for the method and
                be formatted correctly (CamelCase, Tags and other attributes converted to lists of dicts as needed)

        Returns:
            tuple (any, bool):
                result (any): Result value from method call
                changed (bool): True if changes were made to the resource, False otherwise
    Tr   )catch_extra_error_codesNrF   )r   rT   r   r   r!   getattrr   jittered_backoffr
   r   r   r   wait_for_status)r^   rm   rl   r   resultr   r   r!   methoder   s              rH   call_methodr   I  s    " FG}}  (.{FCOO-	H[SX..{STZ[i^hiF G-k6BJFFJD7? {+ 	H#FA{JGG	Hs   "B B:"B55B:db_instance_idwaiter_nameNc           	         d }ddd}|j                  |d      }t        dd      D ]  }	  || ||        y y# t        $ ra}|j                  j                  di       j                  d	      d
k(  rt	        d       Y d}~Y|j                  |d| d|        Y d}~wd}~wt        t        f$ r#}|j                  |d| d|        Y d}~d}~ww xY w)a  
    Waits until provided instance has reached the expected status for provided waiter.

    Fails the module if an exception is raised while waiting.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            db_instance_id (str): DB instance identifier
            waiter_name (str): Name of either a boto3 rds client waiter or an RDS waiter defined in module_utils/waiters.py
    c                     	 | j                  |      }|j                  ddd|       y # t        $ r t        | |      }Y .w xY w)N<   )DelayMaxAttempts)WaiterConfigDBInstanceIdentifier)r   
ValueErrorr   )r^   r   r   r   s       rH   r   z&wait_for_instance_status.<locals>.waitx  sL    	5&&{3F 	2b!AXfg  	54F	5s   * AAdeletedstopped)r|   r}   	availabler   
   r   r   rL   Nz$Error while waiting for DB instance z to be r   z/Unexpected error while waiting for DB instance )r   ranger   last_responser   r   r
   r   )	r^   rm   r   r   r   waiter_expected_statusexpected_status_wait_attemptsr   s	            rH   wait_for_instance_statusr   k  s    h  )( -00kJO2, 	5  	y""7B/33F;?SSb	  *N~N^^efuev(w xx{+ 	  HHXX_`o_pq !  	s'   
9	C9B BC0CCdb_cluster_idc                    	 t        | |      j                  |       y# t        $ r/}|dk(  rd| d}nd| d}|j                  ||       Y d}~yd}~wt        t
        f$ r }|j                  |d|        Y d}~yd}~ww xY w)	a  
    Waits until provided cluster has reached the expected status for provided waiter.

    Fails the module if an exception is raised while waiting.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            db_cluster_id (str): DB cluster identifier
            waiter_name (str): Name of either a boto3 rds client waiter or an RDS waiter defined in module_utils/waiters.py
    )DBClusterIdentifierrv   zFailed to wait for DB cluster  to be deleted to be availabler   NzAFailed with an unexpected error while waiting for the DB cluster r   r   r   r   r
   r   )r^   rm   r   r   r   r   s         rH   wait_for_cluster_statusr     s    	y6;',,,O )++2=/PC2=/AQRCQC((;' yQ&ghugv$wxxys     	B%AB$A??Bdb_snapshot_idc                    	 | j                  |      j                  |       y# t        $ r/}|dk(  rd| d}nd| d}|j                  ||       Y d}~yd}~wt        t
        f$ r }|j                  |d|        Y d}~yd}~ww xY w)	a  
    Waits until provided instance snapshot has reached the expected status for provided waiter.

    Fails the module if an exception is raised while waiting.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            db_snapshot_id (str): DB instance snapshot identifier
            waiter_name (str): Name of a boto3 rds client waiter
    DBSnapshotIdentifierr   zFailed to wait for DB snapshot r   r   r   NzBFailed with an unexpected error while waiting for the DB snapshot r   r^   rm   r   r   r   r   s         rH   !wait_for_instance_snapshot_statusr     s    
+&+++P )//3N3C>RC3N3CCSTCQC((;' 
WXfWgh 	 	
 	

    !$ 	B	%AB	)BB	c                    	 | j                  |      j                  |       y# t        $ r/}|dk(  rd| d}nd| d}|j                  ||       Y d}~yd}~wt        t
        f$ r }|j                  |d|        Y d}~yd}~ww xY w)	a  
    Waits until provided cluster snapshot has reached the expected status for provided waiter.

    Fails the module if an exception is raised while waiting.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            db_snapshot_id (str): DB cluster snapshot identifier
            waiter_name (str): Name of a boto3 rds client waiter
    DBClusterSnapshotIdentifierr   z'Failed to wait for DB cluster snapshot r   r   r   NzJFailed with an unexpected error while waiting for the DB cluster snapshot r   r   s         rH    wait_for_cluster_snapshot_statusr     s    
+&+++W )77;N;K>ZC;N;KK[\CQC((;' 
\]k\lm 	 	
 	

r   r   c                     t        ||      }|j                  }|j                  }|dk(  rt        | |||       y|dk(  rt	        | |||       y|dk(  rt        | |||       y|dk(  rt        | |||       yy)aP  
    Waits until provided resource has reached the expected final status for provided method.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            identifier (str): resource identifier
            method_name (str): Name of boto3 rds client method on whose final status to wait
    ru   r{   r   r   N)r   r   r    r   r   r   r   )r^   rm   r   rl   rds_method_attributesr   r    s          rH   r   r     s     5[&I'..K$--H9
KH	Z	 [I	(	()&&*kR	'	'([Q 
(rG   snapshot_identifiersnapshot_typeconvert_tagsc                     d}||vrt        d|       i }|dk(  rt        | |      }n|dk(  rt        | |      }r|d   }|r |rt        |j	                  dd	            |d
<   |S )a  
    Returns instance or cluster snapshot attributes given the snapshot identifier.

        Parameters:
            client: boto3 rds client
            snapshot_identifier (str): Unique snapshot identifier
            snapshot_type (str): Which type of snapshot to get, one of: cluster, instance
            convert_tags (bool): Whether to convert the snapshot tags from boto3 list of dicts to Ansible dict; defaults to True

        Returns:
            snapshot (dict): Snapshot attributes. If snapshot with provided id is not found, returns an empty dict

        Raises:
            ValueError if an invalid snapshot_type is passed
    )ru   r{   z(Invalid snapshot_type. Expected one of: ru   r   r{   r   r   rk   NTags)r   rW   re   r   pop)r^   r   r   r   valid_typessnapshot	snapshotss          rH   get_snapshotr     s      *KK'CK=QRRH	!1&Vij		*	$)&GZ[	Q<L9(,,yRV:WXOrG   c                     	 t        | |      }t        |      S # t        $ r*}|j                  |d|        Y d}~t              S d}~ww xY w)a  
    Returns tags for provided RDS resource, formatted as an Ansible dict.

    Fails the module if an error is raised while retrieving resource tags.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            resource_arn (str): AWS resource ARN

        Returns:
            tags (dict): Tags for resource, formatted as an Ansible dict. An empty list is returned if the resource has no tags.
    z!Unable to list tags for resource r   N)r*   rB   r   r   )r^   rm   rg   tagsr   s        rH   get_tagsr     s^    X%fl; *$//  XQ&G~$VWW)$//Xs    	AAAoptions_dictc                 2   | j                  d      }d}d| v rd}| j                  d      }t        | d      }d}t        |j                               D ]5  }|D ].  \  }}||v s|j                  |      ||j	                  ||      <   0 7 ||d<   |r|d<   |S )	a  
    Converts snake_cased rds module options to CamelCased parameter formats expected by boto3 rds client.

    Does not alter case for keys or values in the following attributes: tags, processor_features.
    Includes special handling of certain boto3 params that do not follow standard CamelCase.

        Parameters:
            options_dict (dict): Snake-cased options for a boto3 rds client method

        Returns:
            camel_options (dct): Options formatted for boto3 rds client
    r   Fprocessor_featuresT)capitalize_first))Dbrs   )IamIAM)AzAZ)CaCA)PerformanceInsightsKmsKeyIdPerformanceInsightsKMSKeyIdr   ProcessorFeatures)r   r   listkeysr   )	r   r   has_processor_featuresr   camel_optionsaws_replace_keyskeyoldnews	            rH   arg_spec_to_rds_paramsr
  1  s     F#D"|+!%)--.BC,\DQM M&&() N( 	NHCcz7D7H7H7Mckk#s34	NN !M&-?)*rG   format_tagsc                 N   t        | |d      }t        fd|D              r.t        ||      j                  }|j	                  d| d|        t        | |      t        fdj                         D              |r"j                  d      rt        d         d<   S )	a  
    Returns a dict of parameters validated and formatted for the provided boto3 client method.

    Performs the following parameters checks and updates:
        - Converts parameters supplied as snake_cased module options to CamelCase
        - Ensures that all required parameters for the provided method are present
        - Ensures that only parameters allowed for the provided method are present, removing any that are not relevant
        - Removes parameters with None values
        - If format_tags is True, converts "Tags" param from an Ansible dict to boto3 list of dicts

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            parameters (dict): Parameter options as provided to module
            method_name (str): boto3 client method for which to validate parameters
            format_tags (bool): Whether to convert tags from an Ansible dict to boto3 list of dicts

        Returns:
            Dict of client parameters formatted for the provided method

        Raises:
            Fails the module if any parameters required by the provided method are not provided in module options
    T)requiredc              3   D   K   | ]  }j                  |      d u   y wN)r   ).0kr   s     rH   	<genexpr>z6format_rds_client_method_parameters.<locals>.<genexpr>p  s     
?:>>!$
?s    zTo z requires the parameters: r   c              3   <   K   | ]  \  }}|v s|||f  y wr  rF   )r  r  voptionss      rH   r  z6format_rds_client_method_parameters.<locals>.<genexpr>t  s%     ^AqG|PQP]q!f^s   	r   )	r   anyr   r   	fail_jsondictitemsr   r   )r^   rm   r   rl   r  required_optionsmethod_descriptionr  s     `    @rH   #format_rds_client_method_parametersr  U  s    4 :&+X\]

?.>
??5k6J``s#5"66PQaPbcd0EG^)9)9);^^Jz~~f-;Jv<NO
6rG   existing_tagsr   
purge_tagsc           	          |yt        |||      \  }}t        |xs |      }|rt        | |d|t        |      d       |rt        | |d||d       |S )a  
    Compares current resource tages to desired tags and adds/removes tags to ensure desired tags are present.

    A value of None for desired tags results in resource tags being left as is.

        Parameters:
            client: boto3 rds client
            module: AnsibleAWSModule
            resource_arn (str): AWS resource ARN
            existing_tags (dict): Current resource tags formatted as an Ansible dict
            tags (dict): Desired resource tags formatted as an Ansible dict
            purge_tags (bool): Whether to remove any existing resource tags not present in desired tags

        Returns:
            True if resource tags are updated, False if not.
    Fr(   )rj   r   rl   r   r)   )rj   TagKeys)r   boolr   r   )	r^   rm   rg   r  r   r  tags_to_addtags_to_remover   s	            rH   ensure_tagsr%  {  sv    0 |"2=$
"SK;0.1G.(4>\]h>ij		
 3(4P		
 NrG   existing_rolestarget_rolespurge_rolesc                     | D cg c]"  }t        d |j                         D              $ } }|D cg c]	  }|| vs| }}|r| D cg c]	  }||vs| c}ng }||fS c c}w c c}w c c}w )a  
    Returns differences between target and existing IAM roles.

        Parameters:
            existing_roles (list): Existing IAM roles as a list of snake-cased dicts
            target_roles (list): Target IAM roles as a list of snake-cased dicts
            purge_roles (bool): Remove roles not in target_roles if True

        Returns:
            roles_to_add (list): List of IAM roles to add
            roles_to_delete (list): List of IAM roles to delete
    c              3   6   K   | ]  \  }}|d k7  s||f  yw)statusNrF   )r  r  r  s      rH   r  z$compare_iam_roles.<locals>.<genexpr>  s     Ldaa8mAq6Ls   	)r  r  )r&  r'  r(  roleroles_to_addroles_to_removes         rH   compare_iam_rolesr/    sx     ZhhQUdLdjjlLLhNh%1PTT5ODPLPWbS$l:RtShjO(( iPSs   'A	A$A$	A)A)instance_idr-  r.  c                     |D ]   }||d   |d   d}t        | |d|      \  }}" |D ]   }||d   |d   d}t        | |d|      \  }}" S )a  
    Update a DB instance's associated IAM roles

        Parameters:
            client: RDS client
            module: AnsibleAWSModule
            instance_id (str): DB's instance ID
            roles_to_add (list): List of IAM roles to add in snake-cased dict format
            roles_to_delete (list): List of IAM roles to delete in snake-cased dict format

        Returns:
            changed (bool): True if changes were successfully made to DB instance's IAM roles; False if not
    role_arnfeature_name)r   RoleArnFeatureNamer:   r   r9   )r   )	r^   rm   r0  r-  r.  r,  rT   _resultr   s	            rH   update_iam_rolesr7    s    (   v*5$zBRcghvcwx&vvCantuv  q*5$zBRcghvcwx&vvC\iopq NrG   
connection
group_namec                     g }	 i }|||d<   |j                  d      } |j                  di |j                         d   }|S # t        d      $ r Y |S t        $ r}| j                  |d       Y d }~|S d }~ww xY w)NDBClusterParameterGroupName$describe_db_cluster_parameter_groupsDBClusterParameterGroupsDBParameterGroupNotFoundz,Couldn't access parameter groups informationr   rF   rZ   r[   r\   r   r   r   )rm   r8  r9  r   rT   r_   r   s          rH   r<  r<    s     F	T!4>F01,,-ST	###-f-??AB\]
 M	 9:  M  TQ$RSSMTs   =A A:A:A55A:db_parameter_group_namec                 t   	 |r| j                  |      d   }n| j                         d   }|D ](  }| j                  |d         d   }t        |      |d<   * |r|D cg c]  }t        |dg       c}S g S c c}w # t	        d      $ r g cY S t
        $ r}|j                  |d	
       Y d }~S d }~ww xY w)N)DBParameterGroupNameDBParameterGroupsDBParameterGroupArnri   rk   r   )ignore_listr>  z+Couldn't access parameter group informationr   )describe_db_parameter_groupsr*   r   r   r   r   r   )r8  rm   r@  r   parameter_groupr  groupr   s           rH   %describe_db_instance_parameter_groupsrI    s    S"<<Ri<j#F  <<>?RSF  & 	TO&==?[pKq=rM 'E]&SOF#		T _eSYZ%(VHEZljllZ9: 	 SQ$QRRMSs6   AA?  A:5A? 8A? :A? ?B7B7B22B7sourcec                    g }	 |j                  d      }d|i}|dk7  r||d<    |j                  d	i |j                         d   }|S # t        d      $ r Y |S t        $ r}| j                  |d       Y d }~|S d }~ww xY w)
Ndescribe_db_cluster_parametersr;  allSource
Parametersr>  z2Couldn't access RDS cluster parameters informationr   rF   r?  )rm   r8  r9  rJ  r   r_   rT   r   s           rH   rL  rL    s     F	Z,,-MN	/<U?%F8###-f-??A,O
 M	 9:  M  ZQ$XYYMZs   AA A?A?!A::A?)Tr  )rM  )Hcollectionsr   timer   typingr   r   r   r   r	   botocore.exceptionsr
   r   r   ImportErroransible.module_utils._textr   0ansible.module_utils.common.dict_transformationsr   r   <ansible_collections.amazon.aws.plugins.module_utils.botocorer   r   8ansible_collections.amazon.aws.plugins.module_utils.corer   :ansible_collections.amazon.aws.plugins.module_utils.errorsr   >ansible_collections.amazon.aws.plugins.module_utils.exceptionsr   ;ansible_collections.amazon.aws.plugins.module_utils.retriesr   ;ansible_collections.amazon.aws.plugins.module_utils.taggingr   r   r   ;ansible_collections.amazon.aws.plugins.module_utils.waitersr   r   r   r   r   r   rB   rJ   list_error_handlerr   strrW   ra   re   r*   r   r   r"  r   r   r   r   r   r   r   r   r   r
  r  r%  r/  r7  r<  r  rI  rL  rF   rG   rH   <module>r`     s   #      	1// / U U k \ U V Z P f f X R_   &! " 	o 	
o 
 ##$CRHRD RT$sCx.=Q R  IR
 ##$;R@KD KT$sCx.5I K  AK
 ##$;R@KD KT$Z K  AK
 ##$<bAO Od38n9M O  BOX# X7G XL] Xv"c "3C " "JA* As A AZ^_bdg_gZh Amq AH 0 s PTUXZ]U]P^ chilnrircs D'-= 's 'ad 'im 'Ty,< yS y_b ygk y0
6F 
X[ 
jm 
rv 
4
5E 
WZ 
il 
qu 
6R$4 R# RTW R\` R0c # UY eijmorjres D0- 0S 0T#s(^ 0*!c3h !DcN !H#$#26sCx.#OR#ae#	#s(^#L** * S>	*
 4S>
"* * 
*Z)c3h()8<T#s(^8L)[_)
4S#Xd38n!556)*  tCH~&	
 $sCx.) 
: *-;CC=	$sCx. " NR-HK	$Z 4 NS*-;>HK	$sCx. m  		s   M	 	MM