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/config.py
""" Return config information """ import copy import fnmatch import logging import os import urllib.parse import salt.config import salt.syspaths as syspaths import salt.utils.data import salt.utils.dictupdate import salt.utils.files import salt.utils.platform import salt.utils.sdb as sdb from salt.loader.context import LoaderContext try: # Gated for salt-ssh (salt.utils.cloud imports msgpack) import salt.utils.cloud HAS_CLOUD = True except ImportError: HAS_CLOUD = False if salt.utils.platform.is_windows(): _HOSTS_FILE = os.path.join( os.environ["SystemRoot"], "System32", "drivers", "etc", "hosts" ) else: _HOSTS_FILE = os.path.join(os.sep, "etc", "hosts") log = logging.getLogger(__name__) __proxyenabled__ = ["*"] __salt_loader__ = LoaderContext() __opts__ = __salt_loader__.named_context("__opts__") # Set up the default values for all systems DEFAULTS = { "mongo.db": "salt", "mongo.password": "", "mongo.port": 27017, "mongo.user": "", "redis.db": "0", "redis.host": "salt", "redis.port": 6379, "test.foo": "unconfigured", "ca.cert_base_path": "/etc/pki", "solr.cores": [], "solr.host": "localhost", "solr.port": "8983", "solr.baseurl": "/solr", "solr.type": "master", "solr.request_timeout": None, "solr.init_script": "/etc/rc.d/solr", "solr.dih.import_options": { "clean": False, "optimize": True, "commit": True, "verbose": False, }, "solr.backup_path": None, "solr.num_backups": 1, "poudriere.config": "/usr/local/etc/poudriere.conf", "poudriere.config_dir": "/usr/local/etc/poudriere.d", "ldap.uri": "", "ldap.server": "localhost", "ldap.port": "389", "ldap.tls": False, "ldap.no_verify": False, "ldap.anonymous": True, "ldap.scope": 2, "ldap.attrs": None, "ldap.binddn": "", "ldap.bindpw": "", "hosts.file": _HOSTS_FILE, "aliases.file": "/etc/aliases", "virt": { "tunnel": False, "images": os.path.join(syspaths.SRV_ROOT_DIR, "salt-images"), }, "docker.exec_driver": "docker-exec", "docker.compare_container_networks": { "static": ["Aliases", "Links", "IPAMConfig"], "automatic": ["IPAddress", "Gateway", "GlobalIPv6Address", "IPv6Gateway"], }, } def backup_mode(backup=""): """ Return the backup mode CLI Example: .. code-block:: bash salt '*' config.backup_mode """ if backup: return backup return option("backup_mode") def manage_mode(mode): """ Return a mode value, normalized to a string CLI Example: .. code-block:: bash salt '*' config.manage_mode """ # config.manage_mode should no longer be invoked from the __salt__ dunder # in Salt code, this function is only being left here for backwards # compatibility. return salt.utils.files.normalize_mode(mode) def valid_fileproto(uri): """ Returns a boolean value based on whether or not the URI passed has a valid remote file protocol designation CLI Example: .. code-block:: bash salt '*' config.valid_fileproto salt://path/to/file """ return urllib.parse.urlparse(uri).scheme in salt.utils.files.VALID_PROTOS def option( value, default=None, omit_opts=False, omit_grains=False, omit_pillar=False, omit_master=False, omit_all=False, wildcard=False, ): """ Returns the setting for the specified config value. The priority for matches is the same as in :py:func:`config.get <salt.modules.config.get>`, only this function does not recurse into nested data structures. Another difference between this function and :py:func:`config.get <salt.modules.config.get>` is that it comes with a set of "sane defaults". To view these, you can run the following command: .. code-block:: bash salt '*' config.option '*' omit_all=True wildcard=True default The default value if no match is found. If not specified, then the fallback default will be an empty string, unless ``wildcard=True``, in which case the return will be an empty dictionary. omit_opts : False Pass as ``True`` to exclude matches from the minion configuration file omit_grains : False Pass as ``True`` to exclude matches from the grains omit_pillar : False Pass as ``True`` to exclude matches from the pillar data omit_master : False Pass as ``True`` to exclude matches from the master configuration file omit_all : True Shorthand to omit all of the above and return matches only from the "sane defaults". .. versionadded:: 3000 wildcard : False If used, this will perform pattern matching on keys. Note that this will also significantly change the return data. Instead of only a value being returned, a dictionary mapping the matched keys to their values is returned. For example, using ``wildcard=True`` with a ``key`` of ``'foo.ba*`` could return a dictionary like so: .. code-block:: python {'foo.bar': True, 'foo.baz': False} .. versionadded:: 3000 CLI Example: .. code-block:: bash salt '*' config.option redis.host """ if omit_all: omit_opts = omit_grains = omit_pillar = omit_master = True if default is None: default = "" if not wildcard else {} if not wildcard: if not omit_opts: if value in __opts__: return __opts__[value] if not omit_grains: if value in __grains__: return __grains__[value] if not omit_pillar: if value in __pillar__: return __pillar__[value] if not omit_master: if value in __pillar__.get("master", {}): return __pillar__["master"][value] if value in DEFAULTS: return DEFAULTS[value] # No match return default else: # We need to do the checks in the reverse order so that minion opts # takes precedence ret = {} for omit, data in ( (omit_master, __pillar__.get("master", {})), (omit_pillar, __pillar__), (omit_grains, __grains__), (omit_opts, __opts__), ): if not omit: ret.update({x: data[x] for x in fnmatch.filter(data, value)}) # Check the DEFAULTS as well to see if the pattern matches it for item in (x for x in fnmatch.filter(DEFAULTS, value) if x not in ret): ret[item] = DEFAULTS[item] # If no matches, return the default return ret or default def merge(value, default="", omit_opts=False, omit_master=False, omit_pillar=False): """ Retrieves an option based on key, merging all matches. Same as ``option()`` except that it merges all matches, rather than taking the first match. CLI Example: .. code-block:: bash salt '*' config.merge schedule """ ret = None if not omit_opts: if value in __opts__: ret = __opts__[value] if isinstance(ret, str): return ret if not omit_master: if value in __pillar__.get("master", {}): tmp = __pillar__["master"][value] if ret is None: ret = tmp if isinstance(ret, str): return ret elif isinstance(ret, dict) and isinstance(tmp, dict): tmp.update(ret) ret = tmp elif isinstance(ret, (list, tuple)) and isinstance(tmp, (list, tuple)): ret = list(ret) + list(tmp) if not omit_pillar: if value in __pillar__: tmp = __pillar__[value] if ret is None: ret = tmp if isinstance(ret, str): return ret elif isinstance(ret, dict) and isinstance(tmp, dict): tmp.update(ret) ret = tmp elif isinstance(ret, (list, tuple)) and isinstance(tmp, (list, tuple)): ret = list(ret) + list(tmp) if ret is None and value in DEFAULTS: return DEFAULTS[value] if ret is None: return default return ret def get( key, default="", delimiter=":", merge=None, omit_opts=False, omit_pillar=False, omit_master=False, omit_grains=False, ): """ .. versionadded:: 0.14.0 Attempt to retrieve the named value from the minion config file, pillar, grains or the master config. If the named value is not available, return the value specified by the ``default`` argument. If this argument is not specified, ``default`` falls back to an empty string. Values can also be retrieved from nested dictionaries. Assume the below data structure: .. code-block:: python {'pkg': {'apache': 'httpd'}} To retrieve the value associated with the ``apache`` key, in the sub-dictionary corresponding to the ``pkg`` key, the following command can be used: .. code-block:: bash salt myminion config.get pkg:apache The ``:`` (colon) is used to represent a nested dictionary level. .. versionchanged:: 2015.5.0 The ``delimiter`` argument was added, to allow delimiters other than ``:`` to be used. This function traverses these data stores in this order, returning the first match found: - Minion configuration - Minion's grains - Minion's pillar data - Master configuration (requires :conf_minion:`pillar_opts` to be set to ``True`` in Minion config file in order to work) This means that if there is a value that is going to be the same for the majority of minions, it can be configured in the Master config file, and then overridden using the grains, pillar, or Minion config file. Adding config options to the Master or Minion configuration file is easy: .. code-block:: yaml my-config-option: value cafe-menu: - egg and bacon - egg sausage and bacon - egg and spam - egg bacon and spam - egg bacon sausage and spam - spam bacon sausage and spam - spam egg spam spam bacon and spam - spam sausage spam spam bacon spam tomato and spam .. note:: Minion configuration options built into Salt (like those defined :ref:`here <configuration-salt-minion>`) will *always* be defined in the Minion configuration and thus *cannot be overridden by grains or pillar data*. However, additional (user-defined) configuration options (as in the above example) will not be in the Minion configuration by default and thus can be overridden using grains/pillar data by leaving the option out of the minion config file. **Arguments** delimiter .. versionadded:: 2015.5.0 Override the delimiter used to separate nested levels of a data structure. merge .. versionadded:: 2015.5.0 If passed, this parameter will change the behavior of the function so that, instead of traversing each data store above in order and returning the first match, the data stores are first merged together and then searched. The pillar data is merged into the master config data, then the grains are merged, followed by the Minion config data. The resulting data structure is then searched for a match. This allows for configurations to be more flexible. .. note:: The merging described above does not mean that grain data will end up in the Minion's pillar data, or pillar data will end up in the master config data, etc. The data is just combined for the purposes of searching an amalgam of the different data stores. The supported merge strategies are as follows: - **recurse** - If a key exists in both dictionaries, and the new value is not a dictionary, it is replaced. Otherwise, the sub-dictionaries are merged together into a single dictionary, recursively on down, following the same criteria. For example: .. code-block:: python >>> dict1 = {'foo': {'bar': 1, 'qux': True}, 'hosts': ['a', 'b', 'c'], 'only_x': None} >>> dict2 = {'foo': {'baz': 2, 'qux': False}, 'hosts': ['d', 'e', 'f'], 'only_y': None} >>> merged {'foo': {'bar': 1, 'baz': 2, 'qux': False}, 'hosts': ['d', 'e', 'f'], 'only_dict1': None, 'only_dict2': None} - **overwrite** - If a key exists in the top level of both dictionaries, the new value completely overwrites the old. For example: .. code-block:: python >>> dict1 = {'foo': {'bar': 1, 'qux': True}, 'hosts': ['a', 'b', 'c'], 'only_x': None} >>> dict2 = {'foo': {'baz': 2, 'qux': False}, 'hosts': ['d', 'e', 'f'], 'only_y': None} >>> merged {'foo': {'baz': 2, 'qux': False}, 'hosts': ['d', 'e', 'f'], 'only_dict1': None, 'only_dict2': None} CLI Example: .. code-block:: bash salt '*' config.get pkg:apache salt '*' config.get lxc.container_profile:centos merge=recurse """ if merge is None: if not omit_opts: ret = salt.utils.data.traverse_dict_and_list( __opts__, key, "_|-", delimiter=delimiter ) if ret != "_|-": return sdb.sdb_get(ret, __opts__) if not omit_grains: ret = salt.utils.data.traverse_dict_and_list( __grains__, key, "_|-", delimiter ) if ret != "_|-": return sdb.sdb_get(ret, __opts__) if not omit_pillar: ret = salt.utils.data.traverse_dict_and_list( __pillar__, key, "_|-", delimiter=delimiter ) if ret != "_|-": return sdb.sdb_get(ret, __opts__) if not omit_master: ret = salt.utils.data.traverse_dict_and_list( __pillar__.get("master", {}), key, "_|-", delimiter=delimiter ) if ret != "_|-": return sdb.sdb_get(ret, __opts__) ret = salt.utils.data.traverse_dict_and_list( DEFAULTS, key, "_|-", delimiter=delimiter ) if ret != "_|-": return sdb.sdb_get(ret, __opts__) else: if merge not in ("recurse", "overwrite"): log.warning( "Unsupported merge strategy '%s'. Falling back to 'recurse'.", merge ) merge = "recurse" merge_lists = salt.config.master_config("/etc/salt/master").get( "pillar_merge_lists" ) data = copy.copy(DEFAULTS) data = salt.utils.dictupdate.merge( data, __pillar__.get("master", {}), strategy=merge, merge_lists=merge_lists ) data = salt.utils.dictupdate.merge( data, __pillar__, strategy=merge, merge_lists=merge_lists ) data = salt.utils.dictupdate.merge( data, __grains__, strategy=merge, merge_lists=merge_lists ) data = salt.utils.dictupdate.merge( data, __opts__, strategy=merge, merge_lists=merge_lists ) ret = salt.utils.data.traverse_dict_and_list( data, key, "_|-", delimiter=delimiter ) if ret != "_|-": return sdb.sdb_get(ret, __opts__) return default def dot_vals(value): """ Pass in a configuration value that should be preceded by the module name and a dot, this will return a list of all read key/value pairs CLI Example: .. code-block:: bash salt '*' config.dot_vals host """ ret = {} for key, val in __pillar__.get("master", {}).items(): if key.startswith(f"{value}."): ret[key] = val for key, val in __opts__.items(): if key.startswith(f"{value}."): ret[key] = val return ret def gather_bootstrap_script(bootstrap=None): """ Download the salt-bootstrap script, and return its location bootstrap URL of alternate bootstrap script CLI Example: .. code-block:: bash salt '*' config.gather_bootstrap_script """ if not HAS_CLOUD: return False, "config.gather_bootstrap_script is unavailable" ret = salt.utils.cloud.update_bootstrap(__opts__, url=bootstrap) if "Success" in ret and ret["Success"]["Files updated"]: return ret["Success"]["Files updated"][0] def items(): """ Return the complete config from the currently running minion process. This includes defaults for values not set in the config file. CLI Example: .. code-block:: bash salt '*' config.items """ return __opts__