
    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_functionaa.  
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).
  - Since community.general 4.0.0 on, there are no more default values.
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
  action_group:
    version_added: 9.0.0
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
    version_added: 9.2.0
    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
    version_added: 2.0.0
  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
    version_added: 8.5.0
  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
    version_added: 9.2.0
    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'
    version_added: 8.1.0
  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
    version_added: 6.2.0
  timeout:
    description:
      - Timeout for operations.
    type: int
    default: 30
  update:
    description:
      - If V(true), the container will be updated with new values.
      - The current default value of V(false) is deprecated and should will change to V(true) in community.general 11.0.0.
        Please set O(update) explicitly to V(false) or V(true) to avoid surprises and get rid of the deprecation warning.
    type: bool
    version_added: 8.1.0
  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.
    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
    version_added: 2.3.0
  state:
    description:
      - Indicate desired state of the instance.
      - V(template) was added in community.general 8.1.0.
    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.
      - The default change to V(true) in community.general 7.0.0. It used to be V(false) before.
    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
    version_added: '0.2.0'
  hookscript:
    description:
      - Script that will be executed during various steps in the containers lifetime.
    type: str
    version_added: '0.2.0'
  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
    version_added: '7.1.0'
  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
    version_added: 4.3.0
  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
    version_added: 4.3.0
author: Sergei Antipov (@UnderGreen)
seealso:
  - module: community.general.proxmox_vm_info
extends_documentation_fragment:
  - community.general.proxmox.actiongroup_proxmox
  - community.general.proxmox.documentation
  - community.general.proxmox.selection
  - community.general.attributes
a  
- name: Create new container with minimal options
  community.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.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.general.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: started
    timeout: 90

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

- name: Stop container with force
  community.general.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.general.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: restarted

- name: Convert container to template
  community.general.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.general.proxmox:
    vmid: 100
    api_user: root@pam
    api_password: 1q2w3e
    api_host: node1
    state: template
    force: true

- name: Remove container
  community.general.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                  2   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'      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/general/plugins/modules/proxmox.pyget_proxmox_argsrd   m  sK    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_passwordrg   )r   r   )rf   )r   r   )r   r   )r,   r-   )argument_specrequired_ifr$   required_one_ofr&   )r   rL   rd   r   )module_argss    rc   get_ansible_modulern     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)superrp   __init__versionr   VZ_TYPEmoduleparams)selfrx   	__class__s     rc   ru   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_featuresry   getrx   	fail_jsonlxc_present
lxc_absentlxc_startedlxc_stoppedlxc_restartedlxc_to_template)rz   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                  ||      }|xs |d   j                  d      d   }|xs |d   }|t	        d      || | j
                  j                  ddd	       d
}|rr| 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 w xY w)*Nr/   /r   zLArgument 'node' is None, but should be found from VMID/hostname or provided.zjThe default value of false for 'update' has been deprecated and will be changed to true in version 11.0.0.z11.0.0zcommunity.general)r   rv   collection_nameFr'   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   )r   
clone_fromr   rM   )get_lxc_resourcesplitLookupErrorget_nextvmid
ValueErrorrx   	deprecateformat_vm_identifierupdate_lxc_instancery   r   r
   	exit_jsondebugnew_lxc_instance)rz   r   r   r   rL   rM   rs   
identifiers           rc   r   zProxmoxLxcAnsible.lxc_present?  s%   	/''h7C33t9??3/3D&3v;D
 <^ 
 ?~%% E$$7 & 
 !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 	 	
  	/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   rx   r   r   get_lxc_statusremove_lxc_instance)	rz   r   r   r   rJ   rN   rs   r   
lxc_statuss	            rc   r   zProxmoxLxcAnsible.lxc_absent  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   rx   r   start_lxc_instance)rz   r   r   r   rJ   rs   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_instancerx   r   stop_lxc_instance	rz   r   r   r   rJ   rM   rs   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   rx   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_containerrx   r   r   stop_instanceproxmox_apinodesgetattrrw   rU   post)
rz   r   r   r   rJ   rM   rs   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 )Nrs   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   )rw   rx   r   itemsvalidate_tagsr   joinpopprocess_disk_keysprocess_mount_keysrL   rv   r   warnr   r   r   config
isinstancer   r   r   put)rz   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_instancery   r   rx   r   create_lxc_instancer
   r   )rz   r   r   r   r   r   rM   r   s           rc   r   z"ProxmoxLxcAnsible.new_lxc_instanceW  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`   rs   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_checkrx   r   r   r   r   rL   r   r   r   r   rw   r   rv   r   r   r   r   createhandle_api_timeout)rz   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 )Nrs   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   )rw   rx   r   r   r   appendr
   r   r   r   r[   r   r   )rz   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   rw   statusstartr   r   rz   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   rw   r   shutdownr   r   )rz   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   rw   r   unmountr   r   r   s         rc   r   z%ProxmoxLxcAnsible.umount_lxc_instance8  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   rw   deleter   )rz   r   r   rJ   rN   delete_paramsr   r   s           rc   r   z%ProxmoxLxcAnsible.remove_lxc_instanceD  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keyrs   r   )isdigitparse_disk_stringbuild_volumerw   r   )rz   r   r   r   r   	disk_dicts         rc   r   z#ProxmoxLxcAnsible.process_disk_keysT  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   )
rz   r   r   r,   r-   	mount_keymount_stringmount_configmounts_dict
mount_dicts
             rc   r   z$ProxmoxLxcAnsible.process_mount_keyst  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   )rz   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formatrx   r   r   r   rs   r   r   	Exceptionr   endswithrstripr   r   )rz   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   )rx   r   get_lxc_resource_by_idget_lxc_resource_by_hostnamerw   r   )rz   r   r   vmr   s        rc   r   z"ProxmoxLxcAnsible.get_lxc_resourceC  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   )rz   r   vmsr$  s       rc   r"  z(ProxmoxLxcAnsible.get_lxc_resource_by_idU  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   )rz   r   r(  r$  s       rc   r#  z.ProxmoxLxcAnsible.get_lxc_resource_by_hostname^  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  rx   r   rw   )rz   es     rc   r&  z"ProxmoxLxcAnsible.get_vm_resourcesm  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  rx   r   r   rw   r   currentr   )rz   r   	node_namer   r-  s        rc   r   z ProxmoxLxcAnsible.get_lxc_statusv  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   )rz   r   r   s      rc   r   z&ProxmoxLxcAnsible.format_vm_identifier}  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sleeprx   r   r   r   taskslogr   )rz   r   r   r   rJ   r   s         rc   r   z$ProxmoxLxcAnsible.handle_api_timeout  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   rw   r   r   )rz   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)rz   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
  rx   r   )rz   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})optionrv   pve_versionr   )MINIMUM_VERSIONSr   rv   r   rx   ry   r   r  )rz   rF  rv   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__rH  ru   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__)r{   s   @rc   rp   rp     s    	)9vK
Z 
D
$
:
*
0K
ZB
HE
N6
p


$


 @:N``!D$X#
"-Srb   rp   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~   )rn   rp   r   r  r   r   )rx   proxmoxr-  s      rc   mainrQ    sS    !F'GE E4y|CDDEs   ( 	AAA__main__)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESr  r5  ansible.module_utils.basicr   +ansible.module_utils.common.text.convertersr   Bansible_collections.community.general.plugins.module_utils.proxmoxr	   r
   r   Bansible_collections.community.general.plugins.module_utils.versionr   rd   rn   rp   r  rQ  rI  ra   rb   rc   <module>r[     s}    A @m^	cJ	 
  4 A 
 \jZ8} }@E zF rb   