
    VhE5                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
d dlZ	 d dlmZmZ d dlmZmZ d dlmZmZmZ d d	lmZmZ  G d
 de      Zd Zedk(  r e        yy# e$ r Y =w xY w)    )absolute_importdivisionprint_functiona  
module: docker_secret

short_description: Manage docker secrets

description:
  - Create and remove Docker secrets in a Swarm environment. Similar to C(docker secret create) and C(docker secret rm).
  - Adds to the metadata of new secrets C(ansible_key), an encrypted hash representation of the data, which is then used in
    future runs to test if a secret has changed. If C(ansible_key) is not present, then a secret will not be updated unless
    the O(force) option is set.
  - Updates to secrets are performed by removing the secret and creating it again.
extends_documentation_fragment:
  - community.docker.docker
  - community.docker.docker.docker_py_2_documentation
  - community.docker.attributes
  - community.docker.attributes.actiongroup_docker

attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
  idempotent:
    support: partial
    details:
      - If O(force=true) the module is not idempotent.

options:
  data:
    description:
      - The value of the secret.
      - Mutually exclusive with O(data_src). One of O(data) and O(data_src) is required if O(state=present).
    type: str
  data_is_b64:
    description:
      - If set to V(true), the data is assumed to be Base64 encoded and will be decoded before being used.
      - To use binary O(data), it is better to keep it Base64 encoded and let it be decoded by this option.
    type: bool
    default: false
  data_src:
    description:
      - The file on the target from which to read the secret.
      - Mutually exclusive with O(data). One of O(data) and O(data_src) is required if O(state=present).
    type: path
    version_added: 1.10.0
  labels:
    description:
      - A map of key:value meta data, where both key and value are expected to be strings.
      - If new meta data is provided, or existing meta data is modified, the secret will be updated by removing it and creating
        it again.
    type: dict
  force:
    description:
      - Use with O(state=present) to always remove and recreate an existing secret.
      - If V(true), an existing secret will be replaced, even if it has not changed.
    type: bool
    default: false
  rolling_versions:
    description:
      - If set to V(true), secrets are created with an increasing version number appended to their name.
      - Adds a label containing the version number to the managed secrets with the name C(ansible_version).
    type: bool
    default: false
    version_added: 2.2.0
  versions_to_keep:
    description:
      - When using O(rolling_versions), the number of old versions of the secret to keep.
      - Extraneous old secrets are deleted after the new one is created.
      - Set to V(-1) to keep everything or to V(0) or V(1) to keep only the current one.
    type: int
    default: 5
    version_added: 2.2.0
  name:
    description:
      - The name of the secret.
    type: str
    required: true
  state:
    description:
      - Set to V(present), if the secret should exist, and V(absent), if it should not.
    type: str
    default: present
    choices:
      - absent
      - present

requirements:
  - "L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) >= 2.1.0"
  - "Docker API >= 1.25"

author:
  - Chris Houseknecht (@chouseknecht)
a  
---
- name: Create secret foo (from a file on the control machine)
  community.docker.docker_secret:
    name: foo
    # If the file is JSON or binary, Ansible might modify it (because
    # it is first decoded and later re-encoded). Base64-encoding the
    # file directly after reading it prevents this to happen.
    data: "{{ lookup('file', '/path/to/secret/file') | b64encode }}"
    data_is_b64: true
    state: present

- name: Create secret foo (from a file on the target machine)
  community.docker.docker_secret:
    name: foo
    data_src: /path/to/secret/file
    state: present

- name: Change the secret data
  community.docker.docker_secret:
    name: foo
    data: Goodnight everyone!
    labels:
      bar: baz
      one: '1'
    state: present

- name: Add a new label
  community.docker.docker_secret:
    name: foo
    data: Goodnight everyone!
    labels:
      bar: baz
      one: '1'
      # Adding a new label will cause a remove/create of the secret
      two: '2'
    state: present

- name: No change
  community.docker.docker_secret:
    name: foo
    data: Goodnight everyone!
    labels:
      bar: baz
      one: '1'
      # Even though 'two' is missing, there is no change to the existing secret
    state: present

- name: Update an existing label
  community.docker.docker_secret:
    name: foo
    data: Goodnight everyone!
    labels:
      bar: monkey # Changing a label will cause a remove/create of the secret
      one: '1'
    state: present

- name: Force the removal/creation of the secret
  community.docker.docker_secret:
    name: foo
    data: Goodnight everyone!
    force: true
    state: present

- name: Remove secret foo
  community.docker.docker_secret:
    name: foo
    state: absent
a\  
secret_id:
  description:
    - The ID assigned by Docker to the secret object.
  returned: success and O(state=present)
  type: str
  sample: 'hzehrmyjigmcp2gb6nlhmjqcv'
secret_name:
  description:
    - The name of the created secret object.
  returned: success and O(state=present)
  type: str
  sample: 'awesome_secret'
  version_added: 2.2.0
N)DockerExceptionAPIError)AnsibleDockerClientRequestException)DockerBaseClasscompare_genericsanitize_labels)	to_nativeto_bytesc                   N     e Zd Z fdZd Zd Zd Zd Zd Zd Z	d Z
d	 Z xZS )
SecretManagerc           	         t         t        |           || _        || _        | j                  j
                  | _        | j                  j                  j                  }|j                  d      | _	        |j                  d      | _
        |j                  d      | _        | j                  P|j                  d      r%t        j                  | j                        | _        nt        | j                        | _        |j                  d      }|+	 t        |d      5 }|j!                         | _        d d d        |j                  d	      | _        |j                  d
      | _        |j                  d      | _        |j                  d      | _        | j.                  rd| _        d | _        g | _        y # 1 sw Y   xY w# t"        $ r?}| j                  j%                  dj'                  |t)        |                   Y d }~d }~ww xY w)Nnamestatedatadata_is_b64data_srcrbz"Error while reading {src}: {error})srcerrorlabelsforcerolling_versionsversions_to_keepr   )superr   __init__clientresults
check_modemoduleparamsgetr   r   r   base64	b64decoder   openread	Exceptionfailformatr   r   r   r   r   versiondata_keysecrets)selfr    r!   
parametersr   fexc	__class__s          r/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/docker/plugins/modules/docker_secret.pyr   zSecretManager.__init__   s   mT+-++00[[''..
NN6*	^^G,
NN6*	99 ~~m,",,TYY7	$TYY/	>>*-r(D) )Q !DI) !nnX.^^G,
 */A B */A B  DL) ) r  !E!L!LQYajknao!L!pqqrs0   F? F31F? 3F<8F? ?	H5HHc                 (   | j                          | j                  dk(  rSt        j                  | j                        j                         | _        | j                          | j                          y | j                  dk(  r| j                          y y )Npresentabsent)

get_secretr   hashlibsha224r   	hexdigestr.   r7   remove_old_versionsr8   r0   s    r5   __call__zSecretManager.__call__   sd    ::"#NN4995??ADMLLN$$&ZZ8#KKM $    c                     	 t        |j                  di       j                  di       j                  dd            S # t        $ r Y yw xY w)NSpecLabelsansible_versionr   )intr%   
ValueErrorr0   secrets     r5   get_versionzSecretManager.get_version  sK    	vzz&"-11(B?CCDUWXYZZ 		s   := 	A	A	c                 ^   | j                   r| j                  dk  ry | j                  st        | j                        t        | j                  d      kD  rX| j                  | j                  j                  d             t        | j                        t        | j                  d      kD  rWy y y )Nr      )r   r   r"   lenr/   maxremove_secretpopr>   s    r5   r=   z!SecretManager.remove_old_versions  s    $$(=(=(Adll#c$*?*?&CC""4<<#3#3A#67 dll#c$*?*?&CC r@   c           	      F   	 | j                   j                  d| j                  i      }| j                  rmD cg c]5  }|d   d   j                  dj                  | j                  	            r|7 c}| _        | j                  j                  | j                  
       yD cg c]  }|d   d   | j                  k(  s| c}| _        y# t        $ r>}| j                   j	                  d| j                  dt        |             Y d}~d}~ww xY wc c}w c c}w )z Find an existing secret. r   filterszError accessing secret : NrB   Namez{name}_v)r   )key)r    r/   r   r   r+   r   r   
startswithr,   sortrI   )r0   r/   r3   rH   s       r5   r9   zSecretManager.get_secret  s   	\kk))64992E)FG    &&>&)44Z5F5FDII5F5VW DL
 LL$"2"23 &-!vv0F$))0SDL  	\KK		9UX>Z[[	\s(   (C :D'DD	D4DDc                    d}d| j                   i}| j                  rY| xj                  dz  c_        t        | j                        |d<   dj	                  | j
                  | j                        | _        | j                  r|j                  | j                         	 | j                  sc| j                  j                  | j
                  | j                  |      }| xj                  | j                  j                  d|i	      z  c_        t!        |t"              r|d   }|S # t        $ r1}| j                  j                  d
t        |      z         Y d}~Ld}~ww xY w)z Create a new secret Nansible_keyrK   rD   z{name}_v{version})r   r-   )r   idrQ   zError creating secret: %sID)r.   r   r-   strr,   r   r   updater"   r    create_secretr   r/   r   r+   r   
isinstancedict)r0   	secret_idr   r3   s       r5   r^   zSecretManager.create_secret"  s    	 4==
   LLAL(+DLL(9F$%+22		4<<2XDI;;MM$++&	K?? KK55diiSY5Z	 3 3T9<M 3 NN i&!$I  	KKK89S>IJJ	Ks   A/D$ $	E-'EEc           	          	 | j                   s| j                  j                  |d          y y # t        $ r:}| j                  j	                  d|d   d   dt        |             Y d }~y d }~ww xY w)Nr[   zError removing secret rB   rT   rS   )r"   r    rN   r   r+   r   )r0   rH   r3   s      r5   rN   zSecretManager.remove_secret<  sf    	h??))&,7 # 	hKKvf~f?UW`adWefgg	hs   *. 	A10A,,A1c                    | j                   rs| j                   d   }|d   | j                  d<   |d   d   | j                  d<   d}|j                  di       }|j                  di       j                  d	      r|d   d	   | j                  k7  r4d
}n1| j                  s%| j
                  j                  j                  d       t        | j                  |j                  d      dd       }| j                  r| j                  |      | _        |s|s| j                  rd| j                  s| j                          | j                         }d
| j                  d<   || j                  d<   | j                  | j                  d<   yyd
| j                  d<   | j                         | j                  d<   | j                  | j                  d<   y)z= Handles state == 'present', creating or updating the secret r[   ra   rB   rT   secret_nameFrC   rY   Tze'ansible_key' label not found. Secret will not be changed unless the force parameter is set to 'true'allow_more_presentr`   changedN)r/   r!   r%   r.   r   r    r#   warnr   r   r   rI   r-   r8   r^   r   )r0   rH   data_changedattrslabels_changedra   s         r5   r7   zSecretManager.presentC  s   <<\\"%F(.tDLL%*0.*@DLL' LJJvr*Eyy2&**=9?=1T]]B#'LzzKK&&++  -T  U!0eii>QSgio!ppN$$#//7~,,KKM ..0	*.Y',5[).2ii]+ 2< '+DLL#(,(:(:(<DLL%*.))DLL'r@   c                     | j                   r2| j                   D ]  }| j                  |        d| j                  d<   yy)z0 Handles state == 'absent', removing the secret Trg   N)r/   rN   r!   rG   s     r5   r8   zSecretManager.absenta  s=    <<,, +""6*+&*DLL# r@   )__name__
__module____qualname__r   r?   rI   r=   r9   r^   rN   r7   r8   __classcell__)r4   s   @r5   r   r      s2     D8&4h4<+r@   r   c                  .   t        t        dd      t        ddddg      t        dd      t        dd	
      t        d      t        d      t        dd	
      t        dd	
      t        dd
      	      } ddddgdfg}dg}t        | d||d      }t        |j                  j                  d   d|       	 t        d	dd      } t        ||               |j                  j                  di | y # t        $ rG}|j                  dj                  t        |            t        j                                Y d }~y d }~wt        $ rG}|j                  dj                  t        |            t        j                                Y d }~y d }~ww xY w)Nr\   T)typerequiredr7   r8   )rr   defaultchoices)rr   no_logboolF)rr   rt   path)rr   r`   rE      )	r   r   r   r   r   r   r   r   r   r   r   r   )r   r   z2.1.0)argument_specsupports_check_moderequired_ifmutually_exclusivemin_docker_versionr    )rg   ra   re   z(An unexpected docker error occurred: {0})	exceptionzhAn unexpected requests error occurred when Docker SDK for Python tried to talk to the docker daemon: {0} )r`   r   r   r#   r$   r   	exit_jsonr   r+   r,   r   	traceback
format_excr	   )rz   r|   r}   r    r!   es         r5   mainr   i  s   ut,y8Y:OPuT*fe46" .6595!4
M 
)fj148K
 	 !# -"F FMM((2HfE.
 	'fg&(*'* w>EEiPQlS_h_s_s_uvv .v}}  H  IJ  K  L**, 	 	. 	..s$   :;C6 6	F?=EF=FF__main__)
__future__r   r   r   rr   __metaclass__DOCUMENTATIONEXAMPLESRETURNr&   r:   r   docker.errorsr   r   ImportError@ansible_collections.community.docker.plugins.module_utils.commonr   r	   >ansible_collections.community.docker.plugins.module_utils.utilr
   r   r   +ansible.module_utils.common.text.convertersr   r   r   r   rm   r   r@   r5   <module>r      s    A @\|DL
    	7
 
 LQ+O Q+h,.^ zF g  		s   A A&%A&