
    VhD;                         d dl mZmZmZ eZ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mZ  G d	 d
e      Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona  
module: proxmox_snap
short_description: Snapshot management of instances in Proxmox VE cluster
version_added: 2.0.0
description:
  - Allows you to create/delete/restore snapshots from instances in Proxmox VE cluster.
  - Supports both KVM and LXC, OpenVZ has not been tested, as it is no longer supported on Proxmox VE.
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
  action_group:
    version_added: 9.0.0
options:
  hostname:
    description:
      - The instance name.
    type: str
  vmid:
    description:
      - The instance ID.
      - If not set, will be fetched from PromoxAPI based on the hostname.
    type: str
  state:
    description:
      - Indicate desired state of the instance snapshot.
      - The V(rollback) value was added in community.general 4.8.0.
    choices: ['present', 'absent', 'rollback']
    default: present
    type: str
  force:
    description:
      - For removal from config file, even if removing disk snapshot fails.
    default: false
    type: bool
  unbind:
    description:
      - This option only applies to LXC containers.
      - Allows to snapshot a container even if it has configured mountpoints.
      - Temporarily disables all configured mountpoints, takes snapshot, and finally restores original configuration.
      - If running, the container will be stopped and restarted to apply config changes.
      - Due to restrictions in the Proxmox API this option can only be used authenticating as V(root@pam) with O(api_password),
        API tokens do not work either.
      - See U(https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/lxc/{vmid}/config) (PUT tab) for more details.
    default: false
    type: bool
    version_added: 5.7.0
  vmstate:
    description:
      - Snapshot includes RAM.
    default: false
    type: bool
  description:
    description:
      - Specify the description for the snapshot. Only used on the configuration web interface.
      - This is saved as a comment inside the configuration file.
    type: str
  timeout:
    description:
      - Timeout for operations.
    default: 30
    type: int
  snapname:
    description:
      - Name of the snapshot that has to be created/deleted/restored.
    default: 'ansible_snap'
    type: str
  retention:
    description:
      - Remove old snapshots if there are more than O(retention) snapshots.
      - If O(retention) is set to V(0), all snapshots will be kept.
      - This is only used when O(state=present) and when an actual snapshot is created. If no snapshot is created, all existing
        snapshots will be kept.
    default: 0
    type: int
    version_added: 7.1.0

notes:
  - Requires proxmoxer and requests modules on host. These modules can be installed with pip.
requirements: ["proxmoxer", "requests"]
author: Jeffrey van Pelt (@Thulium-Drake)
extends_documentation_fragment:
  - community.general.proxmox.actiongroup_proxmox
  - community.general.proxmox.documentation
  - community.general.attributes
a  
- name: Create new container snapshot
  community.general.proxmox_snap:
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    vmid: 100
    state: present
    snapname: pre-updates

- name: Create new container snapshot and keep only the 2 newest snapshots
  community.general.proxmox_snap:
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    vmid: 100
    state: present
    snapname: snapshot-42
    retention: 2

- name: Create new snapshot for a container with configured mountpoints
  community.general.proxmox_snap:
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    vmid: 100
    state: present
    unbind: true # requires root@pam+password auth, API tokens are not supported
    snapname: pre-updates

- name: Remove container snapshot
  community.general.proxmox_snap:
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    vmid: 100
    state: absent
    snapname: pre-updates

- name: Rollback container snapshot
  community.general.proxmox_snap:
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    vmid: 100
    state: rollback
    snapname: pre-updates
#N)AnsibleModule)	to_native)proxmox_auth_argument_specProxmoxAnsiblec                   T    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zy)ProxmoxSnapAnsiblec                 x     t        | j                  j                  |d         |d         |      j                  S Nnodetype)getattrproxmox_apinodessnapshotselfvmvmids      r/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/proxmox_snap.pyr   zProxmoxSnapAnsible.snapshot   s5    Fwt''--bj92f:FtLUUU    c                 x     t        | j                  j                  |d         |d         |      j                  S r   )r   r   r   configr   s      r   vmconfigzProxmoxSnapAnsible.vmconfig   5    Fwt''--bj92f:FtLSSSr   c                 x     t        | j                  j                  |d         |d         |      j                  S r   )r   r   r   statusr   s      r   vmstatuszProxmoxSnapAnsible.vmstatus   r   r   c                     | j                  ||      j                         }i }|j                         D ]  \  }}|j                  d      s|||<    |S )Nmp)r   getitems
startswith)r   r   r   cfgmountpointskeyvalues          r   _container_mp_getz$ProxmoxSnapAnsible._container_mp_get   sW    mmB%))+))+ 	)JC~~d##(C 	) r   c                     |dk(  r| j                  |||       | j                  ||      j                  dj                  |             y )Nrunning )delete)shutdown_instancer   putjoinr   r   r   timeoutunbindr(   r!   s          r   _container_mp_disablez(ProxmoxSnapAnsible._container_mp_disable   sA    y ""2tW5b$##388K+@#Ar   c                 z     | j                  ||      j                  di | |dk(  r| j                  |||       y y )Nr-    )r   r1   start_instancer3   s          r   _container_mp_restorez(ProxmoxSnapAnsible._container_mp_restore   sA     	$b$##2k2y D'2 !r   c                    | j                  ||      j                  j                         }|dk\  r| j                  |d   |      ry|dz  }|dk(  re| j                  j                  d| j                  j                  |d         j                  |      j                  j                         d d z         t        j                  d       |dk\  ry)Nr   r   T   zSReached timeout while waiting for VM to start. Last line in task before timeout: %smsgF)r!   startpostapi_task_okmodule	fail_jsonr   r   taskslogr$   timesleepr   r   r   r4   taskids        r   r9   z!ProxmoxSnapAnsible.start_instance   s    r4(..335l6
F3qLG!|%%*&*&6&6&<&<RZ&H&N&Nv&V&Z&Z&^&^&`acbc&d+e% fJJqM l r   c                    | j                  ||      j                  j                         }|dk\  r| j                  |d   |      ry|dz  }|dk(  re| j                  j                  d| j                  j                  |d         j                  |      j                  j                         d d z         t        j                  d       |dk\  ry)Nr   r   Tr<   zRReached timeout while waiting for VM to stop. Last line in task before timeout: %sr=   F)r!   shutdownr@   rA   rB   rC   r   r   rD   rE   r$   rF   rG   rH   s        r   r0   z$ProxmoxSnapAnsible.shutdown_instance   s    r4(11668l6
F3qLG!|%%*~&*&6&6&<&<RZ&H&N&Nv&V&Z&Z&^&^&`acbc&d+e% fJJqM l r   c                 
   | j                  ||      j                         d d }|dkD  r[t        |      |kD  rLt        |d       d t        |      |z
   D ]+  } | j                  ||      |d         j	                          - y y y )Nr   c                     | d   S )Nsnaptimer8   )xs    r   <lambda>z7ProxmoxSnapAnsible.snapshot_retention.<locals>.<lambda>   s
    * r   )r)   name)r   r$   lensortedr/   )r   r   r   	retention	snapshotssnaps         r   snapshot_retentionz%ProxmoxSnapAnsible.snapshot_retention   s    MM"d+//1#26	q=S^i7y.EFGbIYbHbc ?'b$'V5<<>? 8=r   c	                    | j                   j                  ry|d   dk(  r|du r| j                   j                  d   dk7  s| j                   j                  d   s| j                   j                  d       y	| j	                  ||      }	| j                  ||      j                         j                         d
   }
|	r| j                  |||||	|
       | j                  ||      j                  ||      }n-| j                  ||      j                  ||t        |            }|dk\  r| j                  |d   |      rn|dk(  re| j                   j                  d| j                  j                  |d         j                  |      j                   j                         d d z         t#        j$                  d       |dz  }|dk\  r|d   dk(  r|du r	r| j'                  |||||	
       | j)                  |||       |dkD  S )NTr   lxcapi_userzroot@pamapi_passwordzf`unbind=True` requires authentication as `root@pam` with `api_password`, API tokens are not supported.r=   Fr    )snapnamedescription)r]   r^   vmstater   r   z\Reached timeout while waiting for creating VM snapshot. Last line in task before timeout: %sr<   )rB   
check_modeparamsrC   r+   r!   currentr$   r6   r   r@   intrA   r   r   rD   rE   rF   rG   r:   rX   )r   r   r   r4   r]   r^   r_   r5   rU   r(   r!   rI   s               r   snapshot_createz"ProxmoxSnapAnsible.snapshot_create   s   ;;!!f:~ KK&&z2j@;;--n=KK))  /W)  X "44R>==T2::<@@B8L..r4&+W_`]]2t,118Q\1]F]]2t,118Q\fijqfr1sFl6
F3!|%%  +I&*&6&6&<&<RZ&H&N&Nv&V&Z&Z&^&^&`acbc&d+e% f JJqMqLG l f:6T>k&&r4&+xXD)4{r   c                    | j                   j                  ry| j                  ||      j                  |t	        |            }|dk\  r| j                  |d   |      ry|dk(  re| j                   j                  d| j                  j                  |d         j                  |      j                  j                         d d z         t        j                  d       |dz  }|dk\  ry)	NT)forcer   r   z\Reached timeout while waiting for removing VM snapshot. Last line in task before timeout: %sr<   r=   F)rB   r`   r   r/   rc   rA   rC   r   r   rD   rE   r$   rF   rG   )r   r   r   r4   r]   rf   rI   s          r   snapshot_removez"ProxmoxSnapAnsible.snapshot_remove  s    ;;!!r4(//E
/Kl6
F3!|%%  +I&*&6&6&<&<RZ&H&N&Nv&V&Z&Z&^&^&`acbc&d+e% f JJqMqLG l r   c                    | j                   j                  ry | j                  ||      |      j                  d      }|dk\  r| j	                  |d   |      ry|dk(  re| j                   j                  d| j                  j                  |d         j                  |      j                  j                         d d z         t        j                  d       |dz  }|dk\  ry)	NTrollbackr   r   z`Reached timeout while waiting for rolling back VM snapshot. Last line in task before timeout: %sr<   r=   F)rB   r`   r   r@   rA   rC   r   r   rD   rE   r$   rF   rG   )r   r   r   r4   r]   rI   s         r   snapshot_rollbackz$ProxmoxSnapAnsible.snapshot_rollback  s    ;;!!(r4(277
Cl6
F3!|%%  +M&*&6&6&<&<RZ&H&N&Nv&V&Z&Z&^&^&`acbc&d+e% f JJqMqLG l r   N)__name__
__module____qualname__r   r   r!   r+   r6   r:   r9   r0   rX   rd   rg   rj   r8   r   r   r   r      sC    VTTB3

?&P r   r   c                  0   t               } t        t        d      t               t        dd      t        dg d      t        d	
      t        d	d      t        dd      t        dd      t        dd      t        dd      
      }| j                  |       t        | d      }t	        |      }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }|j
                  d   }	|j
                  d   }
|j
                  d   }|j
                  d   }|j
                  d   }|s|r|j                  |      }n|s|j                  dd|z         |j                  |      }|dk(  r	 |j                  ||      j                         D ]!  }|d   |k(  s|j                  dd|z         # |j                  |||	|||||      r;|j                  r|j                  dd|z         n|j                  dd |z         y y y |d%k(  r	 d}|j                  ||      j                         D ]  }|d   |k(  sd} |s|j                  dd&|z         nQ|j!                  |||	||
      r;|j                  r|j                  dd'|z         n|j                  dd(|z         y y y y |d*k(  r	 d}|j                  ||      j                         D ]  }|d   |k(  sd} |s|j                  dd&|z         |j#                  |||	|      r:|j                  r|j                  dd+|z         y |j                  dd,|z         y y y # t        $ r.}|j                  d!|d"|d#t        |      $       Y d }~y d }~ww xY w# t        $ r.}|j                  d)|d"|d#t        |      $       Y d }~y d }~ww xY w# t        $ r.}|j                  d-|d"|d#t        |      $       Y d }~y d }~ww xY w).NF)requiredrc      )r   defaultpresent)rr   absentri   )rq   choicesstr)r   ansible_snapboolr   )
r   hostnamer4   stater^   r]   rf   r5   r_   rU   T)argument_specsupports_check_modery   r   rx   r^   r]   r4   rf   r5   r_   rU   z6Vmid could not be fetched for the following action: %s)changedr>   rR   zSnapshot %s is already presentzSnapshot %s would be createdzSnapshot %s createdzCreating snapshot z of VM z failed with exception: r=   rs   zSnapshot %s does not existzSnapshot %s would be removedzSnapshot %s removedzRemoving snapshot ri   z Snapshot %s would be rolled backzSnapshot %s rolled backzRollback of snapshot )r	   dictupdater   r   ra   get_vmid	exit_jsonget_vmr   r$   rd   r`   	ExceptionrC   r   rg   rj   )module_args	snap_argsrB   proxmoxry   r   rx   r^   r]   r4   rf   r5   r_   rU   r   ie
snap_exists                     r   mainr   (  so   ,.K5!%,9.OPe$5.9./&%0E1-I y!! F
 !(GMM'"E== D}}Z(H--.K}}Z(HmmI&GMM'"E]]8$FmmI&Gk*I H),dgl,lm		B		}%%b$/335 eV9($$U8X[c8c$de &&r4(KQXZ`bkl$$$$U8VYa8a$b$$T7Lx7W$X c m 
(		}J%%b$/335 V9(!%J
   4PS[4[ \**2tWhN((((<Z]e<e(f((;PS[;[(\ g O ] 
*		@J%%b$/335 V9(!%J
   4PS[4[ \((T7HE$$$$T7Y\d7d$e$$T7PS[7[$\	 F 
/  	}^fhlnwxynz!{||	}*  	}^fhlnwxynz!{||	}&  	@aikoqz{|q}!~	@sc   +M* ;A)M* --N$ A+N$ -O >AO O *	N!3$NN!$	O-$OO	P'$PP__main__)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNrF   ansible.module_utils.basicr   +ansible.module_utils.common.text.convertersr   Bansible_collections.community.general.plugins.module_utils.proxmoxr	   r
   r   r   rk   r8   r   r   <module>r      sb    A @Vp/b 
  4 A {H HV_@D zF r   