
    Vh^                        d Z dZd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 dd	lmZ dd
lmZ ddlmZ ddlmZ d Zd Z ej,                         d        Z ej,                         d        Z ej,                  dg      d        Z ej,                  dg      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)a  
---
author:
  - "Jens Carl (@j-carl), Hothead Games Inc."
  - "Rafael Driutti (@rafaeldriutti)"
module: redshift
version_added: 1.0.0
short_description: create, delete, or modify an Amazon Redshift instance
description:
  - Creates, deletes, or modifies Amazon Redshift cluster instances.
options:
  command:
    description:
      - Specifies the action to take.
    required: true
    choices: [ 'create', 'facts', 'delete', 'modify' ]
    type: str
  identifier:
    description:
      - Redshift cluster identifier.
    required: true
    type: str
  node_type:
    description:
      - The node type of the cluster.
      - Require when I(command=create).
    choices: ['ds1.xlarge', 'ds1.8xlarge', 'ds2.xlarge', 'ds2.8xlarge', 'dc1.large','dc2.large',
              'dc1.8xlarge', 'dw1.xlarge', 'dw1.8xlarge', 'dw2.large', 'dw2.8xlarge']
    type: str
  username:
    description:
      - Master database username.
      - Used only when I(command=create).
    type: str
  password:
    description:
      - Master database password.
      - Used only when I(command=create).
    type: str
  cluster_type:
    description:
      - The type of cluster.
    choices: ['multi-node', 'single-node' ]
    default: 'single-node'
    type: str
  db_name:
    description:
      - Name of the database.
    type: str
  availability_zone:
    description:
      - Availability zone in which to launch cluster.
    aliases: ['zone', 'aws_zone']
    type: str
  number_of_nodes:
    description:
      - Number of nodes.
      - Only used when I(cluster_type=multi-node).
    type: int
  cluster_subnet_group_name:
    description:
      - Which subnet to place the cluster.
    aliases: ['subnet']
    type: str
  cluster_security_groups:
    description:
      - In which security group the cluster belongs.
    type: list
    elements: str
    aliases: ['security_groups']
  vpc_security_group_ids:
    description:
      - VPC security group
    aliases: ['vpc_security_groups']
    type: list
    elements: str
  skip_final_cluster_snapshot:
    description:
      - Skip a final snapshot before deleting the cluster.
      - Used only when I(command=delete).
    aliases: ['skip_final_snapshot']
    default: false
    type: bool
  final_cluster_snapshot_identifier:
    description:
      - Identifier of the final snapshot to be created before deleting the cluster.
      - If this parameter is provided, I(skip_final_cluster_snapshot) must be C(false).
      - Used only when I(command=delete).
    aliases: ['final_snapshot_id']
    type: str
  preferred_maintenance_window:
    description:
      - 'Maintenance window in format of C(ddd:hh24:mi-ddd:hh24:mi).  (Example: C(Mon:22:00-Mon:23:15))'
      - Times are specified in UTC.
      - If not specified then a random 30 minute maintenance window is assigned.
    aliases: ['maintance_window', 'maint_window']
    type: str
  cluster_parameter_group_name:
    description:
      - Name of the cluster parameter group.
    aliases: ['param_group_name']
    type: str
  automated_snapshot_retention_period:
    description:
      - The number of days that automated snapshots are retained.
    aliases: ['retention_period']
    type: int
  port:
    description:
      - Which port the cluster is listening on.
    type: int
  cluster_version:
    description:
      - Which version the cluster should have.
    aliases: ['version']
    choices: ['1.0']
    type: str
  allow_version_upgrade:
    description:
      - When I(allow_version_upgrade=true) the cluster may be automatically
        upgraded during the maintenance window.
    aliases: ['version_upgrade']
    default: true
    type: bool
  publicly_accessible:
    description:
      - If the cluster is accessible publicly or not.
    default: false
    type: bool
  encrypted:
    description:
      - If the cluster is encrypted or not.
    default: false
    type: bool
  elastic_ip:
    description:
      - An Elastic IP to use for the cluster.
    type: str
  new_cluster_identifier:
    description:
      - Only used when command=modify.
    aliases: ['new_identifier']
    type: str
  wait:
    description:
      - When I(command=create), I(command=modify) or I(command=restore) then wait for the database to enter the 'available' state.
      - When I(command=delete) wait for the database to be terminated.
    type: bool
    default: false
  wait_timeout:
    description:
      - When I(wait=true) defines how long in seconds before giving up.
    default: 300
    type: int
  enhanced_vpc_routing:
    description:
      - Whether the cluster should have enhanced VPC routing enabled.
    default: false
    type: bool
notes:
  - Support for I(tags) and I(purge_tags) was added in release 1.3.0.
extends_documentation_fragment:
  - amazon.aws.common.modules
  - amazon.aws.region.modules
  - amazon.aws.tags
  - amazon.aws.boto3
ab  
- name: Basic cluster provisioning example
  community.aws.redshift:
    command: create
    node_type: ds1.xlarge
    identifier: new_cluster
    username: cluster_admin
    password: 1nsecure

- name: Cluster delete example
  community.aws.redshift:
    command: delete
    identifier: new_cluster
    skip_final_cluster_snapshot: true
    wait: true
a  
cluster:
    description: dictionary containing all the cluster information
    returned: success
    type: complex
    contains:
        identifier:
            description: Id of the cluster.
            returned: success
            type: str
            sample: "new_redshift_cluster"
        create_time:
            description: Time of the cluster creation as timestamp.
            returned: success
            type: float
            sample: 1430158536.308
        status:
            description: Status of the cluster.
            returned: success
            type: str
            sample: "available"
        db_name:
            description: Name of the database.
            returned: success
            type: str
            sample: "new_db_name"
        availability_zone:
            description: Amazon availability zone where the cluster is located. "None" until cluster is available.
            returned: success
            type: str
            sample: "us-east-1b"
        maintenance_window:
            description: Time frame when maintenance/upgrade are done.
            returned: success
            type: str
            sample: "sun:09:30-sun:10:00"
        private_ip_address:
            description: Private IP address of the main node.
            returned: success
            type: str
            sample: "10.10.10.10"
        public_ip_address:
            description: Public IP address of the main node. "None" when enhanced_vpc_routing is enabled.
            returned: success
            type: str
            sample: "0.0.0.0"
        port:
            description: Port of the cluster. "None" until cluster is available.
            returned: success
            type: int
            sample: 5439
        url:
            description: FQDN of the main cluster node. "None" until cluster is available.
            returned: success
            type: str
            sample: "new-redshift_cluster.jfkdjfdkj.us-east-1.redshift.amazonaws.com"
        enhanced_vpc_routing:
            description: status of the enhanced vpc routing feature.
            returned: success
            type: bool
        tags:
            description: aws tags for cluster.
            returned: success
            type: dict
    N)snake_dict_to_camel_dict)is_boto3_error_code)get_aws_account_info)AWSRetry)ansible_dict_to_boto3_tag_listboto3_tag_list_to_ansible_dict)compare_aws_tags)AnsibleCommunityAWSModulec                    t        |      \  }}|j                  }d| d| d| d| }|j                  j                  d      }|j                  j                  d      }	t	        t        |      ||	      \  }
}|
r	 | j                  |t        |
             |r	 | j                  ||       t        |
xs |      }|S # t        j                  j                  t        j                  j                  f$ r}|j                  |d	       Y d
}~vd
}~ww xY w# t        j                  j                  t        j                  j                  f$ r}|j                  |d	       Y d
}~d
}~ww xY w)z!Compares and update resource tagszarn:z
:redshift::z	:cluster:tags
purge_tags)ResourceNameTagszFailed to add tags to clustermsgN)r   TagKeysz Failed to delete tags on cluster)r   regionparamsgetr
   r	   create_tagsr   botocore
exceptionsBotoCoreErrorClientErrorfail_json_awsdelete_tagsbool)redshift
identifierexisting_tagsmodule
account_id	partitionr   resource_arnr   r   tags_to_addtags_to_removeechangeds                 j/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/aws/plugins/modules/redshift.py_ensure_tagsr,     sd    18J	]]F)Jvha
|9ZLYL==V$D""<0J"23QR_3`bfhr"sK	I  lA_`kAl m 	L  lN S ;0.1GN ##1183F3F3R3RS 	I  (G HH	I ##1183F3F3R3RS 	L  (J KK	Ls0   ;B> D >7D5DD7E)E$$E)c                 L   | d   | d   | d   | d   | d   | d   d}| d   D ](  }|d	   d
v s|d   |d<   |d   du r	|d   |d<   nd|d<    n d|d<   d|d<   d|d<   d|d<   i |d<   | d   dk7  r7| d   |d<   | d   d   |d<   | d   d   |d<   | d   |d<   t        | d         |d<   |S )z&Transform cluster information to dict.ClusterIdentifierClusterStatusMasterUsernameDBNamePreferredMaintenanceWindowEnhancedVpcRouting)r!   statususernamedb_namemaintenance_windowenhanced_vpc_routingClusterNodesNodeRole)SHAREDLEADERPrivateIPAddressprivate_ip_addressr8   FPublicIPAddresspublic_ip_addressNcreate_timeurlportavailability_zoner   creatingClusterCreateTimeEndpointAddressPortAvailabilityZoner   r   )resourcefactsnodes      r+   _collect_factsrN   .  s?    23?+-.H%&'CD ()= >E ( 
33*./A*BE&'+,5-12C-D)*-1)*  E-E%LE&M!%E
E&M J.'(;<m
+I6e ,V4f%-.@%A!"6x7GHfL    c                 2    | j                  |      d   d   S )zE
    Basic wrapper around describe_clusters with a retry applied
    r.   Clustersr   )describe_clusters)r    r!   s     r+   _describe_clusterrT   T  s#    
 %%
%CJOPQRRrO   c                 &     | j                   di |S )zB
    Basic wrapper around create_cluster with a retry applied
     )create_clusterr    kwargss     r+   _create_clusterrZ   \  s    
 #8"",V,,rO   InvalidClusterState)catch_extra_error_codesc                 &     | j                   di |S )z
    Basic wrapper around delete_cluster with a retry applied.
    Explicitly catches 'InvalidClusterState' (~ Operation in progress) so that
    we can still delete a cluster if some kind of change operation was in
    progress.
    rV   )delete_clusterrX   s     r+   _delete_clusterr_   f  s     #8"",V,,rO   c                 &     | j                   di |S )z
    Basic wrapper around modify_cluster with a retry applied.
    Explicitly catches 'InvalidClusterState' (~ Operation in progress) for cases
    where another modification is still in progress
    rV   )modify_clusterrX   s     r+   _modify_clusterrb   q  s     #8"",V,,rO   c           	         | j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }	d	}
i }d
D ]<  }| j                   j                  |      | j                   j                  |      ||<   > |r||d<   |	rt        |	      }	|	|d<   	 t        ||       d}
|r4|dz  }|j                  d      }	 |j                  |t        |             	 t        ||      }|	rt        ||d   |       rd	}
t        ||      }|
t!              fS # t	        d      $ rx 	 t        |f||||dt        |d	       nW# t        j                  j                  t        j                  j                  f$ r}| j                  |d       Y d}~nd}~ww xY wY t        j                  j                  t        j                  j                  f$ r}| j                  |d       Y d}~Ed}~ww xY w# t        j                  j                  t        j                  j                  f$ r}| j                  |d       Y d}~gd}~ww xY w# t        j                  j                  t        j                  j                  f$ r}| j                  |d       Y d}~d}~ww xY w)z
    Create a new cluster

    module: AnsibleAWSModule object
    redshift: authenticated redshift connection object

    Returns:
    r!   	node_typer5   passwordr6   waitwait_timeoutr   T)cluster_typecluster_security_groupsvpc_security_group_idscluster_subnet_group_namerD   preferred_maintenance_windowcluster_parameter_group_name#automated_snapshot_retention_periodrC   cluster_versionallow_version_upgradenumber_of_nodespublicly_accessible	encrypted
elastic_ipr8   Nd_b_nameFClusterNotFound)r.   NodeTyper0   MasterUserPasswordcapitalize_firstzFailed to create clusterr   zFailed to describe cluster<   cluster_availableMaxAttemptsr.   WaiterConfigz(Timeout waiting for the cluster creationr   )r   r   r   rT   r   rZ   r   r   r   r   r   r   
get_waiterrf   dictr,   rN   )r#   r    r!   rd   r5   re   ru   rf   rg   r   r*   r   pr)   attemptswaiterrK   s                    r+   rW   rW   {  s    ""<0J!!+.I}}  ,H}}  ,H}}  +H==V$D==$$^4L==V$DGF -& ==Q+))!,F1I)-, %z-d3vB(J/$ 2%$$%89	TKK*4T\C]K^B$Xz: *hv.>GG(:>HN8,,,E 01 D
	D","'#+ +6DI ##1183F3F3R3RS 	D  (B CC	D 	))'' B 	Q$@AA	B ##//1D1D1R1RS 	T  (R SS	T --x/B/B/N/NO BQ$@AABsx   8F7 J =K+ 7JG#"J#7H7H2-J2H77J<6J2JJ7K(
K##K(+7M "L;;M c                    | j                   j                  d      }	 t        ||      }dt              fS # t        j                  j
                  t        j                  j                  f$ r}| j                  |d       Y d}~\d}~ww xY w)z
    Collect data about the cluster.

    module: Ansible module object
    redshift: authenticated redshift connection object
    r!   zError describing clusterr   NT)	r   r   rT   r   r   r   r   r   rN   )r#   r    r!   rK   r)   s        r+   describe_clusterr     s     ""<0J@$Xz: ))) --x/B/B/N/NO @Q$>??@s   6 7B
-BB
c                    | j                   j                  d      }| j                   j                  d      }| j                   j                  d      }i }dD ]K  }|| j                   v s| j                   j                  |      .| j                   j                  |      ||<   M 	 t        |fd|it        |d       |r8|dz  }|j                  d      }		 |	j                  |t        |             di fS di fS # t	        d	      $ r d
i fcY S t
        j                  j                  t
        j                  j                  f$ r}| j                  |d       Y d}~d}~ww xY w# t
        j                  j                  t
        j                  j                  f$ r }| j                  |d       Y d}~di fS d}~ww xY w)zu
    Delete a cluster.

    module: Ansible module object
    redshift: authenticated redshift connection object
    r!   rf   rg   )skip_final_cluster_snapshot!final_cluster_snapshot_identifierNr.   Try   rv   FzFailed to delete clusterr   r{   cluster_deletedr}   r   zTimeout deleting the cluster)r   r   r_   r   r   r   r   r   r   r   r   rf   r   )
r#   r    r!   rf   rg   r   r   r)   r   r   s
             r+   r^   r^     s    ""<0J==V$D==$$^4LFQ 1}}  #/"MM--a0q		1
@	
(2	
6Nvhl6m	
 2%$$%67	HKK*4T\C]K^ 8O48O! 01 by'')) @ 	Q$>??	@ ##//1D1D1R1RS 	H  (F GG8O	Hs6   %C< E& <E#6E#EE#&7F=F88F=c                 6   | j                   j                  d      }| j                   j                  d      }| j                   j                  d      }i }dD ]<  }| j                   j                  |      | j                   j                  |      ||<   > | j                   j                  d      (	 t        ||| j                   j                  d             |r4|dz  }|j                  d      }		 |	j                  |t        |             	 t        |fd|it        |d       | j                   j                  d      r| j                   j                  d      }|r4|dz  }|j                  d      }
	 |
j                  |t        |             	 t        ||      }t        ||d   |       r|j                  |      d   d   }dt        |      fS # t        j                  j
                  t        j                  j                  f$ r"}| j                  |d| d	
       Y d}~Sd}~ww xY w# t        j                  j                  t        j                  j
                  f$ r}| j                  |d
       Y d}~ud}~ww xY w# 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
       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)z
    Modify an existing cluster.

    module: Ansible module object
    redshift: authenticated redshift connection object
    r!   rf   rg   )rh   ri   rj   rk   rD   rl   rm   rn   rC   ro   rp   rq   new_cluster_identifierNr8   )r.   r3   z!Couldn't modify redshift cluster  r   r{   r|   r}   r   z=Timeout waiting for cluster enhanced vpc routing modificationr.   Try   r   z(Timeout waiting for cluster modificationr   rQ   rR   r   )r   r   rb   r   r   r   r   r   r   rf   r   r   rT   r,   rS   rN   )r#   r    r!   rf   rg   r   r   r)   r   r   waiter2rK   s               r+   ra   ra     se    ""<0J==V$D==$$^4L F -  ==Q+))!,F1I#-( }}/0<	[J6==K\K\]sKt
 2%$$%89	iKK*4T\C]K^
W	
(2	
6Nvhl6m	
 }}12]]&&'?@
2%%%&9:	TLL:DU]D^L_W$Xz: Hj(6*:FC--
-KJWXYZ)))I ##1183F3F3R3RS 	[  *KJ<WX(Y ZZ	[ ##//1D1D1R1RS 	i  (g hh	i --x/B/B/N/NO WQ&G
|ST$UVVW ##//1D1D1R1RS 	T  (R SS	T --x/B/B/N/NO WQ&G
|ST$UVVWsx   1'G 1H3 J 7K' L? 7H0H++H037J*JJ7K$KK$'7L<L77L<?7N6NNc            
      b   t        dQi dt        g dd      dt        d      dt        g dd	      d
t        d	      dt        dd	      dt        d	      dt        ddgd      dt        dgdd      dt        dgdd      dt        dgdd	      dt        dgd	      d t        d!g"      d#t        d$d%g"      d&t        d'd(g"      d)t        d*g"      d+t        d,gd-.      d/t        d-0      d1t        d2gd3g4      d5t        d6gdd      d7t        d-0      d8t        dd	9      d:t        dd	9      d;t        d	      d<t        d=g"      d>t        dd	9      d?t        dd	9      d@t        d-dA9      dBt        dCdDgE      dFt        dd9      } ddGdgfddHg dIfg}t        | |J      }|j                  j                  d      }|j                  j                  d      }|j                  j                  d      }|dGk(  r|d	u r||j	                  dKL       |j                  dM      }d}|dHk(  rt        ||      \  }}n>|dNk(  rt        ||      \  }}n)|dGk(  rt        ||      \  }}n|dOk(  rt        ||      \  }}|j                  |P       y )RNcommand)createrL   deletemodifyT)choicesrequiredr!   )r   rd   )z
ds1.xlargezds1.8xlargez
ds2.xlargezds2.8xlargez	dc1.largez	dc2.largezdc1.8xlargez
dw1.xlargezdw1.8xlargez	dw2.largezdw2.8xlargeFr5   re   )no_logr   r6   rh   z
multi-nodezsingle-node)r   defaultri   security_groupsliststr)aliasestypeelementsrj   vpc_security_groupsr   skip_final_snapshotr   )r   r   r   r   final_snapshot_id)r   r   rk   subnet)r   rD   aws_zonezonerl   maintance_windowmaint_windowrm   param_group_namern   retention_periodint)r   r   rC   )r   ro   versionz1.0)r   r   rp   version_upgraderq   rr   )r   r   rs   rt   r   new_identifierr8   rf   rg   i,  r   r   resource_tags)r   r   r   r   r   )rd   r5   re   )argument_specrequired_ifzYNeed to specify final_cluster_snapshot_identifier if skip_final_cluster_snapshot is Falser   r    rL   r   )r*   clusterrV   )r   AnsibleAWSModuler   r   	fail_jsonclientrW   r   r^   ra   	exit_json)	r   r   r#   r   r   r   connr*   r   s	            r+   mainr   ^  sx    -DtT-&-  
-& u%'-( TE2)-* e$+-, <"?W--. !%.?-@vX] ^/-0  $-B,C&[`a1-2 %)2G1Hv_d$e3-4 +/8K7LW\*]5-6 #'z":7-8 
F';<9-: &*3E~2V%W;-< &*3E2F%G=-> -1:L9MTY,Z?-@ uA-B i[5'BC-D #,=+>VUYZE-F %(G-H !fe<I-J FE2K-L 'M-N  $-=,>?O-P "vu=Q-R vu-S-T uc2U-V v'89W-X VT2Y-M` 
H<=>	HCDK
 #F
 mm	*G"(--"3"34Q"R(.(9(9:](^%(:eCHiHqk 	 	
 ==$DG(+FD9'	G	-fd;'	H	+FD9'	H	+FD9'
Wg6rO   __main__)!DOCUMENTATIONEXAMPLESRETURNr   ImportError0ansible.module_utils.common.dict_transformationsr   <ansible_collections.amazon.aws.plugins.module_utils.botocorer   7ansible_collections.amazon.aws.plugins.module_utils.iamr   ;ansible_collections.amazon.aws.plugins.module_utils.retriesr   ;ansible_collections.amazon.aws.plugins.module_utils.taggingr   r	   r
   >ansible_collections.community.aws.plugins.module_utils.modulesr   r   r,   rN   jittered_backoffrT   rZ   r_   rb   rW   r   r^   ra   r   __name__rV   rO   r+   <module>r      s!  fP"@
D	 V \ X P f f X x6#L S S - - 4I3JK- L- 4I3JK- L-W-t*"'TK*\R7j zF _  		s   C C	C	