
    VhO'                         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m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 dlmZ dZ G d de      Zy# e$ r 	 d dlmZ dZn# e$ r dZY nw xY wY *w xY w)    )absolute_importdivisionprint_functiona  
name: mongodb
author:
  - Marcos Diez (@marcosdiez)
version_added: "1.0.0"
short_description: lookup info from MongoDB
description:
    - 'The ``MongoDB`` lookup runs the *find()* command on a given *collection* on a given *MongoDB* server.'
    - 'The result is a list of jsons, so slightly different from what PyMongo returns. In particular, *timestamps* are converted to epoch integers.'
options:
    connect_string:
        description:
            - Can be any valid MongoDB connection string, supporting authentication, replica sets, etc.
            - "More info at U(https://docs.mongodb.org/manual/reference/connection-string/)"
        default: "mongodb://localhost/"
    database:
        description:
            - Name of the database which the query will be made
        required: True
    collection:
        description:
            - Name of the collection which the query will be made
        required: True
    filter:
        description:
            - Criteria of the output
        type: 'dict'
        default: {}
    projection:
        description:
            - Fields you want returned
        type: dict
        default: {}
    skip:
        description:
            - How many results should be skipped
        type: integer
    limit:
        description:
            - How many results should be shown
        type: integer
    sort:
        description:
            - Sorting rules.
            - Please use the strings C(ASCENDING) and C(DESCENDING) to set the order.
            - Check the example for more information.
        type: list
        elements: list
        default: []
    extra_connection_parameters:
        description:
            - Extra connection parameters that to be sent to pymongo.MongoClient
            - Check the example to see how to connect to mongo using an SSL certificate.
            - "All possible parameters are here: U(https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient)"
        type: dict
        default: {}
notes:
    - "Please check https://pymongo.readthedocs.io/en/stable/api/pymongo/collection.html#pymongo.collection.Collection.find for more details."
requirements:
    - pymongo >= 2.4 (python library)
a	  
- hosts: localhost
  gather_facts: false
  vars:
    mongodb_parameters:
      #mandatory parameters
      database: 'local'
      collection: "startup_log"
      #optional
      connection_string: "mongodb://localhost/"
      # connection_string: "mongodb://username:password@my.server.com:27017/"
      # extra_connection_parameters: { "ssl" : True , "ssl_certfile": /etc/self_signed_certificate.pem" }
      #optional query  parameters, we accept any parameter from the normal mongodb query.
      # filter:  { "hostname": "u18" }
      projection: { "pid": True    , "_id" : False , "hostname" : True }
      skip: 0
      limit: 1
      sort:  [ [ "startTime" , "ASCENDING" ] , [ "age", "DESCENDING" ] ]
  tasks:
    - debug: msg="The PID from MongoDB is {{ lookup('mongodb', mongodb_parameters ).pid }}"

    - debug: msg="The HostName from the MongoDB server is {{ lookup('mongodb', mongodb_parameters ).hostname }}"

    - debug: msg="Mongo DB is stored at {{ lookup('mongodb', mongodb_parameters_inline )}}"
      vars:
        mongodb_parameters_inline:
          database: 'local'
          collection: "startup_log"
          connection_string: "mongodb://localhost/"
          limit: 1
          projection: { "cmdline.storage": True }

      # lookup syntax, does the same as below
    - debug: msg="The hostname is {{ item.hostname }} and the pid is {{ item.pid }}"
      loop: "{{ lookup('mongodb', mongodb_parameters, wantlist=True) }}"

      # query syntax, does the same as above
    - debug: msg="The hostname is {{ item.hostname }} and the pid is {{ item.pid }}"
      loop: "{{ query('mongodb', mongodb_parameters) }}"

    - name: "Raw output from the mongodb lookup (a json with pid and hostname )"
      debug: msg="{{ lookup('mongodb', mongodb_parameters) }}"

    - name: "Yet another mongodb query, now with the parameters on the task itself"
      debug: msg="pid={{item.pid}} hostname={{item.hostname}} version={{ item.buildinfo.version }}"
      with_mongodb:
        - database: 'local'
          collection: "startup_log"
          connection_string: "mongodb://localhost/"
          limit: 1
          projection: { "pid": True    , "hostname": True , "buildinfo.version": True }

    # Please notice this specific query may result more than one result. This is expected
    - name: "Shows the whole output from mongodb"
      debug: msg="{{ item }}"
      with_mongodb:
        - database: 'local'
          collection: "startup_log"
          connection_string: "mongodb://localhost/"


zr
  _list_of_jsons:
    description:
      - a list of JSONs with the results of the MongoDB query.
    type: list
N)string_typesinteger_types)	to_native)AnsibleError)
LookupBase)	ASCENDING
DESCENDING)ConnectionFailure)MongoClientT)
ConnectionFc                   *    e Zd Zd Zd Zd Zd Zd Zy)LookupModulec                     ||S t        |t              st        dj                  |            |D ]  }| j	                  |        |S )Nz2Error. Sort parameters must be a list, not [ {0} ])
isinstancelistr	   format _convert_sort_string_to_constant)selfsort_parameteritems      l/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/mongodb/plugins/lookup/mongodb.py_fix_sort_parameterz LookupModule._fix_sort_parameter   sU    !!!.$/T[[\jkll" 	8D11$7	8     c                 j    |d   }|j                         }|dk(  r
t        |d<   y |dk(  r
t        |d<   y y )N   r   r   )upperr   r   )r   r   original_sort_order
sort_orders       r   r   z-LookupModule._convert_sort_string_to_constant   sA    "1g(..0
%DG=( DG )r   c                    ||S t        |t        t        t        fz         r|S t        |t              r|S t        |t
              r+g }|D ]"  }|j                  | j                  |             $ |S t        |t              r2i }|j                         D ]  }||   }| j                  |      ||<    |S t        |t        j                        r(|t        j                  ddd      z
  j                         S dj                  |      S )Ni  r   z{0})r   r   floatboolr   r   append"convert_mongo_result_to_valid_jsondictkeysdatetimetotal_secondsr   )r   resultnew_listelemnew_dictkeyvalues          r   r&   z/LookupModule.convert_mongo_result_to_valid_json   s    >Mfmudm;<Mfl+M%H O G G MNOO%H{{} Os $ G G NO O 1 12X..tQ::JJLL ==((r   c                     	 | j                  |      S # t        $ r*}t        dj                  t	        |                   |d }~ww xY w)Nz1There was an exception on the mongodb_lookup: {0})_run_helper	Exceptionprintr   r   )r   terms	variableskwargses        r   runzLookupModule.run   sF    	##E** 	FMMiXYl[\G	s    	A%AAc                 *   t         st        d      g }|D ]  }dD ]   }||vst        dj                  |             |j                  dd      }|d   }|d   }|j                  di       }d|v r|d= d|v r|d= |d= |d= d	|v r| j	                  |d	         |d	<   	 t        |fi |}	 |	|   |   j                  di |}
|
D ]$  }| j                  |      }|j                  |       &  |S # t        $ r}t        d
t        |      z        d }~ww xY w)NzJpymongo is required in the control node (this machine) for mongodb lookup.)database
collectionz!missing mandatory parameter [{0}]connection_stringzmongodb://localhostr;   r<   extra_connection_parameterssortz!unable to connect to database: %s )pymongo_foundr	   r   getr   r   findr&   r%   r   str)r   r5   rettermrequired_parameterr=   r;   r<   r>   clientresultsr+   r8   s                r   r2   zLookupModule._run_helper   sx   lmm 	RD&B h"%T1&'K'R'RSe'fggh !%)=?U VK(Hm,J*.((3QSU*V'-578#t+-.[!]#$ $ 8 8g GW	R$%6V:UV;&*:6;;CdC% 'F!DDVLFJJv&'5	RB 
 % R"#G#a&#PQQRs   AC--	D6DDN)__name__
__module____qualname__r   r   r&   r9   r2   r@   r   r   r   r      s    
!)2%r   r   )
__future__r   r   r   type__metaclass__DOCUMENTATIONEXAMPLESRETURNr)   ansible.module_utils.sixr   r   ansible.module_utils._textr   ansible.errorsr	   ansible.plugins.lookupr
   pymongor   r   pymongo.errorsr   r   rA   ImportErrorr   r   r@   r   r   <module>rZ      s   & C B<|=~
  @ 0 ' --0# M\: \  5   s5   A A3A# A3#A-*A3,A--A32A3