
    Vh                         d dl mZmZmZ eZdZdZd dlZd dl	Z	d dl
mZ d dlmZ d dlmZmZmZ d dlmZ d	 Zd
 Z G d de      Zd Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functionaF,  
module: proxmox
short_description: Management of instances in Proxmox VE cluster
description:
  - Allows you to create/delete/stop instances in Proxmox VE cluster.
  - The module automatically detects containerization type (lxc for PVE 4, openvz for older).
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
options:
  password:
    description:
      - The instance root password.
    type: str
  hostname:
    description:
      - The instance hostname.
      - Required only for O(state=present).
      - Must be unique if vmid is not passed.
    type: str
  ostemplate:
    description:
      - The template for VM creating.
      - Required only for O(state=present).
    type: str
  disk:
    description:
      - This option was previously described as "hard disk size in GB for instance" however several formats describing a lxc
        mount are permitted.
      - Older versions of Proxmox will accept a numeric value for size using the O(storage) parameter to automatically choose
        which storage to allocate from, however new versions enforce the C(<STORAGE>:<SIZE>) syntax.
      - Additional options are available by using some combination of the following key-value pairs as a comma-delimited list
        C([volume=]<volume>
        [,acl=<1|0>] [,mountoptions=<opt[;opt...] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>]
        [,size=<DiskSize>]).
      - See U(https://pve.proxmox.com/wiki/Linux_Container) for a full description.
      - This option is mutually exclusive with O(disk_volume).
    type: str
  disk_volume:
    description:
      - Specify a hash/dictionary of the C(rootfs) disk.
      - See U(https://pve.proxmox.com/wiki/Linux_Container#pct_mount_points) for a full description.
      - This option is mutually exclusive with O(storage) and O(disk).
    type: dict
    suboptions:
      storage:
        description:
          - O(disk_volume.storage) is the storage identifier of the storage to use for the C(rootfs).
          - Mutually exclusive with O(disk_volume.host_path).
        type: str
      volume:
        description:
          - O(disk_volume.volume) is the name of an existing volume.
          - If not defined, the module will check if one exists. If not, a new volume will be created.
          - If defined, the volume must exist under that name.
          - Required only if O(disk_volume.storage) is defined, and mutually exclusive with O(disk_volume.host_path).
        type: str
      size:
        description:
          - O(disk_volume.size) is the size of the storage to use.
          - The size is given in GiB.
          - Required only if O(disk_volume.storage) is defined, and mutually exclusive with O(disk_volume.host_path).
        type: int
      host_path:
        description:
          - O(disk_volume.host_path) defines a bind or device path on the PVE host to use for the C(rootfs).
          - Mutually exclusive with O(disk_volume.storage), O(disk_volume.volume), and O(disk_volume.size).
        type: path
      options:
        description:
          - O(disk_volume.options) is a dict of extra options.
          - The value of any given option must be a string, for example V("1").
        type: dict
  cores:
    description:
      - Specify number of cores per socket.
    type: int
  cpus:
    description:
      - Number of allocated cpus for instance.
    type: int
  memory:
    description:
      - Memory size in MB for instance.
    type: int
  swap:
    description:
      - Swap memory size in MB for instance.
    type: int
  netif:
    description:
      - Specifies network interfaces for the container. As a hash/dictionary defining interfaces.
    type: dict
  features:
    description:
      - Specifies a list of features to be enabled. For valid options, see U(https://pve.proxmox.com/wiki/Linux_Container#pct_options).
      - Some features require the use of a privileged container.
    type: list
    elements: str
  startup:
    description:
      - Specifies the startup order of the container.
      - Use C(order=#) where C(#) is a non-negative number to define the general startup order. Shutdown in done with reverse
        ordering.
      - Use C(up=#) where C(#) is in seconds, to specify a delay to wait before the next VM is started.
      - Use C(down=#) where C(#) is in seconds, to specify a delay to wait before the next VM is stopped.
    type: list
    elements: str
  mounts:
    description:
      - Specifies additional mounts (separate disks) for the container. As a hash/dictionary defining mount points as strings.
      - This Option is mutually exclusive with O(mount_volumes).
    type: dict
  mount_volumes:
    description:
      - Specify additional mounts (separate disks) for the container. As a hash/dictionary defining mount points.
      - See U(https://pve.proxmox.com/wiki/Linux_Container#pct_mount_points) for a full description.
      - This Option is mutually exclusive with O(mounts).
    type: list
    elements: dict
    suboptions:
      id:
        description:
          - O(mount_volumes[].id) is the identifier of the mount point written as C(mp[n]).
        type: str
        required: true
      storage:
        description:
          - O(mount_volumes[].storage) is the storage identifier of the storage to use.
          - Mutually exclusive with O(mount_volumes[].host_path).
        type: str
      volume:
        description:
          - O(mount_volumes[].volume) is the name of an existing volume.
          - If not defined, the module will check if one exists. If not, a new volume will be created.
          - If defined, the volume must exist under that name.
          - Required only if O(mount_volumes[].storage) is defined and mutually exclusive with O(mount_volumes[].host_path).
        type: str
      size:
        description:
          - O(mount_volumes[].size) is the size of the storage to use.
          - The size is given in GiB.
          - Required only if O(mount_volumes[].storage) is defined and mutually exclusive with O(mount_volumes[].host_path).
        type: int
      host_path:
        description:
          - O(mount_volumes[].host_path) defines a bind or device path on the PVE host to use for the C(rootfs).
          - Mutually exclusive with O(mount_volumes[].storage), O(mount_volumes[].volume), and O(mount_volumes[].size).
        type: path
      mountpoint:
        description:
          - O(mount_volumes[].mountpoint) is the mount point of the volume.
        type: path
        required: true
      options:
        description:
          - O(mount_volumes[].options) is a dict of extra options.
          - The value of any given option must be a string, for example V("1").
        type: dict
  ip_address:
    description:
      - Specifies the address the container will be assigned.
    type: str
  onboot:
    description:
      - Specifies whether a VM will be started during system bootup.
    type: bool
  storage:
    description:
      - Target storage.
      - This option is mutually exclusive with O(disk_volume) and O(mount_volumes).
    type: str
    default: 'local'
  ostype:
    description:
      - Specifies the C(ostype) of the LXC container.
      - If set to V(auto), no C(ostype) will be provided on instance creation.
    choices: ['auto', 'debian', 'devuan', 'ubuntu', 'centos', 'fedora', 'opensuse', 'archlinux', 'alpine', 'gentoo', 'nixos',
      'unmanaged']
    type: str
    default: 'auto'
  cpuunits:
    description:
      - CPU weight for a VM.
    type: int
  nameserver:
    description:
      - Sets DNS server IP address for a container.
    type: str
  searchdomain:
    description:
      - Sets DNS search domain for a container.
    type: str
  tags:
    description:
      - List of tags to apply to the container.
      - Tags must start with V([a-z0-9_]) followed by zero or more of the following characters V([a-z0-9_-+.]).
      - Tags are only available in Proxmox 7+.
    type: list
    elements: str
  timeout:
    description:
      - Timeout for operations.
    type: int
    default: 30
  update:
    description:
      - If V(true), the container will be updated with new values.
        This only happens if O(state=present), O(force=false), and O(clone) is not specified.
      - If V(false), it will not be updated.
      - The default changed from V(false) to V(true) in community.proxmox 1.0.0.
    type: bool
    default: true
  force:
    description:
      - Forcing operations.
      - Can be used only with states V(present), V(stopped), V(restarted).
      - With O(state=present) force option allow to overwrite existing container.
      - With states V(stopped), V(restarted) allow to force stop instance.
      - When specifying O(force), O(update) must not be specified.
    type: bool
    default: false
  purge:
    description:
      - Remove container from all related configurations.
      - For example backup jobs, replication jobs, or HA.
      - Related ACLs and Firewall entries will always be removed.
      - Used with O(state=absent).
    type: bool
    default: false
  state:
    description:
      - Indicate desired state of the instance.
    type: str
    choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'template']
    default: present
  pubkey:
    description:
      - Public key to add to /root/.ssh/authorized_keys. This was added on Proxmox 4.2, it is ignored for earlier versions.
    type: str
  unprivileged:
    description:
      - Indicate if the container should be unprivileged.
    type: bool
    default: true
  description:
    description:
      - Specify the description for the container. Only used on the configuration web interface.
      - This is saved as a comment inside the configuration file.
    type: str
  hookscript:
    description:
      - Script that will be executed during various steps in the containers lifetime.
    type: str
  timezone:
    description:
      - Timezone used by the container, accepts values like V(Europe/Paris).
      - The special value V(host) configures the same timezone used by Proxmox host.
    type: str
  clone:
    description:
      - ID of the container to be cloned.
      - O(description), O(hostname), and O(pool) will be copied from the cloned container if not specified.
      - The type of clone created is defined by the O(clone_type) parameter.
      - This operator is only supported for Proxmox clusters that use LXC containerization (PVE version >= 4).
    type: int
  clone_type:
    description:
      - Type of the clone created.
      - V(full) creates a full clone, and O(storage) must be specified.
      - V(linked) creates a linked clone, and the cloned container must be a template container.
      - V(opportunistic) creates a linked clone if the cloned container is a template container, and a full clone if not.
        O(storage) may be specified, if not it will fall back to the default.
    type: str
    choices: ['full', 'linked', 'opportunistic']
    default: opportunistic
author: Sergei Antipov (@UnderGreen)
seealso:
  - module: community.proxmox.proxmox_vm_info
extends_documentation_fragment:
  - community.proxmox.proxmox.actiongroup_proxmox
  - community.proxmox.proxmox.documentation
  - community.proxmox.proxmox.selection
  - community.proxmox.attributes
a  
- name: Create new container with minimal options
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'

- name: Create new container with minimal options specifying disk storage location and size
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    disk: 'local-lvm:20'

- name: Create new container with minimal options specifying disk storage location and size via disk_volume
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    disk_volume:
      storage: local
      size: 20

- name: Create new container with hookscript and description
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    hookscript: 'local:snippets/vm_hook.sh'
    description: created with ansible

- name: Create new container automatically selecting the next available vmid.
  community.proxmox.proxmox:
    node: 'uk-mc02'
    api_user: 'root@pam'
    api_password: '1q2w3e'
    api_host: 'node1'
    password: '123456'
    hostname: 'example.org'
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'

- name: Create new container with minimal options with force(it will rewrite existing container)
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    force: true

- name: Create new container with minimal options use environment PROXMOX_PASSWORD variable(you should export it before)
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'

- name: Create new container with minimal options defining network interface with dhcp
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    netif:
      net0: "name=eth0,ip=dhcp,ip6=dhcp,bridge=vmbr0"

- name: Create new container with minimal options defining network interface with static ip
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    netif:
      net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.2/24,bridge=vmbr0"

- name: Create new container with more options defining network interface with static ip4 and ip6 with vlan-tag and mtu
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    netif:
      net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.2/24,ip6=fe80::1227/64,gw6=fe80::1,bridge=vmbr0,firewall=1,tag=934,mtu=1500"

- name: Create new container with minimal options defining a mount with 8GB
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    mounts:
      mp0: "local:8,mp=/mnt/test/"

- name: Create new container with minimal options defining a mount with 8GB using mount_volumes
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    mount_volumes:
      - id: mp0
        storage: local
        size: 8
        mountpoint: /mnt/test

- name: Create new container with minimal options defining a cpu core limit
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    cores: 2

- name: Create new container with minimal options and same timezone as proxmox host
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    timezone: host

- name: Create a new container with nesting enabled and allows the use of CIFS/NFS inside the container.
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    password: 123456
    hostname: example.org
    ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
    features:
      - nesting=1
      - mount=cifs,nfs

- name: >
    Create a linked clone of the template container with id 100. The newly created container with be a
    linked clone, because no storage parameter is defined
  community.proxmox.proxmox:
    vmid: 201
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    clone: 100
    hostname: clone.example.org

- name: Create a full clone of the container with id 100
  community.proxmox.proxmox:
    vmid: 201
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    clone: 100
    hostname: clone.example.org
    storage: local

- name: Update container configuration
  community.proxmox.proxmox:
    vmid: 100
    node: uk-mc02
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    netif:
      net0: "name=eth0,gw=192.168.0.1,ip=192.168.0.3/24,bridge=vmbr0"
    update: true

- name: Start container
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: started

- name: >
    Start container with mount. You should enter a 90-second timeout because servers
    with additional disks take longer to boot
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: started
    timeout: 90

- name: Stop container
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: stopped

- name: Stop container with force
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    force: true
    state: stopped

- name: Restart container(stopped or mounted container you can't restart)
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: restarted

- name: Convert container to template
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: template

- name: Convert container to template (stop container if running)
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: template
    force: true

- name: Remove container
  community.proxmox.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: absent
N)AnsibleModule	to_native)ProxmoxAnsibleansible_to_proxmox_boolproxmox_auth_argument_spec)LooseVersionc                  4   t        dDi dt        dd      dt               dt               dt        d	      d
t               dt               dt        d      dt        dt        t        d      t        d      t        d      t        d      t        d            dgddig d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      dt        ddt        t        dd      t        d      t        d      t        d      t        d      t        dd      t        d            dgddig d       d!t               d"t        d#g d$%      d&t        d'      d(t        dd)      d*t        dd)      d+t        d,-      d.t        d      d/t               d0t               d1t        dd23      d4t        d'd3      d5t        d'd3      d6t        d'd3      d7t        d8g d9%      d:t        d      d;t        d'd3      d<t        d      d=t        d      d>t        d      d?t        d      d@t        dAg dB%      dCt        dd)      S )ENvmidintF)typerequirednodepoolpasswordT)no_loghostname
ostemplatediskstrr   disk_volumedictpath)storagevolumesize	host_pathoptionsr   r    r   ))r!   r   )r!   r   )r!   r    )r   r"   required_togetherrequired_bymutually_exclusivecorescpusmemoryswapnetifmountsmount_volumeslist)idr   r   r    r!   
mountpointr"   )r   elementsr"   r$   r%   r&   
ip_addressostypeauto)r4   debiandevuanubuntucentosfedoraopensuse	archlinuxalpinegentoonixos	unmanaged)defaultchoicesonbootboolfeatures)r   r1   startupr   local)r@   cpuunits
nameserversearchdomaintimeout   )r   r@   updateforcepurgestatepresent)rP   absentstoppedstarted	restartedtemplatepubkeyunprivilegeddescription
hookscripttimezoneclone
clone_typeopportunistic)fulllinkedr]   tags )r   ra       m/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/proxmox/plugins/modules/proxmox.pyget_proxmox_argsrd   ^  sM    iuu-iVi Vi T"	i
 i 6i ui %('u%F+&)  33- 
i6 7i8 u9i: ;i< u=i> ?i@  AiB ed3%('u%F+Vd;&)  33- !
Cin 6oip 
qiR  SiT 6E2UiV &51WiX W%YiZ 5![i\ 6]i^ V_i` %,aib .cid .eif .gih 

ii~ i@ vt4AiB e$CiD U#EiF 5!GiH IiJ #-P
KiP v.Qi irb   c                      t               } | j                  t                      t        | ddddgfdgdgddgg d	
      S )NrO   rP   r   r   )rO   rP   )r[   r   rL   T)api_token_idapi_token_secret)api_passwordrf   )r   r   ))r[   r   )r[   rL   )rM   rL   )r   r   )r   r   )r,   r-   )argument_specrequired_ifr$   required_one_ofr&   )r   rL   rd   r   )module_argss    rc   get_ansible_modulerm     s_    ,.K')*!i&*!56 J
 @@, 

 rb   c                        e Zd ZdddddZ f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d Zd Zd Zd Zd Zd Zd$dZd Zd Zd Zd Zd Zd Zd%dZd  Zd! Z d" Z!d# Z" xZ#S )&ProxmoxLxcAnsiblez5.0z6.1z6.3)r   r-   r`   rZ   c                     t         t        |   |       | j                         t	        d      k  rdnd| _        | j                  j                  | _        y )Nz4.0openvzlxc)superro   __init__versionr   VZ_TYPEmoduleparams)selfrw   	__class__s     rc   rt   zProxmoxLxcAnsible.__init__  s?    /7#'<<>L4G#GxUkk((rb   c           	         | j                          | j                  j                  d      }| j                  j                  d      }| j                  j                  d      }|s|s| j                  j	                  d       |dk(  rb| j                  ||| j                  j                  d      | j                  j                  d      | j                  j                  d	      
       y |dk(  rb| j                  ||| j                  j                  d      | j                  j                  d      | j                  j                  d             y |dk(  rH| j                  ||| j                  j                  d      | j                  j                  d             y |dk(  rb| j                  ||| j                  j                  d      | j                  j                  d      | j                  j                  d	             y |dk(  rb| j                  ||| j                  j                  d      | j                  j                  d      | j                  j                  d	             y |dk(  rb| j                  ||| j                  j                  d      | j                  j                  d      | j                  j                  d	             y y )NrO   r   r   )Either VMID or hostname must be provided.msgrP   r   rL   rM   )r   rL   rM   rQ   rJ   rN   )r   rJ   rN   rS   )r   rJ   rR   )r   rJ   rM   rT   rU   )check_supported_featuresrx   getrw   	fail_jsonlxc_present
lxc_absentlxc_startedlxc_stoppedlxc_restartedlxc_to_template)ry   rO   r   r   s       rc   runzProxmoxLxcAnsible.run  sB   %%'({{v&;;??:.HKK!!&Q!RI[[__V,{{x0kkoog.   hOO[[__V,	2kkoog.   i[[__V,	2	   i[[__V,	2kkoog.   k![[__V,	2kkoog.   j   [[__V,	2kkoog. !  !rb   c                    | j                   j                  d      d}	 | j                  ||      }|xs |d   j                  d      d   }|xs |d   }|t        d      ||ru|sr| j                  ||      }| j                  ||| j                   j                  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      | j                   j                  d      | j                   j                  d      | j                   j                  d      | j                   j                  d      | j                   j                  d      | j                   j                  d      t        | j                   j                  d            | j                   j                  d      | j                   j                  d      | j                   j                  d      | j                   j                  d      | j                   j                  d             | j                  j                  d|d|z          n8|s6| j                  ||d!         }| j                  j                  d|d"|z          | j                  ||d!         }| j                  j                  d#|z         | j                  ||| j                   j                  d      | j                   j                  d      | j                   j                  d$      |%       y # t        $ r d }|xs | j                         }Y xw xY w)&Nr[   Fr/   /r   zLArgument 'node' is None, but should be found from VMID/hostname or provided.r'   r(   rG   rX   r   r   rD   rY   r   r2   r)   r,   r-   rH   r+   rB   rI   rE   r*   r`   rZ   )r'   r(   rG   rX   r   r   rD   rY   r   r2   r)   r,   r-   rH   r+   rB   rI   rE   r*   r`   rZ   TzVM %s has been updated.changedr   r~   namezVM %s already exists.zMVM %s already exists, but we don't update and instead forcefully recreate it.r   )r   
clone_fromr   rM   )rx   r   get_lxc_resourcesplitLookupErrorget_nextvmid
ValueErrorformat_vm_identifierupdate_lxc_instancer
   rw   	exit_jsondebugnew_lxc_instance)ry   r   r   r   rL   rM   rr   
identifiers           rc   r   zProxmoxLxcAnsible.lxc_present2  s   ;;??7#/F	/''h7C33t9??3/3D&3v;D
 <^ 
 ?e!66tXF
((++//'20![[__Z8 $ >0 $ >![[__Z8#{{|<![[__Z8#{{|<;;??84;;??84"&++///"B#{{|<++//'224;;??83LM!%!@ KKOOI600![[__Z8/ ) 2 %% t1JZ1W &  !66tS[I
%%!2IJ2V &  224VEJKK_
 	({{w/{{|4 	 	
m  	/C.4,,.D	/s   6N+ +OOc                 B   	 | j                  ||      }|xs d   j                  d      d   }|xs d   }| j                  ||      }| j                  ||      }|dk(  r!| j                  j	                  d|d	|z         |d
k(  r!| j                  j	                  d|d|z         | j                  ||||       | j                  j	                  d|d|z         y # t        $ r7 | j                  ||      }| j                  j	                  d|d|z         Y 	w xY w)NFzVM %s is already absent.r   r/   r   r   r   runningz*VM %s is running. Stop it before deletion.mountedz<VM %s is mounted. Stop it with force option before deletion.TzVM %s removed.)r   r   r   rw   r   r   get_lxc_statusremove_lxc_instance)	ry   r   r   r   rJ   rN   rr   r   
lxc_statuss	            rc   r   zProxmoxLxcAnsible.lxc_absenty  sI   	''h7C /s4ys+B/"s6{((t4
..tX>
"KK!!@:M " 
 "KK!!R "  	  tWe<t)9J)F 	 	
7  	224BJKK!!D.HJ.W " 	s   C <DDc                    | j                  ||      }|xs |d   j                  d      d   }|xs |d   }| j                  ||      }|xs |d   }| j                  ||d         }|dk(  r!| j                  j                  d|d|z  	       | j                  |||       | j                  j                  d
|d|z  	       y )Nr/   r   r   r   r   r   FzVM %s is already running.r   TzVM %s started.)r   r   r   r   rw   r   start_lxc_instance)ry   r   r   r   rJ   rr   r   r   s           rc   r   zProxmoxLxcAnsible.lxc_started  s    ##D(3/s4ys+B/*s6{..tX>
"s6{((s6{;
"KK!!D.IJ.V "  	dG4t)9J)F 	 	
rb   c                    | j                  ||      }|xs |d   j                  d      d   }|xs |d   }| j                  ||      }|xs |d   }| j                  ||      }|dk(  r7|r| j	                  |||       n!| j
                  j                  d|d|z  	       |d
k(  r!| j
                  j                  d|d|z  	       | j                  ||||       | j
                  j                  d|d|z  	       y )Nr/   r   r   r   r   r   FzEVM %s is already stopped, but mounted. Use force option to umount it.r   rR   zVM %s is already stopped.TzVM %s stopped.)r   r   r   r   umount_lxc_instancerw   r   stop_lxc_instance	ry   r   r   r   rJ   rM   rr   r   r   s	            rc   r   zProxmoxLxcAnsible.lxc_stopped  s   ##D(3/s4ys+B/*s6{..tX>
"s6{((t4
"((xA%%!_ ! &  "KK!!D.IJ.V "  	tT7E:t)9J)F 	 	
rb   c                    | j                  ||      }|xs |d   j                  d      d   }|xs |d   }|xs |d   }| j                  ||      }| j                  ||      }|dv r!| j                  j                  d|d|z  	       | j                  ||||       | j                  |||       | j                  j                  d
|d|z  	       y )Nr/   r   r   r   r   )rR   r   FzVM %s is not running.r   TzVM %s is restarted.)r   r   r   r   rw   r   r   r   r   s	            rc   r   zProxmoxLxcAnsible.lxc_restarted  s    ##D(3/s4ys+B/*s6{"s6{..tX>
((t4
//KK!!D.E
.R "  	tT7E:dG4t)>)K 	 	
rb   c                 H   | j                  ||      }|xs |d   j                  d      d   }|xs |d   }|xs |d   }| j                  ||      }| j                  ||      r!| j                  j                  d|d|z         | j                  ||      }|d	k(  r|r| j                  |||||       | j                  j                  |      }	 t        |	| j                        |      j                  j                          | j                  j                  d
|d|z         y )Nr/   r   r   r   r   FzVM %s is already a template.r   r   TzVM %s converted to template.)r   r   r   is_template_containerrw   r   r   stop_instanceproxmox_apinodesgetattrrv   rU   post)
ry   r   r   r   rJ   rM   rr   r   r   proxmox_nodes
             rc   r   z!ProxmoxLxcAnsible.lxc_to_template  s%   ##D(3/s4ys+B/*s6{"s6{..tX>
%%dD1KK!!2Z? "  ((t4
"utXtWeD''--d3+dll+D1::??At)G*)T 	 	
rb   c           	      (   | j                   dk7  r| j                  j                  d       |j                         D ci c]  \  }}|	|| }}}| j	                  |j                  dg              d|v r#dj                  |j                  d            |d<   d|v r#dj                  |j                  d            |d<   | j                  |||j                  dd       |j                  d	d             }| j                  |||j                  d
d       |j                  dd             }|j                  |       |j                  |       d|v r|j                  d      |d<   d|v r |j                  |j                  d             d|v rN|j                  d      }| j                         t        d      k\  r||d<   n| j                  j                  d       | j                  j                  |      }	 t!        |	| j                         |      j"                  j                         }
i }|j                         D ]w  \  }}||
vr|||<   t%        |t&              r8|
|   j)                  d      }|j)                  d      }|D ]  }||vs|||<    V Xt'        |      t'        |
|         k7  ss|||<   y |s| j                  j+                  d|d         t!        |	| j                         |      j"                  j,                  d||d| y c c}}w )Nrr   zXUpdating LXC containers is only supported for LXC-enabled clusters in PVE 4.0 and above.r}   r`   rD   ,rE   r   r   r,   r-   r(   cpulimitr+   rV   4.2ssh-public-keysB'pubkey' is not supported for PVE 4.1 and below. Ignoring keyword.Fz'Container config is already up to date.r   )r   r   ra   )rv   rw   r   itemsvalidate_tagsr   joinpopprocess_disk_keysprocess_mount_keysrL   ru   r   warnr   r   r   config
isinstancer   r   r   put)ry   r   r   kwargskvdisk_updatesmounts_updatesrV   r   current_configdiffargvaluecurrent_valuesrequested_values	new_values                    rc   r   z%ProxmoxLxcAnsible.update_lxc_instance  s   <<5 KK!!n "  $*<<>C41aQ]!Q$CC6::fb12!$&**Z*@!AF: #I)> ?F9--JJvt$JJ}d+	
 00JJx&JJ-	
 	l#n%V!'F!3F:fMM&**W-.vZZ)F||~e!44,2()  X
 ''--d3<t||<TBIIMMO  ,,. 	"JC.(!S	E3'!/!4!:!:3!?#(;;s#3 !1 I 6$)S	 Us>##677!S		"" KK!!D.W " 
 	=+dll+D188<< 	
D	
$*	
G Ds   
L
Lc                 ~   | j                  ||      }|| j                  |||| j                  j                  d      | j                  j                  d      | j                  j                  d      || j                  j                  d      | j                  j                  d      	       | j                  j                  d|d||fz  	       |L | j                  |||fi d| j                  j                  d      d
| j                  j                  d
      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      dt        |      d| j                  j                  d      d|d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      dt        | j                  j                  d            d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d| j                  j                  d      d | j                  j                  d       d!| j                  j                  d!      d"t        | j                  j                  d"             | j                  j                  d|d#|d$|	       | j                  j                  |d%|z  &       y )'Nr\   rJ   rX   r   r   )r\   rJ   rX   r   r   r   TzCloned VM %s from %dr   r'   r(   rG   r   r   rD   rM   rY   r   r2   r)   r,   r-   rH   r+   rB   r3   r   rV   rI   rE   r*   r`   rZ   rW   zCreated VM  from template zEVM %s does not exist but neither clone nor ostemplate were specified!r   r~   )	r   clone_lxc_instancerx   r   rw   r   create_lxc_instancer
   r   )ry   r   r   r   r   r   rM   r   s           rc   r   z"ProxmoxLxcAnsible.new_lxc_instanceD  s   ..tX>
!##;;??<8	2 KKOOM:![[__V,	2 $ 
 KK!!*j*-EE "  !$D$$! 	2	!
 kkoog.! [[__V,! 4! !KKOOM:! [[__V,! !KKOOM:! 4! .e4!  ;;??<8! "!  ;;??<8!  {{x0!!" {{x0#!$ #kkooo>%!&  ;;??<8'!( kkoog.)!* /t{{x/HI+!, {{x0-!. 4/!0 [[__V,1!2 {{x03!4 "[[__^<5!6 	27!8 	29!: [[__V,;!< [[__V,=!> 4?!@ 5T[[__^5TUA!D KK!!8BJO "  	W 	 	
rb   c           
         |j                  d      d   }| j                  |||      s'| j                  j                  |d|d|d|d       | j	                  |||j                  d      |j                  d	            }| j                  |||j                  d
      |j                  d            }|j                  |       |j                  |       |j                         D 	
ci c]  \  }	}
|
	|	|
 }}	}
d|v r#dj                  |j                  d            |d<   d|v r#dj                  |j                  d            |d<   | j                  |j                  dg              | j                  dk(  r:d|v r|j                  d      |d<   |j                  |j                  di              n0d|v r,|j                  d       | j                  j                  d       d|v rN|j                  d      }| j                         t        d      k\  r||d<   n| j                  j                  d       |j                  d      dk(  r|j                  d       | j                   j#                  |      } t%        || j                        j&                  d||d|}| j)                  ||||d|d|       y c c}
}	w )N:r   zostemplate z does not exist on node z and storage .r   r   r   r,   r-   rD   r   rE   r`   rr   r(   rG   r+   zH'mount_volumes' is not supported for non-LXC clusters. Ignoring keyword.rV   r   r   r   r3   r4   )r   r   z1Reached timeout while waiting for creation of VM r   ra   )r   content_checkrw   r   r   r   r   rL   r   r   r   r   rv   r   ru   r   r   r   r   createhandle_api_timeout)ry   r   r   r   rJ   r   template_storer   r   r   r   rV   r   taskids                 rc   r   z%ProxmoxLxcAnsible.create_lxc_instance  s   #))#.q1!!$
NCKK!!t^5 "  --JJvJJ}%	
 00JJx JJ'	
 	l#n% $*<<>C41aQ]!Q$CC!$&**Z*@!AF: #I)> ?F96::fb12<<5 %+ZZ%7z"MM&**Wb12&(

?+  ^ vZZ)F||~e!44,2()  X ::h6)JJx ''--d3;t||4;; 
*
06
 	Z!	
K Ds   (
J:3J:c                    | j                   dk7  r| j                  j                  d       |j                         D ci c]  \  }}|	|| }}}| j	                  ||      }	|	 }
g d}d|vr|	rd}
n#d|vr|	s| j                  j                  dd	       |d
k(  r |	s| j                  j                  dd	       n1|dk(  r|	s|j                  d       n|dk(  rd}
|j                  d       i }t        |
      |d<   |D ]  }||v s||   ||<    | j                  j                  |      }  t        || j                         |      j                  j                  dd|i|}| j                  ||||d       y c c}}w )Nrr   zHCloning is only supported for LXC-enabled clusters in PVE 4.0 and above.r}   )r   r   rX   r   TFzHClone target container is not a template, storage needs to be specified.r   r~   r_   z@Cloning type 'linked' is only supported for template containers.r]   r^   newidz.Reached timeout while waiting for VM to clone.timeout_msgra   )rv   rw   r   r   r   appendr
   r   r   r   r[   r   r   )ry   r   r   r   r\   rJ   r   r   r   target_is_templatecreate_full_copyvalid_clone_parametersclone_parametersparamr   r   s                   rc   r   z$ProxmoxLxcAnsible.clone_lxc_instance  s   <<5 KK!!^ " 
 $*<<>C41aQ]!Q$CC!77jI11 "EF"'9#f$-?KK!!^ " 
 !*<KK!!V "  ?*3E")))46!#")))4#:;K#L + 	8E*0- '	8 ''--d3K4t||4Z@FFKK 

*
 	H 	  	
S Ds   
E;
E;c                     | j                   j                  |      } t        || j                        |      j                  j
                  j                         }| j                  ||||d       y )Nz.Reached timeout while waiting for VM to start.r   )r   r   r   rv   statusstartr   r   ry   r   r   rJ   r   r   s         rc   r   z$ProxmoxLxcAnsible.start_lxc_instance  sf    ''--d34t||4T:AAGGLLNH 	  	
rb   c                     i }|rd|d<   | j                   j                  |      }  t        || j                        |      j                  j
                  j                  di |}| j                  ||||d       y )N   	forceStopz-Reached timeout while waiting for VM to stop.r   ra   )r   r   r   rv   r   shutdownr   r   )ry   r   r   rJ   rM   stop_paramsr   r   s           rc   r   z#ProxmoxLxcAnsible.stop_lxc_instance  s    '(K$''--d3O4t||4T:AAJJOO 

 	G 	  	
rb   c                     | j                   j                  |      } t        || j                        |      j                  j
                  j                         }| j                  ||||d       y )Nz5Reached timeout while waiting for VM to be unmounted.r   )r   r   r   rv   r   unmountr   r   r   s         rc   r   z%ProxmoxLxcAnsible.umount_lxc_instance%  sf    ''--d34t||4T:AAIINNPO 	  	
rb   c                     i }|rd|d<   | j                   j                  |      } t        || j                        j                  |fi |}| j                  ||||d       y )Nr   rN   z3Reached timeout while waiting for VM to be removed.r   )r   r   r   rv   deleter   )ry   r   r   rJ   rN   delete_paramsr   r   s           rc   r   z%ProxmoxLxcAnsible.remove_lxc_instance1  sn    %&M'"''--d3;t||4;;DRMRM 	  	
rb   c                     ||i S i }|'|j                         r||d<   n| j                  |      }| | j                  ||fddi|}| j                  dk7  r|j	                  d      |d<   |S )a$  
        Process disk keys and return a formatted disk volume with the `rootfs` key.

        Args:
            vmid (int): VM identifier.
            node (str): Node identifier.
            disk (str, optional): Disk key in the format 'storage:volume'. Defaults to None.
            disk_volume (Dict[str, Any], optional): Disk volume data. Defaults to None.

        Returns:
            Dict[str, str]: Formatted disk volume with the `rootfs` or `disk` key (depending on the `VZ_TYPE`), or an empty dict if no disk volume is specified.
        rootfskeyrr   r   )isdigitparse_disk_stringbuild_volumerv   r   )ry   r   r   r   r   	disk_dicts         rc   r   z#ProxmoxLxcAnsible.process_disk_keysA  s     <K/I	||~&*	(#"44T:")))$R(RkRI<<5  )h 7Ifrb   c                 .   |Hg }|j                         D ]2  \  }}| j                  |      }|j                  t        dd|i|       4 n	||g k(  ri S i }|D ]:  }|j	                  d      } | j
                  ||fd|i|}	|j                  |	       < |S )a  
        Process mount keys and return a formatted mount volumes with the `mp[n]` keys.

        Args:
            vmid (str): VM identifier.
            node (str): Node identifier.
            mounts (str, optional): Mount key in the format 'pool:volume'. Defaults to None.
            mount_volumes (Dict[str, Any], optional): Mount volume data. Defaults to None.

        Returns:
            Dict[str, str]: Formatted mount volumes with the `mp[n]` keys, or an empty dict if no mount volumes are specified.
        r/   r   ra   )r   r   r   r   r   r   rL   )
ry   r   r   r,   r-   	mount_keymount_stringmount_configmounts_dict
mount_dicts
             rc   r   z$ProxmoxLxcAnsible.process_mount_keysa  s     M+1<<> I'	<#55lC$$T%GY%G,%GHI "mr&9I) 	+L$((.I***4U9UUJz*	+
 rb   c                    |j                  d      }|D cg c]  }d|vrd|z   n| }}t        t        d |            }d}t        j                  |      }|j                  d      }|j                  |      }|t        d|f      |j                         }	|	j                         D 
ci c]  \  }
}|	|
| }	}
}d|	v rd|	v r|	d   |d<   |	d   |d<   |S d|	v rd	|	v r|	d   |d<   |	d	   |d	<   |S d
|	v r|	d
   |d
<   |S c c}w c c}}
w )a  
        Parse a disk string and return a dictionary with the disk details.

        Args:
            disk_string (str): Disk string.

        Returns:
            Dict[str, Any]: Disk details.

        Note: Below are some example disk strings that this function MUST be able to parse:
            "acl=0,thin1:base-100-disk-1,size=8G"
            "thin1:10,backup=0"
            "local:20"
            "local-lvm:0.50"
            "tmp-dir:300/subvol-300-disk-0.subvol,acl=1,size=0T"
            "tmplog-dir:300/vm-300-disk-0.raw,mp=/var/log,mountoptions=noatime,size=32M"
            "volume=local-lvm:base-100-disk-1,size=20G"
            "/mnt/bindmounts/shared,mp=/shared"
            "volume=/dev/USB01,mp=/mnt/usb01"
        r   =zvolume=c                 $    | j                  d      S )Nr   )r   )items    rc   <lambda>z5ProxmoxLxcAnsible.parse_disk_string.<locals>.<lambda>  s    DJJsO rb   aG  (?x)
            ^
            (?:
                (?:
                    (?P<storage>[\w\-.]+):
                    (?:
                        (?P<size>\d+\.?\d*)|
                        (?P<volume>[^,\s]+)
                    )
                )|
                (?P<host_path>[^,\s]+)
            )
            $
        r   zInvalid volume string: %sr   r    r!   )
r   r   maprecompiler   matchr   	groupdictr   )ry   disk_stringargsr   disk_kwargsVOLUME_PATTERNpatternvolume_stringr  
match_dictr   r   s               rc   r   z#ProxmoxLxcAnsible.parse_disk_string~  sc   *   % GKKs3c>	Cs:KK3;TBC& **^,#1m,=9=IJJ__&
'1'7'7'9Ktq!Q]adK
K
"x:'=%/	%:K	"$.x$8K!* ) *$:)=%/	%:K	"",V"4K$ # J&'1+'>K$  m L: Ls   D +
D6Dc
                    t        |t              rt        |      }|t        |      r|dz  }|| j	                  |||      }|D cg c]  }|d   	 }}dj                  ||      }||vr.| j                  j                  ddj                  ||             d	j                  |||
      }n|| j                  j                  |      }	 |j                  |      j                  d      j                  |      }| j                  |      j                  d      }d	j                  |||
      }n|d}nt        d      ||d|z   z  }||dj                  |      z  }|	H|ddj#                  |	j%                         D cg c]  \  }}dj                  ||       c}}      z   z  }|
rH|ddj#                  |
j%                         D cg c]  \  }}dj                  ||       c}}      z   z  }||iS c c}w # t        $ rR |t        d      |j                  d      r%|j!                  d      }dj                  ||      }nt        d      Y w xY wc c}}w c c}}w )aW  
        Build a volume string for the specified VM.

        Args:
            vmid (str): The VM ID.
            node (str): The node where the VM resides.
            key (str): The key for the volume in the VM's config.
            storage (str, optional): The storage pool where the volume resides. Defaults to None.
            volume (str, optional): The name of the volume. Defaults to None.
            host_path (str, optional): The host path to mount. Defaults to None.
            size (str | int, optional): The size of the volume in GiB. Defaults to None.
            mountpoint (str, optional): The mountpoint for the volume. Defaults to None.
            options (Dict[str, Any], optional): Additional options for the volume. Defaults to None.
            **kwargs: Additional keyword arguments.

        Returns:
            Dict[str, str]: The built volume string in the format {'volume_key': 'volume_string'}.

        Note: Further documentation can be found in the proxmox-api documentation: https://pve.proxmox.com/wiki/Linux_Container#pct_mount_points
        Note: To build a valid volume string, we need ONE of the following:
            A volume name, storage name, and size
            Only a storage name and size (to create a new volume or assign the volume automatically)
            A host directory to mount into the container
        G)r   volidz{storage}:{volume})r   r   Fz2Storage {storage} does not contain volume {volume}r   z{storage}:{volume},size={size})r   r   r    r   r   z9Size must be provided for storage-backed volume creation.z{storage}:{size}r#   zvSize must be provided in GiB for storage-backed volume creation. Convert it to GiB or allocate a new storage manually. z]Could not build a valid volume string. One of volume, storage, or host_path must be provided.r   z,mp={}z{0}={1})r   r   r   isfloatget_storage_contentformatrw   r   r   r   rr   r   r   	Exceptionr   endswithrstripr   r   )ry   r   r   r   r   r   r!   r    r0   r"   r   storage_contentvolvol_idsr  
vol_stringr   r   r   s                      rc   r   zProxmoxLxcAnsible.build_volume  s   2 dC t9DCKD "66tW46PO/>?s7|?G?(///OEG#%%!LSS '% T  &  :@@T A J  ++11L"&&t,00:>>sC//488B=DD#F E 
& "Jo   #	/)J!(//*55J#4;MMODDAq!!!Q'D!  J #4:LLNCDAq!!!Q'C!  J Z  } @4  <$S  ]]3';;s+D!3!:!:7QU!:!VJ$ Q  : E
 Ds&   G:A#G? II#?AIIc                 @   |s|s| j                   j                  d       |r| j                  |      }n|r| j                  |      }d   }|d   | j                  k7  r?| j                  ||      }| j                   j                  d|d| j                  d       |S )Nr|   r}   r   r   zThe specified VM z is not an r   )rw   r   get_lxc_resource_by_idget_lxc_resource_by_hostnamerv   r   )ry   r   r   vmr   s        rc   r   z"ProxmoxLxcAnsible.get_lxc_resource0  s    HKK!!&Q!R,,T2B228<B&zf:%224BJKK!!;Et||T "  	rb   c                     | j                         }|D cg c]  }|d   |k(  s| }}t        |      dk(  rt        d|z        |d   S c c}w )Nr   r   z*VM with VMID %d does not exist in cluster.)get_vm_resourceslenr   )ry   r   vmsr!  s       rc   r  z(ProxmoxLxcAnsible.get_lxc_resource_by_idB  sX    ##%6b2f:#5r66s8q=JTQRR1v	 7s
   A
A
c                     | j                         }|D cg c]  }|d   |k(  s| }}t        |      dk(  rt        d|z        t        |      dkD  rt        d|z        |d   S c c}w )Nr   r   z.VM with hostname %s does not exist in cluster.r   z9Multiple VMs found with hostname %s. Please specify VMID.)r#  r$  r   r   )ry   r   r%  r!  s       rc   r   z.ProxmoxLxcAnsible.get_lxc_resource_by_hostnameK  s    ##%:b2f:#9r::s8q=@8K  X\KhV  1v ;s
   A&A&c                     	 | j                   j                  j                  j                  d      S # t        $ r6}| j
                  j                  d| j                  d|       Y d }~y d }~ww xY w)Nr!  r   zUnable to retrieve list of z VMs from cluster resources: r}   )r   cluster	resourcesr   r  rw   r   rv   )ry   es     rc   r#  z"ProxmoxLxcAnsible.get_vm_resourcesZ  sg    	##++5599t9DD 	KK!!<<$ "  	s   /2 	A1,A,,A1c                 &   	 | j                   j                  |      } t        | j                        |      j                  j                  j                         d   S # t        $ r)}| j                  j	                  d|z         Y d }~nd }~ww xY w)Nz'Unable to retrieve node information: %sr}   r   )
r   r   r  rw   r   r   rv   r   currentr   )ry   r   	node_namer   r*  s        rc   r   z ProxmoxLxcAnsible.get_lxc_statusc  s    	U++11)<L 3w|T\\248??GGKKMhWW  	UKK!!&ORS&S!TT	Us   A 	B'BBc                 8    |r
|r|d|dS |r|S t        |      S )Nz ()r   )ry   r   r   s      rc   r   z&ProxmoxLxcAnsible.format_vm_identifierj  s$    H ($//OT?"rb   c           	      T   |dk7  rd|z  }|dkD  r3| j                  ||      ry |dz  }t        j                  d       |dkD  r3| j                  j	                  |||d| j
                  j                  |      j                  |      j                  j                         d d        y )Nr  z%s r   r   z"Last line in task before timeout: )r   r   r~   )
api_task_oktimesleeprw   r   r   r   taskslogr   )ry   r   r   r   rJ   r   s         rc   r   z$ProxmoxLxcAnsible.handle_api_timeoutr  s    "+-Kkf-qLGJJqM	 k 	D,,2248>>vFJJNNPQSRSTV 	 	
rb   c                     | j                   j                  |      } t        || j                        |      j                  j                         }|j                  dd      S )z/Check if the specified container is a template.rU   F)r   r   r   rv   r   r   )ry   r   targetr   r   s        rc   r   z'ProxmoxLxcAnsible.is_template_container  sO    ''--d34t||4V<CCGGIzz*e,,rb   c                     | j                   j                  |      }|j                  |      j                  j	                         }t        fd|D              S )zFCheck if the specified ostemplate is present in the specified storage.c              3   .   K   | ]  }|d    k(    yw)r  Nra   ).0contentr   s     rc   	<genexpr>z2ProxmoxLxcAnsible.content_check.<locals>.<genexpr>  s     Rg77#z1Rs   )r   r   r   r;  r   any)ry   r   r   r   r   storage_contentss     `   rc   r   zProxmoxLxcAnsible.content_check  sK    ''--d3'//?GGKKMRAQRRRrb   c                     t        j                  d      }|D ]4  }|j                  |      r| j                  j	                  d|z          y y)z&Check if the specified tags are valid.z!^[a-zA-Z0-9_][a-zA-Z0-9_\-\+\.]*$z%s is not a valid tagr}   FT)r  r  r  rw   r   )ry   r`   re_tagtags       rc   r   zProxmoxLxcAnsible.validate_tags  sO    @A 	C<<$%%*AC*G%H	 rb   c           
      .   | j                   j                         D ]x  \  }}| j                         t        |      k  s#|| j                  j
                  v s<| j                  j                  ddj                  ||| j                                      z y )NFzXFeature {option} is only supported in PVE {version}+, and you're using PVE {pve_version})optionru   pve_versionr   )MINIMUM_VERSIONSr   ru   r   rw   rx   r   r  )ry   rC  ru   s      rc   r   z*ProxmoxLxcAnsible.check_supported_features  s    #44::< 	OFG||~W 55&DKKDVDV:V%%!ryy%wDLLN z  & 	rb   )NNNNNN)r  )$__name__
__module____qualname__rE  rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r#  r   r   r   r   r   r   r   __classcell__)rz   s   @rc   ro   ro     s    	)9vE
N 
D
$
:
*
0K
ZB
HE
N6
p


$


 @:N``!D$X#
"-Srb   ro   c                 @    | y	 t        |        y# t        $ r Y yw xY w)NFT)floatr   )r   s    rc   r  r    s+    }e s    	c                      t               } t        |       }	 |j                          y # t        $ r(}| j	                  dt        |      z         Y d }~y d }~ww xY w)NzAn error occurred: %sr}   )rm   ro   r   r  r   r   )rw   proxmoxr*  s      rc   mainrN    sS    !F'GE E4y|CDDEs   ( 	AAA__main__)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESr  r2  ansible.module_utils.basicr   +ansible.module_utils.common.text.convertersr   Bansible_collections.community.proxmox.plugins.module_utils.proxmoxr	   r
   r   Bansible_collections.community.proxmox.plugins.module_utils.versionr   rd   rm   ro   r  rN  rF  ra   rb   rc   <module>rX     s}    A @^@	cJ	 
  4 A 
 \jZ<w wtE zF rb   