PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/saltstack/salt/lib/python3.10/site-packages/salt/modules
Viewing File: /opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/mongodb.py
""" Module to provide MongoDB functionality to Salt :configuration: This module uses PyMongo, and accepts configuration details as parameters as well as configuration settings:: mongodb.host: 'localhost' mongodb.port: 27017 mongodb.user: '' mongodb.password: '' This data can also be passed into pillar. Options passed into opts will overwrite options passed into pillar. """ import logging import re import salt.utils.json from salt.exceptions import get_error_message as _get_error_message from salt.utils.versions import Version try: import pymongo HAS_MONGODB = True except ImportError: HAS_MONGODB = False log = logging.getLogger(__name__) def __virtual__(): """ Only load this module if pymongo is installed """ if HAS_MONGODB: return "mongodb" else: return ( False, "The mongodb execution module cannot be loaded: the pymongo library is not" " available.", ) def _connect( user=None, password=None, host=None, port=None, database="admin", authdb=None ): """ Returns a tuple of (user, host, port) with config, pillar, or default values assigned to missing values. """ if not user: user = __salt__["config.option"]("mongodb.user") if not password: password = __salt__["config.option"]("mongodb.password") if not host: host = __salt__["config.option"]("mongodb.host") if not port: port = __salt__["config.option"]("mongodb.port") if not authdb: authdb = database try: conn = pymongo.MongoClient(host=host, port=port) mdb = pymongo.database.Database(conn, database) if user and password: mdb.authenticate(user, password, source=authdb) except pymongo.errors.PyMongoError: log.error("Error connecting to database %s", database) return False return conn def _to_dict(objects): """ Potentially interprets a string as JSON for usage with mongo """ try: if isinstance(objects, str): objects = salt.utils.json.loads(objects) except ValueError as err: log.error("Could not parse objects: %s", err) raise return objects def db_list(user=None, password=None, host=None, port=None, authdb=None): """ List all MongoDB databases user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.db_list <user> <password> <host> <port> """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: return "Failed to connect to mongo database" try: log.info("Listing databases") return conn.list_database_names() except pymongo.errors.PyMongoError as err: log.error(err) return str(err) def db_exists(name, user=None, password=None, host=None, port=None, authdb=None): """ Checks if a database exists in MongoDB name The name of the database to check for. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.db_exists <name> <user> <password> <host> <port> """ dbs = db_list(user, password, host, port, authdb=authdb) if isinstance(dbs, str): return False return name in dbs def db_remove(name, user=None, password=None, host=None, port=None, authdb=None): """ Remove a MongoDB database name The name of the database to remove. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.db_remove <name> <user> <password> <host> <port> """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: return "Failed to connect to mongo database" try: log.info("Removing database %s", name) conn.drop_database(name) except pymongo.errors.PyMongoError as err: log.error("Removing database %s failed with error: %s", name, err) return str(err) return True def _version(mdb): return mdb.command("buildInfo")["version"] def version( user=None, password=None, host=None, port=None, database="admin", authdb=None ): """ Get MongoDB instance version user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.version <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: err_msg = f"Failed to connect to MongoDB database {host}:{port}" log.error(err_msg) return (False, err_msg) try: mdb = pymongo.database.Database(conn, database) return _version(mdb) except pymongo.errors.PyMongoError as err: log.error("Listing users failed with error: %s", err) return str(err) def user_find( name, user=None, password=None, host=None, port=None, database="admin", authdb=None ): """ Get single user from MongoDB name The name of the user to find. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. database The MongoDB database to use when looking for the user. Default is ``admin``. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.user_find <name> <user> <password> <host> <port> <database> <authdb> """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: err_msg = f"Failed to connect to MongoDB database {host}:{port}" log.error(err_msg) return (False, err_msg) mdb = pymongo.database.Database(conn, database) try: return mdb.command("usersInfo", name)["users"] except pymongo.errors.PyMongoError as err: log.error("Listing users failed with error: %s", err) return (False, str(err)) def user_list( user=None, password=None, host=None, port=None, database="admin", authdb=None ): """ List users of a MongoDB database user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. database The MongoDB database to use when listing users. Default is ``admin``. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.user_list <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: return "Failed to connect to mongo database" try: log.info("Listing users") mdb = pymongo.database.Database(conn, database) output = [] mongodb_version = _version(mdb) if Version(mongodb_version) >= Version("2.6"): for user in mdb.command("usersInfo")["users"]: output.append({"user": user["user"], "roles": user["roles"]}) else: for user in mdb.system.users.find(): output.append( {"user": user["user"], "readOnly": user.get("readOnly", "None")} ) return output except pymongo.errors.PyMongoError as err: log.error("Listing users failed with error: %s", err) return str(err) def user_exists( name, user=None, password=None, host=None, port=None, database="admin", authdb=None ): """ Checks if a user exists in MongoDB user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. database The MongoDB database to use when checking if the user exists. Default is ``admin``. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.user_exists <name> <user> <password> <host> <port> <database> """ users = user_list(user, password, host, port, database, authdb) if isinstance(users, str): return "Failed to connect to mongo database" for user in users: if name == dict(user).get("user"): return True return False def user_create( name, passwd, user=None, password=None, host=None, port=None, database="admin", authdb=None, roles=None, ): """ Create a MongoDB user name The name of the user to create. passwd The password for the user that is being created. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. database The MongoDB database to use when checking if the user exists. Default is ``admin``. authdb The MongoDB database to use for authentication. Default is None. roles The roles that should be associated with the user. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.user_create <user_name> <user_password> <roles> <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: return "Failed to connect to mongo database" if not roles: roles = [] _roles = [{"role": _role, "db": database} for _role in roles] try: log.info("Creating user %s", name) mdb = pymongo.database.Database(conn, database) mdb.command("createUser", name, pwd=passwd, roles=_roles) except pymongo.errors.PyMongoError as err: log.error("Creating user %s failed with error: %s", name, err) return False return True def user_remove( name, user=None, password=None, host=None, port=None, database="admin", authdb=None ): """ Remove a MongoDB user name The name of the user that should be removed. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.user_remove <name> <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port) if not conn: return "Failed to connect to mongo database" try: log.info("Removing user %s", name) mdb = pymongo.database.Database(conn, database) mdb.command("dropUser", name) except pymongo.errors.PyMongoError as err: log.error("Removing user %s failed with error: %s", name, err) return False return True def user_roles_exists( name, roles, database, user=None, password=None, host=None, port=None, authdb=None ): """ Checks if a user of a MongoDB database has specified roles name The name of the user to check for the specified roles. roles The roles to check are associated with the specified user. database The database to check has the specified roles for the specified user. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Examples: .. code-block:: bash salt '*' mongodb.user_roles_exists johndoe '["readWrite"]' dbname admin adminpwd localhost 27017 .. code-block:: bash salt '*' mongodb.user_roles_exists johndoe '[{"role": "readWrite", "db": "dbname" }, {"role": "read", "db": "otherdb"}]' dbname admin adminpwd localhost 27017 """ try: roles = _to_dict(roles) except Exception: # pylint: disable=broad-except return "Roles provided in wrong format" users = user_list(user, password, host, port, database, authdb) if isinstance(users, str): return "Failed to connect to mongo database" for user in users: if name == dict(user).get("user"): for role in roles: # if the role was provided in the shortened form, we convert it to a long form if not isinstance(role, dict): role = {"role": role, "db": database} if role not in dict(user).get("roles", []): return False return True return False def user_grant_roles( name, roles, database, user=None, password=None, host=None, port=None, authdb=None ): """ Grant one or many roles to a MongoDB user name The user to grant the specified roles to. roles The roles to grant to the specified user. database The database to great the roles against for the specified user. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Examples: .. code-block:: bash salt '*' mongodb.user_grant_roles johndoe '["readWrite"]' dbname admin adminpwd localhost 27017 .. code-block:: bash salt '*' mongodb.user_grant_roles janedoe '[{"role": "readWrite", "db": "dbname" }, {"role": "read", "db": "otherdb"}]' dbname admin adminpwd localhost 27017 """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: return "Failed to connect to mongo database" try: roles = _to_dict(roles) except Exception: # pylint: disable=broad-except return "Roles provided in wrong format" try: log.info("Granting roles %s to user %s", roles, name) mdb = pymongo.database.Database(conn, database) mdb.command("grantRolesToUser", name, roles=roles) except pymongo.errors.PyMongoError as err: log.error( "Granting roles %s to user %s failed with error: %s", roles, name, err ) return str(err) return True def user_revoke_roles( name, roles, database, user=None, password=None, host=None, port=None, authdb=None ): """ Revoke one or many roles to a MongoDB user user The user to connect to MongoDB as. Default is None. roles The roles to revoke from the specified user. database The database to revoke the roles from for the specified user. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Examples: .. code-block:: bash salt '*' mongodb.user_revoke_roles johndoe '["readWrite"]' dbname admin adminpwd localhost 27017 .. code-block:: bash salt '*' mongodb.user_revoke_roles janedoe '[{"role": "readWrite", "db": "dbname" }, {"role": "read", "db": "otherdb"}]' dbname admin adminpwd localhost 27017 """ conn = _connect(user, password, host, port, authdb=authdb) if not conn: return "Failed to connect to mongo database" try: roles = _to_dict(roles) except Exception: # pylint: disable=broad-except return "Roles provided in wrong format" try: log.info("Revoking roles %s from user %s", roles, name) mdb = pymongo.database.Database(conn, database) mdb.command("revokeRolesFromUser", name, roles=roles) except pymongo.errors.PyMongoError as err: log.error( "Revoking roles %s from user %s failed with error: %s", roles, name, err ) return str(err) return True def collection_create( collection, user=None, password=None, host=None, port=None, database="admin", authdb=None, ): """ .. versionadded:: 3006.0 Create a collection in the specified database. collection The name of the collection to create. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.collection_create mycollection <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" try: log.info("Creating %s.%s", database, collection) mdb = pymongo.database.Database(conn, database) mdb.create_collection(collection) except pymongo.errors.PyMongoError as err: log.error( "Creating collection %r.%r failed with error %s", database, collection, err ) return err return True def collection_drop( collection, user=None, password=None, host=None, port=None, database="admin", authdb=None, ): """ .. versionadded:: 3006.0 Drop a collection in the specified database. collection The name of the collection to drop. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.collection_drop mycollection <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" try: log.info("Dropping %s.%s", database, collection) mdb = pymongo.database.Database(conn, database) mdb.drop_collection(collection) except pymongo.errors.PyMongoError as err: log.error( "Creating collection %r.%r failed with error %s", database, collection, err ) return err return True def collections_list( user=None, password=None, host=None, port=None, database="admin", authdb=None, ): """ .. versionadded:: 3006.0 List the collections available in the specified database. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.collections_list mycollection <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" try: mdb = pymongo.database.Database(conn, database) ret = mdb.list_collection_names() except pymongo.errors.PyMongoError as err: log.error("Listing collections failed with error %s", err) return err return ret def insert( objects, collection, user=None, password=None, host=None, port=None, database="admin", authdb=None, ): """ Insert an object or list of objects into a collection objects The objects to insert into the collection, should be provided as a list. collection The collection to insert the objects into. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.insert '[{"foo": "FOO", "bar": "BAR"}, {"foo": "BAZ", "bar": "BAM"}]' mycollection <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" try: objects = _to_dict(objects) except Exception as err: # pylint: disable=broad-except return err try: log.info("Inserting %r into %s.%s", objects, database, collection) mdb = pymongo.database.Database(conn, database) col = getattr(mdb, collection) ids = col.insert_many(objects) return ids.acknowledged except pymongo.errors.PyMongoError as err: log.error("Inserting objects %r failed with error %s", objects, err) return err def update_one( objects, collection, user=None, password=None, host=None, port=None, database="admin", authdb=None, ): """ Update an object into a collection http://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.update_one .. versionadded:: 2016.11.0 objects The objects to update in the collection, should be provided as a list. collection The collection to insert the objects into. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.update_one '{"_id": "my_minion"} {"bar": "BAR"}' mycollection <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" objects = str(objects) objs = re.split(r"}\s+{", objects) if len(objs) != 2: return ( "Your request does not contain a valid " + '\'{_"id": "my_id"} {"my_doc": "my_val"}\'' ) objs[0] = objs[0] + "}" objs[1] = "{" + objs[1] document = [] for obj in objs: try: obj = _to_dict(obj) document.append(obj) except Exception as err: # pylint: disable=broad-except return err _id_field = document[0] _update_doc = document[1] # need a string to perform the test, so using objs[0] test_f = find(collection, objs[0], user, password, host, port, database, authdb) if not isinstance(test_f, list): return "The find result is not well formatted. An error appears; cannot update." elif not test_f: return "Did not find any result. You should try an insert before." elif len(test_f) > 1: return "Too many results. Please try to be more specific." else: try: log.info("Updating %r into %s.%s", _id_field, database, collection) mdb = pymongo.database.Database(conn, database) col = getattr(mdb, collection) ids = col.update_one(_id_field, {"$set": _update_doc}) nb_mod = ids.modified_count return f"{nb_mod} objects updated" except pymongo.errors.PyMongoError as err: log.error("Updating object %s failed with error %s", objects, err) return err def find( collection, query=None, user=None, password=None, host=None, port=None, database="admin", authdb=None, ): """ Find an object or list of objects in a collection collection The collection to find the objects in. query The query to use when locating objects in the collection. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.find mycollection '[{"foo": "FOO", "bar": "BAR"}]' <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" try: query = _to_dict(query) except Exception as err: # pylint: disable=broad-except return err try: log.info("Searching for %r in %s", query, collection) mdb = pymongo.database.Database(conn, database) col = getattr(mdb, collection) if isinstance(query, list): ret = [] for _query in query: res = col.find(_query) _ret = [_res for _res in res] ret.extend(_ret) else: res = col.find(query) ret = [_res for _res in res] return ret except pymongo.errors.PyMongoError as err: log.error("Searching objects failed with error: %s", err) return err def remove( collection, query=None, user=None, password=None, host=None, port=None, database="admin", w=1, authdb=None, ): """ Remove an object or list of objects from a collection collection The collection to remove objects from based on the query. query Query to determine which objects to remove. user The user to connect to MongoDB as. Default is None. password The password to use to connect to MongoDB as. Default is None. host The host where MongoDB is running. Default is None. port The host where MongoDB is running. Default is None. database The database where the collection is. w The number of matches to remove from the collection. authdb The MongoDB database to use for authentication. Default is None. CLI Example: .. code-block:: bash salt '*' mongodb.remove mycollection '[{"foo": "FOO", "bar": "BAR"}, {"foo": "BAZ", "bar": "BAM"}]' <user> <password> <host> <port> <database> """ conn = _connect(user, password, host, port, database, authdb) if not conn: return "Failed to connect to mongo database" try: query = _to_dict(query) except Exception as err: # pylint: disable=broad-except return _get_error_message(err) try: log.info("Removing %r from %s", query, collection) mdb = pymongo.database.Database(conn, database) col = getattr(mdb, collection) deleted_count = 0 if isinstance(query, list): for _query in query: for count in range(0, w): res = col.delete_one(_query) deleted_count += res.deleted_count else: for count in range(0, w): res = col.delete_one(query) deleted_count += res.deleted_count return f"{deleted_count} objects removed" except pymongo.errors.PyMongoError as err: log.error("Removing objects failed with error: %s", _get_error_message(err)) return _get_error_message(err)