
    Vh!+                         d dl mZmZmZ eZd dlZd dlmZ 	 d dl	m
Z
mZ d dlmZ d dlmZ d dlmZ  G d d	e      Zy# e$ r Y %w xY w)
    )absolute_importdivisionprint_functionN)sleep)APIErrorNotFound)	to_native)LooseVersion)AnsibleDockerClientc                   t     e Zd Z fdZd ZddZd Zd Zd ZddZ	ddZ
d	 Zdd
Zd Z fdZddZ xZS )AnsibleDockerSwarmClientc                 ,    t        t        | 
  di | y )N )superr   __init__)selfkwargs	__class__s     o/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/docker/plugins/module_utils/swarm.pyr   z!AnsibleDockerSwarmClient.__init__   s    &6@@    c                    	 | j                         }r<t	        j
                  |d      }t	        j                  |      }|d   d   r|d   d   S y# t        $ r'}| j                  dt        |      z         Y d}~jd}~ww xY w)z
        Get the 'NodeID' of the Swarm node or 'None' if host is not in Swarm. It returns the NodeID
        of Docker host the module is executed on
        :return:
            NodeID of host or 'None' if not part of Swarm
        z%Failed to get node information for %sNFensure_asciiSwarmNodeID)infor   failr	   jsondumpsloads)r   r   excjson_str
swarm_infos        r   get_swarm_node_idz*AnsibleDockerSwarmClient.get_swarm_node_id   s    	P99;D zz$U;HH-J'"8,!'*844  	PII=	#NOO	Ps   A 	BA<<Bc                 @   |T	 | j                         }r@t        j                  |d      }t        j
                  |      }|d   d   ry|d   d   d	v ryy	 | j                  |
      }|d   yy# t        $ r | j                  d       Y yw xY w# t        $ r Y yw xY w)a  
        Checking if host is part of Docker Swarm. If 'node_id' is not provided it reads the Docker host
        system information looking if specific key in output exists. If 'node_id' is provided then it tries to
        read node information assuming it is run on Swarm manager. The get_node_inspect() method handles exception if
        it is not executed on Swarm manager

        :param node_id: Node identifier
        :return:
            bool: True if node is part of Swarm, False otherwise
        NzFailed to get host information.Fr   r   r   TLocalNodeState)activependinglockednode_idID)r   r   r   r   r   r    get_node_inspect)r   r+   r   r"   r#   	node_infos         r   check_if_swarm_nodez,AnsibleDockerSwarmClient.check_if_swarm_node3   s     ?=yy{ ::d?!ZZ1
g&x0g&'78<[[ 11'1B	 *'  =		;<=  s#   A1 B 1BB	BBc                 D    	 | j                          y# t        $ r Y yw xY w)a  
        Checks if node role is set as Manager in Swarm. The node is the docker host on which module action
        is performed. The inspect_swarm() will fail if node is not a manager

        :return: True if node is Swarm Manager, False otherwise
        TF)inspect_swarmr   r   s    r   check_if_swarm_managerz/AnsibleDockerSwarmClient.check_if_swarm_managerW   s(    	  		s    	c                 H    | j                         s| j                  d       yy)zn
        If host is not a swarm manager then Ansible task on this host should end with 'failed' state
        zAError running docker swarm module: must run on swarm manager nodeN)r3   r   r2   s    r   fail_task_if_not_swarm_managerz7AnsibleDockerSwarmClient.fail_task_if_not_swarm_managere   s"     **,IIYZ -r   c                 F    | j                         r| j                         syy)a  
        Checks if node role is set as Worker in Swarm. The node is the docker host on which module action
        is performed. Will fail if run on host that is not part of Swarm via check_if_swarm_node()

        :return: True if node is Swarm Worker, False otherwise
        TF)r/   r3   r2   s    r   check_if_swarm_workerz.AnsibleDockerSwarmClient.check_if_swarm_workerl   s!     ##%d.I.I.Kr   c                     |dk  rd}|| j                         }t        d|      D ]1  }|dkD  rt        d       | j                  |      }|d   d   dk(  s1 y y	)
a[  
        Checks if node status on Swarm manager is 'down'. If node_id is provided it query manager about
        node specified in parameter, otherwise it query manager itself. If run on Swarm Worker node or
        host that is not part of Swarm it will fail the playbook

        :param repeat_check: number of check attempts with 5 seconds delay between them, by default check only once
        :param node_id: node ID or name, if None then method will try to get node_id of host module run on
        :return:
            True if node is part of swarm but its state is down, False otherwise
           r      r*   StatusStatedownTF)r$   ranger   r-   )r   r+   repeat_checkretryr.   s        r   check_if_swarm_node_is_downz4AnsibleDockerSwarmClient.check_if_swarm_node_is_downx   su     !L?,,.G1l+ 	Eqya--g->I"7+v5	 r   c                    || j                         }|| j                  d       	 | j                  |      }t        j                  d	
      }t        j                  |      }d|v rf|d   j                  d      rR|d   d   j                  d      }|dk(  r&|d   d   j                  dd      d   xs |d   d   }n|d   d   }||d   d<   |S # t        $ r]}|j                  dk(  r| j                  d       |j                  dk(  r|rY d}~y| j                  dt        |      z         Y d}~d}~wt        $ r}| j                  d|z         Y d}~d}~ww xY w)aj  
        Returns Swarm node info as in 'docker node inspect' command about single node

        :param skip_missing: if True then function will return None instead of failing the task
        :param node_id: node ID or name, if None then method will try to get node_id of host module run on
        :return:
            Single node information structure
        NzFailed to get node information.r*     DCannot inspect node: To inspect node execute module on Swarm Manageri  *Error while reading from Swarm manager: %sError inspecting swarm node: %sFr   ManagerStatusLeaderAddr:r9   r   r;   )r$   r   inspect_noder   status_coder	   	Exceptionr   r   r    getcountsplit)r   r+   skip_missingr.   r!   r"   count_colonsswarm_leader_ips           r   r-   z)AnsibleDockerSwarmClient.get_node_inspect   sn    ?,,.G?II78
	?))'):I ::ie<JJx(	i')--h7  )9&AGGL1$&/&@&H&N&NsTU&VWX&Y&x]fgo]pqw]xO&/&9&&AO.=	(#F+/  	U#%		`a#%IIBYs^STT 	?II7#=>>	?s)   C 	E1D2D22E>EEc                 p   	 | j                         }t        j                  d      }t        j                  |      }|S # t        $ rG}|j                  dk(  r| j                  d       | j                  dt	        |      z         Y d}~yd}~wt
        $ r}| j                  d|z         Y d}~d}~ww xY w)z
        Returns Swarm node info as in 'docker node inspect' command about all registered nodes

        :return:
            Structure with information about all nodes
        rC   rD   rE   NrF   Fr   )	nodesr   rL   r   r	   rM   r   r   r    )r   r.   r!   r"   s       r   get_all_nodes_inspectz.AnsibleDockerSwarmClient.get_all_nodes_inspect   s    	?

I ::ie<JJx(	  	U#%		`aIIBYs^STT 	?II7#=>>	?s#   A   	B5	=BB5B00B5c                 (   g }| j                         }|y|dk(  r |D ]  }|j                  |d   d           |S |dk(  r|D ]  }i }|j                  d|d   i       |j                  d|d   d   i       |j                  d|d   d   i       |j                  d	|d
   d	   i       d|v r6|d   d   du r|j                  ddi       |j                  d|d   d   i       |j                  d|d   d   d   i       |j                  |        |S y)a{  
        Returns list of nodes registered in Swarm

        :param output: Defines format of returned data
        :return:
            If 'output' is 'short' then return data is list of nodes hostnames registered in Swarm,
            if 'output' is 'long' then returns data is list of dict containing the attributes as in
            output of command 'docker node ls'
        NshortDescriptionHostnamelongr,   r;   r<   AvailabilitySpecrG   rH   TReachabilityEngineVersionEngine)rV   appendupdate)r   output
nodes_listnodes_inspectnodenode_propertys         r   get_all_nodes_listz+AnsibleDockerSwarmClient.get_all_nodes_list   sl    
224 W% C!!$}"5j"ABC( % v% 1 "$$dDJ%78$$j$}2Ej2Q%RS$$hXw0G%HI$$nd6l>6R%ST"d*O,X6$>%,,h-=>!((/4;PQ_;`)ab$$otM7J87TUd7e%fg!!-01"  r   c                 0    | j                  |      d   d   S )NrY   rZ   )r-   )r   nodeids     r   get_node_name_by_idz,AnsibleDockerSwarmClient.get_node_name_by_id   s    $$V,];JGGr   c                 Z    | j                   t        d      k  ry t        t        |          S )Nz2.7.0)docker_py_versionr
   r   r   get_unlock_key)r   r   s    r   rn   z'AnsibleDockerSwarmClient.get_unlock_key   s*    !!L$99-tCEEr   c                    	 | j                  |      }t        j                  d      }t        j                  |      }|S # t        $ r1}|du r| j                  dt        |      z         nY d}~yY d}~cd}~wt        $ r>}|j
                  dk(  r| j                  d       | j                  d|z         Y d}~d}~wt        $ r}| j                  d|z         Y d}~d}~ww xY w)a9  
        Returns Swarm service info as in 'docker service inspect' command about single service

        :param service_id: service ID or name
        :param skip_missing: if True then function will return None instead of failing the task
        :return:
            Single service information structure
        FrE   NrC   zJCannot inspect service: To inspect service execute module on Swarm Managerz"Error inspecting swarm service: %sr   )
inspect_servicer   r   r	   r   rL   rM   r   r   r    )r   
service_idrQ   service_infor!   r"   s         r   get_service_inspectz,AnsibleDockerSwarmClient.get_service_inspect   s    	B//
;L ::l?zz(+  	u$		FSVWX Y  	B#%		fgII:S@AA 	BII:S@AA	Bs/   A 	C%
"A66C%4B;;C%C  C%)N)Nr9   )NF)rX   )F)__name__
__module____qualname__r   r$   r/   r3   r5   r7   rA   r-   rV   rh   rk   rn   rs   __classcell__)r   s   @r   r   r      sK    A("H[
4)V(%NHF
r   r   )
__future__r   r   r   type__metaclass__r   timer   docker.errorsr   r   ImportError+ansible.module_utils.common.text.convertersr	   Aansible_collections.community.docker.plugins.module_utils.versionr
   @ansible_collections.community.docker.plugins.module_utils.commonr   r   r   r   r   <module>r      sR    C B  	0
 B Z `2   		s   > AA