
    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
mZ d dlmZ d dlmZmZmZmZmZmZ d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona?  
---
module: mongodb_status
short_description: Validates the status of the replicaset.
description:
  - Validates the status of the replicaset.
  - The module expects all replicaset nodes to be PRIMARY, SECONDARY or ARBITER.
  - Will wait until a timeout for the replicaset state to converge if required.
  - Can also be used to lookup the current PRIMARY member (see examples).
author: Rhys Campbell (@rhysmeister)
version_added: "1.0.0"

extends_documentation_fragment:
  - community.mongodb.login_options
  - community.mongodb.ssl_options

options:
  replica_set:
    description:
    - Replicaset name.
    type: str
    default: rs0
  poll:
    description:
      - The maximum number of times to query for the replicaset status before the set converges or we fail.
    type: int
    default: 1
  interval:
    description:
      - The number of seconds to wait between polling executions.
    type: int
    default: 30
  validate:
    description:
      - The type of validate to perform on the replicaset.
      - default, Suitable for most purposes. Validate that there are an odd
        number of servers and one is PRIMARY and the remainder are in a SECONDARY
        or ARBITER state.
      - votes, Check the number of votes is odd and one is a PRIMARY and the
        remainder are in a SECONDARY or ARBITER state. Authentication is
        required here to get the replicaset configuration.
      - minimal, Just checks that one server is in a PRIMARY state with the
         remainder being SECONDARY or ARBITER.
    type: str
    choices:
       - default
       - votes
       - minimal
    default: default
notes:
- Requires the pymongo Python package on the remote host, version 4+.. This
  can be installed using pip or the OS package manager.
  @see U(http://api.mongodb.org/python/current/installation.html)
requirements:
- pymongo
ak  
- name: Check replicaset is healthy, fail if not after first attempt
  community.mongodb.mongodb_status:
    replica_set: rs0
  when: ansible_hostname == "mongodb1"

- name: Wait for the replicaset rs0 to converge, check 5 times, 10 second interval between checks
  community.mongodb.mongodb_status:
    replica_set: rs0
    poll: 5
    interval: 10
  when: ansible_hostname == "mongodb1"

# Get the replicaset status and then lookup the primary's hostname and save to a variable
- name: Ensure replicaset is stable before beginning
  community.mongodb.mongodb_status:
    login_user: "{{ admin_user }}"
    login_password: "{{ admin_user_password }}"
    poll: 3
    interval: 10
  register: rs

- name: Lookup PRIMARY replicaset member
  set_fact:
    primary: "{{ item.key.split('.')[0] }}"
  loop: "{{ lookup('dict', rs.replicaset) }}"
  when: "'PRIMARY' in item.value"
a  
failed:
  description: If the module has failed or not.
  returned: always
  type: bool
iterations:
  description: Number of times the module has queried the replicaset status.
  returned: always
  type: int
msg:
  description: Status message.
  returned: always
  type: str
replicaset:
  description: The last queried status of all the members of the replicaset if obtainable.
  returned: always
  type: dict
N)AnsibleModule)	to_native)missing_required_libmongodb_common_argument_spec
mongo_authPYMONGO_IMP_ERRpymongo_foundget_mongodb_clientc                 <    | j                   j                  d      }|S )zw
    Return the replicaset config document
    https://docs.mongodb.com/manual/reference/command/replSetGetConfig/
    replSetGetConfigadmincommand)clientrss     t/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/mongodb/plugins/modules/mongodb_status.pyreplicaset_configr          
 
		0	1BI    c                 4    d}| d   d   D ]
  }||d   z  } |S )z6
    Return the number of votes in the replicaset
    r   configmembersvotes )config_documentr   members      r   replicaset_votesr       s5     E!(+I6 ! !Lr   c                 <    | j                   j                  d      }|S )z
    Return the replicaset status document from MongoDB
    # https://docs.mongodb.com/manual/reference/command/replSetGetStatus/
    replSetGetStatusr   )r   moduler   s      r   replicaset_statusr$      r   r   c                     | d   S )zH
    Returns the members section of the MongoDB replicaset document
    r   r   )replicaset_documents    r   replicaset_membersr'      s     y))r   c                 .    i }| D ]  }|d   ||d   <    |S )zp
    Returns a version of the members document with
    only the info this module requires: name & stateStr
    stateStrnamer   )members_documentfriendly_documentr   s      r   replicaset_friendly_documentr-      s3    
 " ?,2:,>&.)?r   c                 @    g }| D ]  }|j                  | |           |S )z'
    Return a list of the statuses
    )append)r+   r#   statusesr   s       r   replicaset_statusesr1      s/     H" 2(012Or   c                    d}d}g d}|j                   d   }|dk(  rt        |       dz  dk(  rp| j                  d      dk(  rT| j                  d	      | j                  d
      z   dz  dk(  r+t        t        |       t        |      z
        dk(  rd}d}||fS d}d}||fS d}d}||fS |dk(  rW|dz  dk(  rG| j                  d      dk(  r+t        t        |       t        |      z
        dk(  rd}d}||fS d}d}||fS d}d}||fS |dk(  rG| j                  d      dk(  r+t        t        |       t        |      z
        dk(  rd}d}||fS d}d}||fS |j	                  dj                  |             ||fS )z
    Returns true if the replicaset is in a "good" condition.
    Good is defined as an odd number of servers >= 3, with
    max one primary, and any even amount of
    secondary and arbiter servers
    UnsetN)PRIMARY	SECONDARYARBITERvalidatedefault      r4   r5   r6   r   Tz"replicaset is in a converged stateFz0replicaset is not currently in a converged statez%Even number of servers in replicaset.r   z#Even number of votes in replicaset.minimalz1Invalid value for validate has been provided: {0}msg)paramslencountset	fail_jsonformat)r0   r#   r   r=   statusvalid_statusesr7   s          r   replicaset_goodrF      s    CF8N}}Z(H9x=1!y)Q.nn[1 y12567:;<CMC,??@AE:< 3;9 H6 3;3 :CF0 3;/ 
W	19>y)Q.CMC,??@AE:" 3; H 3; 8CF 3; 
Y	NN9%*HN(;;<AF6C 3;	 FDC 3; 	PWWX`ab3;r   c                 f   d}d}|j                   d   }|j                   d   }d}i }d}d}	||k  r	 |dz  }t        | |      }
t        |
      }t        |      }t	        ||      }|j                   d   dk(  rt        |       }	t        |	      }t        |||      \  }}|r	|||||d}n0|dz  }|||||d	d
}||k(  rnt        j                  |       	 ||k  r||d<   ||d   |fS # t        $ rC}|dz  }d	|d<   t        |      |d<   d}||k(  rY d}~:t        j                  |       Y d}~Zd}~ww xY w)zu
    client - MongoDB Client
    poll - Number of times to poll
    interval - interval between polling attempts
    r   pollintervalNr:   r7   r   )failuresrH   
iterationsr=   
replicasetT)rJ   rH   rK   r=   rL   failedrM   r=   FrJ   )r>   r$   r'   r-   r1   r   r    rF   timesleep	Exceptionstr)r   r#   rK   rJ   rH   rI   rD   
return_docr   r   r&   r   r,   r0   r=   es                   r   replicaset_status_pollrT      s    JH== D}}Z(HFJEF
t
(	%!OJ"3FF"C()<=G <W E*+<fEH}}Z(G3*62(0)(FEBKFC*2&*,6%(,=	?

 A*2&*,6%(,=(,.
 %JJx(A t
V &Jz:e$j00  	%MH#'Jx  #AJuFT!

8$$	%s*   A5C$ 'C$ ;C$ $	D0-D+D++D0c            
      <   t               } | j                  t        dd      t        dd      t        dd      t        dg dd	      
       t        | dddgg      }t        s |j                  t        d      t               |j                  d   }d }t        d|      }	 t        |d      }t        ||d      }t        |      dk(  r|j                  d       	 t        |      \  }}}|d   }	|d   }
du r|j                  |	
       y |j#                  |	
       y # t        $ r(}|j                  dt        |      z         Y d }~d }~ww xY w# t        $ r5}|j                  dj                  t!        |      |             Y d }~d }~ww xY w)Nint   )typer8   r:   rQ   rs0)r8   r   r;   r8   )rX   choicesr8   )rI   rH   replica_setr7   F
login_userlogin_password)argument_specsupports_check_moderequired_togetherpymongo)r=   	exceptionr[   )rM   r[   T)directConnectionz!Unable to connect to database: %sr<   r   z3Parameter 'replica_set' must not be an empty stringrL   rK   z*Unable to query replica_set info: {0}: {1})r=   rL   rK   )r	   updatedictr   r   rB   r   r   r>   r   r
   rP   r   r?   rT   rC   rQ   	exit_json)r^   r#   r[   r=   resultr   rS   rD   rR   rL   rK   s              r   mainrh   2  s   02M5"-ua(eU35*IS\]	   #!(*:;<F
 1)<#2 	 	4 --.K
CF
Q#FTBFFTB ;1RS_"8"HZ-
-
 SZJOSZJO!  Q@9Q<OPPQ  _IPPQTUVQWY\]^^_s0   %D) !E )	E2EE	F&+FF__main__)
__future__r   r   r   rX   __metaclass__DOCUMENTATIONEXAMPLESRETURNrN   ansible.module_utils.basicr   ansible.module_utils._textr   Iansible_collections.community.mongodb.plugins.module_utils.mongodb_commonr   r	   r
   r   r   r   r   r    r$   r'   r-   r1   rF   rT   rh   __name__r   r   r   <module>rs      s    A @7r:
(  4 0 *	1h;1F,P^ zF r   