
    Vh,                        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Zd dlmZ d dlmZ d dlmZ d d	lmZmZ 	 d d
lmZ dZ	 d dlmZ dZd Zd Z d Z!d Z"d Z#d Z$e%dk(  r e$        yy# e$ r dZY 2w xY w# e$ r dZY 6w xY w)    )absolute_importdivisionprint_functiona,  
module: docker_stack
author: "Dario Zanzico (@dariko)"
short_description: docker stack module
description:
  - Manage docker stacks using the C(docker stack) command on the target node (see examples).
extends_documentation_fragment:
  - community.docker.docker.cli_documentation
  - community.docker.attributes
  - community.docker.attributes.actiongroup_docker
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
  action_group:
    version_added: 3.6.0
  idempotent:
    support: full
options:
  name:
    description:
      - Stack name.
    type: str
    required: true
  state:
    description:
      - Service state.
    type: str
    default: "present"
    choices:
      - present
      - absent
  compose:
    description:
      - List of compose definitions. Any element may be a string referring to the path of the compose file on the target host
        or the YAML contents of a compose file nested as dictionary.
    type: list
    elements: raw
    default: []
  prune:
    description:
      - If true will add the C(--prune) option to the C(docker stack deploy) command. This will have docker remove the services
        not present in the current stack definition.
    type: bool
    default: false
  detach:
    description:
      - If V(false), the C(--detach=false) option is added to the C(docker stack deploy) command, allowing Docker to wait
        for tasks to converge before exiting.
      - If V(true) (default), Docker exits immediately instead of waiting for tasks to converge.
    type: bool
    default: true
    version_added: 4.1.0
  with_registry_auth:
    description:
      - If true will add the C(--with-registry-auth) option to the C(docker stack deploy) command. This will have docker send
        registry authentication details to Swarm agents.
    type: bool
    default: false
  resolve_image:
    description:
      - If set will add the C(--resolve-image) option to the C(docker stack deploy) command. This will have docker query the
        registry to resolve image digest and supported platforms. If not set, docker use "always" by default.
    type: str
    choices: ["always", "changed", "never"]
  absent_retries:
    description:
      - If larger than V(0) and O(state=absent) the module will retry up to O(absent_retries) times to delete the stack until
        all the resources have been effectively deleted. If the last try still reports the stack as not completely removed
        the module will fail.
    type: int
    default: 0
  absent_retries_interval:
    description:
      - Interval in seconds between consecutive O(absent_retries).
    type: int
    default: 1
  docker_cli:
    version_added: 3.6.0
  docker_host:
    version_added: 3.6.0
  tls_hostname:
    version_added: 3.6.0
  api_version:
    version_added: 3.6.0
  ca_path:
    version_added: 3.6.0
  client_cert:
    version_added: 3.6.0
  client_key:
    version_added: 3.6.0
  tls:
    version_added: 3.6.0
  validate_certs:
    version_added: 3.6.0
  cli_context:
    version_added: 3.6.0

requirements:
  - Docker CLI tool C(docker)
  - jsondiff
  - pyyaml
aZ  
stack_spec_diff:
  description: |-
    Dictionary containing the differences between the 'Spec' field
    of the stack services before and after applying the new stack
    definition.
  sample: >
    "stack_spec_diff":
    {'test_stack_test_service': {u'TaskTemplate': {u'ContainerSpec': {delete: [u'Env']}}}}
  returned: on change
  type: dict
aE  
---
- name: Deploy stack from a compose file
  community.docker.docker_stack:
    state: present
    name: mystack
    compose:
      - /opt/docker-compose.yml

- name: Deploy stack from base compose file and override the web service
  community.docker.docker_stack:
    state: present
    name: mystack
    compose:
      - /opt/docker-compose.yml
      - version: '3'
        services:
          web:
            image: nginx:latest
            environment:
              ENVVAR: envvar

- name: Remove stack
  community.docker.docker_stack:
    name: mystack
    state: absent
N)string_types)sleep)	to_native)AnsibleModuleDockerClientDockerException)diffTFdumpc                     | j                  dd|dd      \  }}}t        |      d|z  k(  rg S t        |      j                         j                  d      S )Nstackservicesz--formatz	{{.Name}}Nothing found in stack: %s

)call_clir   stripsplit)client
stack_namercouterrs        q/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/docker/plugins/modules/docker_stack.pydocker_stack_servicesr      sT    ??7J
JP[\LBS~7*DD	S>!''--    c                 v    | j                  dd|      \  }}}|dk7  ry t        j                  |      d   d   }|S )Nserviceinspectr   Spec)r   jsonloads)r   service_namer   r   r   rets         r   docker_service_inspectr&      s@    ??9iFLBS	Qwjjoa (
r   c                    ddg}| j                   j                  d   r|dgz  }| j                   j                  d   s|dgz  }| j                   j                  d   r|dgz  }| j                   j                  d	   r|d
| j                   j                  d	   gz  }|D ]	  }|d|gz  } ||gz  } | j                  | \  }}}|t        |      t        |      fS )Nr   deployprunez--prunedetach--detach=falsewith_registry_authz--with-registry-authresolve_imagez--resolve-imagez--compose-file)moduleparamsr   r   )r   r   compose_filescommandcompose_filer   r   r   s           r   docker_stack_deployr3      s    !G}}G$I;==)$%%}}01*++}}O,%MM((9; 	;% "$ " 	"" 
|G"6??G,LBSy~y~--r   c                 J    i }t        | |      D ]  }t        | |      ||<    |S )N)r   r&   )r   r   r%   r$   s       r   docker_stack_inspectr5      s5    
C-fjA I26<HLIJr   c                 >   dd|g}| j                   j                  d   s|dgz  } | j                  | \  }}}t        |      d|z  k7  r?|dkD  r:t	        |       |dz
  } | j                  | \  }}}t        |      d|z  k7  r|dkD  r:|t        |      t        |      fS )Nr   rmr*   r+   r   r      )r.   r/   r   r   r   )r   r   retriesintervalr1   r   r   r   s           r   docker_stack_rmr;      s    j)G==)$%%"6??G,LBS
C.:ZG
GGVWKhA+&v0C C.:ZG
GGVWK y~y~--r   c                  :   t        t        dd      t        ddg       t        dd	      t        dd	      t        dd	      t        dg d
      t        ddddg      t        dd	      t        dd	      d	d      } t        s| j                  d      S t        s| j                  d      S 	 | j
                  j                  d   }| j
                  j                  d   }| j
                  j                  d   }| j
                  j                  d   }| j
                  j                  d   }|dk(  r
|s| j                  d       g }t        |      D ]  \  }}t        |t              r}t        j                         \  }	}
| j
                  j                  |
       t        j                  |	d      5 }|j                  |
       |j                  t!        |             d d d        t        |t"              r|j                  |       | j                  d|z          t%        | |      }t'        | ||      \  }}}t%        | |      }|dk7  r| j                  d|||       t)        ||      }|j+                         D ]n  }t        ||   t              s||   j-                  d d        ||   j-                  d!d        t/        ||   j+                               r^|j-                  |       p |s | j
                  j1                  d|||"       y | j
                  j1                  d|||t)        ||d#      $       y t3        | |      rWt5        | |||      \  }}}|dk7  r | j
                  j7                  d%|||&       n | j
                  j1                  d||||'       | j
                  j1                  d(       y # 1 sw Y   txY w# t8        $ rG}| j                  d)j;                  t=        |            t?        j@                         *       Y d }~y d }~ww xY w)+NstrT)typerequiredlistraw)r>   elementsdefaultboolF)r>   rC   )alwayschangednever)r>   choicespresentabsent)r>   rC   rH   intr   r8   )	namecomposer)   r*   r,   r-   stateabsent_retriesabsent_retries_interval)argument_specsupports_check_modez5jsondiff is not installed, try 'pip install jsondiff'z/yaml is not installed, try 'pip install pyyaml'rN   rM   rL   rO   rP   z@compose parameter must be a list containing at least one elementwz5compose element '%s' must be a string or a dictionaryz%docker stack up deploy command failed)r   stdoutstderr	UpdatedAtVersion)rF   r   rT   rU   r   )rF   r   rT   rU   stack_spec_diffz"'docker stack down' command failed)msgr   rT   rU   )rF   rY   r   rT   rU   )rF   z(An unexpected Docker error occurred: {0})	exception)!r	   dictHAS_JSONDIFFfailHAS_YAMLr.   r/   	enumerate
isinstancetempfilemkstempadd_cleanup_fileosfdopenappendwrite	yaml_dumpr   r5   r3   	json_diffkeyspopr@   	exit_jsonr   r;   	fail_jsonr
   formatr   	traceback
format_exc)r   rN   rM   rL   rO   rP   r0   icompose_defcompose_file_fdr2   
stack_filebefore_stack_servicesr   r   r   after_stack_servicesbefore_after_differenceskes                       r   mainrz      s   &ed3%Dvu55"&FE"B!u6TUui)XAVW"q9'+'B

 "F {{RSS{{LMMQw$$W---&&y1}}##F+--.>?"(--"6"67P"QI^_M"+G"4 
g;k404<4D4D4F1O\MM22<@?C8 AJ%,,\:"((;)?@A A  \:!((5KK WZe ef
g %9$F!.vt]KLBS#7#E QwCSV_bc'01FH\']$-224 86q94@,Q/33KF,Q/33ItD 8 ; @ @ BC044Q78 ,''!	 (  '' $--,!% ( 
 %VT2.vt^MdeC7MM++@""	 ,  MM++ $"" ,  MM##E#2A A@  w>EEiPQlS_h_s_s_uvvwsL   0DO
 1,N=B6O
 AO
 4O
 ,O
 =A?O
 =O	O
 
	P=PP__main__)&
__future__r   r   r   r>   __metaclass__DOCUMENTATIONRETURNEXAMPLESr"   rd   ra   ro   ansible.module_utils.sixr   timer   +ansible.module_utils.common.text.convertersr   Dansible_collections.community.docker.plugins.module_utils.common_clir	   r
   jsondiffr   ri   r\   ImportErroryamlr   rh   r^   r   r&   r3   r5   r;   rz   __name__ r   r   <module>r      s    C BgR
:  	   1  A
*L&H
..&
.gwT zF W  L  Hs#   A/ A< /A98A9<BB