@Ep=qMpN9E=ldwL&2ynW7m9GLY@jM4E8eI58#PmN zpyNhxXI(!s+*)sAvBA|z-boeDD)W0iWK9~{stlf8 @s2(XSDWgs=*PZOV;A(4Ww_{JBP2|kS}nr;pVr3) z1srg-2-`eC1~Nt5!23_ey*m5nim}NHZyUu<^*I1~EiiGckJFAtTwviVyhKO{u5!(3 zqQ-wld3oXv*Z(fdcL8}Bdz>=qp_)Cth3~ TIQ$5; zD5UEo3i@5j3(=&_jFmU7L8UMBV}B^f@v;9n(|~ZuZDfkd49{3 h*$;4d_okV zM(!t-jD01*PdOq`WF8Hi6h3cA`XW0%LgM@B(_R>ee>Zm}uz>Qv8Z5;kExf4f4K~~B z8lspkn-B*>N!`V4if4wsA8{b0l~7>6`oUL3f(lBA= D438y+Puue0wPEDYkqDy(`Rt#Es!9n z<)!TA19bN?R5sS#J9IU_<0myiWBpooL)K*5Y@Or|h2kCRwO_e1)6jSEinl>{op|uE zb{ GD$a!c+;mOeb^( FcQ7i}F<}PUW`3l$N3H_c&pY>6Qo1VqVjjEG;cHqR^WTmy4$GEO};ZtjxyI3S@6U zVklI6CwaQ8aN%K_IP (*x z%uuYpLiLE+YRjy4a7(^D+ul S*8J(DP{YIXLgphkH}+N7541i`7jFW_*ehaRCTz9n9vss>i&l!HQ_W-u|IYQ z@m^NC5#^neVPa#o34Blq#-x8kd2Cq;{52)Y&aolXj3hP?LXBCev^^X_&o_(z-wdhW z@UMO6V^_7=9n?y(9i83P+mO;8jAf6yjQ_%8nHVhgRjION$TN^&_^(rdAJK?N)AF(a zNh6eEEJo;{L?1*5gTTPVM|n<>L76Wut~OBPRt!2gcNIwXsL-Qfbz!kaGeI$v@L5VS zDn(8~;q%sSUDdgh2v!Z!n7!ciL=7d4lF5aHHDCSDzDgfRRy;e}Y-Nzdz!DotymRQT zkT8O~A~QZq&z7@J4^^Hts}CeCGBJnOCciI(|KaxbwILD5it!5gcc!wK!mZbUNf+jq zOU9NgKJk+Z6!5}>4)48PWZ5+Q&3G%`y(QZ5bw6-BA$62CBczYf?G5=4rI2V~GY$`P z!UEi@&^pAj8o!(1G^Fg(_!`RgD#!ZwilIPV-DqF-fz{%?7YK2 x29V%94 zeX(fU*S)*B>rDEmzuv$8bip>06_IJfQMg<-;nm6CCA0C=YDQkKYeBtu!=tGU8GG$W z!~V)frpliP-DaMnehm*cab~vBt#ZoGGoY~oN}MSw+ RD(aiG;e$15*+sU%I2M)|u4S(J@6>N9Jxd5~IrGf;PyBJJBp zjtRKaA*b&udi(aPiR98TxJ3xP4N^vc+d>608X!-qYJDj(;C+sPY)_U6doGIhGm537 z{owK-vSKXwd5UvN3I0r3YRD;4B?Dp$l}G)fsk2*q^SB&^3e-zuFkeH~ 0{KdIk`E3uT|B%^4f;cUzSG#|* z-JSr=eS3c04Sf}Oy&XA!5Gzmqd)Rj|mTBF2k4{?D6Ex-(Y6@4G-}576fA!|rR%9<@ ze`dsEpEmipGjxmt)pfR 1X;iNarI-Z zomL&$L^&t{P{LrHF+xJXy7sFi*+58B`+VM8R#}=Y>R#>7?*#aKF&^9p3qHhwJkLCW zlggulc+h|ldF{mjmc~{vM!)a5>{iGilPPzz1OwWP $xH3 zr2EWG>fAwysUS7!lKjKS*o!i^y4hO7#G8gghF|=FnuL~CG@-bdeI0eGWNr(CZ@#7# z-9F?`;`4c@`Wi7S2rt%%V1?QFUZDKzp0eOwU{pYQgpoRef(Wgs9qeiqpl `SNZhKR>55%VdToT`f=JGPPOuHQVK7G2S&;`tuVh50IWe%-DR>4WaVsT%*U zdM+<7R;HK3dJSVgqU(DSBK&W9x5O@CmQFZt8RuL_muerVX_+y&m0@1-UA@r*%)!47 z1i#oZ>}_co<%k3e_J^MPy`I$SwEY%;X}h^v4Cmbak$nVYU6S7=HAomFoFlKW+a?ha zG%Hdu829y}Q&zGr$C2-;`N^R@mU<1g^=6i-9|mU4O*)cQX(q;640Nki*e_AQI()fR zi&Y3nBga1_YEdVlZYc_~4M1lBlcZKRu*$FlAz61d=-){0jEyZKT6OoO-|Cky3wENE zSDF-6ew8K*_n(!L!pzK^3SK|{+NCo$3q?|@8RVv69lVTHK4_;K9o;==SMVl;k3|!g z*!w+!awke7^}9a2+n}h(>!;LPRM3c5k>i{G0h^y oVad9sP26u^}p)t$t-|(KXiqD(TR9u=(!Ka7sMqW$xM|Q*+7H z2&e@e9{GPH>41Zb>4{u5@&&fJF+1OoV(Vk~iu7~AafX0{4#eE3A?}x-M7@T-1f8du zng%~p wHxmCV>}LQ|<-U0JU4KGB)Qml*DZCp6^oRZE!fc&NrY;^F{H z-61*s8{doY?8Yz~h?8B-gh&8|+ysFBuL L1%;7)=UgIRP1LB9Ub-)Rj{l7vi-|`bkL(8rrNhtP;TLCey_F-V z>~3Z6F7 tlDC?`f)x!8E z67Oej2 ?RyF3#?2j3aW^-h0S>YP~q;s2Sfxma{|cMu{?N&O;yn5QyFa z^@o{J?_KE2kgt7$-n)^R^x@tPPWw8+f3!AQuTnNHqB)(S%Ay9qe^NI{-ho0gS8MP1 zKnO^DXc6=N`0b^9bnpHqn%2k&fZ6v;kJ5rf05A|BDz2IJpb!|>9OB9ifegC5x`N!D zHY~yo_$l-sWX0Gd3Zseq7rBf~6k(I`R%5>@pwxWp!kF_=?9ie+ki3j}Mqgh0 Lm)*Yb?*Kpz{gZL %)9kabOJdYw6@V)7VJz;}@0sJG@8^6CRCUlSG9IrC%rF3wTR%;>G?Ogy%zuNPgW zC5 -Q(FI)qFd2ag7xXUP`Y*^{_ph&TrOKbI4p GlQ%<{bWY&h>I}DUxAW{^K$nKXRoD-N?x9()NgOigN;vW^)xIn)1-*W|9M| z>2^q8fnoLj#|q1AoOxmTChnT>#8w3d)~A6YvSs}%dGCB#n`XPR(S1MvK7y~m}ACFthUHV;}!pxvM#=83^rj#tQK L_b6=eg84g_uKE1 zvw%`Vz;t?7M1$QsnG}9!Z>g(us3>^*v*{&sVkguxdS5H`ehXZ%4yur1(CQgw4oXIH z%CqlD_Z!1?uHqFA`wIoT-^ZxhIIme>UMsVg*&@(e`RgLP<>3S@*|1C5EhdLtKRTUH z5*+YiAIQ=}5>Llm&2xju8c9%xGRn=2b&?V0oPH-8ILU;3=I#$ZBs#d)km|#6s{XX% zLL#K^qb#bfE0q5*Ufz=NvrCdX+QrHKz^w(z@`d{&OKpZX>Ce$z4JL56>sK`W9bUYf zIduX3_61I6lG+QB@E*=d4`bkBcLKa_sli3j8qvj#P(fr$hi~bWCe?|`xv>4rdPgr- z@~_pW77LDH`^!QyHp8QYNpTzd%uf`(6ai&P4=KV$7+O2Fgui>E6Tn Zf()2SV_P@T`!n^>{H<44<;aF{RNi_UqMdM( zouD)+Eum$UypMm^DI5EMt`luPWmIRie)+pud3#q#q!KeO XEhR?Aa@9+1ofrKpj*&%KJE6eSa%wKorT{W{ 4{)SnBe_5gp4W(drk9DIt`)5&9Nm z@ z-6*UyUKZ-$fBsK}hgVDfhL)fRh;@^oTM@G?AbrBgU}!jz2tHIb6?XsD-0rF0AW`*U zs3DJM+;E@R0*d-j66P VqXjC-6O9l(>>Zj}`^9s4?@!xxGs9JFH0YwIyiDPS7z!6T& z#l%NDe*N9d`pidA{ReLfq|Z-TC|lLDJ;n?ICoF9>NPR(PuAk4*x}b%CpvS~L!BE2z zDAv-4#lEY-3VtEvbY4gW4gSWv8apcdj+#loN$wirqsT{B;yzJ!F|w1nnH>`OYDUxP zoYjv;tfCU5H}FKDyDI3(6u&95N)Z7?gq^YDS6G7&((c&B78-8)r~Y1OtuyD$OAz1H zNI!dpB2Q*K-YLcEc$cE%d!s)$8jgKf#C02;_cCjY!4EbyTIJ#FIAbK SmB9_yVFI zn}%W#H5~jF$304d^HmnWz`hYr9{qJ>m~RykW`!uBebeiC>#NP@qO=&f{?2~l2eZYG z@r^SsE03WrY-8jal=2rTerJ#OihUOYCM?{bg}% tR2K(42y5p9o)5}4Kl zWxU>NkM{ObUp+pt$Q~RLQgc*UYHmi3xe!M-7I@Zxi&A#N39cF?o{)ETLh1^x5OCZ- z#yeiLAit%EP}NUy?<_t8{L4&xddJ4wDOA5Z=wmm!h$hgMx1BQ>rOweMcgNI{^-M05 zMUT^s{Pk)o G83DFW?Pz^11(HBI3ETD`LO-l{JFf<{NM7V%R^#t$)*>4=(Ev z({#H&aZ2%F99g8qMsr-0_8_?g-gDKA98y#{dX-lo-*C?Uu~@moS~Q8R(azeb7&=sR z!|s!$O=HZu$_aDm9(Z&@rU8EuV(j3Qzf+M)Y6+Q}JrCGil{=?>nP}o@#hjDfiT$fg zP6PWndCNl>BJ^%r#xVMI0ly4WrW>Oy&mBM1pFOKfwt9+NHf2Q3C9Z>NjBrqWb#vr+ zKgaGTM(uY4@$`Q0V6--K0&M$rb8$!fptf=ThRq4PFdSFhE<_yhb|!FJfA@ruB;0qL z$s2jP-MT?!qQcK(=(sw+9>1RErQ~5H;`^dI<6jEjtsA_1!b=1m=CFJ@6 7W_0bF?-78%M>5%W{lQAT9i<1bl>iY z^r?os9;C%sMu $ACM^n5P7iqnPtO<%d3Q@_iLl1UEckAAMQSP zx|p^=&fMf^IYNOjkgkp6h|7x(O3Lp%HrKO|7b!OL(t9mBmch{bEGfU^Q>Qzd)1ET! zx+EP}B%cVs8q- np+R#QC9*R7#BP}F0Y75rEL2lJ(7NK z*>%AgnE+S7Log-eU@$kf(*p>@_WlTy71U$^GS6nZOglwXCCQJnm@E8dQGLkBI|j@R zoE-#!3K4q5NHn(G`CamaWsMFeC!x9C;Z4*YW=DQQdgJTqbFAM#4v?w?Zv~pHsWcm; zru}`84>zOJ4tU+Ab6x5<1}?TswTzh(QtXh__izixS9*v68~21n{I#K9W~zOBM&-GF z-j?B_8X?}K33JF6Z>J1QVqHk@cXUmy>WE|#eZEIFeMydB;)Q>itv(t5A%T{A!d-=? z_pDbsh!xW{h}_Jg#aC0!QGZ8u>dU&f$mMQhAznPtKbrX?8CYsI=HA D5TtNNd)>I~MG&d{Be=cqC5^wiYU6kOoZF)tl*8+v&b&g@H z_faP32B<}pTM&Npe(4;vm+iWL!6-3kP?`MOU&zRKcqq{{+YcYHdK3*AGtj2+d=Zg8 zYBY|@{Uz7I@ACx~=-1D<_ZJK9BT;{tOrHKtG^ZP6@7`hi-u8Yn3(c%oeg`xr4)V;H zhXHP~u3+iEg1XM%)k5ab)nmMo8;G%B?Q3<677dEH6-|JE&QBjPr->>No?2p|H_q^C z$E+yXYGvLNWM7L~8f@Uw?A9peVQtCT?fhLE(so;XI|%l=+FmRT2r^YuH|qNL?Iw9F zo(fRihH@kHg6)P7tXm7-jz>fGq=8szz;nDSu7B$b!k^+};t+^s=~7htrP5l1g5|I& z0=g8DeLt1pmSEEl1e}Q6x684cN!2WnkXy@m<&m3UuIx?Hzg!Q9@jdUyuDcVFE5jNj z{$z(<2#=3VLk#HrPM@RryzCya=(aJBmS2^Y@b&F3l7Z*F18M!KD_G0aEcsWNpeWxv zSx|cieCXt6Y=7)*wXWRpOuzTjCPrI}>G_YcNKt+UV}+knkLU7w4$A6Y6P@?NJqW^T z^=L9T?fqz<+G_rZIcwG=g)r_(%}EkWHdyI>0~Hh`g;Rp89()x(uldSby}Z$0*E+Tq z=T#QQ`{|%AW 5m276c!7gim_EqsvIE-d;lSxILq45|Gm@AD~@SJ z@xE=1ajC~yaMYlT+<2A`dTI_beTjZ>Kc|%VofvAII7H8v<2kEoHt`0@Viq(uPbOXA zr{_Zt=+;CIN}nsqoY2-aszh+x+Wi!4dgG&X+uymz>PY@KumpuqxpUxtI>7WD#P@jd zPpxTe^w>d(c5sE-4Aw4TnrA1~tw{@h%gym4o*tE&Zx<`F4`~Hj0`!X(HhJ5PJDv(x zwh%Y1EDGbJ1fLri`n1xQ5g==2<>w4{GNaLl I{p%qEqGw}UO152x@fgNiy}=EZEvN)k;#*H^aZGGW>@CHv|+*HMif z@#^i3LATQY7W8jyFLB)|lDL4m#2})`{WWJV9 zqbPRPGW=Sh$(aHrP0L{)ls}E6ylO)nv7O{CaIGrFMnWg;dl3wZZYvp|y@zX=KVy z)VZI(^Hjq7Lw{j8%U`(C4_(X2>QVWM9vQF>$m6PsG65c wd>+?bVvdC+vSSY*sy{iq WvJ5k+50)X(GyKV z3OebYkNGv@!ahaOB)Q9nsU{V>N3GGsj*3-Jo0T@5pxmJg&zR^Bt@9{_D4kEj+Evcl zHp1jnu6Hg#TIm2dVZvw1jPfT?hcC4X!y=bB61_I#_(R;d(uSTtXMPB@2l6uqGjr5X@L>Vs^~nu{E18+Yq_3HRkU!3vqkf5iIO- z9FyrVkKU+CZ$xJX5)-X*B5($QgAkj(rv_TE{7HL=8{*tu49_}q&=$18PQ6h6Z4>DJ zU8Oj?D65VaHMG<54{;=V*{m#DXrqKQTdCIPUo#Edip6g%` zbEql5qn!BK+UH(Ofkmuta5y&JC0FaUeP64FP(Bm6x^5x>U #}VQ4I$=!?i9 zf63pj=m_0wpcV|a4>u>|u6pU}_$5^t4JEI5#bq*vErBwvg0_m5SchoDnLRy7F|-{i z2ykFnV5Vw%nQBEO3rB;`Q+J-9YSej=FgTk@$Cj^2!z@$yhhuj#t&ocg1JgVumXxt# zH}ob7ING{M fAck@1YS8%vFyNOZC#9v8Aq5xD8t->EabK>pZ_Lxb$)dBGYeH}KIDBIKv?KdW z_Azlw1}AV_ADiZ9dD(kdjP}G$smdNL@Yk_e{nVSu%;w0Oa**91z?l3VQJ3 9uUPCEA zP87U=H*rbgWfJkmt?Ci0o9=cSvb39!m_5-N^bsSAt|V-Ab`J18ot**h8wi90q>BfU ze$byw>I=nZ*cZLXC)%VdOMK(}1s|!~;zFF`{zw>Rg55)47gDWJxFYimNTwSlXwh z&kOZb9+6BME*B05l#~aEL)4OvG``IPxrlg!O@8rV*u;wlE#1x?_q-0$JyM$YQvu51 zV`&7_L564dJI7RxQw@@?sO`Bh6zFTWEUa9uqEtU0CNc7iPvbeKph*NWReX)MGC7bB zVvh>NdWALGhY}Ac;%ZplDPN@5$cpD-PCgMLNd2P|G_GT3E)YYWlKLWT)a0H}!=q>e z3Z49MI}|_&uF)WTXT0Dg32DnJ14}s-vlSl+uu1IZ$ceXJCD{CnZ@vfo8Lqh +)>9%@r*v2p|%U|L= pCbEIQ!cZnj~Py@U!JWet$s=s z>=8=;7m2c!+0OoLs5T!~X>@f`wZN~wHQ%pdL8`PJVQQTRrbSMg1JDmuId4BKJk`1n zBk1y){bQcX@d {9IS`^}k~LhjXQMBhhlP6r0~woDI+{Nd&LVEO zaP&`!rz8<+WX|7NQuvOK695ND(`T)Y?hr!Hg?lCjI&ZUPCwf`sdF;AQ`n%VZvnoP0 zc;spwl%+}=q?yu!p>S}X{BV^-KwLN!g6-uweW$ gWLH_wEOWa-Uk7nXj->lkGX}Z+CP~x<_#2_WTlEA$$=fDi#vVE zYP{B6Wd%e-YByDEDCp;j;R?2ma*{81GEoDGAo34~$)WQw9d)pW(o&yOuZO-ul8{n0 zbt^;p_yqdyQ$mqk;8)YSiXSr_;qjtWpRpZ9B0VC +U2OOPT06b(r)$D@}cu>9>YshFLaW#;>p6!#FKd2>ketBMaqwlvfw zuYeE*12A|nXimdlw{D+wqFo(RG}l4TRZ;Byf{Ig0>&GS$MTZt6B$ng=hmL>%t#g}t zMDi6Kb;y4{H-i1=VAi*6)I$0{NgsI0jo$2F0+|^a|5ii`uu)(y<+6o}e)Hy@RrI;- z67YuquK5c+R!XW2Fu#CMp`Tp;k%V(4zRLt|Z$rgTxVs%w)-D9xU`p(V$&fwZ5=7nu z7&!5YSDEgegTtmy0a=P!!H4z{AFgWAX>(b^K~~{lL|_Xh78S?nFp8Ho*Q{^x8Ty$h z%>)BpyN^dSay&3`FmL8RM4z$hU8rYBPALz_KMi8&Hk>%Y;~}sEbb0%iN6w*DeFH~y zwi4uh-`PPb-H0F3?Yd~roc~1i0N3jj@&N 4B~ z1E}vV#HBLB5eo(rx6Jp+V(9yk5gvkkqa>C^GJt?q @0! zi$p^s&TqRB0J|-nap%M8&||d|NGl9xSKn${F G`AV+=>)W*$!O*YEQ{wxyiude|lt=lXi zu3aCArNEne0SxfJZ&lG(^cb@okbHC!u81FX`D<)|ge-E%HQD9NPQ+KTQ*CyEy~yDk zvZo28AQw2C7(sPrnJKav(2U5xKT#Vs1O>|gZK(EC;G1yIDOu((=fNf=xo3vxG;(g) zVznExa0BC;Y7DqG*uyRJFcGN>r<||^(P_||I06 (QpdSCV4!CL=NY86K(#Uj#2CV& z+Sijs=n*`3oFv$TD-&+0E4T;*!Pr5-F?*8)IWk$K!>gpee23@Ka|+eOae@C{n6IUP zK1gDj1Yor=*;M*lVZvHbz%P?X6#n5R1 ofXysHOw`~jo7+PY%R4=`G;FVb{*`|q@Up^G<=17V zdH&~bKn|kC`Np&&q1Qp{w|es0a%Sn5Ffp<(wv(Y;#hu#D;fOY0`)=h1j@=xa@dkU1 z1ogD!3;fL;DmUB0*Uj5|<~N}r8Dxc#?bV}ucQ@v%wsCF##_V-GK@w0$SuBjpJKw+& z1_nzjtq@qAN6~~s-4woTmtLEP-fSU~&})fc;~)hc)gQFR<*|C{6d6XoX9zq(iDHAV!tybO$kh%!-iuBVS}8W -UknVuq#RrZLqGG|0CNbM=fsQWSyV4CTo;xnS9ix)ma8S%>~Ub( z+Se3fzcs1%OjsqM(Nfp?!goF6eJtT##~Kv%=@dMkT~{>0w{z%qbgGS|4!YMpa6ffO z^J($(So(a|db500YdsOHe%$)f RfIgwXKa5MDgoT?cc7=wG zJFodXg0fxrSg6F} o%SX~rdXu;yd8uwXByoI|}lw@FKi zHA-jx@(+CFKjiqi6;4OpSvGXeBdlnSNA-2LkNmMShMn6__V9RX29at#tFMTVuGHNY zZjwS^ZFB|T8MhYVhBi+hko1L^9>#}G0}$<|8Vr*fFd1_WF-zMt7jI*)aEz-p{GbGh zG`O^LSpK GezImym6%fqTNqO2x|m@ps+DKH)irkai^j^peQK`r&Z8qO z0#n&DcEu9aDt8A@`_y_D_G-SIu)SKgV(g&dM~{-fP?n4Bt76!XpUeBN^LN$+|FC z%Jt X9Y?nw;se{@;T+VbB$p>k`d)4~5#V#5Yw88d4;-r5?U^UI{oXc6X_pRYB4Elob$ zX5_Z&AUz?>Wnh=} HRkazce1rTF}I5 zYDRc9BZ-Iaow6A3_G-XJH9wBAMwY_{k9A*V{rOSw9eU3gaP=vn(!FYWb=PU!~bl zP~5Dn+|Z?VSA~{wt5eNvwzF4nl2C8Tk6s6nU)CAb_W^Dv+kPZ4r?m1P8B_PCFFXg+ zB`OgnO=K2OX>HeQEwHLNUv;+Cbu X+YSHVK$4ncY(J9P;zMogtvJ{y z;<8W%+vNF_!u(iA6%mn8gju)4e54UA S9IXd-`)~>=@o{)kqYUQcUjJKvF&WoZGAuEqjF2J*>8*ANaS(m zd=PyG|D}y2H1s{-)&or1nu)b-({E}b2;aXCg8!M$4zk335zyU%&ji|Z=(I5zQeb4! zZ?d>$+T_r0i+K9)AFA2A4%5+p{?a>oK;(dPCT{;Zvygmg=$%LtwqSq*6d6FMq~fyz zNA%_OX-DvRyZlDeK+zWT)+!p1sDNm!xz;nf fP#3}zW7u6USi2OW6p^$_gahIp%*1}MYdslt}O+ZBgye3f5 z_08#pWn_@j#+f%UMEHZDiN1WLC46*{a0b1~c%z2JuxyymRqG!>z^C@D!D~!8tp^G` zo4WK|f`208pFFOGd|Vg_FCDi!AFN-lhp0~+8Rs_qMrf9fA*>#AaXU+OrBlPcC=djx zUwypueAL@ep~*9MieiS&IM6YOjm2f@Y8b$SNv`L#Q_XIz(SAwzd7ZFkk3@EyOYl6c zID-dA)BH@Q7Je>ml3#6|pC^6t!gcF8?5CSRy4uxz#ro~tQ0rz?rEUTjijIey3#mRq z$3~YfCy|aocRKku!+(E*P*-UZY@tq7q}A`RJYe3TSPDh&;9?Xyx*5%4y*|R1UN&>l z5#+QQ_Liexo *gxFPvtc!xEx)6;NUj#l3H-~JZdt`BZhJF&^SK$Q zXIOlTcwoy}T02WT;#)Q7!EYCEr@CXcz~1-tWkRR}qDYbUqJP#>Ik@b6t1r9ba2ryy ze=$k=$f*SH9Zfb(sNU8ih0)dN5;|<2^t#{g$L5y3ZbaWo*l``qQgolK<&!A4%H*j1 zsBYP<3vporWE pr@8xSo9`wEbQ z7!1dBW3zYBQ}t@$tqT{YvdPkQlM|@(4H^)yOn<8!ztSJ!1L}g@?1dm0`@@_dp zeqkghKsUt1tjY7w>)}s%1?EL`5s{cVlR&lcGjk5j2=DOnuD1zeQ5?O^^=FAn>%9^E z5Wk}&0B^z XKB~3qbQmz7yd_9=Pb)_mM%~|Sm16srFfbl4_6M+bSs9TwbV(+`39uD6l z4YvF#59%q5KBHW%$yK(!-;ldqKxSC9FOj4m53NPM0jxer1cExTG^4Gcq~k?^%*A-r z;J>qAXyOIXZ7i50rfA0FEbS=;Nd|d=J~62Ap~dBCZ(eZszs9QVlBAtW9#ZE3C+FJR zfIj*#GL~DJ9KZxvMhMN}obB* ~oogO#~R4o}7 zwE`Jjj5O7XrjHEE&LAi=H@S+1En5&pQn*~xxiZ8yV_gVay3Y1ECm4P-dgZiqBgKuE z%S(s25x!NHGZ+|2hVe>^YYapDORjlf-po-KIUBfUmZZq>iH$I?6U@sf%>|aAsEC8# z8|}ykmLQuB>;oPLI}gI>_~GR6FJ~gZI`p&Z BlRN#`7AVw~kJ$6@15@(o#F4$cCatCgm-rj}K=`K{+s9#^i<~Pq z$1R?6u=gxaX>>aFMHM5Y>X3RoTv6_XS~;i6L7^1-44Vu3I4RJ>pOLWUa^6PJ&EW2? zc(=*Z{Y4;^YEc8yLY$Icwpqrs $ zg;wTO@VDNzC6^N^sOCx+SFW+8*p;im=RHj;&mO*Rp_|7)+u8lT>U@{j&JxF3-D?V& zt4LnICwA`_I~bPzW{bOBpZNCBUx&0b&X~%F?*#uL(sdj6jP9c_g?@dIhVyT!hIJc~ zR3)nqQg2b4o+?Lkqe3ycEU~m@tXQgynp2)PrdDqxYNv=fpR<1-5}0eU!$?utE2coY zXU-ofKKG|?UGbtnbu8(ew=dEO =% z6Sx2q8<;2)%#*=k@g4oQ rG|_)3K(3 zHhN+8^8pyqMEn9iGw^s(Duy<3u)XY{<)(GOb8hSsjCTW5GdLp(?H3=uCKLb!u-$R| zr9uSN1Jf?%6MgLTL(xMJ!E ^*S+`J;PCXQWvd_lq??Fnf;Het{SwPMBkO>?;Qi@@hjk!3L*Tk>c$ zZF?z|q@i~uVor41g ^Oe)^DtCrn?aYODxU`GF k$FsVYAw$9VGYQIQl4138dTZliZWs4~DK2{;P96ceW7h)y9RA0?WURLdfIdWF2e zq!(@|D!MCqvCRk6tdnl}=wB4P!Z|%sx>C-mVX!@{b(v_tbAO2@#Ey$7e= 3n% z2b0pxc%P<=rZU|BvP81Bv7YZRKNwZ)leO(Dbz~_yU<|c+yz;7yWiN(6a@(+C5LeBQ zMzb6S#;al!Yr!09RwUR8Q$zhxm8%mXB`v2JFnT4psdm?O8>UiRLQ9{9-FSF1We%|#czTl%b3LR<{kV!t&vKQYsusfTT`hkZTjGzj+G8;q2k;s z&QOf}S3fVMmfYU5LM4EwK`@}!CSrMFLp_<>Ho3jl<2~j1#Sz~I5?ejx-jEoQf~sIU zP*(S`aH-TI{WjRgby*${$tB2apO zysj?rF(@flglPYmrc1pk57QKkj)Sx$iD<^F;PzX^97!jT<21C# ;su-6L*I)E{ z2}ZPG6Xy^qFkT_vG-2L9%jM#O@3$D|=yomnSUSFbi00)ee i*i1q5Da_xFLZ2 zo03q;{4zE_n+2*eB-^f9Qji{eCuAw+;uhskjQ(2$g(#fQyP)!^lT5H<8rI_~P{HP$ z@q9e&ti+&OVBcxokLfb(qGP&{g UaFngGM*gZn;tk>u&tC>9~!|JGS4)FHp zFF|qfrWWGSjEKn gh$jNX^sOIZDS<4N3{DO #I*CzpK<0FgnjoVTFqU0<3oG#An=db8M zLg@}M&v#vr`JIgV1e?BxBqLbi-JcemPv_DOVn|+kVQY^x1=w!!x4$=)v~I1TsK}i& zg5YpyQgwM7{Dhk7qf0%K@a(|06#WlKmr}=qj7i&+#v5z =?GucV4bFnw;OpIeFf;KmwJS3jONe*DIVN$^KlJocqtgU4O{`{M4#_ z&oD}xX2_N`p=oYEl&v1-HV{iet=PZSoDhpd7uX1^JpyEE=74;Xm#j% =XG zoemzlOH+E&A{#55X9;tQOq-WJ2#2BA3->ZV2Y-IR_xG$OEM!dyue__z^+bkUcM!`q zLCsl*n+pe<3{8}K9+g0OLLOf=-E6QK2{Hp)8~wfU51K{rc)_7{t~oDJYeyq5BUXCZY#+H7FnhKJT|@lk9fK znF!Dl?#_OK4Qjsj!Z*d)j$u=h6fKbi6JSN$r+irF7DTQ*KZ=N8l97}Mc2SKZk9p`B zW4(Ai)oRu9%gtESP^+oK{A2$k@JU354K*h;rHGv0G2U9--wySRhYeSW^A6(sltS)X z(fkl(?Nm~kMpb~J#f(7G^{$)|@F~9*cJh2JVdwu_Y#V!iEGRrac*0Hp*I4NJAlx*Y zg&RsK%C*u17Is}H iFX)2FcPdGqy7*7rECr__SHnhw5;99hvvEXRkW HKcB(oqOP(8ufC`Mfby2$EbeRur 3ItHUGIwETC2$#nqp8Pz9>|f?I`UQ< zT1ya6I`xBN{?3Ia#Eb79SS%WE_zf_(1q8G9`+&t%gF@x-n9xGnT1(J&ABT3DnC=E# zG _|A&x}_2nq5v{i_clj+2QnDGMCsCM?_` zsIw|o!c7B*#@PYtw20Wq{p(75p8f{tlbYJ$LccVAbeB)SKD6AVe!Bau#DD39Zcm^e zBX`Ai(Tg+d=IGc|xUwAGDgt$vY%@%0bj9@^QmQg~xiVs@d+CdW-K`#K(Cq_#Kwk+S zeR20S@r89~B#3P*E&b$EULd!`17yl~d6`QUjM=d#PC`5m#CFEJKi)rpRb}-%Q3AAd zf?bH#BH#q&`+kEgf9Y)nQ&o@kZ>x^v>=Y$K33d@7dj6AW81n=?-5R`bTisMSUfU_~ zPy*1yWZ-x%E>ENG_b3jfI7*->0Ca3T1 6Q_sv=xxE3myg^pO}wmn zQAb%Q_J#yj6$3=zlPzHT!B=3*Fj<}xHT;$_BJH!9IN7BPO=M&_mQL5?guvR~-3N}_ zoHNzUaDsneh QDN2vS_1p6-7xvW=|j?9IvyZ z1vy>73&uuZymv9_`JMIO(&&pm!3b;AvarSw=rayEZe`_=^KP98msjskOsBv3-|0xI zpH&PsQbk_`uHH$t(Z({wfq}qncA$1;db@0Z&*#W#ufeSKE;X53bte wxl9?*>^r@O}`x6G(|KZakDD+t+AETdd0mHitFWx+ul1L z`WShkK DCk)4)o 3nx&IY1Z3LE8 MA}_sme7e%W%s;v(84oywulA~j!B3bk zEN|DeqrDUdG4q8qB*Eh8#MrYC(K~=IE6fR0#x_}- Qyo(}tAKC6b{R9hwr{zzcREz23QbHb-1T0c zm+NLa@>Ehb_!_qI+xOg^?>s$CpH)Y-2K$0i`W+?)oS5Y6Y^Y^4Hwn2d`&U@gut((_ z6NiydD;0*+MBSs*zubXbca=Et)(6pwh1IMy0vHbK-@*^Uwp^@KcefZ7drOc2 IPHbi*fN4u%$r*2v#aKvwT1Fg9`HIT!2BR8!}b+#x6an2xURpQUP~h? zygfH{Xabn-nUL1AqsEh^uBB>wDG&!rv?Z4I2e+GPXnrSSo~jr~Hws`6C~Gs54s^72 z?^XUmnJ>`qycKLey-VeU)Fsf>=1UP4m8(}dwa<$}Gh9UGmzU$t2xsh&Xbw|sqT${Y ze?&mIynob+YPA$2MK__~9={(qDYy=$Jop$TX&dX|w$NQKaZ+h1p&}Ym2X-kctrG)8 zAb#pW=^k8#b?O{q t)J8Jli__tpigGH1r&8`5zTLyzybESwxG+{ zV90yjYht)jTJnZOhnB8xC9L0gW?nM-+ltsyLC{2KDf8^c`wc@GIrt&x`iU#whenBu zNS=l{C^Wkp&?@aG#MF&rFA)&nl2i;T>ao&e?>##l_GD8l2UAo#z2(>@3BOx{u49k$ zctTs^Eq)aDwfIag&qGUAu{!rBjWCEoZ$5or{qs3>Z>(_ CgT|MmkpJe-l4=bj z&-*-rgdwc4Xhl$W1gf1SH?5M!nTem4K44MHYAbM-gQT+`wd&g_ztAMPLA(?)lz-%T zT71&yW_Es?I^uF;Wz~0CA)(6G=@N3zdpOPb^=|muk)#W#`69$1|3%gW_LY+kc7XK+ zT>8qwz7Zdwn~d1Odlvo;CYswSp`-ohocK#a&0t5ps_IH$J@}IuNQ&`eQ-69fPVXe6 z0V-D~?dKVABBMfinFi#vctJjLnsW0p(yF45tzpjb*s2_=s !*VB-F7x^R|ll%0Ju3a%u=N!MvX~Qkj$Lv-FN{{@4?cda*Yah zm7h@&tr+J_@@dYPp7!61#B>R_Hg#ptsGxe|uYY-te>&Zm-ViQl`Hi#o!(G8hZv__f z!d*&QslZmjosq>lN)48p1w% d6CTIZYo(4};Fq^fBx4cFqOQbn>^4leBzj=8_VbejFBEGfRSwv>K(SX=Hb zchuZE$R0Z)-&=t6z3CG2@sdSJ(_MvglF(XG*_yW?&V-bu@bu}r0PnrA>W#9u0j77l zn6Oo)H3KEtBvDvVtL5_dtRy_*I4BzTU)NCszh0d_Wgi)Ilr~o5;v+8=Zkr0kt8?Uc zHlrb{!Q %>|8PPs9@R> 1dlRY znZ>+wnar)FTacSr$BO njj+o)uDCASn&t==68 zg|Aq6eC&`Pu$xd$uyW(^bD6&VO625P!L8xVL@s4uu~4k9+S|ehsx4jzX)P%U9(Rj{ z Y;7o*fJXj=l#Xg)h6cB=Nmg(qFDMQskD= zUutVZgu&=H#k3wFv&Pq`gC)%KYLM*4@<->jI$qU9+yNId*!JlGX+!YhW2}5b1t?oe z=F1l-6xz+myQm||asOucylltlKg*5pL9NA15@yY*8^w7kkk^(9C5IT%SXu=X**Nfk z#x McJxklcppk-^DD>ld-SR9ZhgkWKWS8|94U%Tac1Lw5wFe)EJ9# zkOWmTtG* pPbZ$^ookQn@%Yh7Dy9M)p6sq$cTyI=^tlVGyl`;YQ6(bG`EW>$0`SO#-#$3c z9&G>fL5-N#amf?_IW~z2LGO-evp))G%^y#QTj%t}?;_8yK!QrV4-OdOEG_GdHg-6n z{@(xa*0UJrq*$BRFdVDnC0tp<<&u*f>ZEb1<=`?D)xz`tvxu+@Kq_U4XomIoZwX6y zlGn?Dm G56RMn==q( zjl4Bu!vyO-+;?l>-CQ0iJK}Ta4{n{8FOUWIoGf-Ghnn6ku7yf62@~b7JpR7Y#Q&Z% zA285|VP>Xy?=V3aIf4s#k5KH$Fs1Db+2u^>{f!xWG<5d i#U^gk-Sz`xd+G zICPt-=`9)%8K#uNZXV?1dIHa@%9Y=F==+8WBHlbe8k96rMeMnFQk;L2D6CSFYI~Ih zK`ItV!qQh?;}7$)8Mld2{%Uhp<*&xaNVtZ%Tf83QqfOn@3xC9p<|0XgdFu@W_-H7c zbj@npF-+8#C3|vGgFuFq96AaH4d?Q8HpVsUUxQGAd~pU=IxX2?Hti)WFJeLmF&O+~ z+dA;9xY@x7XOYI7{vbv+>87}$&S$iihxGZo89Vt-kt5OaIf%-F!QrA)71LhRgqDUx zdAkA?NO|qIw_>}eSiEiv&M&{%G0vQX#NTm>y&Xg0uU1a2jBxk;hWG_0Y9!7yCY(M5 zlP4&;T!?^Os)R0x@Bk&IZ?EtqW0?tYhNZr14Ee~+)|P$}A3cQ5*_efgPuuSu5`~jO zR^$?|xGwZsFg=8KHQU|=@~+vE512yZY$VxD6r<;D7@e>fl%!-7^WtD82{EgVX31lJ zMuPWv+ z;+JggKN~T*=cRo3B3BW(GR-A`)`5d8@l_X7f@w7&` 3%)hf|;?{~2rXSTel* mX-| zHqH3TA!6xl=;Flgo*rrWP9yf~G>W8&Lhs7xBlhK{JBUbf8ctL>n?WAUd?cdIQ2V_x z#%|LdLvSA6Qm{kzakhVr5>4kgAsP+?alM)}?*XPqd;MVE)~Z`Qj)Rwz4#iVvlmYv~ z(vDCTfZ@qVQjlV)wQnXrG6^!iUy7Go%oFG+Cr~S 5@04j!Ao#h9gdNK~1o z7@1~BMsM_7;*=spC<0fW+NCgHY(|~cHvOm{iBE5-3@&T6_hp5s3a5zRVBsX#4D(d| z_*=1P?xqquIZ5YR+w#6cp4aj9LhM7F+SBU1APWLFQwM_R?CH;^PQ-{&e6(U!LG%)4 ziX;Ue4{uicfGR{E88af&zdS!iA*VI!`9uivm#>IJS@&N=8PtjGMV#asCfOX%KC7M6 zh{7oWQH@%ZOT=Iy;DqUMTj9K>7{ROdFp^SazTc-qSxQ1H9MxHYk$f`I`V#93M7KK= zBBfLX((Mz{z`HbxWqBnSNhhaj6e;ENT@>xbr-mn7Ia> z>@*Krpw)q_p0wKEYQN%A_q*+?H06gZiQJ`+kJN z&-EP(s+34Nv3^EalZWZ-A4>ljO^uj6ozdO6TO1&wQwM2}5qX+2D9tnKea&8Uv(n z?H;=`yuPh9*zZ*Ry!8W`SZOd^rd-`Q1RJ_B<=DG6L|`vr)OsuMOk8=TcODVSYfFoF zkLpJ2)unWy?)}2)>j1 zUFOm=1@L0j6&cP85}1umUYI=VuRD~Bw5b3W^GKIjS@v~2rFe32hj`0X9A#ac%gHm9 z%Id6f)!}j}$O?=5u{AH6f2PRYo5h-x*r$-^YG?a%S&)SA2~{l|w=joc6d0o|z}mR+ zObXphfPYMb;$+tMXr{cgY|=k%Q={8uRm#p&lMVp(S%|wg5#`y{dl=Mds)|l&(L`NH ziRf@rAtEjFtwM24XI|QA#?vI>9c%Kb+1K9=gi0}u_tYRo2^Hy>Pki9;B0_d3f#Pza zwXsubYWL4 BzdBPpq}x264G%2TNe)HH*}`IZd50 z&3ySEfj-f#Gg-zLe~>LI|2*OFJQ1f?LTk~TxfF(G!cLes^ez7CO;fhm^2( $pc@)&2z?u)3LrSm-Bn5s#LwHarAS-o(SJB52*nRrYgGM{`! znxz|A?gI$=?;4P>0DG&2+HotN^>+AFxXCQcO#cQ7G*I$l7ta3BnFH{(8H}SbbIEs{ z#Fa}oI~^UBm-oYa)U;?p_Ud4Hqym!@Ze8_+1ms0Xm)}iURh6ijC}uNpWglQ#d$~Mp zMqQ)2R_WtdPyyxh74PC`l9r%G@y0Gf@H&$0r(1D(mw&M`$Gc^6DjN^ot80?ZW}T)^ zUNK^A d z^A!daSa_*G)dn7Z#G0)gSu7cN1mq=tKgEUguSN8F1{J*W3bqh}st|3bgqVC|Rd;1L za78=&*M)?eKbi0yk0u(&C)Pc@Y8uUDr)D{_{^&J}OO=n!BRe2bvdn*1H+f&sNeo4r z$+Le$<%cTU6I7rsq?FZbZsdO+v00ERro^sUnGMYYgIvk?|HYoe}6n6fdDLFQSPA zkF@AB^zZ8IPXBzI6_L_gfpZz2-#zDo>8buu9*C3xVjPA%J7-(g4$LfrCVTG##mH}e zTbhEoFK!xCE|Oz%%0D8I O`knQueiK_H5^1QSd)={>2ms2N$gm5m`R%?C z)F+E*XoQRZ3p_%I*(?9W{D2xJ!18<@Diki ii!S3iz)&3#dk! zaj|cBWKhumrW1*j-*Eosho5YlEmSC1cAU%m9lqbW4D4za-8A12f6g~Mci#wTBGnQj zC1IqZbP*=ln82{MS~-Icqi>930PwE+4WR5AtcenPP!n3Y_5dzkQiRETJ3lbu`}*Z5 zBV6;DF$sBSVs$>w9O1s0u|ER0#oI-ov;H2kg=4rtRcUqR`J-0pJP9KB7y3-d$7#Sq z^rRliN>~qj0Gz&R10MmbbP$DlTbP0v$wd#E*_?5xQ;oq=i*?}sO$EU<9kcQtmOoGy zKhLI<^$;~MAKRLXB=jD>E8`THEu|(wJYVC}jl(*6qdKvUFq+{JNXTn}eXuYc6-KlI zBle+WEaW9Sj3NPCQV)yv?fXHY-$U2Ph^;u|nzPUc%wp--MrR^r=wNITz-At*D 9(bPDrt?8w?=s)yoD2zADJ0u22;O-9w z|2H_*HUD4MtUp@}NI_=*2O!-EVs!m?+y6;X3;@=3bb-$tk2ap&sAXNU)7$Z1pCVkJ v68PUA^{pu;Bwggym7q5g7@a=wFG}d{8jI!4=NF*z`#;j+@?zB@hQa>}t2)Q# literal 0 HcmV?d00001 diff --git a/safekit-cluster-farm/metadata.json b/safekit-cluster-farm/metadata.json new file mode 100644 index 000000000000..b690f0fee84c --- /dev/null +++ b/safekit-cluster-farm/metadata.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://aka.ms/azure-quickstart-templates-metadata-schema#", + "type": "QuickStart", + "itemDisplayName": "Evidian SafeKit Farm Cluster", + "description": "This template deploys a load balancing cluster with failover on 2 to 4 Windows or Linux VMs in different availability zones", + "summary": "Evidian SafeKit farm cluster on Windows or Linux", + "githubUsername": "d6p", + "dateUpdated": "2019-1-14" +} + + diff --git a/safekit-cluster-farm/nestedtemplates/cfgFarm.json b/safekit-cluster-farm/nestedtemplates/cfgFarm.json new file mode 100644 index 000000000000..005abe9fa7d5 --- /dev/null +++ b/safekit-cluster-farm/nestedtemplates/cfgFarm.json @@ -0,0 +1,93 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmname": { + "type": "string", + "metadata": { + "description": "vm name" + } + }, + "ostype": { + "type": "string", + "metadata": { + "description": "OS type (windows, linux)" + }, + "defaultValue": "windows" + }, + "moduleName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "url of the application module to install on all nodes" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "resources location" + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "base URL of deployment resources (template,subtemplates,scripts)" + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + } + }, + "variables": { + "cfgModuleuri": "[concat(uri(parameters('_artifactsLocation'),'scripts/cfgFarm.ps1'),parameters('_artifactsLocationSasToken'))]", + "properties": { + "windows": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.9", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[variables('cfgModuleuri')]" + ] + }, + "protectedSettings":{ + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File .\\cfgFarm.ps1 -safekitcmd C:/safekit/safekit -safekitmod C:/safekit/modules -MName \"',parameters('moduleName'),'\"')]" + } + }, + "linux": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "skipDos2Unix": false, + "timestamp": 1, + "fileUris": [ + "[variables('cfgModuleuri')]" + ] + }, + "protectedSettings":{ + "commandToExecute": "[concat('pwsh ./cfgFarm.ps1 -safekitcmd /opt/safekit/safekit -safekitmod /opt/safekit/modules -MName \"',parameters('moduleName'),'\"')]" + } + } + } + }, + "resources": [ + { + "name": "[concat(parameters('vmname'),'/safekit')]", + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2018-06-01", + "location": "[parameters('location')]", + "properties": "[variables('properties')[parameters('ostype')]]" + } + ], + "outputs": { + + } +} \ No newline at end of file diff --git a/safekit-cluster-farm/nestedtemplates/cluster.json b/safekit-cluster-farm/nestedtemplates/cluster.json new file mode 100644 index 000000000000..db12328de3dd --- /dev/null +++ b/safekit-cluster-farm/nestedtemplates/cluster.json @@ -0,0 +1,653 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "OS": { + "type": "string", + "metadata": { + "description": "Operating System to install" + } + }, + "clusterNodes": { + "type": "int", + "metadata": { + "description": "number of VM nodes to create" + }, + "defaultValue": 2, + "allowedValues": [ + 1, + 2, + 3, + 4 + ] + }, + "vmSize": { + "type": "string", + "metadata": { + "description": "the VM size for all nodes" + }, + "defaultValue": "Standard_A2_v2" + }, + "adminUser": { + "type": "string", + "metadata": { + "description": "User for the Virtual Machines." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Password for the Virtual Machines." + } + }, + "moduleUrl": { + "type": "string", + "metadata": { + "description": "url of the application module to install on all nodes (optional)" + }, + "defaultValue": "" + }, + "moduleName": { + "type": "string", + "metadata": { + "description": "name of the application module to install on all nodes (optional)" + }, + "defaultValue": "mirror" + }, + "VIPDnsLabel": { + "type": "string", + "metadata": { + "description": "Public VIP dns label (optional. If set, an additionnal Standard SKU, unassociated public IP will be created)" + }, + "defaultValue": "" + }, + "VMDnsPrefix": { + "type": "string", + "metadata": { + "description": "Public VM IP dns label prefix" + } + + }, + "Loadbalancer": { + "type": "string", + "metadata": { + "description": "loadbalancer (optional. If set, a loadbalancer will be created, with the VIP as frontend and the VMs in the backend pool." + }, + "defaultValue": "none", + "allowedValues": [ + "External", + "none" + ] + }, + "azurePwsh": { + "type": "string", + "metadata": { + "description": "install azure powershell module (optional)" + }, + "defaultValue": "no", + "allowedValues": [ + "yes", + "no" + ] + }, + "location": { + "type": "string", + "metadata": { + "description": "resources location" + } + }, + "safekitFileUri": { + "type": "string", + "metadata": { + "description": "url of safekit package" + }, + "defaultValue": "" + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "base URL of deployment resources (template,subtemplates,scripts)" + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + } + }, + "variables": { + "allvms": [ + "VM1", + "VM2", + "VM3", + "VM4" + ], + "vms": "[take(variables('allvms'),parameters('clusterNodes'))]", + "cltemplate": "[uri(parameters('_artifactsLocation'),'nested/cluster.json')]", + "frontEndIPConfigName": "[concat(parameters('VIPDnsLabel'),'LBFE')]", + "lbPoolName": "[concat(parameters('VIPDnsLabel'),'BEP')]", + "lbProbeName": "[concat(parameters('VIPDnsLabel'),'LBP')]", + "lbName": "[concat(parameters('VIPDnsLabel'),'LB')]", + "NetworkContributor": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/','4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "ostype": "[if(equals(parameters('OS'), 'Linux CentOS'),'linux','windows')]", + "adminUsername": "[if(empty(parameters('adminUser')),concat('admin',resourceGroup().name),parameters('adminUser'))]", + "ips": [ + "10.0.0.10", + "10.0.0.11", + "10.0.0.12", + "10.0.0.13" + ], + "sktemplate": "[concat(uri(parameters('_artifactsLocation'), 'nestedtemplates/safekitdepl.json'),parameters('_artifactsLocationSasToken'))]", + "skclustertemplate": "[concat(uri(parameters('_artifactsLocation'), 'nestedtemplates/installCluster.json'),parameters('_artifactsLocationSasToken'))]", + "createviptemplate": "[concat(uri(parameters('_artifactsLocation'),'nestedtemplates/createvip.json'),parameters('_artifactsLocationSasToken'))]", + "skmoduletemplate": "[concat(uri(parameters('_artifactsLocation'),'nestedtemplates/installModule.json'),parameters('_artifactsLocationSasToken'))]", + "NSGName": "SafeKit-NSG", + "storageAccountName": "[concat(uniquestring(resourceGroup().id,parameters('location')), 'stor')]", + "lbPoolID": "[if(equals(parameters('LoadBalancer'),'none'),'',resourceId('Microsoft.Network/loadBalancers/backendAddressPools',variables('lbName'),variables('lbPoolName')))]", + "lbaddrpool1": [ + { + "id": "[variables('lbPoolID')]" + } + ], + "lbaddrpool0": [ + + ], + "lbaddrpool": "[if(greater(length(variables('lbPoolID')),0),variables('lbaddrpool1'),variables('lbaddrpool0'))]", + "WindowsStorageProfile": { + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "[parameters('OS')]", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage" + } + }, + "CentosStorageProfile": { + "imageReference": { + "publisher": "OpenLogic", + "offer": "CentOS", + "sku": "7.5", + "version": "latest" + }, + "osDisk": { + "createOption": "fromImage" + }, + "dataDisks": [ + + ] + }, + "linuxConfiguration": { + "disablePasswordAuthentication": "false" + }, + "addressPrefix": "10.0.0.0/16", + "virtualNetworkName": "[concat(resourceGroup().name,'VNET')]", + "subnetName": "Subnet", + "subnetPrefix": "10.0.0.0/24" + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2018-08-01", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetPrefix')]" + } + } + ] + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "optionalVip", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('createviptemplate')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "VIPDnsLabel": { + "value": "[parameters('VIPDnsLabel')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "optionalLB", + "dependsOn": [ + "optionalVip" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "condition": "[and(not(empty(parameters('VIPDnsLabel'))),not(equals(parameters('Loadbalancer'),'none')))]", + "type": "Microsoft.Network/loadBalancers", + "apiVersion": "2018-08-01", + "name": "[variables('lbName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "[variables('frontEndIPConfigName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat('pip',parameters('VIPDnsLabel')))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('lbPoolName')]" + } + ], + "loadBalancingRules": [ + { + "name": "LBRule", + "properties": { + "frontendIPConfiguration": { + "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations',variables('lbName'),variables('frontEndIPConfigName'))]" + }, + "backendAddressPool": { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools',variables('lbName'),variables('lbPoolName'))]" + }, + "protocol": "tcp", + "frontendPort": 9453, + "backendPort": 9453, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes',variables('lbName'),variables('lbProbeName'))]" + } + } + } + ], + "probes": [ + { + "name": "[variables('lbProbeName')]", + "properties": { + "protocol": "http", + "port": 9010, + "requestPath": "[concat('/var/modules/',parameters('moduleName'),'/ready.txt')]", + "intervalInSeconds": 5, + "numberOfProbes": 2 + } + } + ] + } + } + ] + } + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2018-02-01", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage", + "properties": { + + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2018-07-01", + "name": "[variables('NSGName')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "remoteaccess", + "properties": { + "description": "Allow Remote Access", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "[if(equals(variables('ostype'),'linux'),'22','3389')]", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 100, + "direction": "Inbound" + } + }, + { + "name": "secconsole", + "properties": { + "description": "Allow Web Console Security Access", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "9001", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 110, + "direction": "Inbound" + } + }, + { + "name": "webconsole", + "properties": { + "description": "Allow Web Console Access", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "9453", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 120, + "direction": "Inbound" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2018-07-01", + "name": "[concat('pip',variables('vms')[copyIndex()])]", + "location": "[parameters('location')]", + "copy": { + "name": "publicIpLoop", + "count": "[length(variables('vms'))]" + }, + "sku": { + "name": "Standard", + "tier": "Regional" + }, + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[toLower(concat(parameters('VMDnsPrefix'),variables('vms')[copyIndex()]))]" + } + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2018-07-01", + "name": "[concat('nic',variables('vms')[copyIndex()])]", + "location": "[parameters('location')]", + "copy": { + "name": "interfaceLoop", + "count": "[length(variables('vms'))]" + }, + "dependsOn": [ + "optionalLB", + "[resourceId('Microsoft.Network/publicIPAddresses/',concat('pip',variables('vms')[copyIndex()]))]", + "[resourceId('Microsoft.Network/networkSecurityGroups/',variables('NSGName'))]", + "[variables('virtualNetworkName')]" + ], + "properties": { + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups/',variables('NSGName'))]" + }, + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Static", + "privateIPAddress": "[variables('ips')[copyIndex()]]", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses/', concat('pip',variables('vms')[copyIndex()]))]" + }, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets',variables('virtualNetworkName'),'Subnet')]" + }, + "loadBalancerBackendAddressPools": "[variables('lbaddrpool')]" + } + } + ] + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2018-06-01", + "name": "[variables('vms')[copyIndex()]]", + "location": "[parameters('location')]", + "copy": { + "name": "vmLoop", + "count": "[length(variables('vms'))]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]", + "[resourceId('Microsoft.Network/networkInterfaces/',concat('nic',variables('vms')[copyIndex()]) )]" + ], + "zones": "[split(string(add(mod(copyIndex(),3),1)), ',')]", + "identity": { + "type": "systemAssigned" + }, + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[variables('vms')[copyIndex()]]", + "adminUsername": "[variables('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "linuxConfiguration": "[if(equals(variables('ostype'),'linux'),variables('linuxConfiguration'),'')]" + }, + "storageProfile": "[if(equals(parameters('OS'),'Linux CentOS'),variables('CentosStorageProfile'),variables('windowsStorageProfile'))]", + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces/', concat('nic',variables('vms')[copyIndex()]))]" + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(resourceId(resourceGroup().name,'Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob]" + } + } + } + }, + { + "condition": "[equals(parameters('azurePwsh'),'yes')]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2016-07-01", + "name": "[guid(resourceGroup().id,variables('vms')[copyIndex()])]", + "copy": { + "name": "roleLoop", + "count": "[length(variables('vms'))]" + }, + "dependsOn": [ + "[variables('vms')[copyIndex()]]" + ], + "properties": { + "roleDefinitionId": "[variables('NetworkContributor')]", + "principalId": "[reference(concat('Microsoft.Compute/virtualMachines/', variables('vms')[copyIndex()]), '2018-06-01', 'Full').identity.principalId]" + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "[concat('safekitInstall',variables('vms')[copyIndex()])]", + "copy": { + "name": "skCopy", + "count": "[length(variables('vms'))]" + }, + "dependsOn": [ + "[variables('vms')[copyIndex()]]" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('sktemplate')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "vmname": { + "value": "[variables('vms')[copyIndex()]]" + }, + "ostype": { + "value": "[variables('ostype')]" + }, + "azurePwsh": { + "value": "[parameters('azurePwsh')]" + }, + "capassword": { + "value": "[parameters('AdminPassword')]" + }, + "safekitFileUri": { + "value": "[parameters('safekitFileUri')]" + }, + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "safekitClusterConfig", + "dependsOn": [ + "skCopy" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('skclustertemplate')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "ostype": { + "value": "[variables('ostype')]" + }, + "vmname": { + "value": "[variables('vms')[0]]" + }, + "vmList": { + "value": "[variables('vms')]" + }, + "fqdn": { + "value": "[reference(resourceId(resourceGroup().name,'Microsoft.Network/publicIPAddresses/',concat('pip',variables('vms')[0]))).dnsSettings.fqdn]" + }, + "privateIps": { + "value": "[variables('ips')]" + }, + "VMDnsPrefix": { + "value": "[parameters('VMDnsPrefix')]" + }, + "lblist": { + "value": "[if(greater(length(parameters('VIPDnsLabel')),0),reference('optionalVip').outputs.fqdn.value,'')]" + }, + "capassword": { + "value": "[parameters('AdminPassword')]" + }, + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "safekitModuleConfig", + "dependsOn": [ + "safekitClusterConfig" + ], + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('skmoduletemplate')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "ostype": { + "value": "[variables('ostype')]" + }, + "vmname": { + "value": "[variables('vms')[0]]" + }, + "moduleUrl": { + "value": "[parameters('moduleUrl')]" + }, + "moduleName": { + "value": "[parameters('moduleName')]" + }, + "_artifactsLocation": { + "value": "[parameters('_artifactsLocation')]" + }, + "_artifactsLocationSasToken": { + "value": "[parameters('_artifactsLocationSasToken')]" + } + } + } + } + ], + "outputs": { + "adminUser": { + "type": "string", + "value": "[variables('adminUserName')]" + }, + "fqdn": { + "type": "string", + "value": "[reference(resourceId(resourceGroup().name,'Microsoft.Network/publicIPAddresses/',concat('pip',variables('vms')[0]))).dnsSettings.fqdn]" + }, + "Credentials Url": { + "type": "string", + "value": "[concat('https://',reference(resourceId(resourceGroup().name,'Microsoft.Network/publicIPAddresses/',concat('pip',variables('vms')[0]))).dnsSettings.fqdn,':9001/adduser.html')]" + }, + "Credentials Url Login": { + "type": "string", + "value": "user: CA_admin, password: the value of AdminPassword" + }, + "Console Url": { + "type": "string", + "value": "[concat('https://',reference(resourceId(resourceGroup().name,'Microsoft.Network/publicIPAddresses/',concat('pip',variables('vms')[0]))).dnsSettings.fqdn,':9453/deploy.html')]" + }, + "Mosaic URL": { + "type": "string", + "value": "[concat('https://',reference('optionalVip').outputs.fqdn.value,':9453/cgi-bin/mosaic?mode=mosaic&arg0=',parameters('moduleName'))]" + } + } +} \ No newline at end of file diff --git a/safekit-cluster-farm/nestedtemplates/createvip.json b/safekit-cluster-farm/nestedtemplates/createvip.json new file mode 100644 index 000000000000..54a91d4d1b64 --- /dev/null +++ b/safekit-cluster-farm/nestedtemplates/createvip.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "VIPDnsLabel": { + "type": "string", + "metadata": { + "description": "Public VIP dns label (optional. If set, an additionnal Standard SKU, unassociated public IP will be created)" + }, + "defaultValue": "" + }, + "location": { + "type": "string", + "metadata": { + "description": "resources location" + } + } + }, + "resources": [ + { + "condition": "[not(empty(parameters('VIPDnsLabel')))]", + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2018-07-01", + "name": "[concat('pip',parameters('VIPDnsLabel'))]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[toLower(parameters('VIPDnsLabel'))]" + } + } + } + ], + "outputs": { + "fqdn": { + "type": "string", + "value": "[if(empty(parameters('VIPDnsLabel')),'',reference(concat('pip',parameters('VIPDnsLabel'))).dnsSettings.fqdn)]" + } + } +} \ No newline at end of file diff --git a/safekit-cluster-farm/nestedtemplates/installCluster.json b/safekit-cluster-farm/nestedtemplates/installCluster.json new file mode 100644 index 000000000000..5ef4eb8ef3a3 --- /dev/null +++ b/safekit-cluster-farm/nestedtemplates/installCluster.json @@ -0,0 +1,136 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmname": { + "type": "string", + "metadata": { + "description": "vm name" + } + }, + "ostype": { + "type": "string", + "metadata": { + "description": "OS type (windows, linux)" + }, + "defaultValue": "windows" + }, + "vmList": { + "type": "array", + "metadata": { + "description": "vm names" + } + }, + "fqdn": { + "type": "string", + "metadata": { + "description": "first vm public ip name" + } + }, + "privateIps": { + "type": "array", + "metadata": { + "description": "vm private ip list" + } + }, + "VMDnsPrefix":{ + "type": "string", + "metadata": { + "description": "Public VM IP dns label prefix" + } + }, + "lblist": { + "type": "string", + "metadata": { + "description": "dns name of loadbalancer" + }, + "defaultValue": "" + }, + "capassword": { + "type": "securestring", + "metadata": { + "description": "password for CA server access" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "resources location" + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "base URL of deployment resources (template,subtemplates,scripts)" + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + } + }, + "variables": { + "pwconfscripturi": "[concat(uri(parameters('_artifactsLocation'),'scripts/configCluster.ps1'),parameters('_artifactsLocationSasToken'))]", + "pwcertscripturi": "[concat(uri(parameters('_artifactsLocation'),'scripts/uploadcerts.ps1'),parameters('_artifactsLocationSasToken'))]", + "pwiscripturi": "[concat(uri(parameters('_artifactsLocation'),'scripts/installCluster.ps1'),parameters('_artifactsLocationSasToken'))]", + "shelliscripturi": "[concat(uri(parameters('_artifactsLocation'),'scripts/installCluster.sh'),parameters('_artifactsLocationSasToken'))]", + "domain": "[skip(parameters('fqdn'),indexOf(parameters('fqdn'),'.'))]", + "publicipfmt": "[concat(parameters('VMDnsPrefix'),'%VM%',variables('domain'))]", + "privateiplistarg": "[replace(string(parameters('privateIps')),'\"','')]", + "vmlistarg": "[replace(string(parameters('vmList')),'\"','')]", + "windowsfileuris": [ + "[variables('pwcertscripturi')]", + "[variables('pwconfscripturi')]", + "[variables('pwiscripturi')]" + ], + "linuxfileuris": [ + "[variables('pwcertscripturi')]", + "[variables('pwconfscripturi')]", + "[variables('shelliscripturi')]" + ], + "properties": { + "windows": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.9", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": "[variables('windowsfileuris')]" + }, + "protectedSettings": { + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File .\\InstallCluster.ps1 -vmlist \"', variables('vmlistarg'),'\" -publicipfmt \"',variables('publicipfmt'),'\" -privateiplist \"',variables('privateiplistarg'),'\" -lblist \"',parameters('lblist'),'\" -Passwd \"',parameters('capassword'),'\"')]" + } + }, + "linux": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "skipDos2Unix": false, + "timestamp": 1, + "fileUris": "[variables('linuxfileuris')]" + }, + "protectedSettings": { + "commandToExecute": "[concat('sh installCluster.sh \"',variables('vmlistarg'),'\" \"',variables('publicipfmt'),'\" \"',variables('privateiplistarg'),'\" \"',parameters('lblist'),'\" \"',parameters('capassword'),'\"') ]" + } + } + } + }, + "resources": [ + { + "name": "[concat(parameters('vmname'),'/safekit')]", + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2018-06-01", + "location": "[parameters('location')]", + "properties": "[variables('properties')[parameters('ostype')]]" + } + ], + "outputs": { + + } +} \ No newline at end of file diff --git a/safekit-cluster-farm/nestedtemplates/installModule.json b/safekit-cluster-farm/nestedtemplates/installModule.json new file mode 100644 index 000000000000..116d3d93ad9b --- /dev/null +++ b/safekit-cluster-farm/nestedtemplates/installModule.json @@ -0,0 +1,101 @@ + { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmname": { + "type": "string", + "metadata": { + "description": "vm name" + } + }, + "ostype":{ + "type": "string", + "metadata": { + "description": "OS type (windows, linux)" + }, + "defaultValue": "windows" + }, + "moduleUrl": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "url of the application module to install on all nodes" + } + }, + "moduleName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "url of the application module to install on all nodes" + } + }, + "location":{ + "type": "string", + "metadata":{ + "description": "resources location" + } + }, + "_artifactsLocation":{ + "type":"string", + "metadata":{ + "description":"base URL of deployment resources (template,subtemplates,scripts)" + }, + "defaultValue":"[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + } + }, + "variables":{ + "installModuleuri":"[concat(uri(parameters('_artifactsLocation'),'scripts/installModule.ps1'),parameters('_artifactsLocationSasToken'))]", + "properties" : { + "windows": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.9", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[parameters('moduleUrl')]", + "[variables('installModuleuri')]" + ] + }, + "protectedSettings":{ + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File .\\installModule.ps1 -safekitcmd C:/safekit/safekit -MName \"',parameters('moduleName'),'\"')]" + } + }, + "linux" : { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "skipDos2Unix":false, + "timestamp": 1, + "fileUris": [ + "[parameters('moduleUrl')]", + "[variables('installModuleuri')]" + ] + }, + "protectedSettings":{ + "commandToExecute": "[concat('pwsh ./installModule.ps1 -safekitcmd /opt/safekit/safekit -MName \"',parameters('moduleName'),'\"')]" + } + } + } + }, + "resources":[ + { + "name": "[concat(parameters('vmname'),'/safekit')]", + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2018-06-01", + "location": "[parameters('location')]", + "properties": "[variables('properties')[parameters('ostype')]]" + } + ], + "outputs": {} + } + \ No newline at end of file diff --git a/safekit-cluster-farm/nestedtemplates/safekitdepl.json b/safekit-cluster-farm/nestedtemplates/safekitdepl.json new file mode 100644 index 000000000000..0ae2b9b1391e --- /dev/null +++ b/safekit-cluster-farm/nestedtemplates/safekitdepl.json @@ -0,0 +1,111 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmname": { + "type": "string", + "metadata": { + "description": "vm name" + } + }, + "ostype": { + "type": "string", + "metadata": { + "description": "os type" + }, + "defaultValue": "windows" + }, + "capassword": { + "type": "securestring", + "metadata": { + "description": "password for CA server access" + } + }, + "azurePwsh": { + "type": "string", + "metadata": { + "description": "install azure powershell module (optional)" + }, + "defaultValue": "no", + "allowedValues": [ + "yes", + "no" + ] + }, + "safekitFileUri": { + "type": "string", + "metadata": { + "description": "url of safekit package" + }, + "defaultValue": "" + }, + "location": { + "type": "string", + "metadata": { + "description": "resources location" + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "base URL of deployment resources (template,subtemplates,scripts)" + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured." + }, + "defaultValue": "" + } + }, + "variables": { + "pwazrmuri": "[concat(uri(parameters('_artifactsLocation'),'scripts/installAzureRM.ps1'),parameters('_artifactsLocationSasToken'))]", + "pwscripturi": "[concat(uri(parameters('_artifactsLocation'),'scripts/InstallSafeKit.ps1'),parameters('_artifactsLocationSasToken'))]", + "skpkg": "[last(split(parameters('safekitFileUri'),'/'))]", + "shellscripturi": "[concat(uri(parameters('_artifactsLocation'),'scripts/InstallSafeKit.sh'),parameters('_artifactsLocationSasToken'))]", + "skuri": "[parameters('safekitFileUri')]", + "fileUrisW": "[if(equals(parameters('azurePwsh'),'yes'),createArray(variables('skuri'),variables('pwscripturi'),variables('pwazrmuri')),createArray(variables('skuri'),variables('pwscripturi')))]", + "fileUrisL": "[if(equals(parameters('azurePwsh'),'yes'),createArray(variables('skuri'),variables('shellscripturi'),variables('pwazrmuri')),createArray(variables('skuri'),variables('shellscripturi')))]", + "properties": { + "windows": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.9", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": "[variables('fileUrisW')]" + }, + "protectedSettings":{ + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File .\\InstallSafekit.ps1 -SkFile ',variables('skpkg'),' -Passwd \"',parameters('capassword'),'\"')]" + } + }, + "linux": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "skipDos2Unix": false, + "fileUris": "[variables('fileUrisL')]" + }, + "protectedSettings": { + "commandToExecute": "[concat('sh InstallSafeKit.sh ./', variables('skpkg'), ' \"',parameters('capassword'),'\"')]" + } + } + } + }, + "resources": [ + { + "name": "[concat(parameters('vmname'),'/safekit')]", + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2018-06-01", + "location": "[parameters('location')]", + "properties": "[variables('properties')[parameters('ostype')]]" + } + ], + "outputs": { + + } +} \ No newline at end of file diff --git a/safekit-cluster-farm/scripts/InstallSafeKit.ps1 b/safekit-cluster-farm/scripts/InstallSafeKit.ps1 new file mode 100644 index 000000000000..39c056ba2a29 --- /dev/null +++ b/safekit-cluster-farm/scripts/InstallSafeKit.ps1 @@ -0,0 +1,61 @@ +param( + [string] $SkFile, + [string] $Passwd +) + +function Log { + param( + [string] $m + ) + + $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") + Add-Content ./installsk.log "$stamp [InstallSafeKit.ps1] $m" +} + +Log $vmlist +Log $modname + +if( ! (Test-Path -Path "/safekit" )) { + +if( ! (Test-Path -Path "$skFile" )){ + + Log "Download $SkFile failed. Check calling template fileUris property." + exit -1 +} + +Log "Installing ..." +$arglist = @( + "/i", + "$SkFile", + "/qn", + "/l*vx", + "loginst.txt", + "DODESKTOP='0'" +) + +Start-Process msiexec.exe -ArgumentList $arglist -Wait +Log "Install Azure RM" + +if(Test-Path -Path "./installAzureRm.ps1") { + & ./installAzureRm.ps1 +} + +Log "Applying firewall rules" +& \safekit\private\bin\firewallcfg.cmd add + +Log "Starting CA helper service" +$cwd = Get-Location +try{ + cd /safekit/web/bin + & ./startcaserv.cmd "$Passwd" +}finally{ + set-location $cwd +} + +} +else{ + Log "safekit already installed" +} +Log "end of script" + + diff --git a/safekit-cluster-farm/scripts/InstallSafeKit.sh b/safekit-cluster-farm/scripts/InstallSafeKit.sh new file mode 100644 index 000000000000..2a7a0ad3defc --- /dev/null +++ b/safekit-cluster-farm/scripts/InstallSafeKit.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +echo "Install SafeKit from `ls ./*.bin`" + + +chmod +x ./safekit*.bin +./safekit*.bin + + +yum -y localinstall ./safekit*.rpm +#rm ./safekit*.bin ./safekit*.rpm + +echo "Install powershell" +# Register the Microsoft RedHat repository +curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum.repos.d/microsoft.repo +yum update powershell +# Install PowerShell +yum install -y powershell +if [ -f "installAzureRM.ps1" ]; then + pwsh ./installAzureRM.ps1 -linux +fi +echo "starting CA helper service" +cd /opt/safekit/web/bin +./startcaserv "$2" \ No newline at end of file diff --git a/safekit-cluster-farm/scripts/UpdateSafeKit.sh b/safekit-cluster-farm/scripts/UpdateSafeKit.sh new file mode 100644 index 000000000000..a97b094a5c4b --- /dev/null +++ b/safekit-cluster-farm/scripts/UpdateSafeKit.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +/opt/safekit/safekit shutdown +/opt/safekit/safekit uninstall + +echo "Install SafeKit" +yum -y localinstall $1 diff --git a/safekit-cluster-farm/scripts/cfgFarm.ps1 b/safekit-cluster-farm/scripts/cfgFarm.ps1 new file mode 100644 index 000000000000..06d0e111b8b2 --- /dev/null +++ b/safekit-cluster-farm/scripts/cfgFarm.ps1 @@ -0,0 +1,39 @@ +param( + [string] $safekitcmd, + [string] $safekitmod, + [string] $MName +) + + + +function Log { + param( + [string] $m + ) + + $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") + Add-Content ./installsk.log "$stamp $m" +} + +Log $safekitcmd +Log $MName + +if ($MName){ + + $ucfg = [Xml] (Get-Content "$safekitmod/$MName/conf/userconfig.xml") + $ucfg.safe.service.farm.lan.name="default" + + + $ucfg.Save("$safekitmod/$MName/conf/userconfig.xml") + Log "$ucfg.OuterXml" + + + $res = & $safekitcmd -H "*" -E $MName + Log "$MName => $res" + + & $safekitcmd -H "*" start -m $MName +} + +Log "end of script" + + diff --git a/safekit-cluster-farm/scripts/configCluster.ps1 b/safekit-cluster-farm/scripts/configCluster.ps1 new file mode 100644 index 000000000000..dace9f62f759 --- /dev/null +++ b/safekit-cluster-farm/scripts/configCluster.ps1 @@ -0,0 +1,88 @@ +param( + [string] $publicipfmt, + [string] $privateiplist, + [string] $vmlist, + [string] $lblist, + [string] $Passwd +) + +$safekitcmd=$env:SAFEKITCMD +$safevar=$env:SAFEVAR +$safewebconf=$env:SAFEWEBCONF +$logdir=$pwd + +function Log { + param( + [string] $m + ) + + $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") + Add-Content "$logdir/installsk.log" "$stamp [configCluster.ps1] $m" +} + +Log $vmlist +Log $publicipfmt +Log $privateiplist +Log $lblist + +if ($vmlist){ + $vmargs=@() + $lbargs=@() + $privateipargs=@() + $targets=@() + + "[" | Out-File -Encoding ASCII -FilePath "$safewebconf/ipnames.json" + "[" | Out-File -Encoding ASCII -FilePath "$safewebconf/ipv4.json" + + + $vmargs += ([regex]::Replace($vmlist,'[\[\]]','') -split ',') + $privateipargs += ([regex]::Replace($privateiplist,'[\[\]]','') -split ',') + if($lblist){ + $lbargs += ($lblist -split ',') + } + Log "configuring cluster.xml and certificates input files" + + $str = " " + $str | Out-File -Encoding utf8 $safevar\cluster\cluster.xml + & $safekitcmd cluster config 2>&1 + $res= & $safekitcmd -H "[http],*" -G 2>&1 + Log "result = $res" + if( Test-Path "./uploadcerts.ps1") { + & ./uploadcerts.ps1 -skbase "$env:SAFEBASE" -targets $targets -userpwd "CA_admin:$Passwd" + } +} + +Log "end of script" + + + diff --git a/safekit-cluster-farm/scripts/installAzureRM.ps1 b/safekit-cluster-farm/scripts/installAzureRM.ps1 new file mode 100644 index 000000000000..e808b410004b --- /dev/null +++ b/safekit-cluster-farm/scripts/installAzureRM.ps1 @@ -0,0 +1,17 @@ +param( + [switch] $linux=$false +) + +if ( $linux ) { + +Install-Module AzureRM.NetCore -SkipPublisherCheck -Force +Import-Module AzureRM.Netcore + +}else{ + +Install-PackageProvider -name Nuget -MinimumVersion 2.8.5.201 -Force +Install-Module AzureRM -SkipPublisherCheck -Force + +Import-Module AzureRM + +} \ No newline at end of file diff --git a/safekit-cluster-farm/scripts/installCluster.ps1 b/safekit-cluster-farm/scripts/installCluster.ps1 new file mode 100644 index 000000000000..270c680fdadd --- /dev/null +++ b/safekit-cluster-farm/scripts/installCluster.ps1 @@ -0,0 +1,33 @@ +param( + [string] $publicipfmt, + [string] $privateiplist, + [string] $vmlist, + [string] $lblist, + [string] $Passwd +) + +$targetDir = "." + +function Log { + param( + [string] $m + ) + + $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") + Add-Content ./installsk.log "$stamp [installCluster.ps1] $m" +} + +Log $vmlist +Log $publicipfmt +Log $privateiplist + +$env:SAFEBASE="/safekit" +$env:SAFEKITCMD="/safekit/safekit.exe" +$env:SAFEVAR="/safekit/var" +$env:SAFEWEBCONF="/safekit/web/conf" + +& ./configCluster.ps1 -vmlist $vmlist -publicipfmt $publicipfmt -privateiplist $privateiplist -lblist $lblist -Passwd $Passwd + +Log "end of script" + + diff --git a/safekit-cluster-farm/scripts/installCluster.sh b/safekit-cluster-farm/scripts/installCluster.sh new file mode 100644 index 000000000000..b02640e0a772 --- /dev/null +++ b/safekit-cluster-farm/scripts/installCluster.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +echo $* + +# Start PowerShell config script +export SAFEKITCMD="/opt/safekit/safekit" +export SAFEVAR="/var/safekit" +export SAFEWEBCONF="/opt/safekit/web/conf" +export SAFEBASE="/opt/safekit" +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/safekit/private/bin" +pwsh ./configCluster.ps1 -vmlist "$1" -publicipfmt "$2" -privateiplist "$3" -lblist "$4" -Passwd "$5" diff --git a/safekit-cluster-farm/scripts/installModule.ps1 b/safekit-cluster-farm/scripts/installModule.ps1 new file mode 100644 index 000000000000..890150f36e4c --- /dev/null +++ b/safekit-cluster-farm/scripts/installModule.ps1 @@ -0,0 +1,31 @@ +param( + [string]$safekitcmd, + [string]$MName, + [string]$modulepkg, + [string]$modulecfgscript +) + +if( $modulepkg ){ + $module = $modulepkg.Split(',') | Get-ChildItem +} +else{ + $module = [array] (Get-ChildItem "*.safe") +} + +if($module.Length){ + $module[0] | %{ + if($_){ + if($MName -and ($($MName.Length) -gt 0)) { + $modulename=$MName + }else{ + $modulename = $($_.name.Replace(".safe","")) + } + + & $safekitcmd module install -m $modulename $_.fullname + if($modulecfgscript -and (Test-Path "./$modulecfgscript")){ + & ./$modulecfgscript + } + & $safekitcmd -H "*" -E $modulename + } + } +} \ No newline at end of file diff --git a/safekit-cluster-farm/scripts/uploadcerts.ps1 b/safekit-cluster-farm/scripts/uploadcerts.ps1 new file mode 100644 index 000000000000..6201a6353834 --- /dev/null +++ b/safekit-cluster-farm/scripts/uploadcerts.ps1 @@ -0,0 +1,47 @@ +param( + [string[]] $targets, + [string] $userpwd="CA_admin:CA_admin", + [string] $skbase="/safekit" +) + +$curlcmd="$skbase/private/bin/curl.exe" +$safeweb="$skbase/web" + +if (Test-Path "$safeweb/conf/ca"){ + Write-Host "CA already initialized, skipping certificate generation" +}else{ +$caname = "/CN=Safekit CA" + +try{ + $meta = Invoke-RestMethod -Headers @{"Metadata"="true"} -URI "http://169.254.169.254/metadata/instance?api-version=2017-08-01" -Method get + if($meta) { + $caname = "/CN=SafeKit CA for Azure $($meta.compute.resourceGroupName) cluster" + } +}catch{} + +$cwd = Get-Location +try{ + cd "$safeweb/bin" + & ./initssl sca "$caname" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "action=swhttps" "https://localhost:9001/caserv" +}finally{ + cd $cwd +} +} + +for($i=1; $i -lt $targets.Length; $i++) { + $targetip = $($targets[$i]) + + Write-Host "uploading cert to $targetip" + + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/cacert.crt" "-F" "action=import" "-F" "target=T_CA" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/cacert.crt" "-F" "action=import" "-F" "target=T_CCA" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/server.crt" "-F" "action=import" "-F" "target=T_SC" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/server.key" "-F" "action=import" "-F" "target=T_SK" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/admin.crt" "-F" "action=import" "-F" "target=T_CC" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/admin.key" "-F" "action=import" "-F" "target=T_CK" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/proxy.crtkey" "-F" "action=import" "-F" "target=T_PCCK" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "file=@$safeweb/conf/sslclient.crl" "-F" "action=import" "-F" "target=T_CRL" "-F" "add=yes" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "action=swhttps" "https://$($targetip):9001/caserv" + & $curlcmd "-k" "-u" "$userpwd" "-X" "POST" "-F" "action=shutdown" "https://$($targetip):9001/caserv" +} \ No newline at end of file From 6a4c541b91861eabbea5bf34d007834519a7e388 Mon Sep 17 00:00:00 2001 From: d6p <43806862+d6p@users.noreply.github.com> Date: Mon, 14 Jan 2019 17:35:24 +0100 Subject: [PATCH 02/66] fix date format --- safekit-cluster-farm/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safekit-cluster-farm/metadata.json b/safekit-cluster-farm/metadata.json index b690f0fee84c..1175d52fb538 100644 --- a/safekit-cluster-farm/metadata.json +++ b/safekit-cluster-farm/metadata.json @@ -5,7 +5,7 @@ "description": "This template deploys a load balancing cluster with failover on 2 to 4 Windows or Linux VMs in different availability zones", "summary": "Evidian SafeKit farm cluster on Windows or Linux", "githubUsername": "d6p", - "dateUpdated": "2019-1-14" + "dateUpdated": "2019-01-14" } From 92275bf59101a46535f83a0eb98fbe310fd9bd50 Mon Sep 17 00:00:00 2001 From: d6p <43806862+d6p@users.noreply.github.com> Date: Tue, 22 Jan 2019 12:56:28 +0100 Subject: [PATCH 03/66] implement requested changes --- safekit-cluster-farm/README.md | 15 +++++++-------- safekit-cluster-farm/azuredeploy.json | 7 +++++-- .../nestedtemplates/cfgFarm.json | 6 ++---- .../nestedtemplates/cluster.json | 16 +++++++--------- .../nestedtemplates/installCluster.json | 6 ++---- .../nestedtemplates/installModule.json | 6 ++---- .../nestedtemplates/safekitdepl.json | 6 ++---- 7 files changed, 27 insertions(+), 35 deletions(-) diff --git a/safekit-cluster-farm/README.md b/safekit-cluster-farm/README.md index b9fb4b4e44a0..40f61827d253 100644 --- a/safekit-cluster-farm/README.md +++ b/safekit-cluster-farm/README.md @@ -4,8 +4,6 @@ " + if($publicipfmt){ + $str +=" " + + for ($i=0; $i -lt $vmargs.Length; $i++){ + $dnsname=$($publicipfmt).Replace('%VM%',$($vmargs[$i])).ToLower() + $str += " " + } + + for($i=0; $i -lt $lbargs.Length; $i++){ + $dnsname = $($lbargs[$i]) + if($dnsname.Length){ + "`"$dnsname`"," | Out-File -Append -Encoding ASCII -FilePath "$safewebconf/ipnames.json" + } + } + "null]" | Out-File -Append -Encoding ASCII -FilePath "$safewebconf/ipnames.json" + + + $str +="" + "`"$dnsname`"," | Out-File -Append -Encoding ASCII -FilePath "$safewebconf/ipnames.json" + } + + $str += " " + for ($i=0; $i -lt $vmargs.Length; $i++){ + $str += " " + "`"$($privateipargs[$i])`"," | Out-File -Append -Encoding ASCII -FilePath "$safewebconf/ipv4.json" + $targets += $($privateipargs[$i]) + } + "null]" | Out-File -Append -Encoding ASCII -FilePath "$safewebconf/ipv4.json" + + $str += "
1r_PtB5I4lj*>gb;E4D9zzhOx513rBL<)2iRwlRV2B$S`BU z9*xDyx+Qs*?1okwQa|7dDZ($TY|Z-myT(`i!CA)r&l1huihtYfC7aL8P~E*)O=ASr zxW-_$zz?|V^Dcu1i{$V?Rmr*FU=_dTw&LBbUTQ~3s3Qu|?=`_Sgb9vse~_<_ZGz=AYy8^2^ZWS_PS zi>*Wv^mfRx1A7iCxP FW?6Q$%q&3@eLqh#iO-J>Ek? z&Web*E@ML(`e2|TCBOEsXmc^in*-Ce8h@Z{ogYrgGS-Ajfg_&D=~c$+M7kbDVWp6d zu)EN+?`3PY4z0a3DgNO~y5PC;72 6IC<1#wDjujSsbqBj>71E;*8C7asG&! >e9de=>aE7}j^}em}R@EV_E6r#W_P zmJ6ef^P;qg)3a$-IEGDnZR@|6EHifG`4v>yM0f(fokO|py|5>8iPxOEzO8;+zgwf# z&$en#tKjc4dNEH)ubh9Mnmsu;J$`Q1ijlIin`WtpPv#VOG=p!VMxD}b!|>N0lb6&c z*7CXv91xt0b)S_(bDR7?ZZD1ZuaXswxFhHH+eynMU-6mI6wR*tjL!@g{Fi5S9>3#T z$uo#46yacJ-;8<`t+DDpGU^ ZNJJ?x9}mQH;usl z-wL^H{QI>+x%R$$TM|+8--4yM9j%X= hj^g*r2>2_rcKNfO;pcW0PkVCZ`RXyjhFLh`x>vT6BDZ6+ZL4HOFD)_$PI6Da zRYlpW9*WVvH|tKcOy5DVva+6jJ=vqbRn?p08T={P--kBu_hxa2bvo?w*7bPeX8D91 zdr@)IVvjf7m&r4G#fw b`xuXLo)sM(n0 {W(Xm~DSUConC*BwDMU^dL zYLDYZrSeKXPIe7fmHVzb!6S)~43ujOxz=9o^CV$AR>2`-qRzQzE0bvvH+kma8Un{e z$!SR$hgUKKRZ9tjvNaxxMoXZ5-{KF!yPI aCFNyZL)?g~J3Y(teQ+ragZkZl|#nu)6 zTL~L9;oPhQc%Va2E3W}iX~H6n*E6HKwpHavtPh2tUAcxhMC9wdnG0JDU(cQRruMD# z)^j;Hi#MQ$@Y4RG>g1KE=vln9yO&qAp&o}6@Y#Jz?gMJ8)iO3co!d%i1Z8pykbgfX zmjknXvoZb3m^6uAsybxb#$i??k6Kl97>&ih(lbIX7$s{Mv-CZsu#z7X*LAH?N8fox z5{iCx4I>&F)-b2VZZ-;i!uosv-#hbL-G5{_@i$e-4{SEcGE%lvdG7J`2qeBfW~Vo% zjg@FZhL(5mTDbYxymuG)wpNSE$JnYn#&KjLs49y%7L9m?#BH}nfsz8P5w&0HR8fyo z*SQ|$wD6Ej2p^#K`c2CM?q*o^sXf2Sqm|cNM?PiS{M{V<>J=Wrpes7 2J$e4T^Q8tHp;Bihbi=Kb}0utdBg{Bjb9@&X*m%8U%G4Q5%W0 z@2C6%U+rCD{_-7bcymR>wFp#oYdXm67$Huho=EnI4AXbZBVQz%&at!u?-se2=WNsj zs7m@yJ(qMKAA`OhZ@Z>?PUpLrSf36%xgeSxu{ZjNc2b4)_>8?2`R>7s&UZ3NqjcS{ zeNEyf`I+ZU> |g?+*>Tn;yZ{urHy7lP+Na6FD^e zJ-Yr58x>ZREVkeChx^E%XF2lZ!n}X2L8TFSw18x&S}?w1Yc|a)n^t0_P6D;*Jm!mP z#F7f2R@=0ktS=EC+8ya JPQ`gx%P6&bqnBp2KVGY3x>5$6rY|eV>eY zdpFZ#@0q{@w-;ph)V$C&_K0x*Vd4aH(OL1j8GXJ!=XPxuD7@?6t?THP?cQXiuur*M z)2p6CPw_&u%%kEy=F)VmWb~%s$C7n!U$RRm*O%#Bw&q5IqF+vxIrOM|V9ge`5m`~h z7*==H{o3f>w$d#qTHn aP}b>uB42Xr@*!IqIKlPdWW--}IxrsGE+*d6B0PLHnL2kI0DP zYHO5!G>_r(6{qFAHoK@0^89ZWUmT_X+|#i?w7x$eMn1AA_(QW(M^>rXHrYV-12*L? z=wl0p*H>K(VsK`VgvC0p@5Ec|jh`#Qo0ehx*+yeM>$CpBApi3<-gE0Lp xA?cQme#CO<*u!mQ-vK LhJud(LX(ymly<<$vJNdVJSR?;88{J%K11 z(&8~K9aO4LpCk&RWd~Q82RY@ll)JcvVC~mU8=y6GjkT0Re{HgH*^7w8oyci(J=b&6 z$XtgadRbY%?!K#Kp#+t#0Ue#@^R&Bg8h@lLhj2*6B`_=*8}Qz>oQR4cI~d$DE}2L8 zW9g^t6|#YDi4QsdmRm=ytZQgBHj)Yy_#C9nh@MTn5&0;6@4NP}WclbNnRZZ)%onX? zpPOn2@RhljSw3OIjz0LXgcrfn@62{lsltMs{GIZ338(t>cz4_q_ol8(xJu3PwaIh; zO{ND{Md;sQmkD}I-QV9OA$F?ozFe}taG}4+8!F6CEs8pn+l#H_J@bD4Zssw)%Imc$ z*=Ns>=!~%Isol}n`sFpWPj)NhKmTqWT>J7eoWJ~joi)f}sR{Wm`+h{4!=FdGSSl#C zvdn6oH6v0~3> Tjsv`SDy! z=9G0VWwQMI)-YJwQ`8*nc)^Ew#!}yXsIg<$4V&SCL4f9B6{5R 6Hq&-YY1nxRYWu z*Z8LuFGg* dT_`K2R=)3&al9M`wez*2qzdk8n7}bvLWCQRM*kF3i>|N%ws+01U>r^L)>$Uw^ zEtAyx^4C!ZyJvEwlO42@w4p|el4tB3$HT?jrV$m%Bh8sd^O6gPzLs$N4tQ$lth#>Q zTceS`Ef|!M9}Rr+-pt&psqiYV!tp)Re_xs1Mh}gWzL)-@`_AZq=5E_Qq{sFj*zOp& zh(zW*wPo|sy>u$MAEV-nb)YWjesT$K#&8(MgMB^$cSs3d-!WdFe H;HMr^52f^*7&Yo`kC23@7TkA`U33OjT1F|_pYkMH{qM;f+ro?i^#5)>_m=z z$gXw&JJS0vMx%A=*P=jqT_&65)3Q*plL1R4O&hmXTV}1WJL_7j{~LSNlG{GkRKQ|4 zJ7<5yuJqjE-iAzz+BcbNJt Gf!d>nqreYG`gSusB zHI-}4tEM?^mf#vX)Q0WmvLDnP+Cug zSmyUFt8uw*y=(OTm1egi(9)84 zZ85KLD$)$={E 8ScnhGFJ`byvP5Yae>{@f3lUxw$D;!y?=t@a_iE
ChLQQMPggQP zz2iE}!N@5?hOlDDbDZp^CzkH8SijaBR3fiJ-j>MlGEM}YZ@&K^;8x6;+bm+9c0_&0 zX#aZ~HMBA9^K`Usc@^h&vi(2HD0y=pmXx>|6_C_lEGMC680Wuyc)edH$8>&7A-c_z zoc5^pw_2&jh5D1VkyOvx`n;XIrE1t{IQ2`ci1+undNnO%ZGI)KwKhFoX4cMjKY6US z>yCa+c_PN ^nm?Olphd;pA`jOZx6vP(e$=gZ zO^yVKu5XPa>JJ9aL={7C01T=%MBbsjH0x6ZFFX&{)~LEJfuH}&pY^f%9Y4V?&Xlgl z<{LKGp4lRF%g^!XpCS-%UZRKUt=Ib;L2Y7`{M^&pI|KBK^7qE08pQ4l;+wHEPN%d8 zoTxoxABgs;xBI(j 0w!YgiO1pmL z=dW_=J8~x}l%(pn5JKzl2 F&CEp5sJJ!+2ch=FxxNlf{Z 4R_$}M({9;)$RJL-LE?i1a> zfv{=OagKZNLGPo@lc2n+HBH_1Wah3x@4H=)7qTAS{I8$*l1l~@35oFcr||^%3v_8K zNyKZbdeN1DSNryDIm3mGMK9@)>K$xJ1$U-w9Xji0GEdpM-3b|!H04}sNl(NHtx+Lk zNRM|Pgl+gxI@&dwhu4uD5+wtn&X)2wuzjD@p;3$McxAgPpsD+(Q{z%w+U98P{QW-d z-7ENFokqv|SMzqtAURmy>EC7f*mmeVw6n`)>mL|R%D2K>{E`%mUt3R4$xg^jIX`j| zw1Lam#aHHQkQy|K>(m(rim0$fp3fl@L@92+yx;8>iJdpZTQBV&b!yK9^D_ $&ZnQ7l-V8WEWb(VXWy?6%?DFjm2Gpv}D3G;Pb|Wpf)TykjLY4`9;Hf=4rE z7H=YtY0alfq^}aEx@wm4+LE8TpR3 Zo`e)L)m%wdc@H z{35%_{9F;wR;X(D2_X1Pbf0|VG@URII*Ux^UJpy}KC-S=o5f5|2YwTq<~|nOYY exh`fcHGv$yf=T k0KPWaXd2*=5>Mo3ZVs(tf&G! zO)&y7j{Ac*BmSqvvu-ELQNX>Q{OMVO^~B%~{wt$F&huy%{XyP=b_|m_5<;wnr8u_# z{M6Q`gF1ygN}DTlRuk^3EiSKi%!|*o4zzW@g!KsBiIW#^H>O`ggI4{8Y-K9bxc#aM z^~YuOT^3tU?OZRj@Hy0k!+XYKRXJrH$LlQp+?a}T <`E|{!D|a) @$VsMA2*Yo0IP zOmAka-~Cq<=GO5WgCOEJ-t>5A|M{5sg@(A-^6~B7xYM*okI=5NTA-K=ee u8#syFd&gIE7@{p(j>@Nk@th3!5~Uh0WeWr%R`hWNv%b+IzP{8!i3nsy?2Ieo{x zo1!_7s003>+8E{NcCaT1+?{@}6VB1Ka0{_xmV!4?sl&iu#~6z?{H0aqp{6qRJE3(t zY#1aSYY=nReqR(wdAIG #^ES93_t4M=6k^yQRAwt)|U0az{R=M{{=|mM&J2Uhid%P zZavqBbIwZ3V855LLU#Yf3CM~j{%AP0eyuUE(-V6({=Pkh9Vm6EzPqwkDY*SzTsO7G zwY^xxJC~`q@HlDpX3|l#rEX!{-l`^H?420qYNaG$J(WQpC%b{ZzD)AyzijLsU$4?d zZW #x9w;_Ol)jIG&}v+)H-mDC_hEo~ptV!T9-4j$K4NE&nry@1=1x z&oqY+te=ra_B_t%miEA9_gv!jG`;*B57CP3X1eP-MjPfD(`@C0)AWn(|1>0Zdr{K| ze;eJQP&T<|IsrH7A%AI<;}ccf{P(cu%WaKkHAv!Zx+$9QoAY!V@=8K&71xcLmCp5E zJTCQt-kG1yj-Az;e(|1(TWZx6Bv~aN$7Eu^(3h`_zEsP{aSs@xgFlXSIX|C$Uv*dl zVD)?2DM0M!?_&0C10!?oUT*(leeA%2<(gkxj43POZ{dDps}PxfV$?oOJ`m`L$LHF} zI<@OIGWYelJPdIaorpi3QvO>S+{ZG+Z})s*xy9FJb?a~py+R*`x`hnNQD6MbWRdrn z(a1}qA5!|l^i+Fd6j_Z+#+*24=&eF(O7A#lzVMu5l<7xv&rHMhYcvrl4WWW!Ul;|@ z!u cV>NB$GUx(p*R(|9O8bKCU}EObF9=fedp&-9^Fwp@l*YgV7lV2dsI`FNo@Ew zYFB@;dC=UkUDJ|^&29 _czp-D+=w;;><_sjeNH=0hX0%He@W zHT;Cl#|E(?=6e4nxAjP69zo@+#=g0T0^h}MRN{Gd#8F*h|22D#A6g_vor0)Br&tqP z=q#WX1w;vOd1W Y;}(T**i1j4pPvUim0{yU{H9iQ<89;X5g35 z80Du)`Oa^hS?BwZ>%XHRn9A$$jY~!D^Y*oCzL;ldd2jC&y^t$e9@m;ZqX+bfjDmA~ z-d|KVkOtQEOL&f5@1|&jydzFM7=y7k7HDht!`lizx8~?!tVJ}nL^6fNr&c|ep8?uA z`Aj@RMkA<#1B-t2>Dk@l>9p=xOC6jum=M)zN#j?D*oo*Ne&D-;CrX!fNcgZ?kwz zI2Ttvu>?~+vjk7@1G4pGPZSS3Jtlb?d1h23OGoN-FP_e2&fjMouO*6u%OG#pK}-HA z`>07eUDSiOeOsLK)$OMCiMjMmN9e+G8Mg&d@GpmJw}7%QyZw=& zTQ`l)1ygy2YW-6Zf@<`=POZ9*E$Y{mHjP)ral}SMe|;Xq*Zz3Xu^$0If0uRd1B(B* zOYJ_SEo%2^&wly*S*i-l{w?uP%Pd4)vIO0nb@g^oZS358VI}CwZe7K1#3lY-kNdMZ zSsaq!b9m>q)+atUiNi) >q(0O%RteptsID|!RLA`14I)tyP(L3;=J>*aDnA)zg zIpT%9gL%)sSLOYlaf?iE$r*dWnf`lk <*F>{r zxk=lGNaKZHc|~gXlTBw|iFaw7$3$xp39uX2cRG-lAu&X=F|uE03fc1+Ty9;?RDmah zt?$ b1D-pt@m?g9e?D>PnT9~8P+0bH2sEgz)lq6 zCvtjcXRe(RKc?xUwRFV;^B$M7K4c~Ksk=1{-fNxEB4s2V3Fol0D=Z=?kHL@$ |?_Z3a)eKG91 zKfPl*>MML{SD(+{7K!;~n*#=q~lT?^r@{WTw2tEe=d Tzja!{$xUx}Mf$tKT7LK?x-8 zS#tcR@OIc=8pIw+i`&PEUU6nm{_D!h=aDv-Ik!dq_c+m6ssMN|@+S6~vxBmZy=YyI zW^a|hHHOVYJH)|Hu1{HTdCsfycptcy-;-s2&tRH5m8jH;I&b=S-`c$X4=%m!{s)(- BB&+}c literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/CreateUIDefinition-Must-Have-Parameters.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/CreateUIDefinition-Must-Have-Parameters.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..5166d2883018173a1a0db992e3a268cf7dcc2f6a GIT binary patch literal 690 zcmchU&1wQc5QOU-@Er#6prGOlcrqS5h=NEC!NaPPWCeF+cSR)R)suWZ%lbn+Bm`ub znVz2Rs_O2q&z&M=?5&!r=|Rt$o;+TKJikqi@g-Vw7E19P)mH;M)1HVnIjM5Rcw(%C z-=11poDgT4XsHdcD`HB2Lj&@C!1S7Hq(@#aAS4$^mwBeI6)??;iFIh}5TAnTQ1n;C zuFmyW)#h+Gy$2qLWvkE|T2mdc>%U@g=*x-ThTD3R=#_WGzQt)?W7yGy489{gR^`VX n>g_U{D9mrg`Lp^b6xnP&y&htl&g|cvxZV3}Ep=F`Rd(YW#$k2h literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/CreateUIDefintion-Should-Have-Schema.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/CreateUIDefintion-Should-Have-Schema.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..b03e49467166c97d99fff3d0808a9954c86bfa58 GIT binary patch literal 2378 zcmdUxOK;Oa6ou~^iT^O7m7GY88(3CCEI>#s5QvCwstVG?Z9^L;vYnz(`qzQ)%+$#^ zeW-+Hfh@=N%ze+f=jQjXsr9Yk9$U+v+7mmlkBgPeD$Cey*?ZP<8}eJ(gq69yv~AuC zn<24-&csR^u`=Q W1O^@!>e-(zA)@ZjvydvUz!s@N^?@tyZ)5AxxNu0(q5 zpQ=o5Cw%w0zv8isJUW|t>r)~q@HNMW^1IqVrm^3ISX8@=XF`S**ObWiY?mvROnqf? zqCfFf%FwDT<@*QcuQN=^XM$8yujISS-gE93_)?ykT~LjTTJAomk}24m**X43wvUGt z6qO!hTmN)cHBud!_pzw6$@$euDVM^>Dzv(lS_ly_VzhsXhN2v@cSLrw`v28)hqyzZ z*Z5U;wASvc7(?o-WJAclpyCCm5V&X4{oC}m+N)dC@DuTjL4+hjMdv)5=y#q0W}xjX zs`|iVQJ53wNLw8vUJ9%jSY+z)xkPY{U*|n8D &j#zhV%sTv#)4{Z!nVK6Q*=?vT vE?gdnz{F|q0 8|JDI#aNTY553q;XZskPM@uM7Tc`HI894!KgYuq9{SoG`*R7i%kkeq T6ManOW0tzDgYK_E-T!|8IJkx< literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/Handler-Must-Be-Microsoft.Compute.MultiVM.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Handler-Must-Be-Microsoft.Compute.MultiVM.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..2df517acabc3381f02014e82dcaf4b11be954647 GIT binary patch literal 734 zcmbu6%}N775QOV2_zpt|BmrG~0Z)4IAPW9m#Dj^mI+E-zv%83hudaUGYKVF;L6+I+ z>8Yu%>VA7|bfe5#Xsm5*=}M=|OjM`H?O4a;D&6w$RFiqqzJ|nEJ%}CN)M}N;B%+Gj zJxz4IWIWS}rg{K71M`s|>VWsrIioIgq(e?64AlzL>O0dnaZZa8*nqZO@HMOfMVm4f zy8m=Gr*?)t=-Dd-BKtZJ8U9D&!CL$QWi9B1@79${cbvah3Tm9U@wy!y9eCZBU;h5@ zD$t`DDk3UI%rbE@Pc5s&VS%q2y$#c}i5Fmc&54sP$&dc*%Q^0h{inwg-b{X-xmd?~ RG}$Dl&bGPIuO0^P;yW|ceQf{$ literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/Location-Should-Be-In-Outputs.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Location-Should-Be-In-Outputs.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..4c7a63460c39d27a3728edacd1ea54c36a316aa9 GIT binary patch literal 716 zcmcJNK}*9x5QX1a@IQo5XaY6#4|u8 n-xtW=QM>smeHt!gR;^b{(Ul1Yhj zc87{JYY``U&_b`&E~#nqJ&ovhhUxUETivi)fsl8Qx_zEsY?wYusSV(EMSTHk0Hbpe z6FO^pH#U|^^hRcBoEjxDxbJpmK;*wlFYqq3BMx biFTJREqR literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/Outputs-Must-Be-Present-In-Template-Parameters.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Outputs-Must-Be-Present-In-Template-Parameters.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..5dc908127ba9b98bc596ddf27fd3d65433cf2c86 GIT binary patch literal 1416 zcmb`HPfy!G5XIlQ65nAJB0;1O!3W?}IOG7WM5`W955?I)Q2eLa1R7QO>a@SHvx%LW zDoAMM^?G*p&6_tn{_|4khh{vfj&-09y4B~6#cM9l?y;`0Wg0Qhm19}zTwT^PE%4}b zCRfk|%Y;?N?x}kEzCpavC*A20-vpn^-qlCW`x4XZtA@JZYYakGL#m(amw4~V@@x;5 zUtpE0&~(kT&d9j*HmvMxLIw`SPRJrBSBFk-&2vDsSe00VpaFOb5Q}mS#C7^z#&)c1 z%=Lhxxt>{f_KND@8}Lrcw^cCH{Tj*h-j9iclf^AiY6goX(M^k0LzyuiRlO5 -fhW#$c~-g)xh`#?AyC#mO7USoZ7T%#=b`H6i>&^H3oI12a3CvQ`9=vx#=4{ z9rgG6iT4r61!GEfNqK{+4lyN+`2w~H>uk;7XkAy=sBDaS2x8#OHeaiHj&)q#3PZCj zY)-L1fjXr>9q$pt^Egf~ne86kmAnG=h?TF@Ge&{Y&LROhBd(pX{%?A%_>QAZv3h6x zueV;id+mz<+YOP!H`K5{lcy$^tnGHpVA$ck?Wf(UZ!0;%&(v^aTXnS8FAxKm@y;50 R{U6cJz3Pg{tLlzw{tKz`>I47) literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/Parameters-Without-Default-Must-Exist-In-CreateUIDefinition.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Parameters-Without-Default-Must-Exist-In-CreateUIDefinition.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..dcb14fcaf7d3453908b769a3d85a03243477e6f3 GIT binary patch literal 2004 zcmd6o%Z}4P5Jm4AiGOH8Bqq|N|9}+_DGMG_fLS0GnZ%O>@-TKX5TW^X;8Z(p$BAPy zhy}8owCi!J>Q;64ub-)g%6J#L&_g}YN4+g2iPlQcUg#CFrN;cOwL-GhQ*~Hp+F;Su zr_y(zH@enmq$Bi&yrXw~FO+H?5R#hBW$=x$oBf{=DcSkHS6|Qhy3vfBW<;5h)3SzX zXx$R`Cgg1XBTeO~r$a8W?pUP@cn)1#w!XnLmq~M?RF#_~Lz0qd7II9m=o0-$$jh;^ zrzw-y OSG2K8+pzjDWA(RTeIVXEbh3^%4lEDR%&DNVI*k>hd1l2rbnLqy zVTQ%2Zg?VY1A9(Au)bpXL<3eM^08?cV3CEMP0$p~I >^T#fNqP5eKclKt*Po4ZDYf5Ezkn+ -An;`n~@x}x*8Qwv`G?tX};kLUifEc4yY_j(!Tcmeb0 i%~p>)!S0I*Rjq3`&EMS@P4gD#?*6k`Osbu8hWi`JK1MwN literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/CreateUIDefinition/Textboxes-Are-Well-Formed.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Textboxes-Are-Well-Formed.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..a4dab3c2046350738f245b90dfda63e6d25d17fa GIT binary patch literal 2538 zcmd6p-EPxB5QXO&iFdFn3sQ+%yZ|@+Nn8{v@plnbRhu|qlsF|$Q6k8z1K-)rrfafk z+zJU~*;((-&dxb=W}II?FYVlB+!O2BeY Vx(!5ABbh_5WOU_DV&@T$t51gE~=6f zmdt5Qvop?I+G}=Ac #9GNvPV0f>i|*8Cg1lxhXMaa1(pf zzRYnw2i**-%vRiDG583-!B^}d!*k_W?ekRDm7`DOQ7h6z`^4B@mdf~k%L_bBVY-X$ z5X&nRHHMi}G_i}BfJ! l;8f%5Jzc{`k&3;B zb30?#F70Ywwc7C9r-(S>g4`)b*BweTag|qiRQ>%OWcza!Tlg#n%v#A^w;1p2d;6Ka zTkjpgk?+_8`wSaB_YH_OoVm^*WvY{=BHY$^&|}=a+Lht!rX~aGJ?HL>Id9v(g0? {{-J-%S9T&hbQY&i2Zr%1O^6q}x|6MW}WH8)(o^JT7*w<9`eDZh&z?~c9zQArmT z|GSy^*Nntbw%G}h-Q1;auZm*bHLCUh75|Uq*i~?Ydc@fO%$NUi-xPfp9;H2hsbj3{ EH-kxcbpQYW literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..d1eb8f8706a831fb82e26c3fc49b5dd257ba548f GIT binary patch literal 2094 zcmb`H-EPxB5QXO&iFa6`N_DElq7T4L3*|@rNd)zx>P4EG#^5+1PD&B*>cDp 6v~g)O&pzH^&k`D%}BhyBbJ zcyzflvBFX;DZ8B0ht{#vRm8$QQ|uSmcC62xu}v-Wc!~eM!l{}aXjEl|9%Gy4d# zAxMOw m5$sLip=U4PPAAH`UA~yCx>F&R zMe(Mq=qYPqF*YHZc-F{vIWPNNcDKNKQ?19|(-HR1yvbVf18Z- z$y2cr*gppSl*}Xi_t8{&uUr*t8E?s5MuefOYN^8};+s0Pj#peZS&Gr?X7n<9Y9Bxr z(Yv}wTmBxg^_HZUzx&5{Cd41mfea=t*=7Ff#81vypnoUcXDMRAZiw}%t6@PU5#4QK zKjoGpR9NaAJfim*kzV67_B=hlpFQ6go8EK%PRt8hYFU~J_HCov$6(ToNXYwyz4SW6 z>w&$jF&kPs5J0gY`kWg%{#wr**9bH-cp73ATj$g(h4j&l_}OGIY;aiMBi1s!%6NBS zGo}jhS=II2Bi1X6TV7FY&l(jdR^P1`)G)VoeM&h^g-VS-oNw(aP1bv~&71DQM{1v( zy 8rT0soT85pSo$%(l_{R2P4w~zZ&I)lCK|V hTcDn@OMmO+s@C#qJN@?=k$Z{HNUv1a^_M(H{RNM3RY?E< literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/deploymentTemplate/Min-And-Max-Value-Are-Numbers.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Min-And-Max-Value-Are-Numbers.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..7329c29bd497fe294a440817bf8f00ccdf01e860 GIT binary patch literal 2608 zcmdT_(MlUZ6g|&E|6!1YBv6 Gi%~F+!>bRn|>KP_VxDdt7M;J{=_QI8Dhcj%{e1naJ-wb zxYX=zt&1WRBQthTnU)1Ja?@2k_0hAHSl~1JADi|)vQPO3j*sI{SS7CIut%(#I!=l1 z=mlw@_1cUOkWR^1>tC?Od%mlWiZynrrTR}@mE(x`6V6cel#7_S6&Lw0W+YXG*R!ml zjd`Th8+lSa#|Prh>A+i4yKgG0&s|pf+F0k%Vfz{PdBDBlI(yX4S#S-HOw$|(rl^!Y z;Yfu`;}P!;xi9S@c3xnzBxXS$)coIeaL5VI>_LOz))XOCsT)(#cx2i5dfah;=6Jbq zTaItm`nQg6bJ?!ro7Mk6#|P&&pRx18$aD9BlnMJFJ(t3%r2Wv;up2v$`n?cG*89Pq zaB^IM8{%hV;cpei{Qat^M^&t}eZ9^bv~H=;|I5!_IZyX@$@3_j#STBo%HJ|N6`y+E r#kKN>`%1H)cix5Gn$K9-r)k~RaFf>UHTip5dpB-JYhUZNv|i#jKM#ZE literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/deploymentTemplate/Parameters-Must-Be-Referenced.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Parameters-Must-Be-Referenced.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..2685df70225057eba447c4fbaff32e2a05f1d509 GIT binary patch literal 808 zcma))O-sW-5Qg8g;D1;`zy@saEO-$-c&LgWcxZ)c-Dt%mC5fPje_efMOKNL^NXYK& z?Ck9G?#$QcLbs~;a}BhuEsb@y@_04!><%=-SLmLxQHkeG2a2&Py%4d>nNqdpc;;9I zyL(D>v&wj(Q{Cx_*cmZPf2>Q^xfXg3dHqI=u_WPq7H;&!%=9P+P0X2=x@C0ST(J9h z*0kqjE%Vmg@ V!-=`IEKi39G1wuqC}lkJZP+bA)Z`sz5gi+G=t>U^%i}L0n;H z{5BW7yr=rEhk76He@G+ZrW jzq28cfXE@qWOjCT z&R+g%9n|m?N;KC@&)SZRQ!7U`(Gy&$ciyckm`-agz>Ur*9_Xp$mBZwqlIo*Uy^M}K zZS<-W+BY;kztEolLbX24*G)7bOKSZA AVi6U|ZhOJAE^`$2oWE9i4rr MJBe-XFO{%|e~ki4TL1t6 literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/deploymentTemplate/Resources-Should-Have-Location.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Resources-Should-Have-Location.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..8b5460f75d8761684a83838c2a0bcc893998f395 GIT binary patch literal 824 zcmZ{i-Acni5QWdR;5#fO&_+z~1-$gG{-A;vTEVudMw+Ii6%_H+)o*r9B|oKfvpais z&Y3gw^S#!SD*lB=I@E#gb+wCR+A8CAq;p~`%~`i9iG1i(5&KGSAdY!cYNMP;&Thr+ ziDFH58E (68)|gSmua**9J_bsDolyZrOl-K V<8D_mXmr0;{?&+vQ&?>>e*qMae|-P| literal 0 HcmV?d00001 diff --git a/test/template-tests/testcases/deploymentTemplate/Secure-String-Parameters-Cannot-Have-Default.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Secure-String-Parameters-Cannot-Have-Default.test.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..6b06218030f22c3ba38cb32a9c249bb40aed5921 GIT binary patch literal 846 zcmZ{i+e!ja6o&unpm*4Wkb-V{f$j?GLJO3-h#<4kCOqXKkm%K`Z>?#YgCpXeHS75O zYtPU3TzxJ0PgK{jj`X10ttZn;8PU4h_@;W{Txo`9qjS};7h03iq-Lh2ay&WKl<1in zdfayG>PF9cBX>Yf;jgL3`$Th%y>C{^F_wnc4}D@r&OomU(A20&)QK@Lc}mo%4tI?e zl}qLXefq3`WxrfQ&gw}K?hSo1GFqJPJWo+?+SY6&!?w*B&xnX+727kqee%d&Gv@WF z9#eUTHTJ#kb0xle?{7+5y2M`ij%-rf=P&6o!U{U6xKHCaq^(2cgi4#8qa^Si)Wwt3 zb$8S?J#Jq{pla>P1G;DA1a7OZ52vsmWtD+Q(ix!)dMe#OQktH-IT?8s 1XQ`1&-kAn^sTca9t4$ l83<7o@in6{ 6j*-^PyGlV HueSKc?c;ZOH|{ptS*!N! zF89Oge1_iyP7xp8GIpJm-19`Ah_^KnwyGkqwq3p1-m1>^4ozq5Hj6vP_ST-eN*ldH z(xuMYzxN6I&gnAuvYlD=I&5E+cz=7BOL{wSn<45CL9BRO3%ATKH~3w3>#FER8oiIJ zY}_fif5OuJ@rt<}j;X(*?uq?BPR!^AS7Yskzn+` (t- Date: Fri, 1 Feb 2019 13:46:43 -0800 Subject: [PATCH 16/66] Fixing Encodings --- test/template-tests/Test-AzureRMTemplate.ps1 | Bin 41506 -> 41514 bytes ...UIDefinition-Must-Have-Parameters.test.ps1 | Bin 690 -> 694 bytes ...ateUIDefintion-Should-Have-Schema.test.ps1 | Bin 2378 -> 2382 bytes ...Must-Be-Microsoft.Compute.MultiVM.test.ps1 | Bin 734 -> 738 bytes .../Location-Should-Be-In-Outputs.test.ps1 | Bin 716 -> 720 bytes ...Be-Present-In-Template-Parameters.test.ps1 | Bin 1416 -> 1420 bytes ...-Must-Exist-In-CreateUIDefinition.test.ps1 | Bin 2004 -> 2008 bytes .../Textboxes-Are-Well-Formed.test.ps1 | Bin 2538 -> 2542 bytes .../Location-Should-Not-Be-Hardcoded.test.ps1 | Bin 2094 -> 2098 bytes ...dentityExtension-must-not-be-used.test.ps1 | Bin 486 -> 490 bytes .../Min-And-Max-Value-Are-Numbers.test.ps1 | Bin 2608 -> 2612 bytes .../Parameters-Must-Be-Referenced.test.ps1 | Bin 808 -> 812 bytes .../Parameters-Property-Must-Exist.test.ps1 | Bin 432 -> 436 bytes .../Resources-Should-Have-Location.test.ps1 | Bin 824 -> 828 bytes ...ng-Parameters-Cannot-Have-Default.test.ps1 | Bin 846 -> 850 bytes ...al-Machines-Should-Not-Be-Preview.test.ps1 | Bin 1514 -> 1518 bytes 16 files changed, 0 insertions(+), 0 deletions(-) diff --git a/test/template-tests/Test-AzureRMTemplate.ps1 b/test/template-tests/Test-AzureRMTemplate.ps1 index 984b361eac6becaf83b7fa67dc2c880355c763e7..3e8ae39b3b26d0cee85970eac64148b9ad899f41 100644 GIT binary patch delta 18 XcmZ2 #O#lD@ diff --git a/test/template-tests/testcases/CreateUIDefinition/CreateUIDefinition-Must-Have-Parameters.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/CreateUIDefinition-Must-Have-Parameters.test.ps1 index 5166d2883018173a1a0db992e3a268cf7dcc2f6a..57a6dfdb2b2e3e558314d4a1c89bf1eb97e0724f 100644 GIT binary patch delta 12 TcmdnQx{Y F delta 7 OcmdnSx`}neCMEz3BLdd| diff --git a/test/template-tests/testcases/CreateUIDefinition/CreateUIDefintion-Should-Have-Schema.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/CreateUIDefintion-Should-Have-Schema.test.ps1 index b03e49467166c97d99fff3d0808a9954c86bfa58..56aa905dbd024df30dcac7fa002abce5ce89ff44 100644 GIT binary patch delta 12 TcmX>lbWUi47bgoZ0~Z4T8xR89 delta 7 OcmX>nbV_K07bgG=`~tuL diff --git a/test/template-tests/testcases/CreateUIDefinition/Handler-Must-Be-Microsoft.Compute.MultiVM.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Handler-Must-Be-Microsoft.Compute.MultiVM.test.ps1 index 2df517acabc3381f02014e82dcaf4b11be954647..7ab282ecd09fc852c564c7566a9aa57380f6d2b1 100644 GIT binary patch delta 12 Tcmcb|`iOPIJth`j1}+8wAEpC# delta 7 OcmaFFdXII(JthDSivwE# diff --git a/test/template-tests/testcases/CreateUIDefinition/Location-Should-Be-In-Outputs.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Location-Should-Be-In-Outputs.test.ps1 index 4c7a63460c39d27a3728edacd1ea54c36a316aa9..8ca1c71904ca58f7d782107f80fc06bef544301f 100644 GIT binary patch delta 12 TcmX@ZdVzJr873B91}+8w9h?I| delta 7 Ocmcb>dWLnw872S?j{_wD diff --git a/test/template-tests/testcases/CreateUIDefinition/Outputs-Must-Be-Present-In-Template-Parameters.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Outputs-Must-Be-Present-In-Template-Parameters.test.ps1 index 5dc908127ba9b98bc596ddf27fd3d65433cf2c86..7a68baf4f68832e3e6c12655a8683c912b839668 100644 GIT binary patch delta 12 TcmeC+?&03h!OFtRz{LOn7IFfE delta 7 OcmeC-?%>|g!3qEh76NDh diff --git a/test/template-tests/testcases/CreateUIDefinition/Parameters-Without-Default-Must-Exist-In-CreateUIDefinition.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Parameters-Without-Default-Must-Exist-In-CreateUIDefinition.test.ps1 index dcb14fcaf7d3453908b769a3d85a03243477e6f3..2fca8dd54aeaefb3ed12e9d5a45844ca6b263e69 100644 GIT binary patch delta 12 Tcmcb@e}jL+6?PV01}+8wA8G?} delta 7 Ocmcb?e}#X;6?Om)XaiON diff --git a/test/template-tests/testcases/CreateUIDefinition/Textboxes-Are-Well-Formed.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Textboxes-Are-Well-Formed.test.ps1 index a4dab3c2046350738f245b90dfda63e6d25d17fa..13478246afaa9568d005402b45646aa7a47c99e1 100644 GIT binary patch delta 12 TcmaDQ{7!hoD^3<(1}+8wB18kd delta 7 OcmaDS{7QJkD^36p#si`N diff --git a/test/template-tests/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 index d1eb8f8706a831fb82e26c3fc49b5dd257ba548f..2ce429913c73ebca5c80e692ac1790f9cce04d25 100644 GIT binary patch delta 12 TcmZ1{ut{Kp9tR6A0~Z4T7q$X| delta 7 Ocmdlauufou9tQvmUjkA2R?9wgRpI diff --git a/test/template-tests/testcases/deploymentTemplate/Virtual-Machines-Should-Not-Be-Preview.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Virtual-Machines-Should-Not-Be-Preview.test.ps1 index 629783ca4286f04cf102ba45af196f7ff82ffe7a..27c9aaeafed214d4c1cacececbbe102008f7d3bd 100644 GIT binary patch delta 12 TcmaFG{f>LXD^?a>1}+8wA&dj5 delta 7 OcmaFI{fc|TD^>sxas!S4 From 7fd5fa0e34ec003c3f223b4b3b1fa20ae1682312 Mon Sep 17 00:00:00 2001 From: StartAutomating Date: Fri, 1 Feb 2019 13:48:51 -0800 Subject: [PATCH 17/66] Fixing Encodings (switching files to ASCII) --- ...UIDefinition-Must-Have-Parameters.test.ps1 | Bin 694 -> 348 bytes ...ateUIDefintion-Should-Have-Schema.test.ps1 | Bin 2382 -> 1192 bytes ...Must-Be-Microsoft.Compute.MultiVM.test.ps1 | Bin 738 -> 370 bytes .../Location-Should-Be-In-Outputs.test.ps1 | Bin 720 -> 361 bytes ...Be-Present-In-Template-Parameters.test.ps1 | Bin 1420 -> 711 bytes ...-Must-Exist-In-CreateUIDefinition.test.ps1 | Bin 2008 -> 1005 bytes .../Textboxes-Are-Well-Formed.test.ps1 | Bin 2542 -> 1272 bytes .../Location-Should-Not-Be-Hardcoded.test.ps1 | Bin 2098 -> 1050 bytes ...dentityExtension-must-not-be-used.test.ps1 | Bin 490 -> 246 bytes .../Min-And-Max-Value-Are-Numbers.test.ps1 | Bin 2612 -> 1307 bytes .../Parameters-Must-Be-Referenced.test.ps1 | Bin 812 -> 407 bytes .../Parameters-Property-Must-Exist.test.ps1 | Bin 436 -> 219 bytes .../Resources-Should-Have-Location.test.ps1 | Bin 828 -> 415 bytes ...ng-Parameters-Cannot-Have-Default.test.ps1 | Bin 850 -> 426 bytes ...al-Machines-Should-Not-Be-Preview.test.ps1 | Bin 1518 -> 760 bytes 15 files changed, 0 insertions(+), 0 deletions(-) diff --git a/test/template-tests/testcases/CreateUIDefinition/CreateUIDefinition-Must-Have-Parameters.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/CreateUIDefinition-Must-Have-Parameters.test.ps1 index 57a6dfdb2b2e3e558314d4a1c89bf1eb97e0724f..3e527feb20d22c9684d596da713aeb0b3c4bf40e 100644 GIT binary patch literal 348 zcmb7`wyY?(1I=gKu_wygIEypARgA5YJ~2VY($Fq@3vY|5D{}4$YkE6 zHf*X$t99N96y#`T?9PbeCJTj6ILMtRA!oB;yy=XK`Syr~v^pFy8o}jsj3wE->9Nx) z)=DcXAxf+h_-ah+C)USs(F)p;1G_T>pV>ejD)OG}9t^xLp=MVjOA}~y{hOO^ji=&; XUoi 5|p?Fv|wkx 6ux{9!K?TBcSlc`XGC&5bj z?Wm#I8F8YK=2{cGAm-?g)Fa;qOs}a1dg8SLA-zDl%rkwBfN54jtV3Ii_zYBsqI(hB zs_H*gTfpJ;9(Wv cQVM`Bk_zv(`l^_35 nZ=2b~VSWqFpVdF3$Y$&5bsyVw=6~+Q?cQH&sljquRX4r?o= 5jR5WO4xABMyr8`kos$HLM>OQDC*(51PA&??^XT8Sl@k-TA>=D%06<$k4E zHizmYr1^OB-kV;KP $*iHSOE`d0{*y`%sreuEe+CwlGaMS z1p!|(J0?O;rblx7lQeley6Ke5pwtMgb*{Ist7>}WN@%e~h1zlPZ6M^eQSr}KOMb>* zl|A83;(hfLBtIWICodJhwML&Fo+^+Et*{_8NL?EuPb)+e0PAT!+nS- * z^cLw2jRXgNAy$K2i93Y4LqSO1qtQf{6Gm7a<5VbZ-$@6oivD5neX{Nwc!22^jGS3V zq2ia{o*GHk`BifZ$Ot{=@c*-5$^I1zr61ucLcE4@>sv4RlEqe!bN4lN-aqBEfl$5= xt>A24iRWdVxe2@QCm%;>HYewYj1z;3B3NuAn+C~m7c^v4wEHiC{z5S8{{!)FgjfIo literal 2382 zcmdUxOK;Oa6ou~^iT^O7m7GY88(3CCEI>#s5QvCwstVG?Z9^L;vYnz(`qzQ)%+$#^ zeW-+Hfh@=N%ze+f=jQjXsr9Yk9$U+v+7mmlkBgPeD$Cey*?ZP<8}eJ(gq69yv~AuC zn<24-&csR^u`=Q W1O^@!>e-(zA)@ZjvydvUz!s@N^?@tyZ)5AxxNu0(q5 zpQ=o5Cw%w0zv8isJUW|t>r)~q@HNMW^1IqVrm^3ISX8@=XF`S**ObWiY?mvROnqf? zqCfFf%FwDT<@*QcuQN=^XM$8yujISS-gE93_)?ykT~LjTTJAomk}24m**X43wvUGt z6qO!hTmN)cHBud!_pzw6$@$euDVM^>Dzv(lS_ly_VzhsXhN2v@cSLrw`v28)hqyzZ z*Z5U;wASvc7(?o-WJAclpyCCm5V&X4{oC}m+N)dC@DuTjL4+hjMdv)5=y#q0W}xjX zs`|iVQJ53wNLw8vUJ9%jSY+z)xkPY{U*|n8D &j#zhV%sTv#)4{Z!nVK6Q*=?vT vE?gdnz{F|q0 8|JDI#aNTY553q;XZskPM@uM7Tc`HI894!KgYuq9{SoG`*R7i%kkeq T6ManOW0tzDgYK_E-2Z<7QM!gc diff --git a/test/template-tests/testcases/CreateUIDefinition/Handler-Must-Be-Microsoft.Compute.MultiVM.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Handler-Must-Be-Microsoft.Compute.MultiVM.test.ps1 index 7ab282ecd09fc852c564c7566a9aa57380f6d2b1..5856e9d454a03b0547c1f2fed536e93749ac34e7 100644 GIT binary patch literal 370 zcmaiuv1-FW42JiEdj}B=u^~2nflTSr!Nia>OX+ZN voKLNJsiuI6l9n#KIb|7^iAs-)iX$m;SUzO0Q*pE2zhkXqPF8|W@%iZy8w#JL z>&}|Y8f&P5G!LwBw^+0z?1+-V$r>0(Tj39w{eBD-!BdPB4sbhyPPjwSVP?(wi}x=I x@;V^QOR9w YN&d!MZ#uh zXWzbgZ|3c_(ybzEqoEFUpli*#j8`Mi?NAePh3@z_D#<+QRDI&87Q_*6O4SNv0#U*3 ziAK8V80VU5p$D)_FdzB8&Uo(=r`M& (F)#zJ%4GXkW%m zt50WZYDd_eo>K)!WM2a!!v9Fz+lk+ytOmVFyLF||J?HP0oT|iIrMe9r?WMXezx@5* zm7_;XRCrVjm}TH(o@!Q(!wg>~dMl=B6VJf3S`!CdkstiomkZn(`%jNKypjAabFq%K SXtGHz65IYtzk2ApF1`aP?tO#+ diff --git a/test/template-tests/testcases/CreateUIDefinition/Location-Should-Be-In-Outputs.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Location-Should-Be-In-Outputs.test.ps1 index 8ca1c71904ca58f7d782107f80fc06bef544301f..81efb466141d368c87b416ded54a30c9e9cf07ed 100644 GIT binary patch literal 361 zcmb7<&kDjY494$;zC#!TTX4e{@T3<(aiE@LhpL%YY&+Tv5%Jw!{ez--FsF~?OTJ%f z<&_bfEsH3S(2I$(8%55a`YHJayM+syw6p!5ETeHYUF~sAtxg9X72#qu#7f(n=|1C3 za>kjiKxEbt{50mSp}L`vAKY5S5D90_pe@>YcZ6j8=z|VmbO_pRq4LhaV=>|E5~J>6 nNh S6ot=P@Et-ZG=W-t0atZXs8~=}(uHlOn$rBxB#4NwuKnf~LJaiBg@nx9 zxpVKCbI#1qccB+;`BO!@)P n_cWs48K%>d#=2#-0wHT5wfj83*f4#RP#eJQiuxSX07idB z9MW0STi94?s12EgaoQ`1!Tq!|10w%bdV_bacj8c!PJIBclAY9M?@6Xt)+_5tiGH6L z8unMCs;w+UQS?u$LbN`@DY2XPD!q@6xz8Kux)9lI_8E`6agP6|J@@X_xajY6Zk!G= H>bkcB9{zZ? diff --git a/test/template-tests/testcases/CreateUIDefinition/Outputs-Must-Be-Present-In-Template-Parameters.test.ps1 b/test/template-tests/testcases/CreateUIDefinition/Outputs-Must-Be-Present-In-Template-Parameters.test.ps1 index 7a68baf4f68832e3e6c12655a8683c912b839668..7cd49cb8ddc43a7de63d31d8fd72c0e21555b7bf 100644 GIT binary patch literal 711 zcma))!A`?442JKO`VQ8pv`*S8cz~UN!w$eCKpYT Ua*u oJJr$iuxEy^Fjm$!x>PX`Mn|4YG~vcLc!lm-G<*Wi@8*IK)LuLz zFt+rjnklHN!U|R!uzuBOw~pq6yb_%oAWAZ#jmQ4gHe&nw5XR56hT9tm|BfLN9#{*` jE}4m8)UR*Q3l*V*7&LxpCvmgV{}BUvh$6B=9DO2R_Alr) literal 1420 zcmb`H%}(P$5QOWD#5;`GNPxsf@Bo~E0|$O2KpfB>7H0xM@ei4VB|^OVvR~Vo*aou- z5*pbv?&+znuAcVW-$K7N;Yqcnb*}=Sz#%RG!@}onXr};5}82Wv+eoSWh&=V}~=j zf<{ yWP@2w4NEd2Xk~`%ad7E3mwT zRjNYc1=A)Y grmRjZuGq7&uesYgNy&4$E6%XqJV& zQ|wQmj_FUwJYaYp$LTq5yGOSruRuLw *jlC&UsQ-@L(B@H5F4z}q zXS_Q*Yin-!dKd;z_x^x{W;o|E t=bo7+9-{N1lkdNg#ozLB)N6+ zVbTgPAL+AZGFM&JBQL81EyJ8wCGA5UmcPc@Xq{K&?KT)~HA0N >> zAytxutPpl^0m+-t+9A-U*)ebnRNxl4L6C}om! >hz^3)%Vsl}w8$P=+ dYRyiQLA>B*g;al #Up3)SYwQ?{BVXL~Z~8 literal 2008 zcmd6o%Z}4P5Jm4AiGOH8Bqq|N|9}+_DGMG_fLS0GnZ%O>@-TKX5TW^X;8Z(p$BAPy zhy}8owCi!J>Q;64ub-)g%6J#L&_g}YN4+g2iPlQcUg#CFrN;cOwL-GhQ*~Hp+F;Su zr_y(zH@enmq$Bi&yrXw~FO+H?5R#hBW$=x$oBf{=DcSkHS6|Qhy3vfBW<;5h)3SzX zXx$R`Cgg1XBTeO~r$a8W?pUP@cn)1#w!XnLmq~M?RF#_~Lz0qd7II9m=o0-$$jh;^ zrzw-y OSG2K8+pzjDWA(RTeIVXEbh3^%4lEDR%&DNVI*k>hd1l2rbnLqy zVTQ%2Zg?VY1A9(Au)bpXL<3eM^08?cV3CEMP0$p~I >^T#fNqP5eKclKt*Po4ZDYf5Ezkn+ -An;`n~@x}x*8Qwv`G?tX};kLUifEc4yY_j(!Tcmeb0 j%~p>)!S0I*Rjq3`&EMS@P4gD#?*6k`Osbu8hHLL{ d|m8oB9np yIW!P3Xw!3d-9hBudU2fqO~tTKBQML$_+V)iSP`JZo>xl5H7uBg#^g8g_(7% z&3X $ng)H*Sch~v~opB zbxo#lqV0mV=l{Wo%v044R00T%g~83{eZEnazp0Gx!mm$oGU2?Pg(#do9;v$rtSp`i z5<_wT3F1Fmf$cc?Vdc6T1ol`S5cU^Qo%pdap P(0Zy zrpj!LxJQXo>> *3{F+%Tb>^AL G zNh>6fWoNxRJ3HshnQ?yoytH$ha!;&h5AA{V?PN7m+RRE;dv?rRZ9|?jYnWNsGs_uI z?Fx%0>}jmEikXU0&FWLzx6_r!xAw*^> l;= z1#?={?36PX_L^N2-gaX|C;!PtZr@fXdwe%B>#TvpBvf5Q!K#9Zj4U0%TtiG5+{7NW zFLPYaKsUuIvukd#7<`1^;4Ai!;kk0G_IWDn%F!qCs1@m ?zdONiI^BDSirkFPtKTvb3+n^B7H3WKQ{OxkuO(yh~LR zo;7c(F6mat=j^x}jxOh^SktId2;z*z71xK|UHI*) ZaS1^;wrE3sQUXm$hPMyw(waDn6;9-ZZY22_qH>8 zzur57Bj2$H_8B&M?i&zmICGsr%2X#!MYyi u6uNjG>?6MOgyS+=@T@}T$YgEhsEB+tJv8&(~^@y?mnJ@q4zAgG)c$D`1rH i4 diff --git a/test/template-tests/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 index 2ce429913c73ebca5c80e692ac1790f9cce04d25..4e15b8638d6959cc6d3f76e24d4d999fb805c83f 100644 GIT binary patch literal 1050 zcma))!A{&T5QguO@(v>uDGAzG@Bn)$EiH()NKM57?ZG4iF(kHYPqv`acgIfFW-E44 z9VxQxnSbX0JenIm6lrpO={HDdimzO@oRoQ5W@JWOTq-L_D7ic;S1!_@tOj|Vx zGi{W1;Q}o)IH)xixej)1zFqZ7P^U(UFsv^goNl%B3~2&xZ5pZ7)CN=^QBw!UNB+() z&&B<+UNzh^jKbTdW?lB$5)0uzUED&kBfoO51aHq-i?@92Y0di)p^^yswLz;!)8J>L zMqQLqeU-zk5)7V-9>2LMfC_&>K5!w!4ZC-g^Ai5dwy%sJtUei|3>;i+yg@Vo!)OVl zBDg{5xM>^JV#@&P4q?+E%pF>XyKjBm{x;bG%(c#12*p?=$-aaFP}SVrA %ey=**dXZ zNDHd!-OSF;oH=uLe*K)<&}RIPtz&oXjvd+CD@$r~OF8Y>D{O_G@}1iR%U63~JM3q+ zz@x{ViItXN$=DT~-nXtDuOgQ2nPES}wqpbCjBRSU$4mY9B|bg(|DP!KZ-C;Bo!Cc^ zjX)v{UH>-GuKPWr+9_-VDh|#_du74Cb1v_~E}YZ39l+iM9{TnI?sTH8+vQ8hsyh{8 zSrl)&ik`8SmS7X2iD&KDF6Xh|vAZSK>uNppo}P1m0V_>qlvkD4d)m&DSWuN=^|#5$ zfIJl&f&F99Psx0a|2~?E_u{Hp%Xmxfaw3deRZAT<5ntD-b-d!T$x?z|H>1bwnSB6R zhu+ma+Vb~_t+yn-{M|pnGbR3z4&*R#!7le#Cw>af0{uJkK1&e`b|b7$T@4E=>CoLK z_G4}-LWQN?!2^1q6X`WRW6#s)``Po2vFSb6? neF!Gah?Klf*h{Z7 zyzbe{8ndCL0|68ZqR+We;IH+>ah-!^22UfbV(XN8rH}!-5kH#@h7Ar&e8gIgSB!TX zHWR84pH*GYJz~AGq~#SQ_N-BXVh!ASMh$aY*Qb=zRH)SW!}->((qz3y+q~&Md}Q{? z+1s@}*wr-IUR`@WQ?~DabLutKS9M=1P+v6{wANoyn|gZqMb+H28olk*F8y6;8U_2} vnG1GHEYi*pRQmo&Z{2@V$-6bJCiW0aiM@9&l>c^msZY{4)8ZQEb^QGsMeb*N diff --git a/test/template-tests/testcases/deploymentTemplate/ManagedIdentityExtension-must-not-be-used.test.ps1 b/test/template-tests/testcases/deploymentTemplate/ManagedIdentityExtension-must-not-be-used.test.ps1 index f0486896048403adef051d075246a421142b7965..3d6d4f4cafda94cf54889eff48405b43e3ab058b 100644 GIT binary patch literal 246 zcmYk0!3x4K42JK8zC)0~HqhY 24^14VpyJDg&2`T6<2kO3K8 zq1B 07KQ@{0NXs@vD>nGex;!Q@3R~Z&ly&5W8wz!F7p+RI>;;NU{#sZ$ zl=BsGhaP(}){qw~k0g+f>1JNSQ!7ZbXDhU-nFGTjy)fa>%skXz0o)h`d=NMhjFHR& XK2l>~w!YHOsrDGFU1GI*X*KN|vZhmd literal 490 zcmZvY!D<3Q5Jc-7@E;lxR7fO0kfR3=f(Jtm!Gp 8rT0soT85pSo$%(l_{R2P4w~zZ&I)lCK|V iTcDn@OMmO+s@C#qJN@?=k$Z{HNUv1a^_M(H_3jts>s4R? diff --git a/test/template-tests/testcases/deploymentTemplate/Min-And-Max-Value-Are-Numbers.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Min-And-Max-Value-Are-Numbers.test.ps1 index 790f7756ba5f4f4955c0983558a1fb54bf3d1b24..377fd4c4cd3bc6c437f6af515529872eb79580fa 100644 GIT binary patch literal 1307 zcmcIjO>4t247~^PA4D-UhQ;g;^f*Qj?FuW~p%mt|>gJKyneC32(f>ZXj??sOD;x90 zjv_rhJxLYUyv)*MGV%|!sIvi=b8eMh_lVU?yc#JZtWdIdO{d=R{_gn=XV$&R7|W{Q z7K0^CXqqgPMm~Fmj8qX3gal&uTv_weQ20y}aEA<>Uk`{}7Dcr1)xJe6+Q6(bYRiRH zT2-j6K*NN~lywJu^}vfIc4>p}a~#B%wHM^VNM&Inq@C^s_@GDaF!LL&m4*( {(BD8hh8;W7Y0CT!OLhlvYn3TDxr-J%_@E6gaJ(hfX@ntj4}LeBmib{Sn=Y^W^j zOAGm!>ld^^eAs2!0c`*agHhlJOB@3)>oKKPWSWGJO}Gw(`$l*nFA=`>`lIj> Y-%5_Y#{g%mipThb3w&knC3Ac{!wJ8qm}6pfi$;#P3~c_$5DVs9;s%av zGR_IC14l>XlA~g^xoX}qvnGzi55sbN(=TJkzTTdFmF#oEpIF5?LoE5dIcJO!$GaJe zOU>Tax+qdHGG_;sX<0BMH(k|JA3a-%B|fwNiD};>`;>p+_&olURpMF>?}$}X#~INb zy&w&=UYijD(ibw;`WLM6f$!?0VvQYYss2+} > zV;(8>MxIp9u}|Cu9e8JI_f19hxx-55jdczkwx4mI2izO3vq$ZmCD-uKG|h2fic0Ad zj#Rid9`Wvw`_dj_=LIJB#4PB8n*ZAl4mshOJ!uf!nj)ksbz>?TkK8xDo_E}@IbJT@ zmgAeX{;lKNT(;}@X7&Hi@xi&xXY9N%^4fhMWx_s4&!uoGX+JbI?8c6xelNt4^?vXt zoE%r+miQT2_*+FWf4?f~Q57p~U$659ty?Pe|NCdJoTvM{ 3CiZ4Cy s;#&FBeWls2JMTho&1bCa%d~E5xJm2wn*2Sjy&JcqwXgN3wDyYs1Wyfv{Qv*} diff --git a/test/template-tests/testcases/deploymentTemplate/Parameters-Must-Be-Referenced.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Parameters-Must-Be-Referenced.test.ps1 index 8a2eb356ded90642917b74d655443994cab4c6ad..8a75c3fe92702aaf6fca7e0edbe9d02a7ffb895a 100644 GIT binary patch literal 407 zcmZY5!Ait15CG77ApbCwf-TtKS=fu@a zyvdB$q^C-X%{m>Bk*ZePL9?T;RmpV3%e4!JjkBw(dY2NP9$w$E=XfqVocxDo%r{ch zQjCsJ_is>@{w#vA@F!Kxk3sq1PN4GSJQ5oWHGE3}G0YgDbCnK185-+&(i|%ki?OXX z7yDvYR^{A=x{vMDr|WH9%wR%a$S^jyM2?_oF$8@;D4s3hh=jJs0cQFd{-Xu#^Y0Rt lB3pL@%+-TxkAc+ cOwI!y=UJS<%=-SLmLxQHkeG2a2&Py%4d>nNqdpc;;9I zyL(D>v&wj(Q{Cx_*cmZPf2>Q^xfXg3dHqI=u_WPq7H;&!%=9P+P0X2=x@C0ST(J9h z*0kqjE%Vmg@V!-=`IEKi39G1wuqC}lkJZP+bA)Z`sz5gi+G=t>U^%i}L0n;H z{5BW7yr=rEhk76He@G+ZrW VxnA diff --git a/test/template-tests/testcases/deploymentTemplate/Parameters-Property-Must-Exist.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Parameters-Property-Must-Exist.test.ps1 index 0f42202ec9c04134b854bbd0fffbde616ab5f818..b1c113da4c11841bfcc26cfca7e693a2209efb42 100644 GIT binary patch literal 219 zcmZ9GO$q`r42AcF-XRPF(}E6OV2&UT=uTWzjaaciq#1M&?`}K(EX*Q2lJ}A?8Zu5v zvF(dMMp8@TkA?${UClJ$tPjbu4Zd6GT`{g#`wJd8>w1GOUJc`WB88Sh3VQ-I_krPW z-NqEAWE&|&B(|7Z%ji@Szt2;nH9Vw%TzsZ*gX#yC;FBA{4T%BoHh1f@5h0(MNGd6w IP$;B$0lQ{Mi~s-t literal 436 zcmaKo-D<)>5QWdR;5&pMm_QAE0Ux0#=w0cBZC4s;e#l1JQ2Oe%-%dy*AhK+Ba^}pL zGjsW?bx^}ClxVJ*p0ynjr&f+^q9?FY?|fTTAf47)5H~u*c%Y_|R}PXBm1G~4>Sa{i zX`@%2;J(4>@rCyM7pnDXx^BV=UQ(+MQLdvRe5}x}P>AS$uR253!@TwkNCQ&aM8T(n zk(uY P+#Y%Dj diff --git a/test/template-tests/testcases/deploymentTemplate/Resources-Should-Have-Location.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Resources-Should-Have-Location.test.ps1 index c521c4927412f59548a359e0857c8c3064f9d3e8..e25edd6f6688efb326fe44643432dc4504175622 100644 GIT binary patch literal 415 zcmY*V+e*YR5PdK7ABGZWD>nE8ee})Cq6 6i!?;xPtj@Ee zCp7&VREjY8nR*24K=Bz;r(USxE6+f}9# J{t^Oo&IiWnXBmrO%r+Fs3E;_ZOZq12fZ$9BLwXGx$o_E20_E99HKw z?a!HZ?rq?3`t&@Gm3_GujD0Mr#&FKO+E8crcAX`nswURqiqim%{khxt7;K716^iV2 zf*W=Idj412zVDRaNr~TuR~+0M>QN88a;hWd32KI@N
(HdGu9P)D(}K|=LPrqasgWb+StY&PYZfrLyeC9GL2S;WA#p7g)Xtaw4QW- W-0dm`jn}W0e>I|E7e?z$`+orv>3@^} diff --git a/test/template-tests/testcases/deploymentTemplate/Secure-String-Parameters-Cannot-Have-Default.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Secure-String-Parameters-Cannot-Have-Default.test.ps1 index 6166851b8399f2db72f3aaa6a746abacb9c92e6a..791e51c2c593684bb0e2bd508adb4fd1fb570146 100644 GIT binary patch literal 426 zcmY+A!D_=W42JK4yn`r#CeWC@KyMpthjfL6?Jx$@8YT5e;!IWwW$fK&*ISm#J_uX> z{{Q!gjC~qMFMHpR5T^wWHHzW$HW8j^vo}_YHpBKNd-a3m )K}1asIN$>a1gaKqV63;-3Hf?SI8|%_`pT1K>Us)x5N4YNMwn% literal 850 zcmZ{i+e!ja6o&unpm*4Wkb-V{f$j?GLJO3-h#<4kCOqXKkm%K`Z>?#YgCjC~mh1Ta zYtPU3TzxHgCaUXLM|#lh){|+ajA&hLd{ez}t~A55(Yb2a3$4j$QZv(1Ii4JAO7u(( zJ#IU8b)#p!kvkx#@YmGi|3q_*y>C{^F_wnc4}D@r&OomU(A20&)QK@Lc}mo%4tI?e zl}qLXefq3`WxrfQ&gw}K?hSo1GFqJPyiZYY+SY6&!?w*B&xnX+727kqee%d&Gv@WF z9#eUTHTJ#kb0xle?{7+5y2M`ij%-rf=P&6o!U{U6xKHCaq^(2cgi4#8qa^S@sEa45 z>+Yy)dfdK@K-Jon2XxQK3EWm+A5LLC$|?hqq%%Sp^i;Zmq%^&Ebzb|tLrjq!6eLj{ nCyBcHBZ<0z=YQ9>u^zF7Z);Wh0;_M!zRSe)<;2BletUia17VAs diff --git a/test/template-tests/testcases/deploymentTemplate/Virtual-Machines-Should-Not-Be-Preview.test.ps1 b/test/template-tests/testcases/deploymentTemplate/Virtual-Machines-Should-Not-Be-Preview.test.ps1 index 27c9aaeafed214d4c1cacececbbe102008f7d3bd..62674dfdad03b1a759715f41af6d61b168b69d59 100644 GIT binary patch literal 760 zcmb`Ev2KGf5I}b%{^1lM0ac-2kg-FCv{9O-L)F10N8%RS=zOG#s{VUT3?U>#m%@OJ z@6PYt)q;dd!r*n$E|8IuxzHQIh7Qw+sloKEJ$-t7|G z4w8t_nuZDlsUhM~WZs|I6u!d%+#^d!VkHYQ)|8wVM%4}D-ChzmqEfD;)MyJ)p+&aw zE&LrEL#7QEMzfIG!U-r}c4VtVjVFK>qK%chL67v~Kao^oi%Tq#P&=LJS*0;vO{SC; z=GL{$rS#ilKK1#7Zc7Ij)kiolBpI`NB114)`%XaD3g}x1(a`Gr!3{2jov@${9Pb4- zF0^BxK(-RJMfL+5M8MxN+rWCB&!x3eZ}VB}eQL$PeSr*FB|j13o2(|>OZ No@Se literal 1518 zcmd6nPjAye6vXF@#CKR#mYP=7e1aZ1^blH=QVxhi2 l`>PMUD( zp|TwBzTJH@JM&)t{#k0Il6R(oUh9=U>uM8;S}C$R(2&?%-}qf=LFAXtl`$^0X2*%X zY|ehrrM~Jr(J||FJkt&HnU XB8e$oYoc&yo3 zN4f<#mcTixvmqVR )Y5-d(x~u z_GTH#zWW`!j8pL1qdDB{&iNirhtyjp UFWZ?_ufv|I67O&CazSqgZZkyvA&3=^YvGRh#Rk8tZe11KNTc^* zm5n Date: Fri, 1 Feb 2019 14:02:27 -0800 Subject: [PATCH 18/66] Adding .gitattributes --- test/template-tests/.gitattributes | Bin 0 -> 26 bytes test/template-tests/Test-AzureRMTemplate.ps1 | Bin 41514 -> 20758 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/template-tests/.gitattributes diff --git a/test/template-tests/.gitattributes b/test/template-tests/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..d2778fcb876d4f1ca59d26d8881572f74369fbe9 GIT binary patch literal 26 fcmezWPm4j1p@5;7!H_|LA%!86Aq@z58Mqh#Uj79- literal 0 HcmV?d00001 diff --git a/test/template-tests/Test-AzureRMTemplate.ps1 b/test/template-tests/Test-AzureRMTemplate.ps1 index 3e8ae39b3b26d0cee85970eac64148b9ad899f41..c065fb5fdd012f75fa5981b5ec3d172fcaa83d9f 100644 GIT binary patch literal 20758 zcmeHPZFAemk^a6_`yZx6R!Au#lg)keoww|@ rl+U7r{AUrt8KAp^0H88x^8CA|7%<6_ixVh&1Ri7`up#G z`~EwH&wq@}-}&i%QEuwI{{B1muT@qk8Kd6oy4+R^t=?oscBL!8b1(>C{!-VAD&KIb z@4x$dw$7J;U#qgvs;tyaS?PxW)pLu(+Y%!U0$qgFt%p2}Sz|F%+d40 1m7^#^ueWVNpU@aL-BZr)}$`jCs-ROM~H z)Jt`jH`l7U)@pW!uBSo=waF@UY;+|v9Ayi13G=G!48&b5bX}{a1dg?Ch~S-GuV -q^%Jn#g6wOy}IGR!zV!;~xh!dyh46de5OSNU4+w+5nt$eV!$zhOq= zJv`=2e{M{F-={%S3+}tiU-Y8etCU9R_o`ekb(NlZnO7KFR`+UA7EP8H N{D z#{4C#dy61xhv^g8l^2Wkb_rJWW^hY0yLt4Z`FsB2X1UhQPo#NqH3iYK?YcQ}o8(kC z6p*Krw>qmX?;W=$`yb74*-cXmQk{XrPUgKHsGNqnu^P%rtVO`jHH8X;c7o779XHih zAD)!85dP^O523lX`c+lloa7t5&I|q1{Yh1Bbk*Does(|)?bD53 tI?w9q zgu+32njB8JdHur9>!t!h>@vr0Jo_AS-&47c)VoNHiWU)lL?v`Zl~m7_I;I3eSiRm+ z{9#oT^i{FGM~AZJZio6a06+)}0ZI&t1bVO97FH3T2a0(L{ookl) uTex<6*zr#Vsk_OV#WnY<*cI8cSP%d$7g@D*79@rEpSp;PA{j=U zk0ZpNI|UtxXJ}rOO|&H0_@bd&hQkwgTf 8 FA&qGK|FV>bYJQw>?-GhfuwFdNVctV;!a+PV zdW4%5T3YnDD9aN_oA{Yr`gsj^baCzE>TPMB!eueCa;dMN5+Y47Qm^s~ySZGg4i!xF zq*hmOM(HS9_waI?ubUY?D_RccIAgA`&BuI1`90lU26g>ZP1r8BW)gM2xqn^K@j_Vg zRH^Zs`{Ux)Hq77LzbJ2D!k6=C-_NOzd-ItN^;7k1Iu0Pez+Rq}YDsrEBh9F#vZ_%l zn02&iwb)jbF3@0fya -*?Wz})Ow#zf*5nlIp2e8tRXk>4dC$7<~Tv% z1Y=?CF )x2+kOH%Y=9$Ki$@KDMp(@0#KN#vAaRCZe)12Q=^qrP zF{wOJGym*@4fq#YW~QYx6&Lw3HvwLIHnf`PPUdY76Ac{?ok6scI|jBL(hU_z5^#h# zuj)?xD2C3F%4yF*N^qVTRi=}5BY<<6%A%e09)yf7p>2(!1W%z=*)9G=o5wYeh`EVN zV_bcFnPRPR%dLy(0P*jRWvJhS{EqQ$%)TnUhI0|AeFxJ~76}?sv?yEjJXCO01K}al zpf_V3>;>8C;064erP|vT@>?(W5=aj*;csrxV>#dld;|GA6bm4Bk*iHU2ZF>EzwTVb zhr8)xXNS2!F93)nA~bUMBS3?_h5xy&x(bxOb+&Cv1UyJltf66z@?EM+hH*NtjM9Mn zyIsH?)g8s|^){FaONZRhQZLpSm@L{G2@72n;Ni-q2bpB@5^=y~&cqv?>d&w+*mU4K z{)aie%5NddK4Im Gn8 z#;&4P>{N^()OqAad>j@thw+mY`Dp?4!E=h~IT8rSfzm?FpIauC#oYQWZ*-Hr%$n@u zIKbSW2ei{b-|HLLo0<3zVH~H6KmD<0WA|6RD=s2LL(-ciS9>HphBx*CIXIa6`6<$p z_<7nO!8NCE_DMUZ3@(ZN8gX=T^x4Rhq4gx87CC3o0u&`AgvfO3IDd_#hkf1W(ZqHj zcT##-4RSt%N`l7iCL!H1BX}yI-@dBfcSXA0zx^vX3lf{dbtUEk&P3@+8SRj+yA>dN zl0B^v=Od)w@9ZW=%r+*jHA28hAtCg;Mrw>BJ3rg~MIL?Vkup2K^P5aP^8`?T`tf%^ zsDHzMZE(YEOM>YRb_>Pd@Cf*aA0wmk#5GW{&NDWSE*F?oM^tfp)Mz*}u%*E`X_$b& zgwFrD)msVj _-z4!W}{kr0)YD@O@h}Nr@RRe|45gz~hAG zSI(XCS&aI?3T5Uwh9*H0g&@8c;^Ce>Y7|FCSRWMzmGMPqf$YamN4QL*k~0GM$2RNY zTJ3-~vDqlgk}Mgqe4WE{H0h&G8@xk%`cSJ~YiFl#oqp#gAd*5BXxggL%jeW6=P(}n zEQe?D AQIU^r1r+PIc>BBIYiNA zwWN2z-UGtNX}&^U)2on`e#j~wVErGiHN7Z{$2TpD%j FX7-Tj !m{NhP)P43;kn&OAkLQ^T8wjy z5MaShNv>aVs6|=KdaHIPRWVla_fyTY0*B)4=rb6<^jpj;IQ76ncZ0En9j4Xr6H&J< z?ofA1Dj_TGkwHVCDFqarJZZc}emBQT(+;C&zm!NcOwW&s+q^0Z##yw5`tCK-kMM1o zPr-3iBG2I952)}&^H(?Ik$>AXi2&kjcxL@c?m}@prZi`aq1SXm;7)R14!e_nTxXvJ zBkA_F_+U|GMAA@>-La{tqG9XwY$|+pu#tej);C!aq@z~A2*-jQhcJ2O=mxsKoN;fA z!FzLYg6a=QRZsUW_V&ei_a9B>6A5peGlo4G= pL0I}olX(CZ@ zgWTVNN4qsG2mg;y*V}+Oqx6D-y_)G?)kF$4kly9F!S1yYmuY|_<|>^;mK-uz_fL@b z-*>q8M8JIpsOcV)-IDK3h}Gm`vQw<6#QsUSYSY$=?R%4EpJHC5(v9FgOzHm>SxY*u zvNdQ_P2A@*qk~(bt4WYSo%m4+H?5@ 5fPdu&Lv$=Bytw>R>z=BDX^aZ=kAk77fAOhU$kF1T`4h@x-Xx}7vkeEKu6 zllZ_OYmc7V$|+R6g<$W{7h;TK z>FFw@?&cB(Q2!+5w5_kXpOW23fi{XpkOjEx!dRl8#0Ul&5ePrVOOct6!#1#qH1dyG znw_YOFA`AOO%a#GAvaIaYQCUmP%5P(Z7#6}4lA7^m&41AMC(z^A!whRn%dKFGGMDs zjT_XhIPJ0sg%u5FkyA7jKrE&B5CIB~;e08HFAR|?jGRR@(NS-%QK8vh@px0>j0NS( zKck+QR)}u7(Len{k^^zoe6>d^>}$ug?YRsiSz*EQ|Cdr;VVpmBC2`e+^9Z? FX5M513* fA(2_@gnYu@ z9wA+R<_h_l !^;UCtGL#~_z32t)gox_6hO)Lrak}T$GJQF-R~&c zNWRI8Hfh?woL~n$=$D{`C&bk1jtdY;lNemSnZv6DflTp358WM oYf*_vxfpOc~t|sog1d zu5 K$c-%d*52`*XdIXZJcM1&Eubc|o`K)0 ^<><=1%9&VU2&)U7#Xo|)0pnVfG zN>>J_;L$0rhr~E!u@Gz`i-odBCV(P=?QE+^HV(X1b3{^88t4@OcmvD^6BbgABe;I6 z`@zf#rQ|cx1EYg54B#XsDsvXdMYww)qIiN8>dxyn)++~~Z+#*|D(1Ph=r(&452Lt9 zCuklliaLqaGI=kT(#Fp?Z(sWbE ;j2Bca;un%Y^%?*#&2*9e$+`~@NHU&iP zB-19xn9O~Vd>8_51d%qpkNHrQC}%e}oaMLzu@rp;63anO$%8O8o?Y >J;!N>V~{eH4JV`QwF z%jLp&O9w(Ge#Vivxpy?f4c9e-LI&6UAudHD&x0TdD+A)RON?j?#Bm>tTSU+40NMLX z5n`n!q2IZ?ZrP0%gK$}1Kn@GX4vfPp2|0;xEHDPr7B6am{THfZlO#lk;Y`G>KGrhU z3zBj~?JTJ;QayZ=_6h3Fyo~^<9&j&H1B5m1w*HJdf;crT=%xWf=vNspe?*^vllRo3 zr~Ddv@YnbO(4lwR1#^0gx?A4b;OZYrc|C;alHR);eAE=N!|Fo=ryIfc(x$1+A-OqG zf$q{=Dp2TzAtqCCF+VvyuAwTJ6vdseWQg&qtd4N!+STkJ?GcDV61vYwK?AB#vSDAy zz&m u6cEPHhCsB0UATMwyo2aSJ6 z2c}@kIBd5(w06GIxRz2Xx8i%(P8_WQIHcOQ>mT42CyCLvK&?=;)-s>iDJLA1`lPkf zfIvjE5>|g~yD&OD58rG!K0#D1d6T4xV?fNC#vvv)2Y<*2u6Rj3zVIrG3h+f{lWs;| zR7dKyzu;??E#9~wrWN}idGRY;qc#Dv2(V<|@RkfD5n3~dAO{qP(YOS_DyVmJtk(@N zqvt&jj8J4T_Uw)KViTdTaRig21&@RwaJIgUF?;h9J2bDTebd&YBO%>$K$F8n*254= zf)X+Ma=y@~9y&0y$> }hvSxmte#_p_+rW(be;ks$b$yUm&`ZtZeOZmxyyS_ zCd6`pXfNb7DJlEiIT(sC1#X}Q5^j8*m%L_*Z!SQGz&qD_hcrfy!no8obGj1b5Ht~S z@CRg9@{T2D%H%CT+l}Pya4u#F(kX?nS=Wm!o8;HXN`c@CeS2!FwU!i4LdK}}$FK{^ z5jfcQe@M)4YVEs4^b-1cv_>T4FMMH-oOwc*8V`GYA7v3EYMGnj9b!B6jrsBJk=ERR z&cX|`iQVf4CESuXe27c6ac|5bk?`6uynpACca|L=`PVh8J*nO@mjvX{)aQW0aR&Xk Uy H)Sp&^Z)<= literal 41514 zcmeI5TXP)8b;sv9RrwBE!j=Kb1{^tWO61bTgiKkK7!isd5EhFf35p^J&;TTwk@?k= zoL?XOae8`sdS(`2;&P=}(qLzMy3hUE)BE55b=3XTopg`8i|%=MYJaV|gYIc}Zl8C% zPrCoKZ_n)WH{IQI|7G{8JMJFYw@ zGX4IqZnSDC5&pcnkAqe)mKcwd$+sNm(s;~mq zf44b~?d}u10zd16F>9QrnO~+WpRWhedAC>4;VYZj*8~z#V2Z-4?&k{3o6wB4bDFJ; zzHsEks0tTW_Sa7~;(HqhjZeEH`~SJ!fo8|{w?luC?gn**X^s`o FOYy116`@u%= zf7aQ(qVxR>o|Vn_$e#8Y!RqXiTi|fp?mxbq#kHW1&C0$5LTL8b{xOD67Y3Kp5$K_k zQ}DHYf_}T*3&Z%ddu{)Bt|Fh0jNZp-jt`T(0KxnAJ@S!rYu~8AEcfgQ$8pETIF{(I za|pad0iY2bhP*$rwORL8TD88Sj}YZoU95;M!VTegopr$UFNt0;{}5j8Flrp$uZ@yF z+9>Q;4(o8P(`;nSw{N^THaS8Xmf-xvD2aV!T_p33t^U~lI?7NfnA3C;#N;x$9 zm%KvCc5F^b;16j9mmhKBseSL#D-KJ;v^u&cJOleXCc{`+;DsZ(>}l2S?Ma?x4P= q+{XOF={@^6z{%48iZpFXt?j)Pf%uwCESWROD z)wsrBwZIR!>+>#y28-nIKvl`P;9wQM=eFYAtzK$JNaOUH$X4i9$jl#&PUqb;C$1wu zHSL1Sk4+ALO4^F#Oyf{;4LhrdVXOOn&sQHBPA_e4B>kfMG)Wb3Am2NelJ+Rs+>2z7 z`<~=}dP)}Lqi)-*2@-W?G<-AAt! 9FoFa!6yml_5Fpr(w(tXsejY4Ne3q12ZlM^BeN&H9MKiOT6xfro;BTtR8_iW57 z`%EN8?DeV9 Q9F68^ijR-S6l2nnhQS^fbq= z&2nzkabA=*ae6k*3dgWXuWkMJl4Zt@ytsr4n+Q+fw{s}Bz328sF7cXE*SFPg>vwCk z`q@^^X%+lkMla?m>6P>EQ?n %`)1UmXpL3(kx}Q+d^=Vd?~6rw(0y$B^>)PXw5(w6Yx`BEx`huZy>0~d z|5nIt G_ zrN ?^m6i4M>&YJdt*YJ}&)`qV{@%BFzc-6JtkYqax39(%H_IpF z*o%s5i#^_SUnbA&6)$3O=km%Tsk`>=9lP^$F=8)$gLJ*Lf9}iai-ac)f4`Tgi05I| zIuyb$pW!_Dn2#-gtwZ@&n++Zv7!)g`g{s5g;c~``@D85_kB;mL#L6+qJn_DGFRE-2 zQ+pgQDwS9Aak6W;s@!+g2_8v=WT0GQ$hG!rpC<|1wF(Xy6LrozwlbL(ag%2rt|4$t zl$@57ad;&&P_>jWC|l#9XtV^{_bvVqyn89v{~+P?jbZ0hLw1R?ozsdLMPcdOaE_xy zDUbKuN_e(OtgAc+ENYmnO|zu6$o_%BfE0 >7m*Fou)Y#ZN>?Jltr zuz9{qHOqSrKiG<{N4rT%pW8U95T1hvJhCGFcuBO^wFXm(RoL_#pW2g}b=&j^EVeK4 z-%i+|38!WyzylqET6qnCN)r}oyq+1=we2cDVtptC?aDR8AtGPr&0N@O_ D*RABPf$wfc*P8 zxg3}sn2qUI#-vH~Qq>{bF%GjDdDN<+!)Pr2m7WoD!6;e7n5FM2g_ZoExUOrBI{MBl zl2G)kD;Uwxu!cD;_Oemv6V~7R|K6G3?*1dgiNC2reqggnmXWgE%5x8|Mj-L^F}uAn zZLCBSGPJyd*TT)m=DoYXx3yYSKE_tvHI5@2K~-7Av1r6AByPJs3X~LRji~)nr;2)% zy3X||r-g@PLihl+*Kb-Da4*BEPwn|t9<99DI`Szy=I`d pP~%%PduzDUn<1K*ssIX3D3{ADRw85+ znIg8V(-Dv771f}5NW9x=dfw+Y3Qd(?2(RvX;q@AN5%1Yb^y-LT>55QodCx3U3u|Gr zR1>}(taQ^lFkIo?NPk<#YEWz{T`fM8P#hTd`tjspW_{$r9vIhKcE0TB)gY+bh}uY` z{UGHR_-gMG^Ox^f!<#E2u0^1#Thl>i#|Uv6^+d8yWSG8N9{D2CbdIGRc(=&CJZGaO zKvmLr>bax?`55&5c-uAAb2{I}#QJpD$pz8mh`rHAw38~V$7k%N$afE(cfONJ8l~%& z?Q0S@$ LgH`&SSo) zMl7iSYPGfHWPOSF(C$b-`*fWHz2@C9DDN8Okvno) jCjLsg>HB2F z+uNBQd(Q+OxV<2|r{;yOu}6ga_Y)_Wi_VJI&FJ&>Ik#uKK;d2gZe2&WZTBWCg?-B9 znqKuBdWsjKWgZpxF_)%eC8IY5KbEX>^O9Xcxw%Z|vNbmv6#a6l%%Ml!18cUhjmU~3 z#<04p?$<{5wv}!{(fY1dS%|*5S6xN(fG+Q)&)2fH)a5p tmSIlt`Zdzb!J zst^8Rbei|CMU!%d8h`fEUVhm^!7yjmwk)*2ZOt$0uC1<7c0K0G_pdJHERPWI{X+>@ zb-%N{g}<_T$g2D2%fDLCZK7@Sp_y8_ ~STebbNfqHa1K=S7}I1nqm8JR&2C ztF2M`(L9FBSDcpf+U%l2$n(EheDO5>=bn!Jq4oU%G4g>$!5^BPdTN!L9g_`YKVVbd zf d!Nm#7o`cAyX-uSr^ytWME&o&zCS)cU}2Kk?_@Sa;|3GF(t=ZP}{ zXR1c5Iv+}LqGo*`8sy|6xy8SUwX|lPDz|OLoGR>?YI9KY>Dsnj8l~&w6ep1#Qa|?h zt@Pd4bzC>gCxTnPLxlID#J4YPP54KSpia^{+jCYM=e0w@EdK+CHsiZyde_)*?g>QE zkQR?=>7Y_|`Xo^hEjzr-Jjf}Zr`*LY1Z%%;+5oMgYpkUl`fHPoi(W(|?nF+T>$#qj zM&>#c(aXy6b@yE@3ni#@4e01JpQhb~)A%E0IfO$hE`edm*ns!8 qJamhTw zA4@-FuaFINOMJ-rx7<2vWnDw7v5{1uz~?Y!M)YjrjmQV-d*8K(CCf)I$+UxVWWH!E z``lDJfUnHG%<>5vcJ#rACA cA22Z)cyTk5@M(N?#m_X3m5vEyrIJU)S{?ExxLs<-ZSs#?`0m-tGr&D zl7064h|UPRp4uIKtzTY4`((F5{`2oP!L=_h!}-haH(7%$mYR_7vhPQvIsAE~i=~2M zE6c1lSu-L<#lUe#vH2$R>RHW7+_T9%iV^5}5q)Vsc@Fv3P3HDJP?A}yp#Fvmo*&P( zWKLP ) zdZiU6(|#8b1W|+U72Jfrf*bDB!JU!Mv?Rg=QQoeAbUPl33Iu5~>NjdCBu9SN$yIg+x1K;na}4Zi^hpdh_-( zl<+T$!sm@fN8jbYmYmcf^t-j^`t?cq!l-uaBpZOAzy{N6X74heRh^W-+@v}=T(9lV zYMG?gm%olW*uKe;PIk~r(uNu>N}jQE91j<7n?_V5k2Gf<%}XvE`dY&6JK(9Iv+Cw~ zZ;eL&wqQ_3el+mOdoy#ZroyYd3di?M|9xe48{Icb`d<3;?mMFcn!98BkRIB9V7qJF zA`+SN)V9q>_tL54evFDQ)`7a9`^hD|8N*>15BB*4+#w}+eaCon{*{nu#_M2Hw+iJ- z<>zHjT_>j1%6~huTjRTW=_h9Yykigd=?k!9H%`>>-Mgw1Ux#m^3!ZdnFCx2IvJ*M> zA-mT7??~^z7>zcmUyB0eb(w6IPs>8ZP6jNIG;Q2kZJV{i?rdtU{%`D6OK$sEQvr+J z?411(yV7%udlND(YF}rr&7@%2Q_AV*z$v+kT^G5B{notGvlQKG7w&Q|F%^^e9@K3+ ztEpUTUNy~Wvjo@Bp*C#Sm;Ipb&=#_ s_PwFEzUzftHrU zYm0e}Q;}v^=Z_4Emi?YXZLRB)m9N*Y_KvNUkGkG^#E$-M+SpneF=w55x>$<~LX(2h zo=eV?Ls7JSor8mBh&nU5$Z$v2lDTRa=RN-Kj0^0J{*$dlwtbQ+>-`fHms^(>ChRkR zXk9GTUhyj0rMz@^BV7u5>^Z#J*GR0xE&}xm=Jxpo`#g!#=yneu2@k77HH^%6bGniN z>K)f%4n|HHGK3XFp5tUUJ+X9$#pbo k#+-4E;v?Jj!=Ii~Yt3ejzz z M0lMZCYq)vIYCYx65 5SWR8ErcGc ~Ek`E~ILC9{ b1uK>3YWYa;kx$O|hH~bhEaSXBx+)ZcbL`r}we{VWQQGw@ zKYx`|-;p~>p(Itmg%DbYM^JCk@A{c_zMGr8J!Z+zJMr@jnHN6>J)aqET9AhJPD^CD zf96@zF-}*V(oNC#yX0GeZ`V2+`OZ4J7 sux`ecy(akmNT5&SoD$(souesRB&g?)}gb0Ci9f7+nbOvNmI_Hmh?oN&>9so zhV*#%LD+^5rK4S=d3YVkAyG0A>TD^01KamWJvM5Q9j|Ox1vGX4bZlH|OWPdHoxk6w zy?X^;tkdXt|7zY&86*emJN>&XAKMO{`*wD@Z2di>N%>ZIi(it0@oVepDcK2`Dd$H{ zf;Mm&yLe{42B|@#xK5p6poj`v he>|v0m8T8O4I-sS%O65Y2hM!)_bS4PzB72inYgP1CkaUN*Op!aG(X^8hC8EO;nvrPP-WDJOf^JkUBf!-4VHsE&%qLH$jsTzd}P z#4oa&%+D3^Y=x?Zp8$f-MEA)zj?)PPp|i+j?)9+r?j!43wJv6QGVq(&H21OKUV~UN z2jm_z%YuwU F}_h6gW!1`@OV0 zhjClcrbJE=>><|FSH~vm1iTl?PR2^$B+uKzL$eDXqT!O#ff1)x*3aMEwY`PV`zTqd zvVXW|bw2O=*DDZ$qP(`K>)L~D$Ypd6tjJbQK~674dK95}jpMm_Fs}>rR|qYTWJML= zNs1AOaoiug8Sy_Qo^?A}jsot3 p)xgOIVN4oj7^%W@Gv#G-%ad$X2E@jhnBk zP=8!T-(|7&)Xw!X3!g(xIDE%=tSYCh<9MB=pBqzAj(k(`Y92S&y`m&cS6Nzl2V#I} z&6 (&jxiaM`shOXjwzKJR8{V#*2oGIzO3&f >1a%syd(HFZ z>-1*E=G}iqVQwA2F$f}l<4uqI_MeZ5UucMXEg#?RjXOOZU=jUz}@NhI^i5$3%3xvW+`|Rl{yUkb&RoS!(Uou9%?F6zY|)g z! X?OVmxKO0os)31;!LVB9Gqnrb3f|)XWud!)8xJKpU>BzZ% zYpWGc@7?i8WcUWHJcslH-#8ovhv7&4+k7t=BWhfg)!Mcm7`QmM`o924+~_-h>QIfJ z+O6mMaL!q28SMKhD`fXyoPexo;*W+?>(?3sJ3Vp7#^1H4umhzI)pu9cDg`&ci|e}9 zxV9IIc;_PZ79J+8UMC$zTk00J?X7AO#@>lxu2xDC)>9euQL-E8>#HP>{>#SR@%1WQ z )Nqa(tqSoBtm6e7UXhtOiNEO*cgoesi8~LtaU!t>U^-v(mZV zi^rut&^z F(=XmLaZ9bbf+VZt j57Ub?zw5WevKv~r6E*M> %V zrrS1Q&dfo>I=>~Q>w+V-UzQIjH?bU>(YVG-!91V7eeDh!=P+@0JsAY~Jtt==ckvhu zPE1=Jb!RrGb*$Tm8H!VZ%OUP(X@WPnG{;I!(|3OU etlz&y=5Pb7;(Up{~sx^&G9D z>o6XZ|A${YMvdY552sc=`O)yDXT&IvONbMEXCHb)?^b&g6o(CaO?B;9n-7i1Du)Li z)$kKG9~;DqnCtzQ+}0zNc?6ZO8vEuV3Vav4QHkf-5l3~2{nzX{zHgBjbqb;ionlRF zp|gNm6c8oA<;-ff&Xe+-9q(z*nMd<&+3FqxvUg_49i*Ty6;W&Z!JzP3rzGJh&A>0A zG0IPq@}1v0v(EP+*MCPtFqPNg8<&dQ=k06Pd@;|^^4{DjdLdV`Jgzl&j2_S@G78S| zd4EyeKpI%rFX1_My`7>B@{Tz5U<}6ESfH)l4{s~@+?u0@u@=$P63G-6pIY@?eg