
    VhQ              
          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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Zdedededeeef   fdZdededeeef   fdZ dededeeeeef         fd Z!d! Z"deddfd"Z#d# Z$dede%fd$Z&deddfd%Z'defd&Z(d' Z)e*d(k(  r e)        yy)*a  
---
module: ec2_snapshot
version_added: 1.0.0
short_description: Creates a snapshot from an existing volume
description:
    - Creates an EC2 snapshot from an existing EBS volume.
options:
  volume_id:
    description:
      - Volume from which to take the snapshot.
    required: false
    type: str
  description:
    description:
      - Description to be applied to the snapshot.
    required: false
    type: str
  instance_id:
    description:
      - Instance that has the required volume to snapshot mounted.
    required: false
    type: str
  device_name:
    description:
      - Device name of a mounted volume to be snapshotted.
    required: false
    type: str
  snapshot_tags:
    description:
      - A dictionary of tags to add to the snapshot.
      - If the volume has a V(Name) tag this will be automatically added to the
        snapshot.
    type: dict
    required: false
    default: {}
  wait:
    description:
      - Wait for the snapshot to be ready.
    type: bool
    required: false
    default: true
  wait_timeout:
    description:
      - How long before wait gives up, in seconds.
    required: false
    default: 600
    type: int
  state:
    description:
      - Whether to add or create a snapshot.
    required: false
    default: present
    choices: ['absent', 'present']
    type: str
  snapshot_id:
    description:
      - Snapshot id to remove.
    required: false
    type: str
  last_snapshot_min_age:
    description:
      - If the volume's most recent snapshot has started less than O(last_snapshot_min_age) minutes ago, a new snapshot will not be created.
    required: false
    default: 0
    type: int
  modify_create_vol_permission:
    description:
      - If set to V(true), ec2 snapshot's createVolumePermissions can be modified.
    required: false
    type: bool
    version_added: 6.1.0
  purge_create_vol_permission:
    description:
      - Whether unspecified group names or user IDs should be removed from the snapshot createVolumePermission.
      - Must set O(modify_create_vol_permission) to V(True) for when O(purge_create_vol_permission) is set to V(True).
    required: False
    type: bool
    default: False
    version_added: 6.1.0
  group_names:
    description:
      - The group to be added or removed. The possible value is V(all).
      - Mutually exclusive with O(user_ids).
    required: false
    type: list
    elements: str
    choices: ["all"]
    version_added: 6.1.0
  user_ids:
    description:
      - The account user IDs to be added or removed.
      - If createVolumePermission on snapshot is currently set to Public i.e. O(group_names=all),
        providing O(user_ids) will not make createVolumePermission Private unless O(modify_create_vol_permission) is set to V(true).
      - Mutually exclusive with O(group_names).
    required: false
    type: list
    elements: str
    version_added: 6.1.0
author: "Will Thames (@willthames)"
extends_documentation_fragment:
  - amazon.aws.common.modules
  - amazon.aws.region.modules
  - amazon.aws.boto3
ab  
# Simple snapshot of volume using volume_id
- amazon.aws.ec2_snapshot:
    volume_id: vol-abcdef12
    description: snapshot of /data from DB123 taken 2013/11/28 12:18:32

# Snapshot of volume mounted on device_name attached to instance_id
- amazon.aws.ec2_snapshot:
    instance_id: i-12345678
    device_name: /dev/sdb1
    description: snapshot of /data from DB123 taken 2013/11/28 12:18:32

# Snapshot of volume with tagging
- amazon.aws.ec2_snapshot:
    instance_id: i-12345678
    device_name: /dev/sdb1
    snapshot_tags:
      frequency: hourly
      source: /data

# Remove a snapshot
- amazon.aws.ec2_snapshot:
    snapshot_id: snap-abcd1234
    state: absent

# Create a snapshot only if the most recent one is older than 1 hour
- amazon.aws.ec2_snapshot:
    volume_id: vol-abcdef12
    last_snapshot_min_age: 60

- name: Reset snapshot createVolumePermission (change permission to "Private")
  amazon.aws.ec2_snapshot:
    snapshot_id: snap-06a6f641234567890
    modify_create_vol_permission: true
    purge_create_vol_permission: true

- name: Modify snapshot createVolmePermission to add user IDs (specify purge_create_vol_permission=true to change permssion to "Private")
  amazon.aws.ec2_snapshot:
    snapshot_id: snap-06a6f641234567890
    modify_create_vol_permission: true
    user_ids:
      - '123456789012'
      - '098765432109'

- name: Modify snapshot createVolmePermission - remove all except specified user_ids
  amazon.aws.ec2_snapshot:
    snapshot_id: snap-06a6f641234567890
    modify_create_vol_permission: true
    purge_create_vol_permission: true
    user_ids:
      - '123456789012'

- name: Replace (purge existing) snapshot createVolmePermission annd add user IDs
  amazon.aws.ec2_snapshot:
    snapshot_id: snap-06a6f641234567890
    modify_create_vol_permission: true
    purge_create_vol_permission: true
    user_ids:
      - '111111111111'

- name: Modify snapshot createVolmePermission - make createVolumePermission "Public"
  amazon.aws.ec2_snapshot:
    snapshot_id: snap-06a6f641234567890
    modify_create_vol_permission: true
    purge_create_vol_permission: true
    group_names:
      - all
a	  
snapshot_id:
    description: The ID of the snapshot. Each snapshot receives a unique identifier when it is created.
    type: str
    returned: always
    sample: snap-01234567
snapshots:
    description: List of snapshots.
    returned: always
    type: list
    elements: dict
    contains:
        description:
            description: Description specified by the CreateSnapshotRequest that has been applied to all snapshots.
            type: str
            returned: always
            sample: ""
        encrypted:
            description: Indicates whether the snapshot is encrypted.
            type: bool
            returned: always
            sample: false
        owner_id:
            description: Account id used when creating this snapshot.
            type: str
            returned: always
            sample: 123456
        progress:
            description: Progress this snapshot has made towards completing.
            type: str
            returned: always
            sample: ""
        snapshot_id:
            description: Snapshot id that can be used to describe this snapshot.
            type: str
            returned: always
            sample: snap-1234
        start_time:
            description: Time this snapshot was started. This is the same for all snapshots initiated by the same request.
            type: str
            returned: always
            sample: "2024-05-07T14:29:24.523000+00:00"
        state:
            description: Current state of the snapshot.
            type: str
            returned: always
            sample: pending
        tags:
            description: Tags associated with this snapshot.
            type: dict
            returned: always
            sample: "{ 'Name': 'instance-name' }"
        volume_id:
            description: The ID of the volume that was used to create the snapshot.
            type: str
            returned: always
            sample: vol-01234567
        volume_size:
            description: The size of the volume, in GiB.
            type: int
            returned: always
            sample: 8
tags:
    description: Any tags assigned to the snapshot.
    type: dict
    returned: always
    sample: "{ 'Name': 'instance-name' }"
volume_id:
    description: The ID of the volume that was used to create the snapshot.
    type: str
    returned: always
    sample: vol-01234567
volume_size:
    description: The size of the volume, in GiB.
    type: int
    returned: always
    sample: 8
    N)Any)Dict)List)Optional)camel_dict_to_snake_dict)AnsibleEC2Error)create_snapshot)delete_snapshot)describe_snapshot_attribute)describe_snapshots)describe_volumes)modify_snapshot_attribute)reset_snapshot_attribute)AnsibleAWSModule)ansible_dict_to_boto3_tag_list)boto3_tag_list_to_ansible_dict)!ansible_dict_to_boto3_filter_list)wait_for_resource_statec                     t        |       dk(  ry|s7t        j                  j                  t        j                  j                        }t        | d       }|d   }||z
  }||j                         |kD  ry|S )a3  
    Gets the most recently created snapshot and optionally filters the result
    if the snapshot is too old
    :param snapshots: list of snapshots to search
    :param max_snapshot_age_secs: filter the result if its older than this
    :param now: simulate time -- used for unit testing
    :return:
    r   Nc                     | d   S )N	StartTime )ss    k/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/amazon/aws/plugins/modules/ec2_snapshot.py<lambda>z+_get_most_recent_snapshot.<locals>.<lambda>+  s
    Q{^     )keyr   )lendatetimenowtimezoneutcmaxtotal_seconds)	snapshotsmax_snapshot_age_secsr    youngest_snapshotsnapshot_startsnapshot_ages         r   _get_most_recent_snapshotr*     s{     9~##H$5$5$9$9:I+CD&{3N'L(%%'*??r   moduledevice_nameinstance_idreturnc                     	 ||d}t        |t        |            }s| j	                  d| d|        |d   }|S # t        $ r}| j                  |d       Y d }~Bd }~ww xY w)N)zattachment.instance-idzattachment.deviceFiltersFailed to describe Volumemsgz Could not find volume with name z attached to instance r   )r   r   r   fail_json_aws	fail_json)r+   ec2r,   r-   _filtervolumesevolumes           r   get_volume_by_instancer<   6  s    A-8{["30QRY0Z[ ?}LbcnbopqQZFM  AQ$?@@As   > 	A$AA$r;   c                     	 t        ||g      }s| j                  d|        |d   S # t        $ r}| j                  |d       Y d }~=d }~ww xY w)N)	VolumeIdsr2   r3   zCould not find volume with id r   )r   r   r5   r6   )r+   r7   r;   r9   r:   s        r   get_volume_by_idr?   D  si    A"36(; =fXFG1:  AQ$?@@As   , 	AAA	volume_idc                     d|i}	 t        |t        |            }j	                  dg       S # t        $ r}| j                  |d       Y d }~3d }~ww xY w)Nz	volume-idr0   z(Failed to describe snapshots from volumer3   	Snapshots)r   r   r   r5   get)r+   r7   r@   r8   resultsr:   s         r   get_snapshots_by_volumerE   P  sc    I&GP$S2ST[2\] ;;{B''  PQ$NOOPs   . 	AAAc           	         d }d}| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }| j                   j                  d      }	| j                   j                  d      }
| j                   j                  d	      }|rt        | |||      }|d
   }nt        | ||      }d|vri |d<   |
dkD  rt	        | ||      }|
dz  }
t        ||
      }|t        |d         }|j                  d      }t               }|r||d<   |r|j                  |       d
|i}|r||d<   |rdt        |      dg|d<   	 | j                  r| j                  dd|d
   |d          |j                  d
      }t        |fd|i|}d}|rt!        || dd|	dz  |d   g       t        |d         }t#        |      }||d<   |d   |d
   |d   ||gd } | j                  d"d!|i| y # t        $ r}| j                  |d       Y d }~d }~ww xY w)#NFr@   descriptionr-   r,   waitwait_timeoutlast_snapshot_min_agesnapshot_tagsVolumeIdTagsr   <   )r&   NameDescriptionsnapshot)ResourceTyperM   TagSpecificationsTz2Would have created a snapshot if not in check modeSize)changedr4   r@   volume_sizezFailed to create snapshotr3   snapshot_completed   
SnapshotId)delaymax_attemptsSnapshotIdstags
VolumeSize)snapshot_idr@   rV   r]   r%   rU   r   )paramsrC   r<   r?   rE   r*   r   dictupdater   
check_mode	exit_jsonpopr	   r   r5   r   r   )r+   r7   rQ   rU   r@   rG   r-   r,   rH   rI   rJ   rK   r;   current_snapshotsvolume_tagsvolume_name_tagsr`   r:   	_snapshotrD   s                        r   _create_snapshotrk   Z  s   HG!!+.I--##M2K--##M2K--##M2K==V$D==$$^4L"MM--.EFMM%%o6M'[+N:&	!&#y9Vvq 3FCK 5 :,->Vkl4VF^D!oof-'E&MLL'i($/F=! %/:5A+F&'	E     L$Z0 &v	 !  

:.I&sJiJ6JH  %*!,/0	
 +8F+;<E(2IIf-j)-[G F0W001  	E  (C DD	Es   AH9 9	IIIc                    | j                   j                  d      }| j                  r7	 t        ||g      }|s| j	                  dd       | j	                  dd       	 t        ||      }| j	                         y # t
        $ r}| j                  |d	       Y d }~Ad }~ww xY w# t
        $ r}| j                  |d
	       Y d }~]d }~ww xY w)Nr_   )r\   Fzsnapshot not foundrU   r4   Tz0Would have deleted snapshot if not in check modezFailed to describe snapshotsr3   zFailed to delete snapshot)rU   )r`   rC   rc   r   rd   r   r5   r
   )r+   
connectionr_   r%   r:   rU   s         r   _delete_snapshotro     s    --##M2K	H*:[?SI  4H IT/abA!*k:
 W%  	H  (F GG	H  AQ$?@@As/   6A?  B( ?	B%B  B%(	C1C		Cc                 <   | j                   j                  d      }| j                   j                  d      }| j                   j                  d      }|s|s| j                  d       dd|||d}|j                         D ci c]  \  }}|s	|| }}}|S c c}}w )	Nr_   user_idsgroup_nameszAPlease provide either Group IDs or User IDs to modify permissionsr3   createVolumePermissionadd)	AttributeOperationTyperY   
GroupNamesUserIds)r`   rC   r6   items)r+   r_   rq   rr   r`   kvs          r   *build_modify_createVolumePermission_paramsr|     s    --##M2K}}  ,H--##M2KK`a .!!F  &||~3tq!ad3F3M 4s   
BBc                    	 t        || j                  j                  d      d      d   }| j                  j                  d      }| j                  j                  d      }| j                  j                  d	      }t        d
 D              r|sy|r;|xs g D ch c]  }|j                  d       }}t        |      t        |      k(  ryy|r;|xs g D ch c]  }|j                  d       }	}t        |      t        |	      k(  ryy|r|g k(  ryy# t        $ r}| j	                  |d       Y d }~d }~ww xY wc c}w c c}w )Nr_   rs   )r_   	attributeCreateVolumePermissionsz%Failed to describe snapshot attribute)failedpurge_create_vol_permissionrr   rq   c              3   D   K   | ]  }|j                  d       dk(    yw)GroupallN)rC   ).0items     r   	<genexpr>z4check_user_or_group_update_needed.<locals>.<genexpr>  s     
Q$488G%
Qs    Fr   TUserId)r   r`   rC   r   r5   anyset)
r+   r7   existing_create_vol_permissionr:   purge_permissionsupplied_group_namessupplied_user_idsr   existing_group_namesexisting_user_idss
             r   !check_user_or_group_update_neededr     sR   P)DV]]..}=Ia*

#*%&
 }}(()FG!==,,];))*5 
Q2P
QQZj>\>b`bcd 1cc#$,@(AA<Z<`^`aDTXXh/aa !S):%;;:b@7  PQ'NOOP  d bs#   *D D?E	D<D77D<c                    | j                   j                  d      }| j                   j                  d      }t        | |      }|s| j                  dd       |rw| j                  r| j                  dd       	 t        |d|	       | j                   j                  d      s.| j                   j                  d      s| j                  dd       t        |       }| j                  r| j                  dd       	 |j                  d      }t        |fd|i| | j                  dd       y # t        $ r}| j                  |d
       Y d }~d }~ww xY w# t        $ r}| j                  |d       Y d }~^d }~ww xY w)Nr_   r   FzBSupplied CreateVolumePermission already applied, update not neededrm   Tz'Would have reset CreateVolumePermissionrs   )r~   r_   z&Failed to reset createVolumePermissionr3   rq   rr   z)Reset createVolumePermission successfullyz*Would have modified CreateVolumePermissionrY   z'Failed to modify createVolumePermissionz,Successfully modified CreateVolumePermission)r`   rC   r   rd   rc   r   r   r5   r|   re   r   )r+   r7   r_   r   update_neededr:   r`   s          r   '_modify_snapshot_createVolumePermissionr     st   --##M2K"(--"3"34Q"R5fcBM,pq"T/XY	R$S4LZef }}  ,V]]5F5F}5UT/Z[7?F+WXOjj.!#I;I&I T'UV!  	R  (P QQ	R  OQ$MNNOs0   :D/ <E /	E8EE	E>!E99E>c                     t        t               t               t               t               t               t        dd      t        dd      t        dd      t        dt                     t        dd	gd	
      t        d      t        dd      t        dd      t        dddg            } ddg}ddg}dg}dg}t        | ||||d      }|S )NboolT)typedefaultintiX  r   ra   absentpresent)choicesr   )r   Fliststr)r   elementsr   )r   r   r   )r@   rG   r-   r_   r,   rH   rI   rJ   rK   statemodify_create_vol_permissionr   rq   rr   )r-   r_   r@   )rr   rq   )r   r   )r_   )r   T)r   )r-   r,   )argument_specmutually_exclusiverequired_ifrequired_one_ofrequired_togethersupports_check_mode)ra   r   )r   r   r   r   r   r+   s         r   create_snapshot_ansible_moduler     s    &FFFFvt,uc2"q97Hi0)D%)v%6$(fe$D6E2fuugFM" 	4#
 	.PK
 	4O 	' #-'+ F Mr   c                     t               } | j                  j                  d      }| j                  j                  d      }| j                  d      }|dk(  rt	        | |       y |du rt        | |       y |dk(  rt        | |       y y )Nr   r   r7   r   Tr   )r   r`   rC   clientro   r   rk   )r+   r   r   r7   s       r   mainr   C  s}    +-FMMg&E#)==#4#45S#T 
--
C%	%	-/<	)	% 
r   __main__)NN)+DOCUMENTATIONEXAMPLESRETURNr   typingr   r   r   r   0ansible.module_utils.common.dict_transformationsr   7ansible_collections.amazon.aws.plugins.module_utils.ec2r   r	   r
   r   r   r   r   r   ;ansible_collections.amazon.aws.plugins.module_utils.modulesr   ;ansible_collections.amazon.aws.plugins.module_utils.taggingr   r   Bansible_collections.amazon.aws.plugins.module_utils.transformationr   ;ansible_collections.amazon.aws.plugins.module_utils.waitersr   r*   r   r<   r?   rE   rk   ro   r|   r   r   r   r   r   __name__r   r   r   <module>r      sZ  hTCJM
^      U S S S _ V T ] \ X f f p _4#3 s Y\ aefiknfnao 	- 	C 	DcN 	($4 (c (hW[\`adfiai\jWkNl (N1b&- &d &&, .>    FW4D Wd W@)(8 )X&  zF r   