
    VhE                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dlmZmZ d dlmZ d	Zd
dgZg dZ G d de      Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona  
module: lxd_profile
short_description: Manage LXD profiles
description:
  - Management of LXD profiles.
author: "Hiroaki Nakamura (@hnakamur)"
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
options:
  name:
    description:
      - Name of a profile.
    required: true
    type: str
  project:
    description:
      - Project of a profile. See U(https://documentation.ubuntu.com/lxd/en/latest/projects/).
    type: str
    required: false
    version_added: 4.8.0
  description:
    description:
      - Description of the profile.
    type: str
  config:
    description:
      - 'The config for the instance (for example V({"limits.memory": "4GB"})).'
      - See U(https://documentation.ubuntu.com/lxd/en/latest/api/#/profiles/profile_get).
      - If the profile already exists and its C(config) value in metadata obtained from GET /1.0/profiles/<name>
        U(https://documentation.ubuntu.com/lxd/en/latest/api/#/profiles/profile_get)
        are different, then this module tries to apply the configurations U(https://documentation.ubuntu.com/lxd/en/latest/api/#/profiles/profile_put).
      - Not all config values are supported to apply the existing profile. Maybe you need to delete and recreate a profile.
    required: false
    type: dict
  devices:
    description:
      - 'The devices for the profile (for example V({"rootfs": {"path": "/dev/kvm", "type": "unix-char"})).'
      - See U(https://documentation.ubuntu.com/lxd/en/latest/api/#/profiles/profile_get).
    required: false
    type: dict
  new_name:
    description:
      - A new name of a profile.
      - If this parameter is specified a profile will be renamed to this name.
      - See U(https://documentation.ubuntu.com/lxd/en/latest/api/#/profiles/profile_post).
    required: false
    type: str
  merge_profile:
    description:
      - Merge the configuration of the present profile with the new desired configuration, instead of replacing it.
    required: false
    default: false
    type: bool
    version_added: 2.1.0
  state:
    choices:
      - present
      - absent
    description:
      - Define the state of a profile.
    required: false
    default: present
    type: str
  url:
    description:
      - The unix domain socket path or the https URL for the LXD server.
    required: false
    default: unix:/var/lib/lxd/unix.socket
    type: str
  snap_url:
    description:
      - The unix domain socket path when LXD is installed by snap package manager.
    required: false
    default: unix:/var/snap/lxd/common/lxd/unix.socket
    type: str
  client_key:
    description:
      - The client certificate key file path.
      - If not specified, it defaults to C($HOME/.config/lxc/client.key).
    required: false
    aliases: [key_file]
    type: path
  client_cert:
    description:
      - The client certificate file path.
      - If not specified, it defaults to C($HOME/.config/lxc/client.crt).
    required: false
    aliases: [cert_file]
    type: path
  trust_password:
    description:
      - The client trusted password.
      - 'You need to set this password on the LXD server before running this module using the following command: C(lxc config
        set core.trust_password <some random password>). See U(https://www.stgraber.org/2016/04/18/lxd-api-direct-interaction/).'
      - If O(trust_password) is set, this module send a request for authentication before sending any requests.
    required: false
    type: str
notes:
  - Profiles must have a unique name. If you attempt to create a profile with a name that already existed in the users namespace
    the module will simply return as "unchanged".
a  
# An example for creating a profile
- hosts: localhost
  connection: local
  tasks:
    - name: Create a profile
      community.general.lxd_profile:
        name: macvlan
        state: present
        config: {}
        description: my macvlan profile
        devices:
          eth0:
            nictype: macvlan
            parent: br0
            type: nic

# An example for creating a profile in project mytestproject
- hosts: localhost
  connection: local
  tasks:
    - name: Create a profile
      community.general.lxd_profile:
        name: testprofile
        project: mytestproject
        state: present
        config: {}
        description: test profile in project mytestproject
        devices: {}

# An example for creating a profile via http connection
- hosts: localhost
  connection: local
  tasks:
    - name: Create macvlan profile
      community.general.lxd_profile:
        url: https://127.0.0.1:8443
        # These client_cert and client_key values are equal to the default values.
        # client_cert: "{{ lookup('env', 'HOME') }}/.config/lxc/client.crt"
        # client_key: "{{ lookup('env', 'HOME') }}/.config/lxc/client.key"
        trust_password: mypassword
        name: macvlan
        state: present
        config: {}
        description: my macvlan profile
        devices:
          eth0:
            nictype: macvlan
            parent: br0
            type: nic

# An example for modify/merge a profile
- hosts: localhost
  connection: local
  tasks:
    - name: Merge a profile
      community.general.lxd_profile:
        merge_profile: true
        name: macvlan
        state: present
        config: {}
        description: my macvlan profile
        devices:
          eth0:
            nictype: macvlan
            parent: br0
            type: nic

# An example for deleting a profile
- hosts: localhost
  connection: local
  tasks:
    - name: Delete a profile
      community.general.lxd_profile:
        name: macvlan
        state: absent

# An example for renaming a profile
- hosts: localhost
  connection: local
  tasks:
    - name: Rename a profile
      community.general.lxd_profile:
        name: macvlan
        new_name: macvlan2
        state: present
a  
old_state:
  description: The old state of the profile.
  returned: success
  type: str
  sample: "absent"
logs:
  description: The logs of requests and responses.
  returned: when ansible-playbook is invoked with -vvvv.
  type: list
  sample: "(too long to be placed here)"
actions:
  description: List of actions performed for the profile.
  returned: success
  type: list
  sample: ["create"]
N)AnsibleModule)	LXDClientLXDClientException)	urlencodezunix:/var/lib/lxd/unix.socketpresentabsent)configdescriptiondevicesc                   p    e Zd Zd Zd Zd Zed        Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zy)LXDProfileManagementc                 @   || _         | j                   j                  d   | _        | j                   j                  d   | _        | j	                          | j                   j                  d   | _        | j                   j                  j                  dd      | _        | j                   j                  j                  d      | _        | j                  'dj                  t        j                  d         | _        | j                   j                  j                  d	      | _        | j                  'd
j                  t        j                  d         | _        | j                   j                  dk\  | _        	 | j                   j                  d   t        k7  r| j                   j                  d   | _        nt        j"                  j%                  | j                   j                  d   j'                  dd            r| j                   j                  d   | _        n| j                   j                  d   | _        	 t/        | j                   | j                  | j                  | j                        | _        | j                   j                  j                  dd      | _        g | _        y# t(        $ r0}| j                   j+                  |j,                         Y d}~d}~ww xY w# t2        $ r0}| j                   j+                  |j,                         Y d}~d}~ww xY w)zManagement of LXC profiles via Ansible.

        :param module: Processed Ansible Module.
        :type module: ``object``
        nameprojectstatenew_nameN
client_keyz{0}/.config/lxc/client.keyHOMEclient_certz{0}/.config/lxc/client.crt   urlsnap_urlzunix: )msg)key_file	cert_filedebugtrust_password)moduleparamsr   r   _build_configr   getr   r   formatosenvironr   
_verbosityr    ANSIBLE_LXD_DEFAULT_URLr   pathexistsreplace	Exception	fail_jsonr   r   clientr   r!   actions)selfr"   es      q/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/lxd_profile.py__init__zLXDProfileManagement.__init__   sJ    KK&&v.	{{)))4[[''0
**..z4@**..|<== 8??

6@RSDM++//>>>!9@@FASTDN[[++q0
	-{{!!%(,CC;;--e4 2 2: > F FwPR ST;;--j9;;--e4	-#4==DNNjjDK #kk00445EtL  	-KK!!aee!,,	- " 	-KK!!aee!,,	-s1   6CJ( 9<K$ (	K!1&KK!$	L-&LLc                     i | _         t        D ]:  }| j                  j                  j	                  |d       }|,|| j                   |<   < y )N)r   CONFIG_PARAMSr"   r#   r%   )r2   attr	param_vals      r4   r$   z"LXDProfileManagement._build_config  sH    ! 	.D**..tT:I$$-D!	.    c                     dj                  | j                        }| j                  r/dj                  |t        t	        | j                                    }| j
                  j                  d|dg      S )N/1.0/profiles/{0}{0}?{1}r   GETi  )ok_error_codes)r&   r   r   r	   dictr0   dor2   r   s     r4   _get_profile_jsonz&LXDProfileManagement._get_profile_json%  sX    !((3<<""3	$t||2L(MNC{{~~eS#~??r:   c                     | d   dk(  ryy)Ntypeerrorr   r
    )	resp_jsons    r4   _profile_json_to_module_statez2LXDProfileManagement._profile_json_to_module_state+  s    V'r:   c                    | j                   dk(  r| j                  dk(  r;| j                  | j                          y | j                  j                  dd       y | j                  )| j                  | j                  k7  r| j                          | j                         r| j                          y y | j                   dk(  rK| j                  dk(  r;| j                  | j                          y | j                  j                  dd       y y y )Nr
   r   zQnew_name must not be set when the profile does not exist and the state is presentF)r   changedzRnew_name must not be set when the profile exists and the specified state is absent)r   	old_stater   _create_profiler"   r/   r   _rename_profile_needs_to_apply_profile_configs_apply_profile_configs_delete_profiler2   s    r4   _update_profilez$LXDProfileManagement._update_profile1  s    ::"~~)==(((*KK))o % * ' ==,$))1K((*779//1 :ZZ8#~~*==(((*KK))p % * '	 + $r:   c                 @   d}| j                   r/dj                  |t        t        | j                                     }| j                  j                         }| j                  |d<   | j                  j                  d||       | j                  j                  d       y )Nz/1.0/profilesr=   r>   r   POSTcreate)r   r&   r	   rA   r   copyr   r0   rB   r1   appendr2   r   r   s      r4   rN   z$LXDProfileManagement._create_profileH  ss    <<""3	$t||2L(MNC!!#vvsF+H%r:   c                 ^   dj                  | j                        }| j                  r/dj                  |t        t	        | j                                    }d| j
                  i}| j                  j                  d||       | j                  j                  d       | j
                  | _        y )Nr<   r=   r>   r   rV   rename)
r&   r   r   r	   rA   r   r0   rB   r1   rY   rZ   s      r4   rO   z$LXDProfileManagement._rename_profileQ  s|    !((3<<""3	$t||2L(MNC$--(vsF+H%MM	r:   c                     || j                   vry| j                  d   j                  |d       }| j                   |   |k7  S )NFmetadata)r   old_profile_jsonr%   )r2   keyold_configss      r4   _needs_to_change_profile_configz4LXDProfileManagement._needs_to_change_profile_configZ  sB    dkk!++J7;;CF{{3;..r:   c                 p    | j                  d      xs$ | j                  d      xs | j                  d      S )Nr   r   r   )rb   rS   s    r4   rP   z4LXDProfileManagement._needs_to_apply_profile_configs`  s;    00: <00?<00;	
r:   c                     |j                         D ]?  \  }}t        |t              r%|j                  |i       }| j	                  ||       ;|||<   A |S )a`  Merge Dictionaries

        Get a list of filehandle numbers from logger to be handed to
        DaemonContext.files_preserve

        Args:
            dict(source): source dict
            dict(destination): destination dict
        Kwargs:
            None
        Raises:
            None
        Returns:
            dict(destination): merged dict)items
isinstancerA   
setdefault_merge_dicts)r2   sourcedestinationr`   valuenodes         r4   rh   z!LXDProfileManagement._merge_dictsg  s[     !,,. 	)JC%&"--c26!!%.#(C 	) r:   c                     dD ]0  }||v r| j                  |d   |   ||         ||<   &|d   |   ||<   2 | j                  | j                  |      S )aE   merge profile

        Merge Configuration of the present profile and the new desired configitems

        Args:
            dict(config): Dict with the old config in 'metadata' and new config in 'config'
        Kwargs:
            None
        Raises:
            None
        Returns:
            dict(config): new config)r   r   r   r   used_byr^   )rh   r   )r2   r   items      r4   _merge_configz"LXDProfileManagement._merge_config  sl     L 	8Dv~#00
1CD1I6RV<Xt%j1$7t		8   f55r:   c                 T    | j                   j                         D ]
  \  }}|||<    |S )a   rebuild profile

        Rebuild the Profile by the configuration provided in the play.
        Existing configurations are discarded.

        This is the default behavior.

        Args:
            dict(config): Dict with the old config in 'metadata' and new config in 'config'
        Kwargs:
            None
        Raises:
            None
        Returns:
            dict(config): new config)r   re   )r2   r   kvs       r4   _generate_new_configz)LXDProfileManagement._generate_new_config  s2      KK%%' 	DAqF1I	r:   c                    | j                   j                         }| j                  j                  d   r| j	                  |      }n| j                  |      }dj                  | j                        }| j                  r/dj                  |t        t        | j                                    }| j                  j                  d||       | j                  j                  d       y)a   Selection of the procedure: rebuild or merge

        The standard behavior is that all information not contained
        in the play is discarded.

        If "merge_profile" is provides in the play and "True", then existing
        configurations from the profile and new ones defined are merged.

        Args:
            None
        Kwargs:
            None
        Raises:
            None
        Returns:
            Nonemerge_profiler<   r=   r>   PUTapply_profile_configsN)r_   rX   r"   r#   rp   rt   r&   r   r   r	   rA   r0   rB   r1   rY   )r2   r   r   s      r4   rQ   z+LXDProfileManagement._apply_profile_configs  s    " &&++-;;o.''/F..v6F "((3<<""3	$t||2L(MNCuc6*34r:   c                    dj                  | j                        }| j                  r/dj                  |t        t	        | j                                    }| j
                  j                  d|       | j                  j                  d       y )Nr<   r=   r>   DELETEdelete)	r&   r   r   r	   rA   r0   rB   r1   rY   rC   s     r4   rR   z$LXDProfileManagement._delete_profile  sa    !((3<<""3	$t||2L(MNCx%H%r:   c                    	 | j                   %| j                  j                  | j                          | j                         | _        | j                  | j                        | _        | j                          t        | j                        dkD  }|| j                  | j                  d}| j                  j                  r| j                  j                  |d<    | j                  j                  di | y# t        $ r}t        | j                        dkD  }|j                  || j                  d}| j                  j                  r|j                   d   |d<    | j                  j"                  di | Y d}~yd}~ww xY w)zRun the main method.Nr   )rL   rM   r1   logs)r   rL   r1   rH   )r!   r0   authenticaterD   r_   rJ   rM   rT   lenr1   r    r}   r"   	exit_jsonr   r   kwargsr/   )r2   state_changedresult_jsonr3   fail_paramss        r4   runzLXDProfileManagement.run  s9   	1"".(()<)<=$($:$:$<D!!??@U@UVDN  "-1M(!^^<<K
 {{  &*kk&6&6F#!DKK!!0K0! 		1-1Muu(<<K
 {{  &'hhv&6F#!DKK!!0K0		1s   C3C6 6	E??A6E::E?N)__name__
__module____qualname__r5   r$   rD   staticmethodrJ   rT   rN   rO   rb   rP   rh   rp   rt   rQ   rR   r   rH   r:   r4   r   r      s^    'R.@  
'.&"/
06,(5<&1r:   r   c                     t        t        t        dd      t        d      t        d      t        d      t        d      t        d      t        dd      t        t        d	
      t        dt              t        dd      t        ddg      t        ddg      t        dd            d      } t	        |       }|j                          y)zAnsible Main module.strT)rF   required)rF   rA   boolF)rF   defaultr
   )choicesr   z)unix:/var/snap/lxd/common/lxd/unix.socketr+   r   )rF   aliasesr   )rF   no_log)r   r   r   r   r   r   rv   r   r   r   r   r   r!   )argument_specsupports_check_mode)r"   N)r   rA   PROFILES_STATESr*   r   r   )r"   
lxd_manages     r4   mainr     s            '! / C # $  U48Y-
\ "_0Fd &V4JNNr:   __main__)
__future__r   r   r   rF   __metaclass__DOCUMENTATIONEXAMPLESRETURNr'   ansible.module_utils.basicr   >ansible_collections.community.general.plugins.module_utils.lxdr   r   +ansible.module_utils.six.moves.urllib.parser	   r*   r   r7   objectr   r   r   rH   r:   r4   <module>r      s    A @iVVp
$ 
 4 h A :  x

w16 w1t6r zF r:   