From ee37d23483b4a1ddd40c6669f6483bf126df9b2c Mon Sep 17 00:00:00 2001 From: Filip Rojek Date: Thu, 27 Mar 2025 13:54:57 +0100 Subject: [PATCH] Added: cheatsheet --- kevin_cheatsheet.md | 184 ++++++++++++++++++++++++++++++++ kevin_cheatsheet.pdf | Bin 0 -> 38515 bytes kevin_cheatsheet_fixed.md | 218 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 402 insertions(+) create mode 100644 kevin_cheatsheet.md create mode 100644 kevin_cheatsheet.pdf create mode 100644 kevin_cheatsheet_fixed.md diff --git a/kevin_cheatsheet.md b/kevin_cheatsheet.md new file mode 100644 index 0000000..b94e80f --- /dev/null +++ b/kevin_cheatsheet.md @@ -0,0 +1,184 @@ +# ANSIBLE TUTORIAL | NIC.CZ +###### Vypracoval: Matěj Kevin Nechodom +--- +### BASICS +##### ClusterSSH +- v PERL +- nejde verzovat +- 4 terminály = 4 servery; příkazy se píší do jednoho terminálu a to se paralelně odesílá na ostatní servery + +##### Vlastní balíčky +- IsMedia posinst + +##### CFEngine +- old AF +- napsaný v C +- lowlevel + +##### Puppet, Chef, Salt +- pull/push model +- mám server, ten obsahuje config jak co má vypadat a klienti si ho natáhnou +- podle nějakého intervalu (default 30 min) se to refreshuje +- Puppet a Chef je napsanej v Ruby a každý klient tím pádem potřebuje interpret Ruby + +##### Ansible +- YAML => Python (2.7/3.5+) => SSH => Python (2.4) + +### INSTALACE +```bash +apt install python3-venv python3-pip +python3 -m venv .muj_venv +source .muj_venv/bin/activate +pip3 install ansible +``` + +```bash +ansible-inventory --list +``` +- vypíše list všech strojů a jak je chápe + +```bash +ansible 1-ubuntu -m 'command' +``` +- lze poslat příkaz na různé stroje + +```bash +ansible "vm:!1_ubuntu' - m 'command' +``` +- lze poslat příkaz na různé stroje + +### PLAYBOOOKY +```bash +ansible-playbook play-1.yml +``` +- spustí playbook play-1.yml + +```bash +ansible hosts -m setup > /dev/null +``` + +- vypíše všechny informace o všech strojích (lze použít i pro jeden stroj) + +```bash +ansible-playbook play-3.yml --check +``` +- jen checkuje, jestli je to ok; validace konfigurace + +```bash +ansible-playbook play-3.yml --check --limit server +``` +- lze specifikovat, na jaké servery to spustit, !! pozor !! check nefunguje u všech modulů, ale ansible je týpek a v shellu to nepustí, takže chill + +```bash +ansible-playbook play-3.yml --check --diff +``` +- hledá rozdíly (--diff) + +```yml +check_mode: no +``` +- lze vypnout check mode | ON/OFF + +- shell nechceš používat, protože pak nejsi schopný checkovat, jestli to např. doběhlo, je mnohem lepší použít ten modul toho ansiblu + +### HANDLERY +- udělej něco, pokud došlo ke změně +- dává se to pod hosts +```bash +- name: Install webserver + hosts: 1-ubuntu + handlers: + - name: Reload apache + systemd: + name: "apache2" + state: "reloaded" +``` +- volá se to pomocí ```notify: nazev``` + +### TAGY +- jsme schopni přeskakovat na dané kroky, nebo je i skipovat + +```yml + - name: Set hostname on homepage 2 + template: + src: ./index.html.j2 # naše šablona, která poté přepisuje soubor v dest podle té šablony + dest: /var/www/html/index8.html + #backup: yes # udělá backup s timestempem; nepřepisuje je, ale vždy vytvoří nový backup + notify: Reload apache + tags: # na toto koukej + - configure + - index8 +``` +- ukázka, jak to má vypadat v yml souboru + +### ROLE +- strukturovaný proces, lepší orientace v souborech, uspořádání +- ```ansible-galaxy role init nazev``` vytvoří strukturu pro novou roli + +```txt +roles/ +└── webserver_apache + ├── handlers + │ └── main.yml + ├── tasks + │ └── main.yml + └── templates + └── index.html.j2 +``` +- struktura složky +- main.yml se musí zachovat +- ještě se přidává složka ```/files```, kam dáváme soubory typu .txt, .sh, ... +- lze mít více tasků, které lze volat (nejlepší je z mainu zavolat nějaký jiný task, poté se vrátit do mainu a poté znovu zavolat další task, aby to nebyla špageta) + + +- Playbook, který volá roli ```webserver_apache``` +```bash +- name: Install webserver - Apache2 + hosts: 1-ubuntu + roles: + - webserver_apache + #- monitoring_apache +```` + +- Lze použít Ansible Galaxy, kde je jakoby "store" s těmi rolemi, které vytvořila komunita. Má to vlastní dokumentaci, verze, ... [ODKAZ](https://galaxy.ansible.com/ui/standalone/roles/) + +### KOLEKCE +- velký třest roku 2020, kdy se Ansible rozdělil na komunitní a nekomunitní - ty komunitní věci jsou v "Panos" [ZDE](https://galaxy.ansible.com/ui/repo/published/paloaltonetworks/panos/) +- vlastně nevím, k čemu toje, byla to nuda xdd + +### PLUGINY +- jsou to vlastně moduly +- rozšiřují funkcionalitu Ansiblu +- máme více typů: +-- callback plugin - je zavolán po skončení playbooku (např. mail výstup) +-- connection plugin - používá se pro spojení s ovládaným (např. ssh,local,chroot,docker) +-- inventory plugin - dynamický inventář (např. aws, nmap, virtualbox) +-- shell plugin - umožňuje spouštět shell příkazy (kdo by to čekal, haha) + +### PŘIBALENÉ NÁSTROJE +- Máme následující typy: +-- Vault - bezpečné uchování tajemství ve verzovacím režimu +-- Galaxy - sdílení rolí +-- Lint - statická analýza kódu +-- Inventory - parser inventáře + +### PŘÍKAZY +- ```ansible-playbook playbook.yml --tags nazev_tagu``` takto spustíme jen sekci s tagem ```nazev_tagu``` +- ```ansible-playbook playbook.yml --skip-tags nazev_tagu``` skipne sekci s tagem ```nazev_tagu``` +- ```ansible-galaxy role init nazev``` vytvoří strukturu pro novou roli +- ```ansible doc``` - vypíše dokumentaci +- ```ansible config``` generování configu +- ```ansible-community``` verze komunitního pluginu +- ```ansible-console-all``` ssh příkaz na všechny stroje +- ```ansible-vault edit host_vars/1-ubuntu.yml``` zašifruje pomocí AES256, kdyby se to náhodou dostalo do gitu, tak jsou hesla zašifrované + +### EXTERNÍ NÁSTROJE +- Molecule + +## POZNÁMKY +- modul ```raw``` používá pouze SSH - není potřeba mít na vzdáleném serveru nainstalovaný python +- nějací daemoni jsou schopni checkovat vlastní config (např. nginx), v Ansiblu lze použít ```validate: nginx -t```, který ti provede tu kontrolu a potom až teprve ti udělá ten zbytek +- Vagrant společně s Ansiblem dokáže udělat virtualku, kde lze testovat playbooky +- [Multiline in yml](https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-in-yaml-over-multiple-lines) +- [Cool výpis všech serverů se všemi různými daty](https://github.com/fboender/ansible-cmdb) +- [ShellCheck](https://www.shellcheck.net/) - řekne ti, co si o tvém špageta kódu myslí :) diff --git a/kevin_cheatsheet.pdf b/kevin_cheatsheet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cc2a2e94fb18349b97fe6ca7d7390bb20e98e884 GIT binary patch literal 38515 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

MtOra6Xism4wc@>CiH=37E z6-zYJQ&Mz;Q30AHf!>ofGb>OzQ56~N5-QzsLrXCP=WB-k3V*UpBW6Y8|2N%%axoD3vQy{v%5+nR`TBWCxB^lgBS zCigK%SC*J<|Cuzxk7>PjGRV689TNj5g`mK63m<*Tbt3 zc@(gNb}MFG0~Hc)Y}8!*QpExfR75P!rFZj6|CuvQ=rNILeHqPDs+$`+N6c=p8RD2-a zK9?}ikew1$VJA_MElQ>S?yEl;AIYWWE!hH*l`nJWHfhOn%|#?HUACm&VW2|gbXD5# zSaIkyK(x%skD>){WC7vu(9qIKKYvAtYQTFtqOf{;hG$^0cl5ryP`@Hn^v2rUAQk7% zYjss^OKhK6!|ebuW)15J(z2&1)DdRth&fVDPI!)p3ijDBsZeb-i6I0$O#2M;cgLL9 z=M83hLe2hvMio2jKZz=4rhjYg=_E{rSMVbSz3__Aoj70_WHfVu2#7}t>V1owpf@mU zj-d^!a+<`o^k|l(4nacas5rNu%Xf{wbadH@HMt>pdlxEXY3+cvKexyyaLyGy#mOo! zEEgd9UQ}b}i+n4>)u@OmJzcD5eSf~Z9nHEXt&ANs|JdO3@kv^%2$>f8Y(gl8-TJt8 z{t-KW{@$#3;#9P-Pfe^bY^?~9S;#q^`MjZFM%DCHK*)KE`@yvxxRt?sQy5Z6uFDj) zb>5kEF13J8>XC1ZE+JRCaPX)P^?IPPQB2I5e(Ir|JoDfx8mXJZQkpgrknmRr*8EMD z$k>M4C~%AnDnkW2bp)>b+axs^+Zh0PqCuo!p9`Eu6L`KJA*j7h;d6QgXjkhw1^~o%PBU;Z7P;kk4>3=}a_K(mraQycN zRVSg(rhpzX_=Y=v?C8G4^t=#wtGO5CEPtsz zIDKwnS737vJU#HnN(Q9`Am8G3JK*sVLaJU z!*@Ei!VO?JABq(faGxB&I#hfFR|}~qm3{{07iFtfCvTV^A-x@k@GL=cWnK8Hq;5@l zIIM88a47W|35)?J{#Cuz{)=cDgxI3)Cs}OnSR5pv4K9gDZlvEp2$2zc$`N}CWv%B4 zZmkbel>Y*Z%tLg##scX9xX*+)%!n;bAymK+^mZ9Y6qvCQIMpZ?03?8DzzOov>@zye z{+1(u1eO$-bv#WIX~JqhJd`Gy6C%egcP`z^;|<~R5Zwf4)2a2J)6Urgh&S$OM=rJi z+;fc_j_1+|246f&ZHc5o#%qGbe6#157hVRi-}R&SZ}=3=Hsk*T=YM4Qvv4r~8|TD6 ziw%B6{+sV`p5{coE6H`|UQFB#;Durud%-b+JorXI*$#x|yJ-;%Kq_9KLt6%zGct*H-NV_Z@t$2JPv{w3vzX z3FlY(Kg-T9=smJCK5)*s>CZ;pomTMohjteqFK*FSOC$|TlFbdLDmr*{-Wo%BR&w^u z(!(?3)Dd?L=|j!mH{R;CmsjdvG$DXZ-pDRicGV}ca!F-}-BR2SW-#Yns0eXVM_+0oA#GS!<_7ZjI<=}i%9a)R9ev7-LkXxvEd}_&F==!EU@CC9!?F zt_%*Jsm;#Q0_EE`h+u@6+<&;19RKL~VPyTcYndPy<4=z`bmJ9{zhwn0Z+1a8EUdsv za`COiwnp548ZS-+hT!uN)IA(PlKy!*+37AcB3JKRT#@~jQw(rfY)~qa64G&G0jnd< zqPhyoOj4QSs{awmYRS&AdU)ok341%cxj4T#d9&`Yc0vJPu;u(i*OrF=Y)+veK@NIj zOT%!@u61LhBj;Q!2bVF!GyF+Zb?)J4m|(nyduHzSqA$sq#M>}Nw6@09VY#7OO19O| zt3_?qhPZ_$BcYRlVdUUVW{VFy<3F{qr{PvO5%Q2qeC0;@?eKueE8mJu0lANus2)#< z@5c@q#|TWssOhhmIh6bx9+^-%%!E)sOo&J^G?B0*m%p0qe*c%drF>}hAAZ>x1z17T zI?yV9CV5~7kLqLW#yXN*LIzTxAV?h;iqc6=G+&?A$B;Gkl_(V){LxB#(Pl+^0L zYzI&T+%8zwD=ZV9RU^!LhzwYQ-T(%iup7d;2!6DqMF#hy$Jr8xZ+dqy=b$snRuw7F zwaqH*nypsa7i&QEFl@@ob)rth9k^QhwdD%yRjRS?&)wJl#s9?3LH|#1Gco@=?s+ZC z0D4r2TUS02d@j+uWeb?!jhrE~)rQRkz3GPJizLDyv$lLwe2@A-L4RmZ4jnctC#B}1 zCcl>J%gl_d$y2uQWk~0-yS!=n1N>DR1&A3D^B$ z^pr|Qo+Y6&t|t=FV-9nR{;NPR7VR^U;yo5N$hK=`;{d7k767&DrpjD+CsBhMp4x1gggwbYIL%wS=~5vU$%+r zlFoBCW@k^L#sh-iwm1c9G?f&mDkfhb>ZYqb{{xpnT!ARDzei4Z}HN& zzO9Yy@65aT^S@%bnjDk&zH3l8ff}TjC8vn}_3!WQeB8duNprys#vGxRR4FBfeQde4 zc}*i7BB3TJ?%p>Lmy%nU;_<%-xg(1{`nL4%$|tdMireT)W}DuDBa~D>(%wz3(6|;s zY6)e$Ib=f;MD=ZhgvlSl0s^Cmg9Bg91vEXa(^i6ARz(Z(%w^U+hn$Yy zY!;46vUxPgY^S5-PH`?Wn7Rxr?&dr#FB6Y?_$;_noBzYfGyU(tP;xeKaIZv$IQt5Z{=>6I+VJST1Gbm2?o-f1J0m!7n{0W8FZ_3m37lHm|A7H zmSqK$aT2LGArRVH${`71M?D0ph5-_bLY+tj9+z_qt+j8HOT%l+>UYw)>)qjxscdhx z%lb6agLHOCU}mQ0^h?*yefLQy1v$AS2{N1pa;qR-L3kFk`@WU4Q>dX?H@zTcm^O!B z0jMqs1vsRx!JY&;_lSzu^wJo9NELD6fhfCmd}JX-oJ;7z*8zE;;EKW_-mE8W97GntGWzl}e&u=Ziy*+0VSak&*;|lphRy^^f94{c-vsiOM->3j?B~)8Vim z>*sh#2A_J65toz?EIU9W%7ZE&HH*5bVfZ@35z(b)@y8b75qXoBQ#vSvN+e(jOPA)6 zn<~^T)Xg_hax8OK{?+tXQ<$bWS>A8afihH6qN<2hUXn63Jok4Qrlib}0#su1yn=)> zc2L<5Dhl8rCwL8(!{u2xA+BsYZ-bl< z!54(IvB;t5&1qts*Nwm@P6gYN5NqHlDbFpEC5`thY*yWzgv=qsf-iw(^g^{0xS5C< zkua-zMT_+>d%?9!cMPy?un;)jXz#uOA`c!>8Y+^qRL;ko2hwy?deBbJ(hIX}x~P(a?o8=Dz7mfYIkq3_+wj@LP@WuYeS23A@fI9pZUg6Aff+*AwnWI766ed%m_0mOKBoFY(;pEw{6#r7Z$*U@mz zQbM7R8@K3ADh-+R%LfU1@9L*^UWG-4C8=q;f=jLtPtUKz7sku&(ju`+jEY%*v;A~s zzF_rDUu+7%jXD?kGRGF9qNRZuPTvsg+7R++aw<&tfxuAN+gBg5{V2PLixOqf;_!1{ ztRye(2xC#cyP2+JjaUQ{h3>>U_pwWgS+&3IBp$C~jMGwFQosxnLT;qDmM(Fb4_GP* zcny6nMd=;8QPn4E(1+!cp6>o6{6OOxkqW!a3m26Kxgh8 z+?T$L@V3K*54Hzo=K=i%XR|AaXfa`f65JHF-iLM^5TPDQ$Ur40bfyIxyogH+ptA8J zi0DF;X7?J09MDsr19-zTo<4!|(%Eh-yR})|9P2n=adFxhwA-PO z!mwl5+dM}>cJ>i;inR1)n;kDb)h=JzX);e+r958T0i7 zo0#y}8DOWBFWbPF-pPYbw!uF(w`K9IIh5CC^SDvC2L!ol$;~fV1W0CZ)vcivYwej^ zrYE_tc3__yQv&cy;4=J78&(M_OA2=q!Fxuv@-#@ZlB%(1XaXc}Qy3xi^No>`Rc=+y zsSBkp`C>_~?-idV3nzcEY3FQ#3&_wf>~9NxVr>Prr^W;d1A7dqCUyG6jNy8jG)^x0ue$EL$$ zzpONIv@Ca;H`gIZ)?QGFA|I@1={u}6sjhC8Z(nRXI1YKIdiUIt9Y{l|_GvB0Zk8*8 zTP8H&9>}tQh9p)RGqgAycb?AcS(5Z{062bYS63obZ1gj@E-=d>?X=9jtAjzC4xo*q zPEg$(Sa{);6X3W!VyrJd{%WeTMu_bWYjN+>Z;eLyF-bKdb~qdg5?d4ZD1lr~aQf6d zeXa%LC;f81)pF}SRXZ6jv;%LY`cg4i|Ka&dt>%k$rT_Bya{Vi`(68O+bF!OrDgxK$ zbLz&%1$r&eW`9L#kX%1C1da=8Ygc#@fgnJ+(gKz-=s^-#p3UWVOtW`LW#toBq3r=4 zm??-K<{OqhQv3hgiMT zX!7iCX%tbPXTb(Sv*vRGwr=E~2FQ{RRc$z0Tfdo7{A1|EsuZX+X5C%&+VRLov`!8T z>xJ>euD&sk^OtO0n8dR>K9ViI>Ll~Jmvqzp{4fNZt-V{oB&n{ECLom*q5 z&37rkZSkECU_twe!9=y#1S&aCG*Sm6#S6UttSR4{2oT+9tG+DyMQ|AF+G(V>Z2V&B zR%y*ybUeo5JHT7pn>p9r1L76b^^TO}#DpX*^2B3?6Gh|}YM?aKVC#Kw=j7(4c31XD z#I0FaZXwoy?Lt7>5&=|k_1%5}YTQE75gOOz5~b5*S=E;x`6@@f()_?>z!wRFr+a$as~edQf41dk?u^jt3*;RGo*+Wr-;kmhXh^a7 zb=bnGUHjxOnM~47K-mQ0js~v8EH|ADGbZbi!@E%yQJM^4c)_=!*zZ@opg;s1+>&e^TX^W7r%j%u!x1lrGV#J7mxUk_~ae&+J@Ph z*@kUI%VWw~@OKZn`EkEc&bPq@G)HijXb&r&1qka|mRvCeJb2bBkg#%TRUTyY{Y7|#lXvhpMdr*X|}Q>Qnr z+%js(%GcK76U-obSoywUn38H0VBiP1by$STNXMyu!qm|hnUIQm) zxjeR|7z%-QW!G7Ak9GQs&i=-NNC$i|Q0~rYnm4bq1lP}K%wiVgV^X6-y^Psa*byG>^>EI6gzBZiRE}mK+pFi=z0jSO zkJf!twpg=~b=B0bnYXSF(fxV}Qde5$CPb&ceDc#;BDm5T{5mPqtSVh6)47`}VTL!` z8BGb@RBwYiWhc&;?HnEc@DlmR8-Q|G+VjLd`?iO~`JspCoy+2!kY*b#90qd;BX4I) zGU6nP+hI=Mu#>X0J$9hlr`9}AkH$B%=Qj%;P)JYX`_2fw8RAVX$XH%-g3pe!^_kB< z!MSp&@givScf8Nu0B}Y<^Ua!6jWn8W!#+C5iiSQnsV;>i?dPX0skwY?4*tkS}sby57KfF`@K## zl$I%VX=NL{@tPC90!#V1WhKN`T-BOFbdh0EK3G{bCwg>l8?|hp zWo84b&W0n$9JVAwZXhkr&S6*$+YWgTo*%!7}bB^+471+J11;ue?wid5XzC{QP$1S9)<9;lPw8DZ)RX47MW;yFUeFAA=da&rhkz$^;?a^ zG$iiG1LM9P_q??lLe~uvrA)62n;?ey zIl5oMmgwNF4pv)reRS-*Ne0=n4 z9J|%PG;&VUf-ohB6O)lg%qjM1y-F%-M>k`PO{IxXtUVN&d#_0=50vgB#P~tL5Er`G zdZv&tp&glwqJ+n$p;#0i_J*zp3KV|9EDZH)x+PIxCZ%BpZfW=em|+wpB(NCK#x3U+ zkVAe%RI@}>zuITLAO|n40XB6D@sZ4hGw~Oa@-*bI@!wuVcWgA3^IuL>bFaRxR7kg` zEy$54qFcQmhAKhIfay&SCTj5RyK;?wglFV|ju<_k9J;D-Q^GUvbgZ zPj7D!nUB{wj`O8ECnUp45Cq)Ei3hB%rM>OZ_!0_>Fwqxlx-W|k`WjGHr8G1t4z#jV zOVuE87lauwq2Me>I1dj|WQO(%Yb?j^5M=r{W5ZHUFP6Se8gY69Wv+GC%vA^k1R7D89uKqj7yK^+YVe`|;H&(%_SXNa zufoL6_HWxask^JAsx{XXmr*jy6rjpTr<7Tsh$u88M$wr>hUX8LLWPIVQ)o#&$YYy5 zQxHPBIA(~VYoM;72IL~5OO)!N8w@j;s3b5X97Rn?Gp7f}j&TL0q`lZ2#HSukbo%Q0 z{!w$@(NZ~aoqo%zLQQO7Dw3zzRIS!DT*ps(RsU-nYpzvkXr9Kc;e%NQs*!7?Ky;CL z2#{PG!163hEK!**SbJR>o2(z3-Z%>ZNXA_sv-{8^eOG$~e(sZ%7jvS^Run5#q7>z7 zQ>aM_nU`IlQj~HDq7S9#!_5q0BP$&!H2{AB1DnvXk{TBcj$kP{`vC#Pe6UB$o%??} zQRN#TOJf}ey6GqzRN4gP*d*oHGywuChc8T0k)7wj4HuiMI2TlPN{OUXOjrw3o$Ud| zjU){%IkbzIw#&w;ipWlfnFgySp^P{N&gNlt!KgarbGcg0HrAy!WdH`17DnFTSTojB zFK=hghQ3^;;$pI?hZi}ShzF*k!8cpdmDI16t?tpwo7R7Qq;aee@>b(*V0U|3*XvoF zRNhim3a4F;#YXFyx^(T4x%ny>4Jjd0icw@L(?~=(lHw5sQncgDgj7IANr+)Px}tAp zYWsz{fwse8?L_JN&W}~feJRaxktKFYH3?oE^Ol`8lkIBns&VMxt$p9>I>N{4vjT!b zAg*k#%v0{$7ToGmp|hmQHcm5m^#|piTv@IaYGjd^SR9y6VmmVr^Q~7YeQbXmDcxpl zLS(JeTuxxw25CdIr^ppm6B_;Y%maLQ?d-ZG_J~x$K!LD)E?G4PR1F(DZDBRyd5-D1 zx<-Lu#}Q0}Q`ig1#nO%p1h#R`;;pKG`U;ub71fJtE2ft{6fAgQf*ip--BCWec0Jf4 zy(zX=SLdGgSvO$G6Mttu&b_dz>uzvvl2a;7{@I|TD*dOB*uoEUhPH0^-iupi;%Ler zN`t_M>?zv}xix4*eh{I*LRyH0lVl%Kk7ct?U&_WdiiBfve4bvBq>np^DoDsDn7afX6R&-P@)q z#Z-4qg1Fi1@uM(6kmG@tiAKvuA-+d`-CbpSxk1iLykft%xFAHZ2-FD>c^ZA=mgpu0 zO#9bZVaZ1)3I!MIx6p8r6BuK_sCVFWR6p;Z%#^6s}CZ~>=ao#L4@{<1f$=T@+6L5k8f z#$AMo?;#T?P;5@XIj`!be;`rkc<~+}<<9N-tjvvM*^>d~NLYI_!Z`=gh^^h5=(Hir zjPH16epY64q^}L-GiyfN$bejwPHGm9YAE?8bz57An?}V~VgC#F>zkGz*-hxw*yk7O z=zTqfK7P7fJsaf>K!ZPV6H+GEP*3(@!EMuLznEaOA%s-?TshXPu-ZRE(MJ@2E;H2A zxSOpwpPt5zX3^I_B;{Pgu4O^TG_FV~(PV(W7TE>QpzmxZDdgo^WZ6MqOjp39n6;j` z;mFL>uqL;gg+tEYIiCBQ^}w{Bcsx!jwkS?L!k#t!Na!=xJF7ILOxKD`GExT3g@hcH z?AGzPF?)?f6#h8#qXRt?XWPe|pMA~ot_bJT_ebl!2d~j>2OJ;6(3cx;WY;b=_$%*x z)ov^;!9a22?9ibbed!W|$X{jR#9o;EbyMA8z>ByICDYcb4QT~y#yNlRaaW*K?2y$Y# zA`WXS;v?ec837-s=I!+T0q~30e1v6=P{ZpXq!ATzOX7($-r_aY)*n?OyK)l8AIs$d zZfU&FM`FOyYBb3H97q(Y3M+pjldJ$yVvFIKx|1M z;Ehs#5DVNEbxh2IxWkV&v5f=0xtef z90`?#Pts$+^{)7L9Le0D*t(KN)bcgo%8P7XD(b;lGSmT<;EuNkT+e&fh2AZ}1WPz- z3R<{M$4&-szrPtbvGO!@o_8}NT3ePev^o!umZ~;aOWo< zQ1#n&og{sTeoq*Xc0a(twb&Hb^iH0V6^CckuFw!1xu0`DU^(`qN*m@j^C9=MH47=4 zE}%1N0a_%hyR#2sin@ZM3+YEc_lfmu;!JdkG+=1I;rq55ar+#SdKiPp;j0aYcUPB>!|Q|Bi7t7|7+?5%pjI$$TPKX1b_+2cxk< zH?MCqU=)r?Psw?4_B5^s{s1`=SGPJNNobM0AxpF}ZL_}zZ;C=o-c(I{KK74UY2r(c zq1;{1p?7N8*=fbe-v9VbEkmZyH<&~=l0 z*eGm`$w`5j#P^|*T}`W98rBp=Gcp^}n^ z$CqrwL1xK)BItL#^97Y2K-hy)D;`j~4Ve(yCDV(coU#f8OzOh}IlrMjYHr!@6}_WG zfqaIc&|zi_4!faZSF6O}5`|KE{4dJhsap_e$=2MqZQHhO+qP}nwr!iaZQHi(+?~}= zr^c<@qw5c>cv~Z8#5ZRc8pJ3i7ef1_5`%H71Isc0jXHxYcD`K<|1fo`2rxhsao~hM z61l$W1mTS}Pvip!3othz(`r~xq`dcnEOQwoRVqjJx@|GeAZv3Zrp<(QEhmTWh%2Yl z>8GVu#UNl5+Bqr`#A)3z&t9QHPcgst_Ee{bXYTJ`$~mAMz*f6nE@o$k_GBGbs|O{X zlAWk-->|X{-OXE@%6fm>(~8}Z3{UY`<0r{Mtk4HwWf#_?<+k3{SnDF>Fgu!50klZ# z4mkUn|AREiENQ9pdNbx$LbD70H{|6YQMOC|EZ11~Qjv?{?P}&S}mu^YN%)>Dkl; zLm$OR8+r0{t;2>^Uy;;uPDl79--R^n7S(OtM%3NGj}6Q@9@TUdigjYN3B!;3Rrq}% zBdjFMrg3at)x)t|+Wdf=bIuz5v$%zF0{zn|bhC)4)78)h#sfGE4Aos&@ghRRZN+Yxb`m8z|7T*zdV_pu z6`a?W^ScaS?QUyh;*wAPtL=p6vqe8+F3GTp%r_(*g_gKHg;+n%p=4{IB{Xg$;JUFW zul5^ya>tmGsx89f$$}#;edgIUDF(J#qBJ%)`dUo!7ZtkpS7lxkwG@>85!`CNkP7kg z#Qr?1X>k&ohmy1Dr`$TTRO^tzUO8j8rt)M~l+`fRfhm0iPh} zIW*73R#x*Py~O83yNqjiSxwtrJ=z;8(RD7bvoEZzJBbNNZ8G{4rw}iS%N{XsAmRm86 zp~}SR!AQ#}Y-*D${G*?#!#Abq=_!F#KU*#M64VpOc`wA95tq$m8{2v9uYY`JxF6@K zQ&qevzHD|SEg>sAIl20uS&zkqT81mc3UZwKrn1g6)rmRv!P8M+)fk3d&gBxUa20roqd?F7j2*k? z)RfK1srY=g%918zR#Vm2sKq3z?#UN_z}`$O;Qv8>|Np|f{!f*U&>+bsw~I7z|EIOO zFc1(*!vF>h4&np=po<*zHmr-Sh5PsBP4&9{fTw{^UF=e33%w{(N~gA9sp{s+}l z=Yg-~+u{(v-gZG>5@W&TJNX0KIt+-b=-2_U19^jeBY!EABDV4ASm-IJ1o}86@G2pc zNo29u4F{v^MMTL*!a_r+Op?iDGI&NGT*IcVb8I60_tPj$x6>Fh{Y?^VCO9^l9GgxQ zr4B4JY*bWAXaw*s@$qP)q0(y8>QhI?CXA0v2pbh2798i|lWXB%qmwC%joQaU{Ebfz zoPIex6KMFDB=D$}Lnck@KWnsTwJ}gD6KG+fQ^ZFnOpV7TO&py%X;ca$@;Lo^i1HJIw9#x@7DUnc{_A4|r6Lb#n(eT)B+3S4o z4LntBLi{<%eCF2~t}U-YZCKdAu%lzg$c&O3&>Jn+U2MSEki8+ZV|!y}22PEh80c;I z+5og8dZTCu(+uhjr5jDxp=?OoptNH@46GYk*SV(ApN7600ca4Q2ah!v(4s;Ovm0qO zK+r-(jTGolwosnLSS zeLReJ;~2V(q!0-gA%$1FGIVy)`sw%%xHeg5UzqGhJR{R22;w?w-Mi0URr4)W%Vx)J}G#2A|~LwR^GY2L+zdZ;q?zdFp!6xS=)@snu@QY$Q+pffXUQ zfVVW>3|>vGFE^*zZr~`gvep$gRn>KLn-T-=F8&+PnaStCV}XP%Q?o)hPZ#Tujg9sd zMlV`r=7;TF=6zS^ix&0_HC_3(C$64P_Y)yX?oy>KAA3_?c>W3UY=fF@1hT2rg_BXGnIWeV;FBr_yvUU4`gFg#-wH0iG>$DRn4E|Y z6{5T#(t#t_4XJrP>UCdVZPRcP&6aKPrTRXKZsf;wO-(BWz6p~nR%<*eN+$_jwkG2T zEf=`Ncgv&WA%@=+3_D*%tW=pHWh$(zD!SC|ys0k+JVp!yD-diK8)TPY6?Q8c1AhDm z7sFND!>OtF?xueta6kT$J{0XTMDC>II96T0L3Y=LCwxi@4%2&hfqiL71**NqIfF zG&|*~HJH;#(CjZ@+HWGk6h0(A6uB1h&!vyW^KisjB1$5=xZuPF?^d?$wNX$GbZMQW zK>6lm!p#*i+sM~Kw$P>9Xd@%;<`J$+_Jhh1URd?+hEvGyLZ>bASXMibZW6-i#-JwG zi0;uoiyTO}Zn*vCzD4!~S=&^BCKk2ekrAq%1zl{I6x;cuwuZ(F=R>XMl*%d?wK1u( z$^ktCvSC`uNJf8rpb{jGc0X3*NsTNL=+Q%-@g!nBFu=6LU=hY6msC=HT12Yw2Ak~r= zp7&~lFO}^D&s>}q0C&LbQigk&dxSQ<`c4)QzliI@P@ubxe`OSO9HzxKtxpb;wKbh?b$TaC*q3Ng+cr0A+h!;WHL*3Dyv9?W z=piUBUWeEdT&{&BD58#zQi(j?gEIDj%q2R{-d{ve$E9cIx#YOGR*=KOg{Pw9ax%t9 zLZoGI!v)B9JTWY|@i=anjrhn#wIG)teI4Mvb$P&*IsRgjAIkL7wT%tfP>K`4)8cWU zW(cj{n;kkQQ)T$Z3e-hRM`#7@ZXXQixzd*V^)Vvys*ijFKL7Jfa56=SO)aRfKzGFah99(wA(#E zm*{o2VtM@`_q*=uAuhGH1zu_}1J#fl`veq5>n0@+v@UZJkQGHmUfC^do!8If_phYw zq-_h^+1WH zB)fPxt)oh}v;->s@U4P7zgQImqbgR{#S(o|J3deRJ)+#yw1SyZ#V};U6!eW0<{ra# zhIWjm+&l7R3ukv1nk_6u@&o4VI6M`X@zg3(z2FmBc|x)|?LSr8DS0;1?uE_t+%~Ll1j;1fjX*jmLyZ z-|!M=E1%Sc-y+TV%XJuasrSZOwK)T0Y_|@=+q(a7J6mBF2Lo*vQq-M?|Hspe-7;8U zeZxrBj(aK^@{uEnv(2GSfffbp3iwG!<~&Gn(rzz`KPpiHn8Uh)@%|%vb>9q$lv;d|DEG(I#A!`r>7(P8w;#H`H>1J)^Xaia{d4fvyswx(s~0*0cj}ZL?v}q z*;P_iQBiU-gFQ|Z_jmuMnH|F^!8hc}KD|L3&ug#_A?8(bd;@o&$mE?=2jmPD1?Tp2 zoFV1kWLH~&1-A()V{qNUD4kC}QINE}+}w<@0vmVmAoQ2QQI8O$X&(r^*oud~n1MAm z3Ia$9TzmV#AR4cywq0VFBk4@;4SeTj=UBB*pn;784=1fTBBcJ%%h)Y1a}M zX~nXJtpn0byex=<%OrClfhfav0liX*(o`yI==xwB_zV@K^XTD&lu0lh{KGYy!yBca zrN>znDYZj2`P?Hu^L|vUw@#6xzr*1?MamE9jM9Vgp39~+@$8*?7V0;KO0=Tv=>ikU zDX4k)Np{#x;gfY~P;y*xGXaty04~dSPW5<1pEJ5Xg(F!SBH?H`qI-hve7$vv?5{qE z=ii66=+K`2ukYSJlUN3tz%suQKI-2X6avkpi~{*7BSjT?$`nETaoV9=MFk7j;MYRZ zBEhi4xKFQ)1AK7#F(6-;ntdw*0x$f!_siScF+`g-R19Yg3ify5*j{uJcp=?4y7O}F z{lG1@LFK#dql%`z;Q)jAfl@p=9Ev<*%tM%ep5y3`4Er9EZ>B-)qiyb z2;h0}kpAM>a3r+6>9E{0V}W3_PT_zy#-qJ3LPqa_VHa)Wae{OWr5}x8dI=N7>cQEk zq^MrJnA*gy7RZ-)(exj6KoPNT70f9<8GH5NCaGD>pDmRV>Lx0?!vZM;Lut**PQ4A8Pk9~7M37Wi50Lraj9G(L|lG{9fK{m2GJ z$ z_r-EkC#0XhjeNHZY@-OR-agQ2k`-BmBWZ^G~`EB+y5&A~A`34fwwljlA=^jLiy;2m`zsy*)7 z)^FdFbU}8jUJdhPYf&yF|Ik}dxe1WVldVDplb(|D7yi~DawtPo1h`Ic`+)66yq8CT`n;2=>#Nb^1 zN0_eKpnnCy+`#{i@@&zvRjhawD3>&{_aBX4fOmqDg-qj+4>+DIDGSU+TROXNjOzQB zjzpeGcfJ%OioYkyhGWdlVjf#Q1| zXe$Ecn<+3#Uvf#na21sSrKth54Vjl|h%TZ%YSUo@D&FM`l!JEyxMidGuW%OlbdbaB z_#*SuN}*)qb9Sb#epy2$K3T4BvuUg8d3$TRynb1qV3Pd2GmO_+;xr*K{;}K@D0qY} zz~*XrXEHcsQ4ey+je&buz`f`)62dy6`FLGIT=6B@r_;z7EKSrIxitFdj7TvCN!Umd zmVyl{<7knXf~Y^7F6%kwz{k*S{tNexdtD+E-VwM|_7L_@j}Y2NDZ~7TW7Ec1?)4s3 zp(6ftLOXkkY0MRW^)gasrmQCHfZYnCXg0g@(^@YRt&`ksAnSA#@n-X< zT04<%nSiabpc+y%8-liA8t0w?%Ng^ZlqIJO$fMaXopQr`czYrA0p6HNtCssA+C17X z!#{o_eokE1fx#u=#950`nKLtjpnpN_s;8r+*f>J_Yofz9QiIsaM` zDHpArmFzXUL@X`p1P>S)#)uizv~+yj?H1RU5jMW%_BXzgwqgg&uMKLNn%@;1h{rK|ao> zYOvVUm@q^Au|-n$JjhHkYVY};DhLS+L=r5O9V936Vm8VzTpTFt^&ZG0DvRc@;?i;m znW&`fZTqs77)lj}0xhX1%K^&7S9E?ErOP%yJ9F4QQ_N51{T4eX-`^^+Pk3M1Z@o&D zp(Ql=30SS$lyl8U-9Uq23th8oPGd)H%YWSA$AuMQNh-on0o^(EpGXofe7~ySM{p|= z?82+r!W#4tx0zO(mnN1=t=uT_-5-*=bb4~nPrn15;wWRnsPSDg9OI?n8s(=v?Y&7< zauzG35>3vlGo4reeH?677G!g%%3sVWB0>i4@45;-gGvO8tIKpqNhANmnp3d?23iMl@SyZeKL>ft+}KMkiP4^ zMVSs9iCEy$9ZatpxHyS3YEcJ{h80J*6;qbNm7r`IOiyV@2A)pE>(7I49h?%|1I-@_ zTry^?j{HP)JP`dS77EPi-V%=YrlOyIRO*?T$YjoX`w%ke3x!om;g^0%i=IV?V{5CT zgTUb+k@Y_EZm%tJzk@#Do-+c$h*A9WVR1@cof&^E-{TJI<>A=4I6wD@*SwjvF|oRd z4R0HujS;-#Hc74P$l`mLWhV+lpUucOgH7$OY%XTWbRqMT#+R#f5*&5fZeq-~o-aO( zHs<*yTicN-WhZe)(_N`{K{e4)TgivqrxPQpU@R7!pFtWx zT?IX}4A`5-sqS2I1LAvBo5`&4xGjBUR;xE!uwubnrv#{rGlGn?c%=t!&kw%mCBi`G zxJY3B3nvuh1I_z}fR2ttU+2GKon^L180He5k7Oc#w>2fe9VtqW&^!Rbak_pR){dPS z3BsvP;PDCar6On2SdYF%oO>;Yj#m+1m^dtW4|h>*jG|JeR;$c>-kJx}62*RasgwX* zF?#f86k?Icq_Dsl;R3^V7U)>Wb#v7jU4D9QC2bycbbC<;ZS)~Ot!;(9&l-cuBBKbz zucrYopXk*2BQfp;CD9A?r^q;ntyeQq!t|U43-t+xN}#R*Q$3wSt=bwqbeaxI6;XXOlIrGZ_*J#{ zYDE0<=)y7XMeAj?L_!MIWutN$M1@02Lr%Gd{Z#4Yra(&L){+(vaid#HyOXXpVn#Ka z_z}6h;F{3b05y-cKy3D>G01Y36CTaF9i@35`6s6QIEx9iImR;xxi7qyzkp3A^~lG> zNoy0_PsKBVdgI_3dOt^3>5nJc6PVIeIs_w`{+lEd8m~fQ=9%c0^Y6%&%5euvK3{5ugmp4x_1jbWEQ_~<7uy7g#n2{EbVekM3 zEsXzM!Q1ZGuFxXvu0Xrt$vo3I?w*4d(WpPa`ZTau$_YY@} zfND}r852{R=oO~YR`t*2)=L-JYoW~han^d?JwbGlr3i=4qGDc!N~JQZ721rziUs3# zygB6PiPB124(}|^Bak2q7EMeo$u6zJNJ=vUhHq>!d&HO%Jm^DHTSaatAINjy-G2F& z+$jt9G2>&qnjcV25B-_tN67Zm*7xD_iMDa2OD`RFtS8z9D4Wp;t7umaPE{SOhF_}w z7cGIx_$j)VNMrp`^-(cepICBw6KVld;)xSf&54SxQKt}QK2~ET^YMOW+|igdCP#jL zaDL?#QwsE{Ktt{?I=MiH;52@?YMdB*b|wcJZSjH&B!5VM^jUTwVLp{QG*Q2KtH=uU zl!xDvxC0j~xs+GfE5SeN@i}vORYzgw{%>3xTf;*zi0j}R;?taf{aB5>3CTMVI~Fft zAkJMJdKRvxW)fr)hKpi`YZSv3yk{EQxsY%q2?ES0&qOJTE z=sk{+ZmocPbU*gV=;U73^hONhw?}4Fe?FP$kiS-JaW3L=_sylKlc|#1DpjmtgSQvf zqewWwy!JysK+VM0mL4&$5d?9s5uRijG`&nGIyIZqXfj!^wv(vUXLGv;d3v_H@&L}L zd2`uyj$`}pqoQ$=#_^NO(umYNMuccsLE{9KAH?a5y>c&m5DQ;>inL8S#|z|^6!5Aq)o2P z*6tCbu=*F(JAKQ)s#^J#*9*Z-w99+fQ0LsFfqO2vr1HG2vFnaQQhqP;zfL#kdz`wf zoEY}!NBv)V)vtzha>GPl%Da1N^Qdb`ma`$fM^@w)63F}H;qWF=BB}j z7xTRfpKN-s-%hQW|9U^Z4Eq!4PY_c1?HM0ELcsUC^LfwB60Oj0yvwcJEj;jL1jpYE z|4m3R4#J*!rTjfb;5V8!mz}SjFpQ}L^=eCj0-NwNO}OS~J-_Gb&Sqhtqm;nYUTCat zYw|6(wFX!+O1OnRzt==OKI?XC@43<#s{@{<=U8`_V}}%}`RNxJru()e66+#%*Lbz3 z3QAVlxu6C2!GC<#7p)zKym-xwpCBKzAA#Msd^7*IBC?4(dfPtr9@YL(r!pwvoTD<# zbI`>-*#+--JIUkNTeD)oiV+j;Td?4|xwX4uIKh09Ayc-~i}UXP1(j8=Sp1)sZU5m_ z{=Z)WVf}CH?0=!V2n{pefBocl2K@Ec@GT7j0L0K3NFj!C5D>vDV1j{=fpGv%kPwpK zVqjok0ctv-e*dT1|A7tvZx?;c92`vl86y$;Uq0!zHa4RZvNm_PwABr_8QgK$L?Jft!Pm8dA>!+9>yR$Clx?Uy!nJ6!FX+Pj;j zZr?j^a**NO-Pc_DJxK57@Ydhfzpa09@eHk{?>%_ZQK{7@kB;rVrnQJ;6{dtx(q>Pt zMP5-UKxhaw!p5XV8|pV3l5Jdt@bpMp7@=+R>&H&@Pkt94^a&yK;+ju>*wIjmYm9JS&#zWw6Sllt?|hygjCM$>Qae zL_|fZNb>OToXxa$?WNPYq`!sR#>QDEGbkh_bTWqbbek4+kqFitdKHt_P8^dIEKMS4 zbco>7L8RCvmZd6%C?gfdR~{zWw@CvN6{RA@>LL;y_Mj?du!>T`B$pixl|n^ODN}p; z?Q9E%)$z)cY9co2VwI&xo6RIiq$*XADwRg)b9l8&;~dhdiOj;CjZ>OUR|O|G(mb1e z)ImXJwGP^+$qj1byQQj=LZ(oY7%Hhqq{>`=-7Um70i8r`B4YOOvVu=ojldX_Gh{uG zoFhDkwTFp}AP+=6kfkHvAoPtm9{?MZG-PWCfg)jt)rcY>$l4GIMJN#EL=YE5U=XE; z5g$T=6c8grR>Ov}y~~i7XvepZD2IO^g*?7I;m1N^KbFl3W#eXmx9s2XA5*`LkM$>z z0ErtSoXLew@II&q7ta=n?P1QhGA$`(Cnw#N6;Q_GSU94QsDM)n)$UcOmS zr{_$WoSofEqK&l;ao;m*?89(#u`mW$eg?&#Cd$^{5wR$uZNpxs=S*~|uMO_GErKDs z6Z4Dd-{m^X1dzLooOtcTD9xm%R^6hwP#9QE#3dEk1egX=UHylW+hqf#jbA8dSVtf6 zaMx>>SkZuVT~TSu`?)B+;|KUW*FBG57*j922Y%1;0-I*}1Ux5T#-Lso#DK4l-M-5u zK#_-%08~?P5J8$RQVYG`-u(B1%TSneAkVuXA7p#R%v7w}43!gQLUMTheO#Rtl4zg^ z`~}T#^C%ipWE361EkjqP6VFOZz{uS0LStzOO5POI&|^K~@rj}yav6rk_Rez0yT|^p z4sQ&zlb85UBKskv{@8Vx!kVohw;5!`@(vFXS?U>k#@;25o zDuv3R?IzB*)|WOT?>o2kUo{W@l%BNIRiJi$W%(w4d5}}((w;fU2UrqB(31MQ>s(8= ziHEP+6*Jn8%E&OPAmY8nU;Mg$8fbSTDgYuf+yHclt+r_txQW|GR@}A60m~(Lfo%X!#Q%;U zHyFcQYG4+AF(@xrPK4-u`6&kN2`7tm0QRi?+%`|YNCu9YIEhg%gG9}mS4+M!bS}VT zb)>fWmP66ie_#adix2Ha_~&Vla^m#9jf|FF4_%`!Zb3TUC*ugy+Qf# zB&A)vNswN>;?yZ<%Yp?X_U8c}HX|WAGF&YK|92uva zAdub11Qj8L*5=c>%zQ$XctT?B5r>UK!u>0eTJ4Jvr2coo&@A z>#*o~?0ee$WHIrv{#18k-g?Sv*0P=B;Fj+BqG^RQkk({ZL}q)|H7yIOs10}`pi&~j zW>ae3d&cUot?Lq-R_GyOCY8pehND?aF$bVB%W+5W?pNlq+YG>h7wgY z-V)gKj4+hl0-u=+2i=^xtfP@TppeYOTn!DQprfOq+XH@#exv-d^j4>fYeFGkA6N5g zLOid|hOT~beJGvn^g8beF>Fe|RFOs6{IP z_#1d=IZ#Z?5?<3*FfD5ulnDQE{Mmcm!iU~{+)&M;6$XtbQ`u_tXumRD|gSo+#m z=orIlQ^)Tpswkh9MTy+)>Cq^8-j+J%u_)dA?g0>w%ZaweXQmta_$OH-`20;UvXyLh z-eU@E3@mXA8J`(-W)m!0L!a6}$H)UQ-D2=b(}XF7Oa#cX2d3)0BW7?=MNAz8dTLlq zRkuhg7YDqehLnF$kL3iJqz9tnf$KH#JicRp{Gb`ZR?pjuc9X}CNSn!r2{Up}0H4sD zWZ%6XB#k?>2&b(ieE8`>hR@54bunK?)d7HINUQAEbF*v#%?Y1$s!aR1eJznV&z4qQ z_+L&#-~+V2sDqfp5MUld61g}522?U+PPzzvt3A9e!*!`Z@>S*1_`)M5f8wQibw?|b zA&3AsXe>fvUSr{fp;H69svf@V*l<~8DvWD2u|9C}IYu?~%RMp}JOmL^_|Z+>%lkGK zjF-N^3;gTr3!5tW7jO>Qd>qJ0>>kW#GGVbAoMR~0Be+T7v~Gjhm;KeypL~Z537chSK-0j^7a5#@er|bx>t^^CCuz=^^oP)c3T=ZFMhC@A@9c-*D;lI-TD0 zJ3~mc)rpXt4w|0iY5p0eLA(}yBf=L+8uWc z9{qDd4@A}qk9AEAL!o9`Ph*IvAu|$2WxL-xsEYi}r|Q!F8H`bW5yF&j<5YppxJwWY ztwnG@{e|3l+T}50%-5oddI~FduG-is7&@aW2L^ss^%RQ|ZK=yE7Z|;Owx0`tE3R`K z^#(Y!N~@F>p<+db&@3sOaruP{q^%3L+&(pS6oiGe_^Z8{@i`nLJC^w0IInTGZFE;k z!&5la7+QdhkAn#(kLP934(@75la}gdOVockUUS}9GQEd)>D!}l0ADdq%_p8&MlGQ@ z;+Pcz3+xkNa1?h&75#FP*C9)i6bkv1^AP zQ}LfWicAs+bLCbso$f5oBUkOd9U6U=9k$#MmRqh31-o^11qFOzaUqddVBL^P1w}&& zT05$6M(`O*bc^G+mpcQ9Y`Uz4Udgc7F*+js28n!SAU*mM@zj3(PW>IN)lUbxm+K)! z2{qI*w=G(xZCI_;wB-2b!NG-TqyI8>#HanzeCT5@{&|Ieh#fsVTE@~^QQ1)o{Lbp4 zK&o+QJA+MCLS}t=|UUUNNeciDqmi$W zuwzYHRY?JMJyp~9*QkNJN7I`5Pn>AX2Ik>JuMw&%@-B;up_7mWr-E9$Rh+vYOrU|8 z7J>#T1~%`rZ2-V3qDlYRauz3D)Xfo}eP=q{e9;aE8%W^jiC}X)bZ}TPSRrs?uxD3x z6n?y)Omp_b-G3$@WzLVPr~d(hZkRW3ws(=%D(tKU(#MO3h?0$s zQD1OR#GR#>=;@YQ>y!p5oep~^xR`;;+Z!e+`q@<*zwnbsL#zv)bwTd}A zTG8qJoN|A=g*UC{p$h^_9KYJOt(B8kxHDz7OE1=5{;F(pVG9 z98D$oCNX(?)bvO+Ot${#IT`x_(hsn+n)Sy*tbQl7q$f(kD;%wgIkP9{2IG2h9W~)< z0n)Gk#j83<%gm%NZ|jH$@3=ZDS_yt0JZe(*MP^D@*EMlKPCTvVZs2uf!)+qpw^ks#qJAUCu&_CI_-KJgq-gB}eEhO4ahnAu z4zP`JS2>;Mq}_>KXDZe6oF8&%)pDL7dZ$ z_IE=!mn191{{;Omz*7MR)xMOvLs~?~K*Y}~5SNCs9!Xh`R`NyXtnmG~BqX7C>nk5e z&<=G3CTqsd?_inm+~db=dCC;pv;MqhUz8}pC>TIj=*P#mxUNF3M;*2mV2`}Gxw$yA z7HGE8n-&wkrAP>{FXZbZGApRZ#4!bs4PZ5sC1r3Ft1p4Qwl3uI&{#^*U&MuPO$xKDgF&&tSRi_ zm-dsNkBH=dFz+%l{D-af|2_g>`fp*P|L+JOfd$ovm9+Rraia3(J4g_^D~$D#+$&f5=HPB_tb}Kxm8iWc1aj==H^G%Uh|4_`VSEZCCzTaY2ld zP6d$wMFnUl5D*BVKvDt%dVnONi^|))wYFXyQBv0HNLP3A+`d}eO7~p&f7deuR+@Kq zoZXz5CVrfp?|yE7cD`Z(kRura1@70gTCHKdhOnk;jzdbpbiw-5M&(S)J4*sUF{B|i zxMF;T#>JvBDgkEFp~OpyyzL9*{h5E76?tHXKsu2>yzfXb2z`^j&>9s#S^DS6e8K*m zECiy#i5@m$K>C9Fk|pT5Gm{JxEY!*@T-0ts8@nDpKJJ`?5et{BUe!3?n3!-r{P+^` zvLx!2s+(q8pWe{Ys+%iNCtb8gzHkM@Zm%je$9QfLDowm%vJ@uEt=p8*o}o(4RLh1@ zE9Rt2lv}fyX_+yYEbEj{mMTxmR>f>l%`aqHK#PsiYc%xb%C(x;K4;Y`m9ke`fP`eR zRjag!9WnCZqnt2OCC8GvERm5L%PGNDW+H$1m6q`RM|KWorB0>QYxnak7`4x5f+6P? zHjTG(IUn|yz63@%uBq6Np~aILHaC8(6a6E18DEjwP^3o|8&=k}u2pGpx8f)nXv@Z8 zG~yDb2;F4|%I-H%3_sRc1634gIuP45Flc?G-%BMZlp^}j$s@uaT)qoTno2wdk0Hw- zRgrH)un&^PdjppNa3Dl-@d#sVbmOP%&2c_`+PfhHI*%{Iv@Jf{%6BzuY+YEqxvO@K z1FCm)y)FMdM`0I`ekl%*zH1Z_oD4>F>z+|*$pIdc8ZS*G*){yciP=vW%GR0F$q@bb0o1hqsCG$moyUNTX zmZc5QFsI;En3sk-c&U|P4@Dc`WGb?5J{&orX4k>`xEv%$=fCy;aowed!4C@x2vChD z|D)Bhrv=frxl6&6XlZ!|%T2K!$UHJ~?eApoE(4q}7#+HxcGqckp*zK0XqCZDwNN_zQH%^dfI z^-^{empkWj`X~pa*JHvD-vJEJnxY~`I)A{1CGb-yE z3%ixPecUQyMOBmP3Gl&J@KSAUGHAWiUETRBveWxPE&k`a3{9a?dY2(uW(1e>>+-Qe zD86|Y^~ww`MJ=G{@>O@|xIOToUOOu5DNd0Ub;VBpBBY%fJDT@6@$^y-s+3r!jZ?T2 z6e0Ydg1F1`>u-18cZv6bW{vVoq*Pj#43MCfka~Dq!LzZfEv~|*(p4W%)Ypx!9KYhM zSt2uNKH$`x$s6jX2KYM;!@9H{9R1?P~SMcoQPQEt~|z3>%y*X2_b8 zmI}$sKJKPOe&QI|1#eEB3pEOP)(R?btXiJI_bA5)WJFN`@S#)iP}vO|ok$!&A|QP< zK|DaXL~{MYP8G^mb+BF#wnX6FLDpB-MH6-c4cLEOre*blcu4 z<-MTVaG00V>zL4!D8$$tB&L17pjcEoK|@KT6!x@vDsc0@07vyYxyrIP-k%WQNnQM;~ep9s?NRLtC8 z-q-ZjD*z@5r`%WHjV2wIzJsl-%~|F~Ox^!2G1yqD?Mte)XYnEY=sUM-mtUb>Z$eqT zgq5@NIElx3n+Jl?Z6x07_m9rg?~sl~4KyE&5PQB=MYEzjD?BP4q+8g=4@P{h_BT@xHF5@K^&|+IF8Z7wlCsXObC4Iusw9hJ$Z#Vm9%0HulyW2;sSVu#**wtY*1%`Hg z!(B=SE!mVIk+_TB)ID`^!vpR1Wh9v)&su+9WGX_)JM}!-ASiF|*Fngq;<~U-Fy)$I zZ5;aaGK9-I<#0<2P)DWx?DhpAt?Kj`Ng>(FoUbE*2LxfhEm<( z_!AZ0e={U@ankrgwWIUHz;wzG~JO0YC3b0|f>_`m>z@ zE=d3n6B58q2nlh33qqoV@SwV`bw6UE#x1RZzvE`!cGbr0+P<`LE3@VN!qMza+~n%M z>TEvSd)EKU`OCTY`?H6Gh=v;*DN@AA?RIOTdQGp4r0m*cWNJ6umYqLGzfTeXjv*iI zK^CP?af&Y5O+s{U(9LnCpG46jM+7Hbl)tX*7bWD}2WUiH%lJq!Are?cH0gb|C zCMq>~)gSR}oe?WJ?WSpmXg!ZciJ3_izmYe5En~E(5p1B!B&~^>Osqa0^@PcmKaqfM z@T}D-HicrL(W~|KL_#K9xXc8mraTN`AKRlrw>0^L(Mu&?XXpaO*=(!t1=gIZdXa%U zsnaP%ZH|PDDMp>n43#U_%f_i$PA_4^3Oex-6wlV_F)5jilbPP(s;(t=7`H5|y|~y; zauLHtmcPQ_>69y@StI+2A5b1{S##P@gMqy1W5d}7q#bViXLpp%=+2P4QFk4W2ADg9 zk}*|7K+eLsffEs?m=XMyJyGVFVG{2p&?EHy$pX3$tR2A_lKjD9)aPBUh8W~7RD{7y zXgWW{P49&%e|x0F3-dxUK(So<3Q#$yp9H&-zW!k;Ty}%|UV338Zujre>z3uH~BB_rq1 zPgX7|S%3{92LDOQ?!JSAVRg+f(+oLcGhfh_5J^pSzE#>(y{f83Cj(=#%I$ma?ROet zI2dhD&kn%nOQX|?yq6{Lvvivn$3Wo?Q1r*Jm7OasCkXSPfb+xTLyLQRES_Vkb<>Jf zHR#vWEh)EQeUXjL+1e8yhNF06a66eq9CX`+`R5!*)d9#U|nLEJLIpW-TemStuHEg?ZK|Y zH@@eUKb%1$=fLgacF|DEh7Nj#HJ|dHQc2LoStcI9ZSMjII8+zPB`2NEb`9*jW*~jsZ_OuWqce=qP{Tf=~I*wv4Jjg3^+K zc}^-{SXo$JS3oYlYYZ{nLc3}C@>8>{CuhNi&VI#dN;s61EDNS1X)fHDg10KQ{2Jg| zR@%b0DSN6~hTNw$l?Ckuf6tKbY=76`x%h7U=KZNpb7l);CFWD+>MMBmJ>iIX{g zrNKZZ{iIEa3D$d92s@hQYpVQl{}ud7Funf5iX7F!vZ~5DLNbgkp_B%Lzi2OwQAZ1>VH5UoAsK1kxxGzh^Tsy|8225;SBbLwUT zoUZ}x)l6}Um15xkDeOF>;o!DDuD1vwTC_3IJEKSMy#yJ(Gop7UMh_-LiB3fCqxUXE z@1sYQ7(^FgL`(4I-cR>=@3Wr!?X11dI$!pe|9|hZe_KKsUiw%ja1Xkr_U;*@X9Gz% zHYAYlU@!+#Q+gxu?3^e$P)wXk$h+bGh-1OGMg@@1@S=t2VZ||ryOQ%RxbguEmL_>g%{X)*_)uzNb;)DViVNo$VMe=vJ3GF)uc@k z-rLcwc$YkHACCb{;q%$UGs{BP4HwW&(>sCC+wzES8u6lW%_Xo-Waji zcXWh)g!WXi*CI-Ja`SR2Yb&Rars3XdW#7N6z<0Y#sE2w^|T-huqI zdu|@TyEScfc4{lqnQ3%g+{5SYIEZ+{U%K_GyFAuGx)wZ$fnfzsDNQxs(Kkp?t~nJ@ zAND3$Ft+iw8~lpxVX`(qIC(r6)Dmc={g#f2VVW-AO=e-7l-rQ!fDvM2uVXvMmBAwg zZy!W^#Enx1NII=-zf6%MAOn4w`gX64msB|lzp-oX`mmITrFh?74W6vBtRixfcKQgl z3Z>OKM7cuitA+s4TPTFd6qQl`vh9^akThWS2kPf>SJv7@B`T<;9PDxtHz|k?lg_Y< z9&ht*KNm*DmU8K?UnVySZo`LmsAxn*r7r7r6 zQ&5$VE>}EuZl*}`yCig9`ITRgg`0>SA}TwD?z0?zg=l~+)6X3plH%pn3QQ`3j>9Jz z!1oOF+5U^Fg<^U)(iAI#WB9QrhB4vfk}tgTw{_BJIhqYh@HGHRF9Qj_$%H}j{fk<# zzxg9pF0;K?gFU^gkKrYN_R zZf2;#31PmZ|8(PZ02=`1uasGNNm$`Rm+R#X`Ma@sI*0 z*K+Knrvd<`bvf5md%f{;<-cwpRB% zEXXN!CLX@+>`vFX2oRJVIHoZC_64WCXw<~zJJ$IsXk2y!`JaAOX|hyXWUJwkhU*!l zl-`}gSO?3YW8*i(zW%j+*TDvL;(-~I;eerJ_@y7eX;SZ|*bLsovv|IKbb8#EufaWq zOSw1IT8^RBcL`hL7XfBzE?TG_NH^M^Nqx_Dv}!g?>A?j@Ne>ul|s3m$>r;`A5MlW zvafj^!*nH2lr?-BJa+9nzE3W-Foy)aBTR`{%w}VdB(8QYyZ_M}M+&kr_#Wt!r#TsX zF3@(|?BVj_#)r5Kr_B zKtL@4fVa}ifM0UC`E9;CK>XO0Gb_GJsa5%)*8Chf`XkpqP_iPOJ+BPlC^k2KIK2#D zk02bRXbdIBn_=+vf98%znFGueXHld-sE)i1ek3T}SwTe_LBC=*v|RNhDl>0!4gqaM zu!@nad_4y_`UU*xJaN%FGPs<-g@gJUkk3*=x@DYSM-#5 zm#||$ z)g&@-7Et$kIt>0Ju_@*=abgqQDB<)-`4!JVm6Jf(e%6Aogub^$kpi<;txHp!NIkc7 z_xVVTs;{gD31#}A!obsnh8Zr0l4I?HLC18W(BaiDJdQKu>d?;h+IX+^3lxG^+e`&5 zKg+=h4G`E|6S&rCVz%o6jqxb}@S#hISR=;m@vFzmZPDKhJ>$1Dh=A_8IPP zB>Rid1|4O1U@7`q1oGzhQouB$^!08^8UNwoX~bJpf1pfBPi;@t`-7VxFB7=KFXtBL zbSoW3t;4s@dQwHTltNWvy9PY7jXUEQ?(Xh83nILzxE5`J5YuY5@#Tk$hBtc}52p54 zw8X((B`2*b<5&Lon|;pYqSzBix*AXEZA;49u>DqI^1cQ?blZE2?!+9%psqm4Y|)cb z;|}XXVD+hDl+dIeGQc!`3vYKeA=ZZ{pmFr|;6m4!v6m>oY9?CMbJF_uK}*hMof_Z4 z3%^9a&;+;JHIJ>LC{cMPk-R?;z=2t+OCjqfXMxs}7+6kW?dW7(QP5S})sn5gZc=oi z5%vE21k}gUTZ2wzn8inv31sKk2MHXTj~eS;(9_?ib0Xvy-G;XQhMRZE8f_W~rPv+~ z`U;#1R1>`->sfZCy==I2+GpOhD`vxnrSp2O`T#@QM5EEp07nnq(0yPyll$)0w^nMR zTdSdT{k?nHy9h%qZ<(2~%e081KMRaNHR7DgEIW@=C}L!ol37COa*+3OKO;Y7Nhxr0 z{u+)Q{7Uv#(vrvVBqZ=^Q!MP2DgVJqC1rCZCHjSFABlSrC2&BdS}!jiOmpa>jCSRa z@NZ7OL&39e_3QDAH&gW0>z9mT*TJ#U3Y>)KVWKFsq{itm_qX56DRX(2&DOcXU)_Ed z+^>D1B6751r(lOEpjs%2oM8%m7Wy1S3gJGQ_i96)v6{6qzk3f-z?u<#J;uM&jm2dZ zcz#s_swvwmDW~ru!MQT9Q}lSeCv(zQd2aI~XXRVolvodTO6sNt$qM53u_q)8me1BE z`G4zb3lKhqC8NB}K*L9_mu9kHkiu$`R@uruma6^b{NK1G!T)cUjP)HL{OU?(Qepx^ zcH%aow!#ATLiQ5k4tC;#HV%RikeIlQI0#}7k@?>@Eco?3Jba1%RfX2)S9gbaFoFJk zG;j)ZU=kD*<2N!B{1XCM{DU0>{dJ;%71<7Y{hS7ViXI||$-u6Z-Y6aYIs;y8GmaZ!Q1-Bsy)0jx|&Dp=f+**d#H2Y{&#A9d~Lja Wq23M0J literal 0 HcmV?d00001 diff --git a/kevin_cheatsheet_fixed.md b/kevin_cheatsheet_fixed.md new file mode 100644 index 0000000..a4a9501 --- /dev/null +++ b/kevin_cheatsheet_fixed.md @@ -0,0 +1,218 @@ +# Ansible Tutorial | NIC.CZ + +## Vypracoval: Matěj Kevin Nechodom + +--- + +## Basics + +### ClusterSSH +- napsané v PERL +- nejde verzovat +- 4 terminály = 4 servery; příkazy se píší do jednoho terminálu a paralelně se odesílají na ostatní servery + +### Vlastní balíčky +- IsMedia posinst + +### CFEngine +- zastaralé +- napsané v C +- low-level + +### Puppet, Chef, Salt +- pull/push model +- server obsahuje konfiguraci, kterou si klienti stahují +- podle intervalu (defaultně 30 min) se konfigurace refreshuje +- Puppet a Chef jsou napsané v Ruby, což znamená, že každý klient potřebuje Ruby interpret + +### Ansible +- YAML => Python (2.7/3.5+) => SSH => Python (2.4) + +## Instalace + +```bash +apt install python3-venv python3-pip +python3 -m venv .muj_venv +source .muj_venv/bin/activate +pip3 install ansible +``` + +```bash +ansible-inventory --list +``` +- vypíše seznam všech strojů a jejich konfiguraci + +```bash +ansible 1-ubuntu -m 'command' +``` +- posílá příkaz na různé stroje + +```bash +ansible "vm:!1_ubuntu" -m 'command' +``` +- posílá příkaz na různé stroje + +## Playbooky + +```bash +ansible-playbook play-1.yml +``` +- spustí playbook `play-1.yml` + +```bash +ansible hosts -m setup > /dev/null +``` +- vypíše všechny informace o všech strojích (lze použít i pro jeden stroj) + +```bash +ansible-playbook play-3.yml --check +``` +- pouze ověřuje konfiguraci bez aplikace změn + +```bash +ansible-playbook play-3.yml --check --limit server +``` +- kontrola konfigurace na vybraných serverech + +```bash +ansible-playbook play-3.yml --check --diff +``` +- zobrazí rozdíly v konfiguraci + +```yml +check_mode: no +``` +- vypne `check_mode` + +> **Poznámka:** Použití shellu není ideální, protože neumožňuje ověřit úspěšné dokončení operace. Raději používej moduly Ansible. + +## Handlery + +- Handler se spustí pouze v případě změny + +```yml +- name: Install webserver + hosts: 1-ubuntu + handlers: + - name: Reload apache + systemd: + name: "apache2" + state: "reloaded" +``` +- Volání handleru se provádí pomocí `notify: nazev` + +## Tagy + +- Možnost přeskakovat a filtrovat kroky v playbooku + +```yml + - name: Set hostname on homepage 2 + template: + src: ./index.html.j2 + dest: /var/www/html/index8.html + notify: Reload apache + tags: + - configure + - index8 +``` + +## Role + +- Strukturovaný proces, lepší přehlednost souborů +- `ansible-galaxy role init nazev` vytvoří novou roli + +```txt +roles/ +└── webserver_apache + ├── handlers + │ └── main.yml + ├── tasks + │ └── main.yml + └── templates + └── index.html.j2 +``` + +- Playbook volající roli `webserver_apache`: + +```yml +- name: Install webserver - Apache2 + hosts: 1-ubuntu + roles: + - webserver_apache + #- monitoring_apache +``` + +- **Ansible Galaxy** nabízí komunitní role s dokumentací: [Ansible Galaxy](https://galaxy.ansible.com/ui/standalone/roles/) + +## Kolekce + +- V roce 2020 došlo k rozdělení Ansiblu na komunitní a nekomunitní verze +- Komunitní kolekce jsou dostupné např. zde: [Panos Collection](https://galaxy.ansible.com/ui/repo/published/paloaltonetworks/panos/) + +## Pluginy + +- Rozšiřují funkcionalitu Ansiblu +- Typy pluginů: + - **Callback plugin** – zavolán po dokončení playbooku (např. výstup do e-mailu) + - **Connection plugin** – způsob připojení (`ssh`, `local`, `chroot`, `docker`) + - **Inventory plugin** – dynamické inventáře (`aws`, `nmap`, `virtualbox`) + - **Shell plugin** – umožňuje spouštění shell příkazů + +## Přibalené nástroje + +- **Vault** – bezpečné uchování hesel +- **Galaxy** – sdílení rolí +- **Lint** – statická analýza kódu +- **Inventory** – parser inventáře + +## Příkazy + +- Spuštění pouze sekce s konkrétním tagem: + ```bash + ansible-playbook playbook.yml --tags nazev_tagu + ``` +- Přeskočení sekce s tagem: + ```bash + ansible-playbook playbook.yml --skip-tags nazev_tagu + ``` +- Vytvoření nové role: + ```bash + ansible-galaxy role init nazev + ``` +- Zobrazení dokumentace: + ```bash + ansible doc + ``` +- Generování konfigurace: + ```bash + ansible config + ``` +- Komunitní verze pluginů: + ```bash + ansible-community + ``` +- SSH příkaz na všechny stroje: + ```bash + ansible-console-all + ``` +- Šifrování hesel pomocí AES256: + ```bash + ansible-vault edit host_vars/1-ubuntu.yml + ``` + +## Externí nástroje + +- **Molecule** – testování ansible playbooků + +## Poznámky + +- Modul `raw` používá pouze SSH – není nutné mít Python na cílovém serveru +- Některé služby (např. nginx) mají vlastní validátory: + ```yml + validate: nginx -t + ``` +- **Vagrant** umožňuje testování playbooků ve virtualizovaném prostředí +- [Multiline v YAML](https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-in-yaml-over-multiple-lines) +- [Výpis všech serverů a jejich dat](https://github.com/fboender/ansible-cmdb) +- [ShellCheck](https://www.shellcheck.net/) – kontrola shell skriptů +