From 10575c0aae89ff703bcb00d1f3536968f3f69582 Mon Sep 17 00:00:00 2001 From: Rajeev Kallur Date: Fri, 17 Feb 2023 15:07:21 +0530 Subject: [PATCH 001/159] Add files via upload --- examples/ilo5.zip | Bin 0 -> 2952999 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/ilo5.zip diff --git a/examples/ilo5.zip b/examples/ilo5.zip new file mode 100644 index 0000000000000000000000000000000000000000..7755775c29c7a7d4e39ef89c209c4d5d6b1f18f3 GIT binary patch literal 2952999 zcmb?@1z44B)-~PIDc#-O-JR0X-QC?Gozf*K(%m6Qw{%De(y4&_2lXA%nR&;V??2b2 z9JtPXA9&VY_uhN$^&AChP%s#vhX=8*l-jo^KmLOPe04B3GBI~FqgMdD3Kj4@)VEiW zPfeJe0={bn1_FBc>0hrhGuAgUc5tM#aJ03tj^(xOW-gwaFxpMObD@Gk-aHB#F#zi${I5HOq)oodGS1P<# zEk7Rk39pZ*@Zcu=EqpEPb0iD{D8yp37k#{bTS_0G4_!(GaB)MDD`nWLqv0!Y7CPIM zX)bbJCKigHRs+8%h+8XKCvoOFy6{d~cM$q$*L@n5^hTcuMVUFi=j>U$M!b3>_xGXn);uHP@loVf>A*T%?z{T!Q~m4k<^r$FA}TYW8*H~6T^O|7 zR?PA*2l2h|Vn#cDy+$6{h+uetYxD3A`O!5pw=pty`*wxOwzrgkKnj_JNvXj}@A9S- zYlk=B?wEwVNp)Xq0zK^Z9hav8zv2S>Xg3$eZ_s>yA<1t5qW$_p5^G~8eItD*{YPj% zEP=xD3Pc4U2@V1TMELKP`~vN`tZg>|CggET_^Q7hotD;W@>7KV`orqR-hQ{^fW-O& zRH(kT{-bs!9k!*$6P}J8XkWfi&~e;GIVMd1{fbH&&Xh`qJuN&pnPkRupSowMDyS6& z44Mu@K_b1g+N8lby$qBzC6uaAj+dv9SX6LQU~!x%g@s#?%J)QPuZzLeDMz8|%Z^r` z@-_|p}snAraEm;XSd6CUb@`#8+ zy?779<|4-DbY^)zSFg#u$6ngyV#;rhN*IzQ>G7*Yh^=76$6}3093>BU9tA|kUbanf zTsp{j1V~ZMvh3mGY<`|FJGuVKbGKd?f&7{8=B_uJy3UIqQ-mkcTaF|F(n~Ud52FS+ zCX6Uh1im`H{i@9(F#qfL7?H=v4x&BQwtOOMv^{SWD-`AN-4}!I{F=orJUMVXPJ)|y zxNtU;)9MnHoX@75$K{z9f|f$sWV+qZ6pyGi6q-l~c~4kJuOJi(I^c`mPIa#O;X_>9 zw!GtdBHS*eqCqO5fy;{a>=lf6kIHj!gO4i4;;ltB<;r|r1#ISqb+Qa7Jj38x9|YOG zg61>%80iFQUji3JrzHi~ttN8_O%FGH@l2BqVA#SQR=*FSU;(FN$vojG(uZ_j1ZodW zK3a<^8XCui4G)ktc>1c)G@>?yxQI@g+(pc76h{7K@N>cgYP@)_P`#HIWPZskskCCl z1JTNCW#-rov1JvdJs)$itM2K1+wPOPpz_s~z1YZ^mY?^iphqRANuGG&Jz)qn)rdR5 zStvldnXiv$t|sAEA4bg=Kye8fcc{-PD?FU1o74DWkanonHfD^Imr5x@~1BcvTMctXmKW8aGFmB(sbY4O%s2 zzUdt<@M~h)h1w)7y}Age&X}Seo5mrNdK}xaUO^m(9n17ixpW7iq1~!xCJC#Qhb2*RrGiyPZ zeQs5+cYq8t!r*Q!rClz`Z!{b*xv%d7`cO=w9TingH8i`51~d`4@fiqMs>$F^GK>z9NT1lR3eg?s*yH{oj$p*;12 z%}7E+^8x+Kk;cs*13+Dw!41l(>6g=epQH)H7IBcC>BSCe6zg(z*7v&Xvgi#HDyy(Q zC%u{^dy6xD%4|}qlSs>XnprE!4v9@T?u~N>uFsZ+o|Bx-sN5JA-EuGr1hsPm19>nx zIAj8)LSHD8f}|JEnQv^YwAA%3anA4pOg|7@s*Jy5M=sBqd=Uk_BU{xuKpx5UIGN0P z3?Oj~-A09vj>%PA2v%r8Clj zu4OTMj(FSpmW7+TO`UXBa*o&xt7m<$xVvi4rsyCtxU&0@Fq90=sr;n4=M6RJ&NBi#x=sIgl0R+X+D)4M{xAdT5;oZXkmkE)ufL4$vfLH(y|MK z+;!iiijzh+-!hpP} zQ^BfED-ETlZAHlExLQ0mncSwRFarH7z$c)Cu(12#FF8N)Nw~CjTil6iN^fnXrkuqs z70h=jXr+58&a_W49VG$VWrf4=?qd37@S1YdecDxO-)F5p8>71Kq3Af;ytPmBZpZ+; zo-W+43wWmKVWwR1D$xaAIf@Jo<~WUv=#J%_BNd-B7N6s%vR6e| zSltMMiaC94zV0{^7e#^gF|~+%jdLkyD7IMyw2iAX_zZ+YS~Yg|wb<58UF7?et*CIK ztqodBG_=ZL%65^?>l;un-a-rF+|Uu>Z1RYbSDz65-vmWu%%fj9lo8E)6#7z?J^yOn z!)CH980RePp=|hh=aV#Y_49k+pCuis|F0$8(_hOjK|@1ZXB#JFV+R*=L*qvk9_eot z9`WC<`>~DV-)unoXB&L4GQZb155Gf$u5_~kpk$N)l#Gmjy2axX(m1ZmrkepS=CJ85gfnk%8n@5#N!5+Rs5(u4R^ml&A~nH9T9E6CD1ldokv zWW74B-XGRA8#RYfi6K^HvaYm6f4IraVcu)E$$(+PNY&h&S4JckI%-oMf{pCJRW~aD zK^WI!FydAa9^FEc?HT<%Ne)vj2$xP>73}8uy0w|c#Q6M4Vte1oxS5)t1miR`#Z!Wm zs!j))c76jGdvNWk?14NYrsiR5l`qX;(L|DmyWs|*Fh!A?R8=T$;;(yRUnjD3a9dss z3idO+H;I2Wiq<}DnPU61_jrH@(^K>y1ptpII1mv1pThIAF-c0$u?=8A4LM4=#)n!g zL^2MSZcVQyjlV`4sK-W`>_mDgxW5p<9C`0en}Agc*N;X!=I%Z=_iU#>Hs-SgF^K|w zfk@{o2JsMc#xS;2+X^qeRp zM+((lRo$c%>JZCM-PXA(G@fh5E6+sG$6M&}NR%izXpahk?&CN5O$WwqcfwcD6l<7+ zw;PZ#B@PpI7vnbPc{XX2ocaZtLB(Zu*eUkC@OUZDtpq;K=ASASc`o<0TuR^2hD(#|`_La|{72 zUiyW_kbVKx+8OtP5aSAtl${3U6b@Z!b*%`r_7ZOW02XtlC0nopusCxn?J_`j*VR=HTmyF;>qB7=XX03JySBMhfcdiHFqJgVJ)GKPaI+5|idRX8&skI*3v zsx^AB1_h6x#82xBiiV1q*t6hhsnwJm#e$D0ysDqnyPPznNiRXN2M$bx=cLkCGd~ME zBtl1RXrBf;hE`rITzo_L`yu-P&vHtKUn+pbOn=T|X8K1gR?z~m7}J~mgdee9oLIL$ z^^^Ii^@K>DUVU3?ECgQ_R_$wAj+*1uIU=)SE=>7a-ko!=hOaExA-BWgd&K?=c%&fh z!JqX~(LsHqKle*D&su|lPMA)x|cd*DTfo28_fl$Dc7`p18Hqqe=gugBr`aivlQ zH`x2GS=$DhrV9^M+UCN!^t~-05o$@!9kgUx9+J%mlUJFp;q_?wQz}BbSzz1Zq~@L# zrFuDp4>%?taIyrQ&UOeXJK1phdA$tsJS&LD^O@Q>j(z zrIQtgv-Wk)PJ*KMv62EAcL^RLEIA}J`tx26M8(|mMk_z6uB|NCFq~sE5Ub~7L3;@v z1Fpj&QQcVAm@~a}yK-`9C%9__r5x4AJ7Vt|RVrQi@I-qu;?6&+6O6hhmY5UUW9}{H zKOq9i|Y*!6A5Ig1Q9`JLnQvtge#y&LFa{H|gEANn0j2o)c$h&uRqU z?TqA2W5;T#I`=D;%G)YLYi^Q0mDe(Al2EF=fJ|p-2jx;UtBZ#h6K&d`p$vvvf(eG7 z2SrVkwEqIBAs~Iw1Qc487aPF*>XbjKn{b`G=*jzuiS6^MqD&?&a|2q<0+d)xHWIjQ zI_Mt34(?r^*!fl)9;x|R%9XpiIbW!5AA0yX-6!s7jjjU;m4rjV^PgY6$WCm*RX0e2 zz#q?MHqsh59GyWr5Rr6Wt~tQrM+k@DeAj75%NA=rT6d38XeqWT@KTGR%|!uJX=Hpe z$2>^e7=*gV%e9x+h}BNiw_AGXcsI`uefRpAHJB0b}@$y!EA5Y?=-8j zy;@l{ALYF&TNOTVL|5Dk+EsGSG}nogC;ub{S{qg5XnJhQLtG2SgQ6|1h#dthBRf_E zwj;obvP6I;5GXkUe^2m4+tAypQ?J0>LM&Xd318}%F^@D3=G>?fmZ!SbF^^l8W*+D> zUId}AKL(s4VvuVO!}0hAX&tJfRK3{Ap-slkD}9_O1K$to1I!iqTn|YZctr-Y*WQ)f>d(6I0hd7Z9BEqsE&~ARlIg#|*_+SNr~Sd*vDCy8FQ63FL$F` zfoOQH1Ocb9oC2aBavq={E_mF1(JT3K^aM3_-Y>rllS|t_Mrq_oz_9JwZ+4bCy>~p> z(@yNX+G-HPIqN%}dWo<{LX6N%0B55r6a|RnxnXoXrN|TPfoMHnE6pcJO zdtW48lER~$uv)$31IrXKYm0HuC2AN9EC;GU<7u(*)hwDYRaWPAFz^Hy7)U4cgHj?u9p96bhCEY%326q*7E~{&f!*gk2B&Ml?s~Ve_s+Z z|1Er?ZcfGyHu_dSIz$BrTNm?($;~&Oejg_M&UTLfZ9^FmL508BRrLR`tFW160lxG4pEq*f@LTD7w8EiKm)m}D$Ugh&)3b)ay&anTUaWk}87GqrK_rG1VwvQ4L1 zxzTHXFF=?JzNP?^Ptx!vHg!SwWxNm&s|-wJA`lu`1}>oH4eHuf@$ZvRwHFIlb;s9? zfX)L~d^&ut=fGoSzSGN+9&A8&>S+c{3F9G%58mZAj(t&4{gIrw`;cC0j11Hww z!;)c}iGJEGVjd?hFPO}%<0ifuxxai#!lvX8*$pd*m8|s=QEHT4dPSo}9;Lufo_SoQ z3bp!t`iqyU7TGnRbuDu6owEcEClcDpu_GxSPBmMa+#rw|&|HJKCrOzeTvs)w-5sK> z)pPd|rbnG`V9=RUs=`HK-z0l+qA7Xi$>kex$rNb*j+8bN*6Yw^^tU5ON%nYV5P(=6 z06qEtU&#GDpE6^(VFBk;kZ0GuT}E=evWS;T2uUXWn>PxPXVnwIB;+Zq6dS%*$TS8} zP&S<0HzT7p%LXpj+M)3U`A$-H~X=vR)V}1aUb( zRb9C;(dumiI_mY05uX}lNWF&Cb=6l#a7~(QNUYa$P$3B5_Lnrijbj(v!3-Ge?RI6) zJC#%upZWj;ep`vmXY_8ZZkh%Z!%_{b`W>1jht^=h@U6a{}q>~F8yFF`yZ_|WHno8#rK%Y?3Nvt>v_<>A$vfz0!` zQEn09zK^eOPVGD5i=e}P-7xp{>&X88vyRYoo7{my!)&W z5Q9V;rjkSMnfW19&PB@UWtyZ3v8$g+ERpTnlenGFuEMLhxt}d3B}Jg;(|cQLs+R1~ z!SmnVM9&b?N2P@Da3WV{lyq}8$}P28iyP3AaCBz+DOK%oLAdLo+Q?*&8It6t8|4%m zQ5t=$a@?=}nDmfEnO-cu6oe#+w@V7_MS4YK*lL}C?x`y@>u-6>TwQ>Lr8{e)vUdv| zQNzxDTa>OTQEz-J_4)&5Wx;rd@AiucIU@#1YC-A!DEYgUkB=I+2Q(B^nrX%W zNaO-0wIqLw#?QdqQk$?@U_kY*?B&m~iV2HV3#^wn6sRlx7y&bdHw)c#0!~B9R{aE2 z_Vd+z7j*PKV!eetvwZJWmZ#UziKGwfXu5?vK9(4A9kCdxRiW$hxfi^fT<_#6*w-5{ zl1bpBFN(dhDsq0d5?}|X&ns2MlqF%GT#Wdh26T-SueR;+y1Sruxioz!c4z>})OVZ* zt3jxdLn~Y?m+C8Wr%?$rAIL^Lk39Fb@$gGB0u}BijE_2Ua0;}k?$5A>g5YC)TOChR zdNW+74U$A66wja;;taMq@EqJO0(n=NM@;C}2*;C_y5@bO&7?EV;v#2I2r**Y&XseXz-K+c%z3+<5VF#ztm@u)0bv{(X(nzYUS<|~ zBL;L8{d^2Kmv8UqP$4==(=1^Ka8Tt{ug$2P2jA}{A3KZRDa8o~BO~FOjpOi;`MK3* z_$3C>G39;4Hga}efp1Ppt8T_vZlItxQnWYYm0K?2A&hAvXUTpBqX!sYjXrbX$8wg? ztb{>s7>uxYhrGq&KyiJOusi=G)?cC*gTS)lIdWgmGskmP#ryN_%Ce#@@sDN9)W9nQ z$d#OMgkmj}l6oLg$m&;wyEx$p^9H##vrZ*+Bk_IBJs9HMedMXk%A&%Hxx%UW&NP-* z??lWSnC3dMoR8o49Jmg%^qM)_sVrZ3hAiyalvrS!*S2E!rlhm)`zU9WsMa9K8Ll5uTpabcETO6gT>?V>_N;F{1tT#v% zLL1i-!RhunsU)s{*-pX2|4YW3SShm@KZAqjmHdt28h+N^O!QTb8akVkSvMob+k=Kp zzBwSa(aCRz`u94596$&F2mbLO06cp%4*yN+R&nSV zuAdY%C)>?AY7ry{mBEp`;6S7NFk;8Te+)8-zO$S&d;*G)kQPFoJk=gPhFD2F{j6PfBo%maYt69AgOFE+mi z$*(Z~JW0J3hva$~5L=(^@r#5Q&eRgvuZd{FtL#Zf`+8QB_OQGT7&)dtk<3hx`mfY(XQ+* z_EVFej-?wUM1s;F>gv_?;jv;rw9l;hGq7V>Fmkx3JY6W9x}f<%X%MOo!CM2ZZY0fj8{?Co$6+EO z*Vz>?U0$;^L62Fy_YoW_9LC5|&;^;>MzJcGfq=S>IyVXA}eo$?)je=vEl z7BsOpB7U&o+i`UR`Ln8cpe^gTCGi7UI01;z`~g{hp+}tJLwg>)DtnDEl0_K^3=PlN zRka=n@d16yKjn3cp>v_mLI7dN{UH|v*Qdp{EAEk|9Uo^Kg}V&nR1Uso6u^URIPE#zi zQgs*&539T8(l+E<2&v~Am=|AY2^2+kaZusGldw>tWi>yELTkWkf5;w)=VEFtEeH4J z3qYqCtK5}{(}A6GrbSz1vKIvu6&)1jKDKPBd6~m{$qtgzJ8;=t?5`ft;{gmSQZ}Il z00`~?FsS|jjGu(4i)||fVMGk}>~dAlE5sB5uWR0aUPx!ApNrl!SnR)SBq^rY>&mV{ zze|S>Ggm^E;MmSQSf~x79fwbgS0IE_xr+-mF#g|wK4*N3k`^Lthn?y|NI zYASsYScf!4!qIYuUh_hiNqMOY-VBNjQDn@U;gU@i8s94_12~}ERfn21p{-{z+AL)U zufp8*gc8_7hRWqOl*KOk!t_ZMrpxbP=lY4}qg6-sIfG%_GC4HE}z6 zoCO1}cZ8>RYc81Ac$z%qnIeg?nUbxXT9ytwa!Yo*HWl#h2CXccU2(BnGH9a{jvL$7 zp2(JjUBHK}VK5LT&2N$76{49HRH^}eVU6QlXsv)DbQ?vc&|KM~~D4zU~?Dn?Na zJrf(9(gR#}fxZz^>3PScY~Ur17vE}XN6AY-P2Co2_4Ybxsh3e#`dfAo@{H@^r~sp_ zVCK8<{5|{$x!gdYyq|7XhF{KSuXomn^C(bhyg*Tcdrou6yKX7L z%!2R3d{HT__tCG66^+3q1=BebeIV2NgRQ6=J2ZLMff4l=)S|md!FYuV4v1wvkalY8 z+hP#fG^f?kRkTJB>nM}vmU-D0^X(f5@~@qk!)OK6(NEB01FPO^Q6Kt)Zx#3M?i!0x z^|a0+3ddzWGf`115U4_`xb@k+f+CwxXN-4nw?lHLhp3$!u~2hCip_muLOIKdQ&32A z6_}MyL_rT<6%zlxNU5I-XD0kEBHdDhM>yg%zA;aJ++S)=&rd#woC#+%zfq@C!<{qx zF2Da$-Uwb?#MahkdIbX>vcvZ$w|-ZG{)Agf04K1#jg|YO^6Oz6KQ!8||At%t*ydMm zJ+!Tu5Nj>r_khYv)Q%2&loVbOL5n5O3a>Ts^slz{{(IY+ykp(o?&Zu~tUJpSMT@WF zGBQ{|)AwqNJ=>}liX70klG(p`^NF8|fCUl<>UAMS^frjHjRdfQzEX7$ ze}TVcc?=q+SZS$IVrt@9E*L&xI!cK^%oSIUYsII;T{7l`VKE#05duNoRcwN>vry30 zHt~nb3(ByX6;OE@x(DiE@+@Dnt3~oK>tdd+Nk}jkIqa-)Dc;rNhS&bAygoolQoQ|9 zd0G9V@=COu+HVk`fqsT1f#X1>)cRZ414mUSbLO&xh0DTrKyE$`;{b!zkKqX<#>dOY;qLhw7Dfpz1w$=kb`_gn(@ML;H zQ5cQItH9euPg-45HbnO89qMdifn_LdX}ojiT%Rp4J#Hq5M#8CC)4LU3?b)M^IeQAJ zh^{y^?P%C@vKI%jmWm#5Vo~D1@ZmS}&fgngR2_{S9x0Ww`gV5aHm2Wr@k40+ZM(lm z;NNWb*q}oO*f78nbXWxdrySt8rGvAC#iL)s$=8r&%R_zUZNj(1O#D z(b5Dj5!w?S;^3_$wRDCzT=7*?p17_a9vp3EW!=oU3&?7mQB-+3?b9XXl=i;bdY)xf z8x~L!T{OWYMKts^FgOU^Pxv99bv1QP4=*IH;S`$$V1L(&PVgT{C(nu*HSOF-!AP|u z49zE2OQ7VRh2!)>oc17bH`0VGEt&^ogg}(HVNSfQ{RrOMHfX!7pfC)%nmGc{?tsSx z`t0&PX;6dJVA6fMIsY@E+5SjqG!}Y8&H^PIcDMo4H0)XWqI<6y@0i4pOC=#9q>_b_ zvoxt^qwND$1xmHp0$(qJAWJsB6Wj<>j$`yWk%dUJc8|P9a$LyzU-ut*c;eF-AB!bOvHwdIjJvrZm2OLrX@wHi4-c6i< zgxSZ;GVr_{?{GvxXvla+7a8l?gyzBYly2Io6-^ecXoSG@?1@4+`lc4J6D-UwQ%Snm zEf#_1a`f|3ooZ#@F9tf0Ee6SGXcUOe&CMifcROE0ynEqbX7SU=H-+((t<*divb1}v z$}ke1TVW=buiz6UoQD?svUqm-TA(sS3#&WVc2Q;O&{W9}tkbdm>0eZ<$nrJvPNy8x% z^gAUVuAZR;>1{>CW|Am$MP$xHe5-CZU?-vp3Jpyh(k++S0umxSViHXwNCic;h!6Y& zKu;~?(A1+;RVg`YsE&lCagcNw3cI2Z$X*48uo-RVrBSUTcSsk-#_KlBk+*$)bHj0- zJz$l_f~weEuXb{1oxzYH)t$W*jO`A^NL_7n65SdsPAI+lICGbuscGH7^&LX z#FLZe$3)bSr9W8ug7uDx2)jxI$yt8cyX~S%j0uX<+ZS0>^|pG=hlR*m{;r!`FFuyVZ(sR+4f|va z@u4=+Ye#$CvBmi-#G}Loz$-y5PGABM0$%}`{ZFKM?3V$M2IkvHC*X)+BA=xqFN{1; z74?=g%nga8z*6UpwZvRr*pZF0NL84d{h&T!k5`Rjg__0ZH-g9#@h_wd0+_3OqU}Mu z@TNe=cviyv3ecv>pW4-@ zMm7z@o2g)4*Y@G)SsV}@nm5|ZJ0O$8xxzq2(gb=@z#!!S3maZ?z)DF8rqEOHMgm$v zzkB{OzL5Z?6&)b3RnSZm)swDX7h)1>A_4+ip6qR4h>O&)Ec3HrQU93j*t~Is7K%^s zcV8JWbNZUiy^>=CRa@OXU)^tp-mUN~aX&HY15Ce6zfZq*IwSY3#F4Q}IziWIsrAZ6 zf|T5m$v}+NZFqaqRpK^p@tO?}I-+7h_(lbk`;-PIr9afj;`*;WQ}|LqDUNrqTDg1FhV2u2(0Nf*P zBpEo#Bb6V%7p6I<5uuqTG7-1cb497n&j`C;Hd38dLFbxba6fBj=TxB{M!TO3Cz)5^ zBEKeIG1OLMk) zt9-JF3vTi;R)c8nM_3h)t>{FTW8#_di2bv<`uDZJrIdfM_R)`IYyopW0r11Q9faxXa} zDV#x^N}A===QgIGnnYXr@JoQs zspDfaV4A0=D;lUAh9Y|fm`N6Z@GkFztZFTAPGpiLTlt9zqY8(#=I#)W!P?w)p8eu_ z8AmwE+NkQVr!g9IGmeFPCZx-t+8i49vbNjbb4sa#)r_Vk?00sZuu0JTx9f1xatktacC0>UKn zpOeTVIQ|x)pG^C&d|x}$dGW)w!<)VFD%oBHX=&Nd%0p!pBq3*va)3V)81`HkCgMcn zj$|y!L>VTIs~Q*OXhj>j*jXrQm^hU3G0rBbpce#0bsw%V^|%GP5#JtOf^maaBBxAm zY~~Gv#1f=yg3I*zgg2Ems-8H^fIPZK@gXwDj-w|ZOjx{t$ox%E{1<=suR-|OdPR8? zNX7xMUiJKm^(y&?^-AN1_39jT1buXE%uUV=+KsL;Igbq!F!sojg&y^{AZrw)@`Ff7 z$Neh!w6Xuod%rG;sp%->dFU+Mr@Vk51fj>wC4jOO z*GJ6RlD44COSFpKSYGCE)xE`xzCG!$iZ$)04qR$MJ`E_DM9stc}V9~`VlMvz^5mX#x8mP&?I4ix7KE{@C4&OA{)exY9eg-aqV^8JK&s|o# zbOz(_An(4PWMgZ!kkQ`rg8Fw+c(g4)F1N`rVj)NkkaxedJ?_CD(D=$o%H<3|V;&3$ z=r?2Czd++>z$GOBghl~CsZZhssl@vfW<4*f7(6--$o$R`QF!)1fo%SeZ4sO_q0941GhSlL1aff$P=Ly$Bg zNe>yLjnJv30(BqC^%q1;5UL$ihwI19tgkM#d|En|w_n|he~?fx&w~`=A+UJZJ`@DbW=_+$B49ehbDG-2it<#hweg zDk&dL2Y2-Zmo|-ctqw`oLbY#+-#CaJ0pO%yN{5vh(S82?q#z^}h?eY2_kBoL*_I67 z6$8p09cVt`Z;C;-(~Bd|dD00TviM;!Lk!VaqOl9IftS~Z)7frj7xCxF`aTlsQx8EQ&;%)3%WtLt@TbH#qDSX|L15gV1 zx#Bn98)As%P$3#6P`)VqhD%eatM5FvtU-

ABn#vZSVteb)_jngY}XRT1}Qw`6L4Nkp;<+c_Lzo2W7n0EW-GirI*9g z7q|XL+)W}W?g@(c>|aRw1H(Bwo7x(8tXHyw>I}1=2j_n<^mX90M+C9>(vwA4Za(vs zJtt{-aiXleuy&*$CfRb>m6`Qy>9N4^UsIRqk=FjOxI&}aIy7(6gJMn|U zE)UPugOK?tYL|^UWmrrYV}wwU*mW~EZl|T8eJ8iia!E3XaXt-T46AFMUv@?m;)J>>oTxQf=-y|+F6xpfSW*c_Q{D78fAs?-FYFuinE}*&usHlj>M}i| zuD7Dr!!+H8e4U?WM!XOtoQyA=fjAsF-rb#$(3o2S)N=6SydC4M>zs9UIf%E#&9Yp_ z*IF&z_V<*32r02)fIAH~u-B>lX{^L1D?t@?aN+~i6tcLyiud?QrZfz)+{ zgXc5LLf1V%KFKIokaf^;i3$g)8Fhbn6cL5#R@&GId_*Z#7KU|DHOI>>mwSveqL~Gb z?WuK+_q&GM_? zbed^;X^B8O$w~KwjH0-t#Lh%%14N>4KI%*2bU!ds8|%yJRO>ekm$s$s4O%zPf9B}_ znn{mk!H312etzu_ZsI>mg1g=qmSmZ|^AVtE9?I+QLBm;+1C90mcB zU_}n^UoN4+A1)z~Z!RI@2bWOW>mM#5DZi%)5x8H!xrEBQ7?kGFez=67CISF1q1HLh z_9LTLA`NM2Mr^0rEP<#`mi%KNeAZSV+GDmWCCQOUjVzImM*B}&_1&)4cx}t!-Sz*G z1xLFc=D^(FvmlK{m>`~j+;#9PB-5F!nGG zj`lT4W?}9bS{Rnf^cA#E-gySl%U}1XD8mlcM?D{O#`%zh`sHe>6=@+HuHT&0%slg? z#MSZ3BkAt}lYWBD{)c**22d~mM=Jdy^C?No1GJF#m)H2|dq^&n(h{2_L@;sB0ww~V zD%A(F=(iMPibAhKc-kwI-qdDr zSqC{l+^uQ~Z8%One)T4vPCb~JcI!@P-qh&QqC>ggV&uz{7SC6r$*6q+6`bs1PhZZ5 zS5{@_LCr~r8HvZK%|O3Y`6@FT9eHqo+*k(ZfQAm!)c_VgYtq4s>(j!g@9^`JslIy5MD$sxwRvP1&5<2^rh8ieW$meq2m%HTYOMc78=U#jAV*NV0ANp` zms`cElf>T1K_k$QQC6a+_m1whPbHDR(Fid``QMzGd<|C3xJZ8z`L#-?P(_+Ag?_yp~HT$7&w-~ zg9p&#OH*p#4Bm=2l+LH21z$VeZWjltby-aazSQ7(&Y8(?A!i2ht$Ag5C`q#_e&jWr zoZbSxnQwV*j1*JsU9}!ya(t5umQ9e31juXhTzxTWE`m-8(4_l0S)oGj^V{d}bG~+7 z;oWv2(mpq&M(W+vLq0kj{TLlE(Z~<)`a)C}bL@$`11Slma+=n~Qn3%-k ztf1pg1pUG6)+5971E2x&J^fDsWVHR0yvFi4uPJB&#>S{V7`F)V2llC|A!}J=a`OV* zxh<_w@oaCg>Wj8E3*^M^Zx(9HYFjobIajy503RyUCTRa&mIyptKhZ1z!C(%wA8AuA zjdzU42M;tn-p(Zjkl27%go=nTT~gH2I#PTe zNt(a6fB&(EV|~P!hsE0L^M!w02(tdhm|yM?05>*)*g+=F`Lz%P5T+$2ZzyE{psvIB z?8_H`+GwIN!~hukmMvtutA>9s1YvgkquI`ks;WQnTL_u~yAl4QhkN$8hm*UHg?L@X zH>ZbLvLB&npfn1Q93#vG0g@y49*#WMyx%Sxilj+?ZX}V!!~m|l+2-fN_gDR9pVOTH zJ=`VP$>Ap&dZ_$e`;CJi*=z9o(ARvocVrQsWL78ubV*|dF_6a}ZmpLBP9}d$8E}Vy z@%QZ29-28;HGYt8F77VVbN?A%olE2sS}v2+i!3Sq4#AxLy&uXT`{zcb-zqsv}D!9j66xk z_ety*7=NK8c`bJvYcH*TOLIP*&OPfA00yo<K0KaHqc<_W2DYT6V8n8=dDyiuv%d7BxMQC za&THJV>i4~_wR#yg2`kex&?iWxUfH0H}k!It6LcYg`&_aB!$+RS}L3y&#vGWC>5!4 z+H>UX#;*)RTG5d_5P=_$T&?Zv;Gkx_q~#n}FdlRvW9s{c7n{hmqfD5-@O zz<6FTvfTwc`OLUt9O&V$orjO#!)bu*;CJU~Pk*99Yl=tqBF09wjhPbW@p}V4L0KLKLSjXPo!Y(Zp<^0 zxWZ8T7lp=`nl_|s?0+XER4)Ye!^dIF{z(>NdrZnWKz9Z(7Ou+PB8=?ipOc{<4<NPq;cMOdl!=6d%|!a7Tc_$_#k{x| ziZo6b2)A6s5`f!$;dWB!r{Knf#h7`=-@<(*ZL~jaRWzbeGgnR9GL>FKMe0_k?+L0; zAv7}Xu&Pi~O0;mqkfalZ`V!VK_nvc}z*22tYs-9n+l@fdo+9>*SRVvY;tk3o%H$1L z_z{IL(sg*w0DW0KG3CUov&C|yV|dARQ}^A{!Wv|*&9^;OV-$A&rx4})v~iA`QpPc+ z$N6ZDsFI2En^O}dY!LK|Mf@MB?rm8lBR&jhZR3rIO_i?BIW1EFV;v6^QeElIMyFfr z+8Hx_N|8K81gS4vNpJIsa$00N5H!42GXO&kPExsn(po4eO<9lQnV3)3!B5uO6wQ)M z4#odJ@QnR8o=M792mUe7*#C)V0MFB3cgKlNaP~FzQtatRlEsb$rYPY}`qP?IM{3+2 z=I>Uodw3okt+uxN)M*uK&b~vSMOZHNFiqasm^$4f#;&-V?-pCs;CQYD5JAXUz3t@5LfGrdR}#>35qUpjbryRxEbqivfzoObscMd|eD$LLr;E z1LB4wXZ+T$h!wg$V%-RXT_h`+ZLE0BfhT6ijSWvXgHMKI$;E{-7?QY*$Dm6aa3yns z!5|xJ=m>x`0<;ANDVzYw4~2v<|!jNq$9pj;AdQi7_nlCTG! zeGE56WM6{^@T}Y|2i!B75T7OlG2B~6AIcd&)DK7h`PksuR z4+m%2C4Kn=CK!K`{MaA!OzFW?joR_@8aH`wf`JgKd(g;&fGS?*gdimGf-qW3T6Z-h z=y>_yJ*Eu>uk+2Fx2;xo7RTiqY+8;J&721jk%{eLsRTmX%FL28%dgkjNwniY7%)9xeo76QBFl-jy z6AZ^BaQ&vWhB?*4K5>+WcOHtgms20Eos;^huJvgbikPRESzC2O93z7mr07b82I<GgaH*~t&(}oX2>JGH$Q!WL6cVr z(rYU&P{Od2e!Y%fq{YXG7 z-C_Nefc9<^*Rlf=&{aSJnktnHNI-Au!n@B6iM5sj31|qG{Xy`D%Wjw0XG@JWciZ{Y z>(lW?<3kgGl!pcdJVhcQzpuu7Zyx5yYRgT^Az0E;+cwMOeO7Lv*x8Lx3k7E40{DWW z&kWI5Ll1gVh0V`wUZd}-A;wZi3MM9S5$54e0W0Z`V}|6yg%IhlVYNJ)i<2Lkq&i6V zcxMsqcmi%f?a6e&4Oo`Ua5DH3qYa@>-f*tTUQw#eQF=Ngj;el^<>0iUdv=1(qih2?=$U^`A{%S?D!|MygN{~rozJq0!y7_FR^9O;Va=-KB5@U zCsLj~(_d7%^Rm-#^?@I25o9z1oP#dr86U?>v6MY!!7aI9JcmeVjoL@Y>2sg^--q$$ zI6bbYZ|xQen9^fu#tesdE1y1YXKU-O9%55SaKOX_{*VFTAb z7G!mb&wUQwX(4wVFt#M?EO0fH<1Hy9;FJ%>%Xy@(Z1|4AtRc7dlN9C7C$py$S80!H zKND!{#^Bk;`ZJtF{7?TyzkODRehci0+DP5|Z6EdEM%q~e|NZ3|@AAq5s4rxRHtiGK zpygOX?}oZNm!Q*1sxpgCEg;C8u>y#aH z5lmw~JeB>Pg2**Gct41X|5Gj2-aecH$4qa{>ottX{+d?vgISiHdm83HOEy{I#O`ONnVHMe(_1MAeN(cA+mjV$guuDqhzy@~EK#%6bxo(5^6 z*z}T3XYfu_vFZ^VucY=(L?;VSdfU_)QO-Tnz0X~UE3%~6S)NKt8-DS5R<~I1Vy{`4 zX16=3aj)d#!JVoEX{J6s?e>*D{gpg6uct5vtgC7ht5~1Znf422k&s76JphXvqWuDV z^UK|k+6(k~L~(xtcb?A!o2GX%Sy$VNZE6MFy+o_}O&#$eM~EYyD^#~=PEAToKazJ3 zGwc@mUeNi;YuMIz5S=e}_K2`-8(yZ=%sbEyaEYTz(f zVwk7+Br}z1+v+*W8VB+ULGhT=(|dR9ASu9lWui0b^0RRy86MQXe}YiP;pn!wH(}xJ z@^G0l1dIyOq(1lz26^mW{=s8=w?Mcg;++>nd_v);`?K=-nd;ouuU5HF*2ZO3OsKxz zftE*EI7tu{W-jv^eK_04UXL@+ruIxEoA#7R1KG)Qto57cBzt1s8)j_6&lfM9TKXe5 ziD=6cT^o#u))eh17n{9?pnYeB!L2%8z6wNbAeV&H?jGW5H{YC!t_c{Ov6A4-txA1U z=C@Bt^WqGzMQ+|Gl2dvREd^yOZ3KTXipx|->*SC$K*^FcZDQ^3@ce}oKU8+{Z`y-*tSp!e3izStENVYg=4e;aPOunA7CtqyD=8zw$na8 zd2B!Ntgi0(#9CXY;VbVaT5}vS70+$u8Z?y%4h=y!!!%{|e#=t0u!-)H?^!rN@k`9S z`s?ne^o*=-T4WqBIWhBo;Q;Ny;Ql5I@;@nf>!laahy_S+CQ0rB#V^7=_&J3rJFMNnE<{f{y z8f*Yp!xWpT%`%xGeq|d!iB#;n1qVy9467uNs{y7iWO-08C)?N1t(|b0Eoe^+7`{zr zA@N0^hf7gQORY{PceEOA*popQ^o{F&6fX3gJ0?Ky)F0{Zf8&CFeap;fXxOESqd%8Z zz7)p#5G>}E#dJ^#?Lb~OEBP?9+%Z#u4zJ89Br~>M+PM3BJ%Y0+q)a>llpOr~fwTJI zD1#TJ4fG5lmFfK10i5*rKdtV1OA)?P($@_N;HK+~_(;e+KhAzS2z4nvaZ(+CkC<0^ zu1vk@iuRVgKDXnes>I{&BlW833u@7Pe;kDOGQ}IH73txQ-)b`a$j1zAL_Kz~VB8rV zyW6c~?~@X~bRiU(J>i5+L3fysA4gMtLU(}9qcgMp_7ci_htHj+_#@Y9``Uwx$|noC zxbgDbuc;+H?$GZ>RKQGnG9Bk}l;VAW+f^0NTBO9sszgSRs>C={(+%DnglkU0A{ASV zmge#MhV8G&(hmK86DlT!pQR%b1_)2f#bWmc0`2g0ix(f50*!SIvh-kr{Y5#zocNW! zY=rIeq4i^nxW#${h;Xd2v0*O3W8+q3-a9&n3KAN zg*Dtby$?FUq~!Ho51>ccN-^fbll5%5PCK|5D$IzR>V-F}qZQHI$o&Q=#CRW3@OxyH zrK@O|&LB8=POXS`=To|6i;i#NFs~adaVIv)_eO=(D$%Gcr{-+;&9D_W>|)$07OJelq$rX(4;U&ndyudBvh7*AQ2mb!ykD1fej}(z#;7?|o;@>BCnH zOAf+a&I|GnwK>BBqY%lK%7i(e@ElvekecAFoeORwavgpCz%Tg|`|3#oYMgJN*id|E zcX+;H-2Eo{<3{bQU>rHNiM@{op(fUp&dtt`@Db?|cHYDmTJL;I)E# zQg)t8z8^;erW;bf0?;>{@`WQI2OmL}T?pXh*Tq8}^AM?i%<;ZuXkv zwWb11l9;%Iyt4A4icWq?_2=EU(Bo~)9L1uW@Ys)+`Wss5&&^Q0Q0{#`fI*rO6FSz# z3^<(dYWZrC6HTkWvq-r;6M(qE+vGIYq3KfnJT&+jMs8X`0mlGckKOyp<7kiM89j>G zCYMs>cl)7t6u1baeOBscCsU<+6$3SCjfwC{S`6-OlAu3{n^d(k3)sQ*?~=qx6kxJ~ z3&`asED7tWAhqRwH!~}IKw{?EB9Paii`hD9to9VrzbUZ4Nu(9ig~06+m3&*xQ;RYc zj02Ocb$IA5SGC5Q^%Exz$^7BTZ*-=Nv575a=U=$8-dRJ8w%iXPueFuVJEfc&D_ril zB!lA0d!|f>rQ+N@b>`~|UY`PxTsoE;-M&K#ClRYBS;k4`H zzc|$pO3uI2y>;|9uNx!7*2PA$JQDs{TrVur@%}dc0(1Ofjhb03+7p6mNq!lu(!tE} z@}^1DB*Mv-83RY(!_`Z$%naS)u?vyWz6n@qv|h)WA^v3OoeH(2E~%EOyOjDH4&y4$ z7g$h&4V7J~68>lND^jfVCeh47o=A!SD-U)#N2hx4y^Xgxb#B+rp0M8*!!#|NXZ3f1Jb6AbERJrsjhoO+5cG;Hy{ zuTL@A5gXml8;%aQHWer{P6cym?R_WfGm%oT&I@5tpZ4bK#wg?=k)YSHv?WKDJktGy z>TOO$BOYH$mpr7epK0ZmciY&!)EM-cPLQOm1=v|a3%DQEN#^g)pX}pRX|Pvfr7t69 z0;7M*(`Gk<~>2|~FmTM|v zkwf6*NJ4cGal$#7*5(xFw?c;c+!2i)hiCZMO{35{YdhUCRkU-wvz9TfmqU8px)<>F z?;05WE$A+9v;{=`!7l!2q5C(!aDFhCYnz>zgO$NA@Bj6l+wYGf9sz9VZ;YW#41aQ< zzX;4f9C6d32|DDQ`nj+yz-%4?%trC{4*8Ap{HF5Qd&Y9u&@;h)Es{a&TJ>hg&`gKW z_^9$$?P3R{gno70`6g?(U8OUFn3KecWY7cb%|A=`D8$n?-~c^gvLZT6=RiMlu%)5UVprIty zLn5IQopz5Q;l5PW@qIb+7(1#%iEU`76U7cocMe{>OV-2M5jLVBQavGUE?kogAU7z%BH$6OG&UzAXeHMQDPTYMg4rg!S z%Yy*^RD9)?ScR-QjbSJR&&#(KugYRi=gi|sJ;MSWsGkc^I$dtp)a>-Xpl6_U*&JXI z0FUsHgyeynDzkVc$k^h(V3E^*jscsFH;W)}k!dmEhj5&Ni=v||*k7xp1x#Z z8|mthSP^04m5~>s7}Rl6>M=kD595qlt<0HBbSIE~;l&X2)2u~I`6B1>sINBdmV>CSwx4_W{Z%bunqk8J=e7S~Iu2mGG`=dq`|2rt}>2dU{+6+yp&x<%~ zBJ(}tB^EgIsaE7Ucl#f@l8A9C1?nFS4FiSJKF#)|M)B?MTloZN@{>7yd>xtcNG3=v z6}1)6;k$&*S=xv(u>Hb{Kwcdg~f+ej7!ghBN<66`kJ1f^~!gqJXtG@uKpfdc@fa# z!>=(tE{|M4U#G(uov=qH*Aj=jdfHW4J6?aIBlu6)lfOMgQZ%x+2a@yGQ{uG_2s*92 z>5;-u{L}mooc7N^sDvyt{fwT;9|VM*{|yk9!Tte+I3OUDThcZCzX3wwDxQ`w2V$o?YMLr1Z>Zjz3&p*NrdO5_1ZS^}4cGRPd)NDzlgH}QZ&|gUn znY>BT82JGpOe{X<`Q?p`*GMWf>w#?WR;p0)Et@qLL0(7;LU?juki+Rc7@-yb#QEBbh3gWb6mq=oiQ^FK>heZXCEggN6%Sd(@|#; z1TRu7M!e{bld(|cbR~0qb^5viM0`Ry53@03;b=WGRju)Y<%8PzKxmCrE9YvYr6>y> zp(P}vmBX}p8hMm*XQ89C0IW17PtOBwwq$3?{tspElQPTDI=-C46A$cKGStP2;E_}t z;Ro{v8#gqebpTzaC{z};R(s&vp6m9e*Cqc9bnfh@aO=Kgip{60Cx>e5!&NBy5;}6@17HgRcrTkn8 z<-=Cd5#G~GMXV15TC-(vDyH>Hy4BB%xXxqqy)-))p~|w+#W_1=(d)`m!Kq?;?kBGi zMh756NyteiuC8(LiI`ia_%{o^l)cJ zn?Gt@0fdR%)Y+K%NKpKH-Cp+wC^glgQD zf?>dC8~8Z?^&<}a>vo9XO^pk5%A6Gr?N20By2Vre83FB+D~+0}T4C2)*ko=Lfv_6y zHC!3Oe%87jxn;SG@<`JXYUP$Q=TqC1UN{=2iEO@HP6LVhr?vn7lNnq80`^ zV?R6m457lw8z>ZChftHu7_S{+O8xIq-2<;2VG|p8{EnqyL;0Xo4+N0vNloEC92`8* z8Y7%Z13F_L`@l`yZ+rEjIF;xSe86q|2|lnC|48&h|3ZYIuyUMw_f!9R-1*QGA`N-V zrDi$d3IYGB0O3kvz`a7iF(ol4D;ROo1!|Z8VOi03=Z(m#+E}o$Q;Mo|2}A~S13@jT z6hH#QPYLW(zic{z+rZpuWW>Je#1ZB~H^Al|U76Y^UbNI-3<+ z$&DWTf<*8u?R(=v9I-Qyjo*5{97?Y<=Aw)9OD)zVu|rp zmxDvXlkrPBPV%WFISiYEq9I5^+^BfJYtcMyV}dBy?z-F`+Hrlp)NalGt!N7-QH#49 zA6(-BxJdkz;geO&FkjPMgMi~^Ixo$xbu#b~$t*l0oz`__t$3YLeAml>m?vqZJJM<$ zea#-FpV%a6o;=lQ<|>xSjO`B1lotR~Pl1yyYSgtCX?iyrpmmRi5P7E}*H#!w*VO-; zj0xt>UdhR;X)Qk2TyV$yS_QtYT(%s&S!}l`h}`!2M;6ffB4e~4*ZH|-w27ILeLUOO zeW|--#$JUcSzriAexl7f(^1a-)HfRT&dqDm#mr27WP^mav{Wj46V7EnJ>=38laZ(* zzn-Z82xvoDehtOs9ZvP#SIv!srtVgCr|89zE0*=)2Fl>{(VQt+dFCO0oI{xm0I+0R#Uv(le{MLyi zdX;d*cL*Znn)F;(`NJJsun|o0^eogK9dO42&rodUQNq?W9*}eA0uBhE66reO*bj2Y zTEYD2_#Yp?ia_qZEA_%Q%EEb@ugXThbRV432kvZoJo8yIcJ`|MttC{rVgjB&VIEH zxDieVT_iJlY6b`kDF7_g_)lEqFHo#gkqN#A#TP{%38*BJ^UFCgQ03o6B1Kr93~CXF z-J3^^?_}Fdef?dVn-nbGP%lG)5V<>W4)?q+W_e(WU7UW&99`FIL^ zlzK+?^0Vhq;JH3d5Xf>U8m>jeeD-6Xut-w@R1~{HMU36LGhO>S*C zVd1>~*p=RbA~zDw5IS-%Zu1@65^0x`DE~s zA{358weAA7Q|&831kI9Y=Nh3d?!kpFNu4t*XqD8upSolAy|l|7_Z_yk*5f^KIL0@& zLtc8?cLDkB(fcVH(rT295Zyzb2*ZpG;V!vyc%sm*H1u$G`F0LOs=a( zymWqR#yb!w7KJcf4@TM?$bqYN_?oTYdJvzwryGQajWl#y($yVBoO1|R#3DXh;8A9XxsP>3eYNcMH`Wti!|8L9!@AKWvRmfNR; zze$5C*Ml%95DprI2Z{1j|!I(Y||>+kh_{$Y-B|rA%+w z1$*?@bpfaI}J}dPl=MV?@58jT7V`bGNd_J3l~$RDny{7OZWxSZMKs9Ml>X z2#Hp?o1`A0XaUEh*cf~q<}hsP82i@myP?qs@o2j3KBhIFsUXYlQlVPZ#>y?XvZ+{2 zM?H_Kmafz{Tkz=5yExhUE13!sIA!ISrHjdqgLx;u!1@r`w;N4Q=LS&(!-Vl8`w!0_ z1zEkfKpX)fpO1@F>HuY;2xGi8C)_i`c|Rt!FW3!8ZgXL!eiisFoBk7aoF8ZuA9@}1 zPTJ6ZwaKzvMk}E7%f@h@2P2`$@Oq6@N06M20%haX7E2;6?6VSvKr~^c_)vp6Z|U^~ zN+>FTd#CiVi~ho>oBo`P@YzwlXXkW<7=HIEt0{8NMz*-DzKvSWRX(3O`l7Nz=>%&L zKqYTurP%(^$%noKnm_U>!!+u8M4&d2e1>QD<73gl*^#!-Mn`)a49%_gADNnTbCr?0 z2S-hcWr8=Kqpr8I1(;Dw#R`GBIQvqNK6ojRNn#rWAYa#$Gtbi^Eeu@OJ3WEpa}LIr z1PpF3I%nF_Drj|;U(;lS)mo(8Up*?e<18}Ugy}UV65ES~y8q4O{ZtQ`D^o@?lWVq*`?~pLx-@V_^vvEEtZjJm7}lXNOW5tpB($}xP(i+XuXR)STpKj ztQo=HjyrisN9UR;YPV9TG6pHx9rYI-93ALSkGH6K@rw@riF~(52bunk4uX!`iHLRi z34ymq2X7qrujruh|0pa>_Tt_hYy?K*6V01g7>O0sJoN0(Ey;fo2T>Z|J&q=H{$MyT z?m<8Tw?YafN+v}l)1N<}T4wZePB2G<8tFeJ4uUQc9HQ02;MVEjjf=cV2XBI6`d^^f z{YtEcFYj6%M4Rx#khwUSAcmVK^_4WZRtL?K?5y|KmS9Mu_E-;#8R%lK0J<1d;`r|Gyw$XH^>;z6#26~5k zTrDRaTO+jkY0I%o&R?B5zCk5&AY2B=aTIMGzi={Lp$p)9?|dJ45pSinMG%}FK1ROd z)Mfmf;Z5YO5cx8V8&%aR8y0^Ny+L8<94RQiPEy&{icAYqAZe^#zfC^l9NV{CY&ZcCvg%a(LP% zJ5BZLw;y`GER7NR1h68OjE3`+vG6qJjz5BfXm*3QUyM^?jUbar@x;Shpn~%!N-h)W z4_$AikBvg|N1DnS9}<3Is{i5*bMVd{?+#j3jWc)@RG=i2BHLgOTTYC2(i31r?tk70 ztW59wb4)2nCYuXE|p$Vb{6)PnU9PnP!JFqbk-XF#Cpd-m=4m4@S9D(qi`(oWX_c zZ7@?&Ol@CT)2`WI_HfWz5ZTUY_9OO;@FXCX$ z-2Y&45OjaFl9o+Iw=NFe>=-HgeGXno`!NSQg8iCyQ00}LddeGL ztWNCok-nI#7c}G4QS%`y@C%f5jtqK*7bVO>roV0VW&4~=JP&R5Nbpk69i`FF2VjHp zsA9RkatYm3Kz* zMN$3aP|?teBh>wdWxTkrr^A(ws~o&7j4dkTb0>zmBq5=LG4gxM+A=&IJkb|^@`=!e zPWJ2uc3I_9-)AyEI4nEO{ysak1uIA5)(q*AlSwNlQs%b0F^! z#xL~orQp=9T*$Y9={c zWh~PjQU+=1Kj>h#8JARy5X2dX4w8p@j-YTpN=2)AqQXZsYpvSmN6`2Y^*pYtcW%jO z2dS*a`7jbHUeYGRA~eeKQ%fyVfevCG?m58$PA7`S!C>FOnX zSIDQ3Y%JUNJx4v$syZ=m`tGNG1+?KW+JrGFMw;D9a#>*=RfjOOo?vyBNBK6&v)Bwz zhoef@V=((78q{Y<T>BV2^XhrSY=J@eMy&l$=({~S`0(%O;GYELhb;9sbCQytv=m+Bzh2F=}~R^_C}a04H0 zLyYWTjYViTWoDi?fCo4<*MN0Wv_}zG_#@4*9+Byls-J$!iPxv`uY#_xAj~TmGj;7- zU4!ZAec&arO<#m8GVZ{gVhY6(+UUDgRTdYk?nvAKpkfCRS&E(B$4*Pg*sNuNxUb8@ z>5i+Kb(No(qVLU}l&OC3_YO4=TKc@SaL9hT&vMFdwb*!tiV+p)U*i`|Vbj`FkO^PG zP5awq2ZMGdI+*$M8AZ5f-2^=}HMSBG^X^8L?S@HE#W6e&>;nXip^$tAB+^+2_ufrG zutYz-nZ8$f0eKUF%Pes>mFI|e%@IuG^tq2XUy3paf=sD=&w&CCO zMOBM!9MwE7F2bHwwd;+>zJ4F+2jh%!PN^s0EaxTb9+s2&A)JaOh3LgJ>L3Nk5or2x%m=LWh&!tXx9lb-eKIZuPcq!A9fg% zyzxG;o){bw0v4L6^@ozg?dvXF*^zm`y7+Uq7q%H@&RJ@X(U;7Pp-x~%re$Ty-#)V8 zDbtU7ID+z-!{>J7 zD~40wp#FJAzCCsDW~bGkqw($W!9U8ce&d5m^8Y&#-;P}dbbmw{GA_5z2Y)Nd`tc%Z zQt6AL65fYGlJ6uFq2Zp2XCx2hBbob3+kyqp6HOJR2E0hZkG~`PFiYveQ-1rXs)KKB zc6p}*Nt}Me98cdXS5O+N7QRO`vX3Ypm9K(5=$i{1uojU+BD(wsbx`j3gYpgwcb{0x zi}GGt)Y!H<&eiy5Q^gK3D*meA*cBdyj;dij^mzhouTCyP%bh!uE{T1<$ z93P*xM8i1*>b$Dkk>K*G!0!XpK`D?r`0=MY7(L!eq51e8GtFrugqVsX1O}liuYe*Q z{37@p)<@BPussyG0wptH{7hXzP4(TtUkGA~>p!e|dXx zNCUHox-FtaLc9Di!a>}%I{4^^ItceQShgZc>QG;jxM}^2Iy-YL>SdDsiU9nl-fUo5 z-1A9h> zU^HQ@Tg4JknTwa;oN)Yp!#NlTe5n80iU9w(JwC|%cYF|Z+&yTo+MhG=?eW1I$Ne)O zR1z?L=x}3OT=p+b)M(~DR?5RMkr^CnX~us#XI8JAGm=-%nX;eGnX6~3magjClV||v zOin0J-+t|!kp=R{oa^`a%K_)iTaa@m@y&zr)cUED$8&^L+npza7p$gK%|4rfi!BpR zo^#xLC~Pv?w8CumiIjQ_hlI3-lgd&5M{b2yC| zBK}ve=1&uK!JeG0#6O#;$7}*sL8}s%EAL?W->phO7nx!uwsZUP;EjvC$p>%BgNBel zQE>$@5B}Vl1Xu{aA-_D|4DtB~d2qL=QJFm%Bo7h;@?amFPV7|mnF|647KM=+z%)3E z$mkE*K4Fk1|C9%5(Rb6%3|Xr4t#T*q6Yuf9aptP3YmG;<8tseD+**(aju24|bOG zU(8TMRFHjrxfp}Av=W4dbEk#It+w{hMhLqgRD?b^HJ40OMusr9&2%fXv~D0`@p%#Hhp5F5m=f+Z#d#% z$y>9`Iq8ib@*tQ#szo$z%J=o-uT>)4$>(fHb_P#3YhUMY;XBwx(T7!nceFH6?NrN}L|Z;9tZDT=#IxdYil7?))fDdp6ZXgXPf+)>#gDA)Wn{ zBEUYlN+Hl)H~_3n&KrKw!9Qo@+oOXwTNOd4So5uo{Di{Wql16cFaALXdw~a&|6lrL zDDZ)0ac%(VhoM1Hl=P>|K|Cz`fP1op^>Tbi?zqYAo@_Ph(y|75=m=>Agc zXPa-I4&JP4EK`{Rc?SX4G+>kAQ)o7-m|V>c@qAsXsZ>7mY8yVr@J^I2$yCZ4>dQLE zXW+{UPfYh9gktt$43e0`E zbM|U40|s|dm_4a2Ov@9Mu;*u$xxVQi)n+rKB)ME z4>s3k46dQe31ichzdYq&c}CKn!Pj2cGFw54-!g^p`?ff+i|?*Ju8YXi*MerCLAXoZ zJb4LZlQ9Mj!Z>g~rk+3KL9tbo4x3-{pdd3Iy!cD}synj8N1>cAehk7Vh8|Tm)ei4% z)=J}o#vG?LZVbXy1~G0zQEJ!nAk=U2p!Ju$zC;HSU%;71T2 zL^^0sf6iHC1#FAgh&pH&p9fy14R5WWYKc*`V)M#TjP!n00wJHcS1c#%_gu4>>Mqy* zW$k3gSTpHdHxE3d{P7IwBOfl8Xkc3`h5hk-l!&>Y8|0Ju8VfQHRsrTgb8xa1sd_X_ zJmawoaPbWj69w7d%!7YM^lpz1viuz#1RZx118NWhEpa55D5-G-<~o$O}N4!T2c;;u+BR$3QP*a_KqqY7eVqM3LpHmH~N?1CR&x2g+x@ z&18b)!N5fc*p@S~D|s*kBoCT5{E`O~yJ>2k0rH?dAP+9%-_>V!5m`s|?u93SO$rkS zP*E5_#aREBKCQN7$bfm!6Iv2CebQRem?mfmQtKO7xJs$86JQ=(lozS*aqhG!c?zkk3+( z?-o4H#n5VPpD>zPh)VM5!9e^lssyZyr#pJC*2UcL_RGM!I3Yti#Y+=!0S-V#-BQrH zxRc&5>csyf4p_n3-e;m^u^&FJ@!Zgl8wpQy|%W zMsfy&aGm;sd$lee%v`Hj?*grh1AnZGdpV^UK0M z<1~_uce2?(ZhKJ((g#6&5Ghs$A_|c_9fa9?RU&!^7f;AUM#zgQ8ydx%v1I+NAq25AD$Uv zo~-%X_2Q2W8O5Tg!|6`LT}*1p(7!LLpMK0f)aD2U53GxEoiqu@`tjb!G4>Xb9iLp8 z2OACBjWp-XQRN7c$Qy{!-#2aG&vcFB<$!!LR0o+NNhmA`R2M9;DehbuInol#`e3$wlbrMcVUj=iU@pWJA6&hc3Gl(rFIUjFP55gR{uBCcj}Nl`9UlZ8 z_q24H^5;x^dwlT5asPr3BLB~k2R*QWTIa-#v(AG@1>F0*EH7l#f#DeBq-KjGL~L2m zMYhQMtz!Xj4+0$v5_x|`i$U%|f5cj~5|d57;CDW@p)XTIEs19mHIf+2e?*HxPHIrF z?hhyRRj^JLk%8tfCp8eP`xPzz8LYdG7XPC>2u{6?fBW*_jf=d=2ZyXc+2S8d6Y#C* z>!k_Zuce9Zqbo}_A1F(bE^pe41iPZ0WVdCvEpu7>;?<{;`jR_RnnyShyASAK)Yx9> zO14gGk8K4@g*>5fU-x!5c3)_UJss3~taD|e$p^B7_-$7Y!qC7Qxcn$U^P=! zZ8JFr8j=}QR*0Nn-2qFri&@x0jD`?aW(yMQBvl2ZEAe|QN+l}F6{7Qz*Yx^JAP-Fs z;GuzkrDjf@2!P^}(Po+t*aAKj*S<{7k0Ci|*T+W$mGMd*G{kD@ace!7QQBMwqeUog zXp4DuavFIOFsa4k)dQ{qgo|<4jc|{o8}9$Vrh|XZ$hSuaZ`Rd=P6^DvK>i7Zw?_y6 z=(Yci4g!W5qn7`-(PI0*j~4T${{PE82)e&4)S{N#mj`cl;QuKPX3SU}D2WS*s?!5> zP}s>=`k|*((YvidQ4AnO#{p&wau0&&U~ln23_u4xyl(&>?KSX;wKmUw+B%^DfUg$U z^P=VSqc_4{3hrOP2XYUZ&%>M#eQ{059J83^QJT0zY=9hfpBR|Z^t||Xkp7w&#`qgJANX9Dh8A- zzVgYu<$1u;MpX6^rg_aU|A$Y88RQ-e1R>uO-ibR3TWll;{!1JMU4+D@g537OJIOeR zP^3*kns?rZxOT-i%v~d&TS>jUJxCthxRwV8Kw%O{cV7VceuPOrT(64(-}H?ziS~7v z1aJ=;`LvWWD<=Spk$Ghc5=F2D4>)`MIFTQNaBaIHDyjt0@U?r;5Lg%2&K0~t;Pp`! z1B^1)bTI4pFbToxTZwPBx-;V^(F1}(YOUX}K{2`>vg$wue zul2M)Y}z3jVU4H(9^XNgsO%P83{iZ?G+Uj~mIyq))5v-$L2nugJRSE$K1zeKfB(WS zh;+h%apaRw3EdL=k9R)Ysu!@gM4-b!RipH~Rdd`gZZwC3F7g8v{w4?vZ#P?f<05a; z!QZyUKEe4LSMne=;r*GfMJk=7Si6Am#a8-sv0(ra$Z#_p; zmRCsIh^p!#M#dx6BN*979F0<3GzPqFfJ!6qU@l2_F<3L)!_ZTSG%VsUV+^0m)*GGk|K5QA&oPUyX=E} zub|**f@HM^@TjOg5dzWBl;HO%Ekn#2aAFEMg3#=bVC2<@5NA+0p85%c0WKP>Mk;LM zlCN|X7?5~A^^_YukKSuI-5-;!`Rr`j@y$XR(e_beR5WLF)3IYnQf%VBS)s%+DElBB5gpp_#^VUM!btNC|nGnB3dOVVi!~51uRVl4uPc! zU(xoa254zw(e__Zk!(ZwYDo5r^#z5CW2!&9GTIKvb4$rwEluQpElnC)f*I4<^Syoy z$*#}eBw7rC+GfH)Z8Jc)xMedm=?+cNV?x zpICTnrGtNlNt!@UOSJDuT@c>yR}yfH=8EEgmQ^yUoD-e*6!v1WU5!>n%d-IIz!;o1lIg%6{j<&KJlo4AO*U%yg^-C z2DJ`SZ+IDqH$2UOuC0%xucFF|lj(u3t(7wbe2J0`T~OJwM!R+AkH<6ZXKx~)lhfsm z=f^SvVbr(!~Gd9)BF$##9dgn z68uTCA6XKd4W$bpT6|Wuww=iRy{fioxwv5v8BPg-5@navVxR;cdg0!I?+2TN6B=Z3 zPJj(Mr-Mod5tDJl1g0n8&t z?r8r&wryy5+*DrEFct2s_;LU)R*X@d#||%vC~}W2Oq2)c1~lYmEL}7 zDyDej(Nv{F(=1VzuM=G&gU|$wwJIZHbgbg=2S z(m|;FY;;iRATv-p2)qjkDjh`X6$wnW0F@4|eYz?gB>ho3nEs=5@DWfth;pNJ(6Z$G z;lQWs(!sKyrGsr7WxcwpuStxisyBhs!J~lloklZvYm_)|?BQr2RqO^3LC&w?$b;B* z<+eFwYdP~2yqqCgTi<6ZOQ18?Qt(RiQewN>Ry(vW`$Qu(|1?RrI6k0lCdk& z;bTU(p&UD-$=q%rFK}M8T^PV*XA1XWaM{7SXKdo$^t+03gguh$s9K3Pb?@aK2aqvHdgH;{v;24?(qf@{JnE9x(F$P zhYoTu1V|NMx3B_xVwed;OV+(PtT=biFj(q{v#YL!Adi8%OE(Xr)}D*|U!TlZV<~_Q zG?yZvG3~DTFbs_f?Tir>NjtMc?xB|`!<4srYm4v-3aK-EGaC&mHt_d_tbc@LoI6#b znY+aoeHAKp3gD!`Q=?3=aj!*b=e_wcDTLPMmF}7Rh@4hwx3yfljcjgcu zY$rzBM{hW&vrgt5&YOSyA#1Z(eZm*W6c2Y#>QO?c6xOm_j`T?nf^9REysIb_vLXz0 zQ9$&*OZ&h|_X{p=@^ej0lI zPXdclH7w_w;O()R9p3`>5tbDi##=;A_blE5Jqu=GtC1Q)s?}vkxgQEA?yvjOYAeL4 z2ZVcXN)Kt!P`^vn8odLsKxq+1XG0 zK&fH}VJn2b;4{GTlaw${c4i4k zwC5*?AE5jtu$knpT!X$M?CI#}Vhto=_q)Ez?}rtDckTu@D`PNf1&<^vL-i@3A$5-? zWZ|UqV6|fgBVnO`+}VQ{I~>JXZ7~UgKpf$FAv#u9zeLSlAn<}|mQ-F)XK$VXr z9o{SEf#n+l^eSMdHVxWo71q;&N>}}_OIKO%wKqAl>{qDV1)fl6>zkqvJq|820glon&YEap_>}fIp)L@L3`Y`Xrj(^ zzL#2BFJ2x$@HJI{SAU{<`f*FM{>G~tpzBL|t^FP3ltBaH=(i@J{2n6teE<#zDrQ(o zlZhjce)(fyCj2l#Z3^UYA;Cf!i!eU!g#*0DoF~l<14$v8?OH&$RxZ%3RSVxD2I|&A z^X00^a*L1|j@TWuW55H^~*GxQhmJ?%p139s{ zjb|rYX&PgLL(xbB78nQYL-MKorcUM6IJ7B;SWsMfd&$2ddVJ2nCkJR#<~9qmb7PGY~#2{m>zs zWmGZwIHNYAm#`9_Cok=2vf( zZAKa>1=+r8jEn}ySVJ_TwUb+au(5O9H>lmU1_iDR59%B2USHCT=TkvyxFna(vx#QQ z%u|$V_Ne{D_L_#MmcdKbA}lMjB%KO9Wsg_ zAhwnq*~sEi{yYiLFr&{ZH{z~%qhW>>lp%RXpgwukt#ts1g8o>H$tSY>SDrz9%dh>I z9=TTyGwg`r;S6VSpbW_(p=YVPBk79L)VCXt%l`>`x5fl-L;-#=!9Vfu)|lXp(|%`y zHy>M6lK)>IygeY)>tPAh2Y`?i0K!{qpT2RAH<;kB4%R0?2Wv=%xRfjc(81dC@>d6| ztRb%B zMaF#O01JX*v~smtDkqLo>mKOK7;6(x!ba0=R-b%JSLjM+a-WLQ z9w1?pwB`&j34S%KGyi6I{zauf1gL*H3Il*d&bDD>u{R({R4jem3iMA8v;Z4oJ8*0D zw(i7SP@LElh!ZDJqIy$`*Dj+JNZzxhaBlPv(T5=pfoGJIy$;XT&tUGU^8%TCl%tnh zai67Rm-pW)8+0H4SvF`M>f#z4)gZIHy$_~|!DzN3ea2HbnI-nMuN4492LKR%mJPa9 zj4}Ku8|01nBtG{3s(}^WEHdj%^{RpOL*!o#tV@PwWb|(hh!6%OEHX0u8L7dYMzGkl_uI?BvO9q+h0)5a28RKcWZTjE{g0;r>7Dy#-L0 z>)OVPbVwthba!`2N+U>jcXx==A>Ex)0t!f%G?LOS-Ca_Wp7)Qs7rNKpXU@0%X1+7C znOQSyT(kb~j1N3q?{(kT?>a7O_~SD0-=|07|Idtvf0>A!;s5hQWY*^Y@I(Z3d{FQ> zNq<}h{u&;+D+6=Gh1X8^(6;>;_#zoX2l!Oc2|m+oNwu1CxlB;w0b9}q z&>j^T@2VyW-A^w1V&eLV1?y^f+JG^L%5J_iNwd`LT1;(GzR~(P)~VAYP3!o~MTFwg z;_${WY6|NSCdjiv7k;3GL>NHJ6v!=ZD9P~7?L~a^VTka>s;^0loWh#kYqU04LWFvp z>x$c|TZP)*sprS8tGT6dHI;EK-VZ%jyqom#Q+h~}R-!xx&_dFkxKq}g*hM0wa375V zGzE!Q2gf6*!4rrPM<*qXr}1V)L{a9k5Gb4=H>_KlY-c-%AT2Tp**m~vZF%j*IT_8e zfPqw$Q(cc(jS5UbJSes=D@TgCD>dGzxqQeQu~g6Xow;`al_#)TAWYRegU&5`c`28b zW{Z%C^~Eh*AQzV!W@?@Jf)k4(V(eo{6I=ofE_qnNmg15vGDB!s7Ch{}WG2aU`_Cx| z8GcNpICw#L7bhCt6q(T~-%^`#lFi0rT6z6%j7hcot{oA9+-dx-A>hhXP4dj0AxK-# zv~iSxE$OgpuXBu*$f6pXLC?z1Y0_D}lu*7yhmP`O>MC3Whdo{^Z{6MjP%X>?oRW1# zU`v{!APU%$M(!JArZ+0280~A5z92~#&Y0tPUSOv*gS~G$;!?GtL6=PBSz7ljGxJ5u zyx+sXZm4fyq^lz&RN0?T?|`R&zxMu^47?Ko_)7+Yp2pl5E+zA$gz1mTz&lU-cQWu3 z(7CM-d3;+y38N!fD-KhYQ}n3(>%7>IQQJ@KG^l}+*8&y5PFn-mX{9($H4t{1ITeas zeIWXLxa^yp1Av`&_!onb!`s2gz%PRl!P~(IzGFB6&);LGwJKa?Kry;o=IW0aoyJ?= z4~zhIx;rXzRr*1{9SA$^{sTMh{TL3wP8(umLEK`e@3v6Z9-S8g*l8YdC#k=|P9K1h zBQ5;5*l8sIJN+Dlot__xBE3Y)OI8=JGPnw#X=l=wdhIF8k($}irJJnm6F>gow?<>o zF@9?wMFq`8{-_GPbBuRY;ICL20}U&Of7+govYG_eWg48t!8s*oPByfwB@vp}CdIu}>8NkZO9v%T$nQ`2<>97|@va4}g zwK=4=jb-cxWdlBwQuwHK?Su}XZ5h&Gw2iM_yZ4gGl7FzayofWshoKABQlie2mpKJh zJRx(Tb_e;qeT_LWBB6Qg@1^>%hK}3R77;EG9zRjbut~L^HJjny&0DTabDl251!Q0e zAOi=im_agdnDs9i_^E8hZoiZNm)noqCEsJ5HoIY95hj(I| zq-4LocptO$UGXM<;t%wTB2>_Q3TQKRd`G;Y=qz22l5VzarL#6Mu*n`j%eIA;c5a z%1H%9_YUF3-b~uv5?;{x@ryy&f$qOQY6t!r8u?{CTIe%i2R`^);`HO`+x2LGI88MF zoj854e?&o=;Di&Xx?ql?aId7*KFWv%mcnmfr_#Vv%d44sv6t^vLSo-b)fg~tnn$o` zBj$_6N?aZBCZ7}y(3SK{iz1Jlq2Nc-GC z{Ydy=?dHC4kaH`Ymv+|=JJ2wr7i0(W{jdXVW7$AXoE1MjAsfw-tZ7|9IRtEBF@w$Sxqif{ZJA07|pLwv^ z_roXyGH?o`ol(0~Ap4uSOI@u9LmmdJ=!6O=EJyQITm>mdwaM+3}?!|Gjn@#9$Y&GV2k8Bm1yhWrz@H2qf? zLK>U!oK*AaZ-2f0{(kNKF&TJg^Zzdy`1}3$$7JB0r~R!A{O?8h=P$xGQ-StBE(Gr! zd%$n|K z`4Ir&CkPlj7a5%BK()-}aXc`^BYJxcrqCWbm66UJZ-SsqEC@V-YlQ_aC)Y3vZr) zaMST1+%)SYfSX3X2@K(k-bMC2Gh4KRYs_@TY<8_(25{3p>_|y+Z@#+CTryaMFUrv9 zOgXq2sQ`fyMF1xw%mjNqDMb(9WcVF?5M~TW<mRh~c_oRkAMs(*H^$z{o=UejqD3v%&l@r5jq=X090BS5OcL#*W)9DSEx3D1lQQ9=N%y!{l6sy z@8(574^h59GXL{^_>b)e{=2w{qTK)0*I>T?f4v5SPER=e^7xP2fxm`Dez5}+BZ~fE z2k!n@i~fflDExPJV8c6&J@h9%_$Kh$aYiHv2nQ63{RefyP4oh&F$cLYTmB)n2o_s{ z?jL!daM7&qsplG4A~LZxM||xzuP>_8DAD0p+oauk6T-tnOcqxYoXw1wLHhtUNb8Ng z!Vtpxc*0k1#A0?S#sjDcRTZ&$u{iYVO+Ua5tZs4!+(5bDvVu{-4QzA$FiY?aN)``> z!PzeLFEypA_jfn2cFUfhHA*V?^#;XLTfyf(^kIQ+R`vOY0yu#k>1M25NP!bAiX% z=i~m6fxOBIA8zu5io_#X^NJOM+W5*~tuT}X3~yzia-X4@0ybeFZFeHH;xln4k&Y;U znLtIekGjv%`$G6kFAD9_Br)kS+~mr2W8~bono>9J3k{jWhmFjKtCi1AUg(ZYo{2~c zBA!dS5?u(to$V&&PGy2+;x3jb6xpU;C((Ww`GPG1G!-UxT0Tkb;S=5^Wn(VdJkjH< z5K6G0MZZ`RB)^XO^m<_LQNw5rwRNaV#U_u&aS>);Y?JCNrJP*jf=#P*^NNorSoD|8 zsMu##mv^GWzu$U)Ob6as`Tt7?f}X~E4ZivF`uk%#@XpizRtL&lAtMg_-@OMrO%HGP zq@6)~(nYr|bof=uFu-~YD`-8YH;FoRc`ztt_LOw|AL}vq7rH1#VCLw#7;o2O*!l#X zb<1}RJFFim8T?p}ab0ls5?`4z7=$lyaf@IGwKDd-;6!de7LS48t-^NfD}*JE@wxq9`-Rp6at{Ff?l zF_GZ$sh@i?u%Mg>sDti32apqi2UH-C6GH0x!k`MYH3;i}88wOM?hd>Bx*B>NGZnY_}Wx zN%tFx-A|>@>*Tw289`HFP;S^-t#bsxYcU*rG&|teZ1=VVnmMIFt;By#h0*U!h06n~ z0mw9nBJ&+Gy-SI9O*yCy?8%TpC!zB$JSHgx_GHAYkq2pqe(uR&Kp^I@i?h#%eww(y zeOo~Xs$%+HLHFpkg07WO{g$l-nhL+XxrI!R-&W97@ZGYtssP9|CkQf)2SBD5enO^) zen6&Q=4H`La@GSCbmxMg3c79SZs5fj;=}N5N(59vm-A}{-EB&Q0!WE~vU44vlt>TC z<=Y>2p#3j)pyCfZkoyw9oa>ccg>mB#JJ4E$$`r5zqyMcP`26L&H}TG9qySWq_fsza z0@?jdEeqY-_u?lhjd@Q7eo=ufy3QaKIEM?UKD;JE1%DX}Bb6c2 z{6)_SCP4Yp@c3+UeFov%V^1ObhiA{cpo%Y09~@BM$9YKZt1I;NlcvVn1QhH$w8mqB ztFXx#f40Nd4OxwZs7082kKzn~0y?E;*|l=JWwsBZ4SS%fCAj0I{`$6VJ zW~|PZ5UrU{T{|IGE;`jzhk1}0^1MiTjMKJ2^QIt3q2${l)-++&qs71Y!%T>{wpdbQ=yr0!Nic{Bmb z-~GVj4WxNdbX}PTY@DadO7?fg!*;87;!P9*A=r!w zy!^gFGK+U3bS%Cz7WNj11OGV|Hn|-O!=lsR8i!GBj}8N4VSOC32PkuK0%BDXN(ySj z81P*!QoQ6usE`%mU0lFe_(}N}{6o8PT6RYQ%;d@WGb#?KrmHJs+46T zm@&#Gd^Mnoy~Cs35?&v>C=q~X9e+*(-hM&wtWHqZlGcM4K-ZG|yS38qFx5KkiW!#M z#*sp8f(~Jt+k0;gbnh*49d8Pkzxe@E{g-}VNyKk{;P3a|AJc&xe-|14{Q~@BI`GcZ z{#FP6_a^+aejw-|MS4xO{siNCcG1Ad?ufYlOwqW&1btp4CA*b+~JI12w_ zFigMf@S~0R1MK&WX;2$+{6E@=n~19%^?oYB?OebQ{H_E+e&C6^Ho%w80Ql07+_mM+ zz=%ZMSaJl(me$K|#OaX>V(lk+4{HzRPQVXz0Q^9!`@wIPcyTO-Q(60Q-zF$hKV%Ik zxg6ehYZu+5qd43-w7o!oVfW|?8Ox4vdiUF2S?e^~i>HUIena}bK@n{jRv1jLpB^rQ z2E(b%Daxf~>;EVtrnoI5W~jX_BZi{~l@S9Y5|TGS8L|1VWyC3W%81cMv)#dQ`fR(1 z5T5Jb1NnjDHaxqaD-pm;M>tRX>>( zA2I;4%E~~1LQrK_n;rOmxcw&DFnw-$)dpyvdjX~b6{^mq@OS_yXpiz>DW!)|P6H++ zxb2+kEc}As)|}k^MJTc`&_dJSMnBpF1x1R$#RdD&K!agW8Syx1F#OMD#5b=1io)6M z&obigkX0z4ZY0ke{vvqa56XAyK@*t$^OvL#fPLvZ9ZbK!8UL}E20_<=9WSlNTA3Cln!5%jm;E0%b#Dpo3SX%(m_0^Svpb-84o^i)3QN z)>5HR$~qzY;RgaK5v3n~AkeV{@&oryq8_Su9mx52IuP`b{UpM4LC9U+5R}`&K0yKDC%Mj0|E)cfGXKL zT({%@RPP+<9P54gy#IJg-hg8g26*ijYb5!Xfg{Xm~C_~gzJe;>k zA@z#EP^LZs;j|h`0lKP3lZXFG*<-PLm^E8sip}NkaSf;L`*1BvxocF<7YhO@5o6dT zm3C!(%OK-gXxHE&~DD zei2a3PQ+iWaS92%0Jq3smWBu(#-^HRWOyWw)8oD^0mj16Z4<(qW3)?|EAdW19cS`2 zq)sZ#x3(v^-KT*~mlX$9kUDa_2zno8>~3F;#ia8Ut~mFu6WA!V6`3OI&0cyC6^sVRQ6 zj7X*2ADBU{WBxf7#sQ6mB|&3hEb2OMpoI9*!uq~n5F%1}|7{6zyTvXDBY1Z#Odoz2 z>IW>!++qZc0gRwn`=yp9Xeq=(#jo`+?EhiketE)C?TeJZf=$!3aVae z)4YJtZh19V8Q4)nZ4-)Bu_>i~EEKY~VbhTUDY*fl_T%rbaR6x5jlQT@1*>m&Qggq* z7ymI8$aO~rf*!Kmz&7{u8vJ7_kn8VN;Lo>U5xXB9Bi(Dh47vZJWho6tk>3Kp1GF6d zy=BRRrEG{e6`EaLW_hX=SdL~9a%g4&mZNiD*EWwHe~w+i%{TVJ$pOn}q?-D%9Q^=0 zR8gs$l8Jg9M2%skkoQi*W4N1)c75_?!4BpbRU;#Vu7N-A8N+cBoPknjqv%O)4(dioMaoY z1CtllGw7v9kT^ex=4V+Ir-aYT)ZUsgWHsd zDtbE1(O;7ULI68Rdal&n z!4qdb8HTF@!DGD2M_Qo1xp67-v-_1Jqmw}Mdf;=@@0VU5aOwRBi6nvg<_JtjkgGP_ z>5^%HkceGo&Wmo7*3gy}9|AD5^BwV?f~xB~DiBnn_`jk8x&BTCf}VEw`uk%l@Xpiz zRt5g|9{i*CAm|)*+a}lkxC*>;j{i~xN;rp9tlUCXe>DT&1D#9myOEH#(XD^897x#= zK5_jDv>fPrKSq#|;F{c#^?Mv?Q5t$AOj3bG`^p%7#_abUys2 zp56>kLEIQ5Lr?{$va6KO09ASbqq-&6py8TSdeLVaomt55BM(%vr#AzgOZHtpc%@*X zf~KO|)icT{j0;;?p=%~@EOL?k{)GBU{v{PS!+5S@E8*>}ul>{;Xe+&om>$TKp-O7mKw=e#|H;#pT@y!E2c{o8KWUGSM z{MF`c*`%xtY2?&^%6S2a4g#D4|Q;Jym~$=DBEJW z=y(&l?gwC8jFr$&x0Hue^RhI+P+M)nR2 zBEpQEjKJ5={~%)IY-V62>SS%;Xl7&Wa7Ubdj2Dz`WyI**Cw&o^uoX3^WXCM~2$q8@ z$rT0J$lW2#fW#u{QL9V!tZtW&AX;_fh}7kU$F~WxZ%(tjUP$&C(3*#h8RYQ%4{9NV zSndlEktDM`uNC+x)AA8xOf0z}f(h&KQ{|u%k>t=}&JN=3j7f?H;dJXuW8DEq(U~BQ z?fkGTM6 z)+Q>J!%L2fNvT?W{RUZ_I*XpJ^wLcwH=GR`_l@nf!8d~t?i)Dnrf0|-0fW`2gKhDH zVuR^?tPZqg1IOi_MjEWF<8|5Bx*8R%#zP~M-UV@+7Q3F>4O7ZNZlz4s(^D^QX|w=l z0{DvmO@r|KPmfK`#@^B4_HFC?2mc;@;QP-$nCZ@o9O$EW3paVhfNwQE;GU59Pe1yX z`(a2B1pS0Ls1KTdy(kS8Z#XANzY|*Vc{n*6Vqt}obgz6{-0V2H zy|tiXv>LZ*@AlhlS4rl8 zP&^LNNi*v?s~}pT*>~4Un_HzgMHJ2hqF}H50LB{T4()R{3R6s5Xxv-limxOm2}^sz z`03Uu1hB^T4OnAC!n;kinp{Q9bTG|{zxI4=$tei)V~q``@zj0dx6{%&dZ6qB0|plO z7!2%x{BHmKJB;bhg|LgGWwXS2@G|!rS$Pki3I!a)mAkP{B}iVe=2Wk`P#U{=BGM2& z5VPoFe!v+GmWW8=HBI5dArck&%&XPym{wmaLk&5qinaNH+ zypKijr1#QCIuIk+2+`w1z8|s%;VD&X#eM%pM-VSYql8LjmOOpj_IwT_Mv@k<0#;2kPRXCqs^Xh$P(in@;*@*dQDO2p?4n6!{xGqs;q0tKjs zOxQI}9ZAQpBWyaq`AAk{MbN72^|cy@aGVWrWX$GCcB4HP@x=G$o|Qp>D!?~w|f4I*w5ic-cQfdh0%5G zS=hP4vYO`ZX;i+F2zm{uD8{b5L~i!h3rM{dCjD@BGM3I(TqL`=BDLKzu}%ZT8u&M= zP`p9Nnu%FYi827}=S7r78ZUT)`xA7+&#T(}Zxb}3-A7Nz7Rd{yXaFU7L7UI2Po**K+-pNy(-KX4&V!Y?bcW~$R4OiDUO7{nt%M%E0{*&1<`N`?!UQrQ(fG9BNH4;n zV_B%YP_xq1tyKC|DuDmX*{v~aY(RzeT-G{OMg9> zH<;7kBx_9zx4p$+-KqGgWOGT0WmI;suLI1SVbeDQWP;4+y%AX-$z;k~_IcqyhB(Bg zWz@pL=I|#Cx3{}ODTL#LV`NoZCVG(KD$ObcH`z6anue~CdVFf>i_c}WmBCv zSjUgb8TPKE>GK@k?ZisOiG1V@FxsW>Wa1JuOxq@r=1Agq+}Duz@vrN(3q*#=PO61? z&=tK=&UbGtJwK0!95D>tg=k%MLa-MSH_`d@{sRl)uX|p_Li1{&EuZOZFJWg&<+5yH z{a>@3Zh31;HZN%}g^AC1x_ULsOyf=FjjDkir4hqWLW;yMzu&vh5fVnnoFr&jg>!+_ z%>mQ-9-{qR8f_K2sS1&zY~-_dWng%B`F8)z zOPJ+!)zOyE#sMD4)ND12Iay~pbTK3d+owKq$tdkS#d}8nB@uzp`SMEiz5I0Ih%`g^ z^^fs;T`Qjl3vLDCF!X+K;~#US*$b+kY0->*>VvRKT0@xui4}*uK+Jn^$-1NS@aE=fz5a z&#-{S|)H?g5r#mf6gJRl2^9oO%*&AkJZ@CwG z@D>Upjt$Ovb3^tu7?7yx`T`aA8O<73UzQ*9ITtj{%YhgApL8Q64W8%eNEBGz>}a37 zdfty|%->}o4{crUC}fH-&G@jt6izw#0Ob{JOSFHvZfEFbY`#?(RB47SNr)`U#My<* z)Ma($yv=S@)u%{kEsTj~>mJ?O?1H|U-L;VWtbOcdfS0LB;RcBjg`cwEXbkYD-Jf>11y5CQ3egzHV0YxnFGX^b=gSFv9T) z_0m}Vw(Yl#<*<&CjUDp(b-q|sDaw0n@7~0{M^5a1qMgt{`=}!2l)tNk!2IMyH@^Y^?h~RpZDqrktlS{hJ9QCyd-szBVWHkNQ94^xze-NmOEh@* zxYLvoZODqOOwZb?>ijb&)Y_?alAKkEM3C?4+T$A|OuG?L+#D7UiL^!d{zFlIi8Ds@ z`d5+1RTPbKDh-!dvhV-3u6zVa(|HA-bPeGsDeq%r&kHKLuA}TfmX=^?8w@ZZa?WJv$u4U)6erwZZEI5oaGwcJwefU zT&L96UqSn^`%4N54xR7jjOex*uZH?50UHS`3@^H-)U!u@PqTPh(Jep15AZ$m_`sGIZw=2 z+bU&Fdl+GxuQiqGEB=SApx%pQrZ^s;25rn{I!62-{=Gh3&R!CEMkm1el=#W{>`|Jf z1XW&GVYa1DgWutNKF>M##)_;0IG>+rir4*B;*w(OZoHOgd-ohEyBj|$Y9Vwxht7A) zU@TT*T%5IiZ$OKdA8f5#lB#w%zXN;+otp`*bZh`10TTfU_&*+Z|CE6L_}=)-sJhjH z;$J{okZzuj*^3EfVe@N`HmQ)@0yA>`P<|=GMu?gFE_;$`+&7O|E1b~MQoOEUgO1=V zzv9B;{X+WBp4S%$OA%ifdYkVjIE65O?TJ}E=sDE`Z}p6NIwct`Sywg`f?Z%}Ew z3?9k(^>lOB{PV)j_1q*l*r*rG5HFw5ji@&Ug#}tdA^E4(XiZc)`aHy*o<)Sw#PaiM z5`(my;Hfr$Gro0P(Vsc7S?M#IAuRcFz|M=gbbS<>ac{jU^BLj<%)%B@>BG|e1rb`6!RzF(c=Yc#g=*|A)JtCOm4zFfW`EVs zE`1^>0hZd+fJ{jGZ93QcM6y~6NVF7Vn8NGL%XNicAnV{ZuZ?G4@ZHQ^erA)AnpZKJ zVR5!aw{w*Xw;XV zKdGi51M_IGI0uaUm9tr;R=xJnqY0YN zeJ8==joL$_3SYW%d!0W9<%r*V;pJq>dtiezYyzIth8d2RroHp+ZESRbH4FjMPS}Oa zrE)Lv@X5!gLpG^vUJGQEnxc+psG7Rnrf6|`CU85)MB>f5{@Zn}wFQQDijvELj0#&4 zK12o~fsU5TTug8z3&bJBRm8=-+a$(B(x|UhpQ^23K=kx1Lht92&T1ttJstV{RgZlq z^WG%VhJLW3P)R%M5N;%dg#`q(3VN&QBGUkBMv|8nWwzLRnRiEH=Qus@H6OkVFw!r5 zv2cT5-toQyJIW!aaZ(Qc6E5;n^J147k1#q*&g2#Ci{W?m*`;`y*K5dwqvnr0sh`%4 zcPV~y&>UYhPLD=69IxeRbB(!dJ1BT#sA^i1gxqe+n3NrKD496@TSrr1P6UdKbm17_L~{rX zc!d@k_mM3fwrG9M1*1qXh>72tsYb+Sd|X3fijPd*&3g@DE2}-sW+Nw`#q;7uQb#B{ zlU@V8G8U@(aB;Y0E+!$pT%@*h{xUvc(hRS;PGJCZ>O^K|Oh>5#*uwTNt&)vvmasMGJF|lO{TGI*Jkez{lx5uH|k)f{y}HD0{Qq znnqpU;s;d^cWaK)`ylKR*W~L!Vuc;q9}3bZW3_zjdty6O2TT9iWMS#}VuoHZ109L- zNzYL!bJ|c;gml{tPCs<^kZ#tB?&|1>_rUb5K)OARR&Fd*jRj|1z5fTA$N=WS^-UhB zSH)H-A_+?NODMfWJAEeH!4wpG@mG08Le_fDtS)Ir-I;syTU~SapuNN^e#|~ zF^|U5H-?0llvwt?;cn46lR+ur^Z6A)T=E&erSb@z=huNd*CU?^s!u=7V2JxZ4z|(d zH#(RZVoPXse(Q8EhN^8!k?Pt{%8zF#M<>YaB2G2=$lyAa7`e5LpAR=x;s~R=TWBC^ z#uq1Wi1*&!oB#>Wi0%FeUlikWo2o9B#jh8;_qz)(;FuinQ+N+W>1%v9hp?!v&e zP^mR7gA)k9SlH5xO}LwU6YCDUS#WVUN42NkL$SkT^_gVV7*h{N+_&zW;~o|ac+?xT ziL4!~ukOao)JL<3&6p5!vXbf8@oCW|g)<2TX{bs})KIOc0_;pik-*u!I;}4GUUJiF zdSmVV@n_oL+Wn8iXVM;3R5@p}RgPobh%HN9=e>SeP~G0-R5ZKLwAJvue6Uo=n5${C zYroBQX@_>nEJhr=Fsw}7CLYJUR@sUwcS)obr8dQKt7jc|SwYoCiATMXCAJC2>E;sS z)EAbYSm4XBL)E=Y9Q;fd-=b|JF*BhLG8Zm70jB2a_Y25KZD!wcfgc>ydG3j?oIKsg zSEc+ivhYf`XHYkX?d=9f=9ZW-iu}E4hT!YZblJv+YNxo{3{;P#MUFLs^b_4vb{pCI zy=$8^h!iTc?zf*S%F(%s>8Z8BF@Ar6roYLu^wdY+8WVb}}^7feQqM5ciXvK28 zjG_rI<*;j7!g9^b-s8N1-iv?r)rTQX;FC#g=2&P`P0Aovq0j=P#>Atmqr}}MzI;N0 zeCpM>6$lH5%cgI4hMQ5p8H@j+|HpjCQ38E*UEUzyPZ{_h`hUNb{`~a+F43BV+mhh( zyUF{>ke(q=vwB&?nlS*$r8hIWM{uVuotQAdX&)v5%I7ML0wdzdGdyzh3;459dN;KR~$ZCAAnz$O3-riZFd7_3z_x6bcCa2aMdfeJo%?32>tv>{fjxBv*Dis z24LX&V$k*S5k))xCWCQ{^s=1jGo5%GsanWSQuWoq3or-ainKTZA>K&2dk#M+Ds;u%M6%yZ>WT@&+H$z=L zLV2%ktw|N8Uo=F`#$6=(cCYVdL&2OU9*TR_0ZGQIyKi!Z)zI?;M3p&e44UwIs;yq6 z43m?k-w9l+k3l=;=h#oU2o9X>N>#>{z4&+$Yzx$>`hC!zE0QeQpDq2>1ICe-j@&K+ zkmMm3#2m(=3a2F>&SgT3Pk;PBulCmZKaC*NlX zMVtYnjWdh%rYTEB@OCR_UJ`+NI*-mMvZrcc<&M86H+}R0YFwK>+m?b{{rts~x9KIO zl}8U`qWA@>6ry%RA%g5XqC}>!B!%Jx2w?yV5D8=fN}5F9BN5@LT+x24GgP=vqrUs% ziNXp?{I0n7tpz9^O$Gs2fTIK;3ouVW-vzJ$FMnEq@qh(bz#EqyEFqFyJjrx{II@Gn zJA#;kHr5D%W6GK=kUN=tkM9G*5|gTK9X+Epyaev*(pMry^yg^0rez(%)a-|erhaJe zqh6D6Q&dgvl9&^|Bgt}?L740C`cT2sqCqd|LXlU~Rx#d$=Y*3Fkq1R>L$W%EFvQ9V zZP?PP+Ui#Tr^o7)Z*Vxz+RVN(gqQe8d1}MeAB{Faj6g3bl3}0LGw{*N#D}r3p30}l zQbOj%L+I%?ZB|%k9n#C^d#~}^jn59Mx(qhf;ITe=TK&FEfnFKy!4Yf{RoP30!} zsyMAKFpdu{`t|QCi}*|nFND{k`3qCtPb*D8j@1Xp)FIQ3Ier-m13ObO8*e3<2E{l} zW$z^gccbb4R4nKkb#iD=C!ahhIXW^brBtBoRw zp6Y5+;QnlJd-*kzdZD5@f1em&0pglnD?~|+^-x{p?_2TG9DTl4oRyhdwyyQ9rA&v! z%8gmbdV!{?_&6XWR8vvbC!`nn17|eN(TL`ci<`CSRD5DPvSo(rFV(nT6YiU#A5mB$ zK5yt3kZkFBodS_iy&XQef|)E&4`-`jBRQd9r%H&Fn;pJvf{7wCGWv?TY^9kv;K@dh z5qBwMh%kX0m4__mlkRkH{rvszi^F_qHbr4~m@O36v&b+*Z$wO$9uIJv!?uXaBwJh>iPwY?5~wwOt#GgDEZYn@JIPh4W`qfWGH%R% zpIzoWg{&&JwRVr@Fqy}Xi<`FQjrQlqJ(?=TJ~InrJ3iBds3-FM7@o(zT$RGWoG85& z9w5KRp-DR9P5zQFdCgc~um5b!A$k(lrHN;9Iwnsd+P5H?xW-)!$=42ir^rLpK1c7Z ztdncAX^}L($<^M;7Ho^;4Oj+OxXhj!(K=qMV`J_H zm$H&!9^1+eo2c^C)>w8c4}4Td%NM8?uf%6&t5cRp(;zGN5B{p zQYDh%C{nriR^nYdA`HVc1YKEWPIK*_HNK0b?_s;KsZ}g_A7TGiv#+8E%8#FV1s%O!XrSVVPYq+WT80d zfaAp>q>zQ^7xTV@zS&o;a*N<%lXa?kO@WqJ^g>*2vPw)Y(Jt@$cD|k7p`83K`Tj!- z@J@@>Uuy=xYrp@{0=)B#zqJ7WD+2$Z2wZX15%dQ{VDf)%0p2;cUoF7T;s*`#-`aXy zA}}l);d$|NHlGkfLeal8%{DKEnG7k_a+g6?bDB{C?}s5OvK?ZyGy>-N|Uc;g_aCr za>=UL41r3$!0e=1)i~Fni$Anz>7}paiKtzAp6mZ2E$C!nd3v)cb9nb72f9=F$G2ze z7R}ZgxrR^>`n*pCw6OE6`*pr{ysQJ8_6n=9>SR*#p)%c`Wy8URsqxYg0%w0)M3bvz zUBMlvTr#r7dOb@3E~zz9)sp#QpcE=|R+{dqFw(gDLOy#bB@<#l92PVehQfs4G9b(}wB(zRn);1e)LFakbN|Vztu46F?5aTE-QC zIc`Yc*K8Npt8?0!=cp&U?#1is+++ zT^|;Sba+>U-Y%~N8-(aL;04Q=0eI;;mfvU|EEN=s5uonGeJT1aQg7+Tci6cyWxKb7OOF^o5nyl*g(xjk~aPAt)8abJM^yn&R zB)ltx!HLaX^v3i>Fh)`)lx#F;Bur8vI|nNhRnDdC(X*;vsE?mjcB(Ssmr7XHe*y=c z`ibD;43Fxg(DhhFXQ%Jsrx|Z}!zZEV>0Vprg{v}>BoH69x}eza4?5fngieQ0_;`Wc zSg)JU=$N4J-WNO}tQil148BtiyI!FQpK=w0c8}~P@|dwh7}C0Ku8TdpUnmhK7&i+A zO--V;j-`Q?y)uYBu-%da3D?W*%ZzFnG#OEy@4DC*G&D%1p=3&b)|xn&g!`wDnvNsM zdk{VLlC3S@R6=ZrYK53gq;+2+b?}uIgq-wYT;nU6+qX%SeKVwsLC3-AkCsbD15JcY z{27otp-pp@Ev_oC*>)8j48vrf6pvc0V`mFi92S0ZKXX9jaFeZh5Wbf60#j45-zQ{C z&Gs1&6;`1AGkyg6$LUa5VdV>1Zs7DlwO^m+D%aYJ=r`Q^Z-=Q6&jlvlW!SP}-+xX* z1wqq^kHkAy?7kGKVJ_v*+APyVr8UrQ*S zCkNACiDIRAkY$6^-~`EDtty}fkL37pzN@VcIA5tO_ioF5i0eIAy)c*#^W1SU+7VCQyX-hkQJe zW^C}_5-f|JCp3O~I}kokVANV3T2P^yZ|W8H53*X|0tUi5QYXiApKqd=v*(}BYC8Lc z0t4aHufRa~BtWzO{o={kpjH5Pmw>@TriPY~SXr7gZuT-sPRLIyS$IqoX>twUEKzw* znp>t%2Vc<^#jP!*2Nhl`pBE}A$qSTM&n#mFwlcR%HTQPE0S3atxoYRC1uBmSCJ8E$ z$090w0?mEDX%w+q?5I>K6s>bBzoK1d!<%}E9iE!z&ufJNFPy8aSa_l@LlwUopx7l# z3LCXOR7l;>$Mo3yBw(hntElm-*4wiA&iDIbU-9oPCEyPuPHL5cHS85>G4M$mELn{< z+zg5t%;tzw5!&rGrV@d<>|dIMizx5cgn#iT=0QY)WvARiq;`7v5?q+e5Sj?%{Z0Dh z+gW0B=sYu-(u>5*7FCgwxURt3%BeMt<@<@#^{YZoSL9@HpEE8YUDVp2;Mhg>pW``& z<8Z#gxz3qwlinpJ9_DHMDx}r-yz0tx{82%=Jjs`DDnvmEk3HS|Sv_b-SAD21R@vll zilSnB-)$sJbfr*???&K9&)eeBY2&u4)6KzJ^*3$zE3=BGNy zf4KPdi$06GyTohl0agj0i{|5p|JmoCmUy8H*+;8quRD^{Kr`B-RJT}eqB`aEem@5{ z+t#D}!1V0yPn*{dW#Q=V$>uUj+K0de73@}0Q9;VJ<-8Y%k~3(Xx*;$Wz_tu$Qw<$u zGl^A=yDZ4XCQ?VsZ3%VBYeuHq4NWX3SAG}x0{LU)>t=)t%8kHuETosLo-!K2lw>$> zzuHdpAIu>H_;RZ9(5?6f^$y&omG&>=EcxpUn)G5>I31rKnR^=`96llEGjG4|Kw#5s7&&h~HO z{H3cwht;>yORx`&)C+*adh(x**8dV^4bd%<5Q6su_Wc{%7*AA_XFq1S%2yqa6T2Sh z^5yWD@l2+v8J8(hy>v0zSsGX3eU+#H>)FT;H+AMt?DwGx{-KyZn=}J$i65kxdG0l| zGgWF_J2sRr*I~JnZ1uREb+rbyss_tN6?I_7)VBv zm+<8bPR>xiOH2)vNY^AMT4{WqJntpA_?Mt@(a4Ft{z_>g~mu>=41|82$k=luMya|eB9D%YcEA>fCU9XNNP z|M6%3^7A<)YthPx4Si6*-~!9XaT>uang%hXjEnTBq5O{95DYfjJv94 zCi*7*U~N;SDX?ypcIi{lpp^?(5_{NJ$E;ooEV|{*nJ3$3>>AvAzz#(PIB17r2pia; zSo`$TMMoUeAAZ05-9@Lv7X4hM2e{~GuOSIY)KP&gTBN%62xaG|$7C_$Ygx@=a4VF@ zZA9>aQTt+gUYI3Gaj#g)Sb|(^ws}bfIUjXIXmk=YgiZwTx}gO}7xeHzYkzLAl9i_; zb!~2_jC>9(?&Fid_2qy)A?tnJB|EP5)>_DCUZ79|F5BD2TN1ece67zrYE4=J!_Af0CNpx`hIo{-;|=YJ47q>aJYjU#BW z9z1Y8cYfz56LdoC;pP_~p~1kua06HA|M-Od`k~y_&;WdM43Co0Zzx7*QSp9YQ0eg+ zCQ<(ncW)V%<+indBPrcTBi)kH9n#$?BGTQBbax{lQqtWa-QC?FUDBfPUiWhCExPx9 zp0)P#>Hpqey#3%jJg#w#d;aD*&N&8^ujG`=PDVc&bQ7Wtg`;sH>b-{r6-bu;wF#f7+B>JA?7t&bUj7RD!qdg4A&7+fWh&s{m1-|QYyuR?kulna;M zFw~dz^*uIBJ=8jF)NWRhdQ+@*`%El93KerH9YP3&x}fV(cIm8(32tldC~=ppRzCFs zjjco2Q<~6E3sF*M=9&c~@kVbZs?tZX^qa2Ebt9kV^roQJ9KZ+^!4P?+eS>glsCTAg z2r*kCs!&^gU)VaFD~no_Iql-PEDXLOozrV(^fR zicd8XS%a_nv+#EvTM~ZYduXug0gy@Q{?h)n`oh#yRba@)B)hQHn?f zKG@8dvm1ORW7a${d`lLw3~CEFUnU%@9`fHC?*Vg4^$INpR0{ zO)9Rf(~0fvKckYWVUnAMuCQ`h2is#C&&jT}H8ZIqTiv{KRXv4D7^uJRsy3LZI&&zt z{Zz7)T55K2<{-nn!IznCL#i;r)wd;j?RfMWl4SoaYF^qg7*F+_r(XlF$_&l+{`}BQ zgDU^anMsx-(mfpZ7#(OmA`J$GBod3S^%(HyhG0fXByD5RY%s#uqz>BH;r=cC7k;na ze>{}W8{_y=s66-0yor2;oeWY1KvG%QX_8nC})nf>JJPI^Bm_ESrq0pIfx#MKOZHtr@0_ z4(sE{vl~LOTzVjBCaV zt_6mU-i4qKCYJTB}51M^vv0U@ykv4zm^xQ@IAd4d24{b7UOvv+kIejmEb|6gyB|1=i_x8ET+IGu=~aE+ zE!8hdhZ6JCHmjC++bw73b=sv>kSoMTt|zB6yZjjyhh34irlhw^w`aVgmBq}`VR??} z^-coB63+vQILjc;zp&E>I!erxnQ38Ro123hzs#jjQ-Pay6;OeHr;V!?IDk$iJeUj4 z%-RMiYy#=u>m32$W#-tH^Sy*1O{yW7?{Z4^K6Q_j~!$&!-wVq+unHm;4 z1I3bAQwo~RvV{|mHJGXW$u83d1e6Gz1&qW$qUbhH_esrAqlE4(l~pVjpfU+a6B9Oe zQz#+^HZO3?KPr7n9N<~ibU+ZlpidpHXD;VUgFX1d7?x=q&me=7F74?}x~+S6A9;TD zcl3?TM`y};ms;`rsw%R?!L+E7NqJLOSj;uNP>){|fUq^P{hQAfmMdD@|eKXn_6ZmPVOIFX#XAav!q zYgs!DWMikWv$dV{V$T{%?Ujq1Y?)B^ciaiMce$x0Ce;(q5BKb4%+dk34(t``jUQfc z>XgLrNPDf_JJg_Xh!+{Q4G<@@hPR$Bw=Imtjt#jwX(c8@6VGM%*7!((J0f#$z>vyM z@%^bQa^DXH!LNkr$znTlHuP@l1$Fe&;bne0QM=)LwYbf61jo52=BZ-3@Lop$i^rDW zS#z6{X5OoI3XZnteMs-Dj(PLoeRmA*C~AbBstfFr(D7x| z+?~+Uky6dA7@}1vV;nowd01%UTi>o=E2BagkS@~RNVpVi!tR#l@M8DZ3k1Zge#SuSgUmj$CT_S^uqI;;+sHwj{Y zIP4Y9*;BHM{uOS;>yi9)F*^N*Y#u z`o<4q7iWVpEuJwG%>#LwX=fP~V++jQt%I2p~a|9{-5BmkD zk1>x&jE{*9-8`y=@y^woz})CNb_pyzhF{mJAE7Xpd+}pQy|)jxhY2{xn|83$Y*<@7 ze$m4{GI>Aq;;ut8n%IR~37*yI{;_tQ9N3cU_{cG<>}5Wi6?PhX>=jM~=IbTAcY$oQ zyOfiIJ)N76==O*nSA`q-HeplO$54=aW*3d(G}~X6`VuC}r+&!T0PjZJXh!}@qGKf< z4~~aaB6ex(yH(7q8Z{wI*16R5C4)38&!1EvLZ@hhB$-i9^ z-k2A<^mOqplDhPy_=F3+bkze zCbD{%RZeGF)9uSize~3ww)&CHa`UXY!CAf4zViI{3 zBo8KVAqVdlF$ro^PqFe(F$od-MM|#WpJEcA_yU$pG09ROG0Co1ekYI@ zUo1D%+Cl zMHddQKf?Y)lm~_AdRZp72SB9r|AU(Jiwjdr3PeVqevpy4Pq_CZ*?~XFh|@rRau({m zyN>sWO@g)G>!s5IMfWw7fg>t9Z3tS!vWm_dFH6sKkC-N@yHM<)5AbQ~2 z`to=d-G*=hx&nuzYH^LQ9H$ILee9Tm+DG9jquVdeT1-A zX0pv&Pr>wgzg_R26OGP&UUzd*(B1cp{l0g9gF8PrjYFZj$h9(pml0)vD?E%p`^XVW zasZWn7t2wn=TT_51=z;G|A@Uw{66R?51>1rXqAvNdHlmK&kVW&Op~s*7UbT&h zvIPqBy!c#)5-D2Ne<9-i{uYpvP60Vdap9YJ1vx(>Vc1h#ZKaTaBz9Qlb;E*wwgIzU zUa}s7*yR{>-PnUFsJmsKPh~+8pBZdv!F~PXz+c0nR0DF-E1ZtLyPDY6oJ_FNo zL^-bPIZ24uD^j{0g#9eOOty97Z?aa{JY5ol=1fQ&*K6N5`Wiz9xtF<8n8VW$FPA8L znbO4CXSW5%>lFNs<5P|C?rgQidYMS4o9_k^_n;^VJYR+f3>PVnO$C~^ZFvAq;4H(y zT&GqJp}qfY-v>P9!YSPQIYM$-ORkV3IhC=!>eq`|YnEAqEfXBmhq(sk02`?)U)HV@ z6pu!0&rldPmjJZc}NXP&i z%>ZnqiVv_6rKEf@@kOnmF5`U6TZoXl`v}$^(O4PgJ~J7eV@`rfq)ffAC%w=gTQ5<< zbhq22oOYKyM-0`EQ-a3J(6=17%0Oz87)VVjuAl#a_?6Dn=X=81MMMqfcD)vzlX&uC z3&B7Ra)U?%gwj{Uce(uZqFh&vW2eZh7hZK#&g!(xWTi%~-k%9my+bcyGw_hV-lTOG z@-1y4W}WGu@pXLAH~;$jY}7F4n-A|9A7?#8AT%Yo&i)vQoT_ATw!|EtlIl*BF4ygh zV5Ah)usox+!i)E(Y_0CmCTww%kNkZHq8r_Pzf7aj_U@9ReX&%iXNgvs>_B}w!Z3{r zwocD-JHqB@d)&#HNzfLd7-3n`*TWFk#_YZ3QC?MS-sW8=MTRru-Ma`8E9&Q`LME$s zR11H_%6m0wh$>hv6SW3nqZYqL+R^}kjn>cLIX{q+WR5%8) zQCIe|d?D@lld?&Gjr=XJhv5?4+YYE$4L4*Oma*V2 zAJ^;5Re*^+TXS2fWuM^w^nG#7;vz+?sSWR2JBw633*%>A#Kk9TrqiL%yR#z19TI~! zMMXHh-%j#_$9NR&)gp_pTSt5D2PyNB#MqrkeLW=oGJt2cT%Ic*UH2%&>z;YbED;{Y z(5>_77JR%Je7CbDaU~4Gd9Tdb+{YQO2TkdJXQTgCPkP`|`>7{^79V8{%KHZ-{kMA3 zgT;TYg4&2F{APTiW9a+6rDk|vJ7nq1`w#~lA8|2i9uzMf zukd_7E?f{Cvc;OIy;I04=S5ws1o;`;(TO z3>&tIW8}k`fsy1G73T&^)ut3=*NE8-3D#cQT2G_>3h~L(ZD^Rg7uJkHBiOJOSKnvG z{mymtsig+ zW=Ef9X%vzYet&y-{wU`hYA0Y|9y@E0(`fj%ss*WKcm#4A?VbWxe@BrV+V=?s8)Uh$ zH(Qszu6BP{3sx%%<+ZI8onxO@u)mCKpkDXfrzc)PIhy$tYJ2fS`f+e(3S)nPYA-C-~ME7Z{I)aB}PzNx#!u{j*nFIb+f zxVUPUsN(t@qd4(iUmJd5$TPP){a&m&;CXiE4u5W5fPhX~kY;p5ARnX@PHYB!0M`6X zCiH_&%yaXF1Sn{{6tMZ);69ajpa>^F)lQMvJ+<})vLB@~|1E+HW7{bHEfnQNuCt+5 z5IWpqX(5Nh96lYXY3^)xTpl*lXvw?7+*}O->XTw3l23Vwcxtv;%4St@FFsBgPYEZ4 z!4n7TY%`CFzz~j7k5l`pmD+zrYl!noCJG5HUrLe;*n-6*6wrWQ3Nd6D0ewdzKzY8$ypFK0g@7x6J8GBQI~x> zr%DpXs8A>dNJ`+9bd~W9UsUpGs^PaI`$cceMC++$u3O&Z=-PP3Yi*f6YdH@Nv8Q}< zGT7@Vd+ez3S=x3>@tGO}?Uy$a1zVRUGNx3DS^IY-ad?s`aggmDbiS30d6TOW&%WXIgJJKP^++ut zvphP(daqX>cFUW)#a8UzkgFm$Q#HSvLLo(I4&tU8fSXdMB>_$8%5EPA(3A`TO$q&E zHsDs*<@TNtAg$af*%?+1u2&1PbZ#~R;M7=|*PK{XB!8st3Py=)#*qAx- z*BO}y0`eHXseF>dzHym#^vAy-ZIO&08tK;hr=~OuXi8xqO{r?=i>fnnpF)S9gSC%Y zDk0m-GHRY3pebF_un92&nvy;pUv|yc6KE{d)B_?GB<=pd>r4iu+S2e)NXxrMC{+>S zxyM(Ep2~z$8bS>N5`i0Drz%@(Z)TIaN*h@%WS(=rt@p!z3KZfZ5FpOef`o%|LunA# zJ|YIdLAWtJqRlnSeq84Z1tO>C%w&nobq@{%XRlZu@LLLKHgt#9KT194{O;}nhu z*YlY*9eUq72<@W?-%~Isigg((twrxMC8RWy3N{U{DzqQ89 zl?KCb;BR-!o2Fk~Oe*Os8#fp4TeL#E{C;eif1cE%{(-0@_pUiLh%zE2R*T6te@{K&AkL8dJ@-c$&OUVn zTOa=>iDCRAMY+HH)v>7_!?gTz|7%W8UJ;?iA;6r-{6&)kY;(3t^VwSteb=k5PSww8 z9AZ_%vkL8FLzp)w@yzO-j7x`8r`K; zk+_BqXd21NDa3oh;wvAZV)dmiwpcERQ*cko$EG}N`RQV~-D{Tna6`V~p(RKCoVy^I z%uAwe->Xmi{{*Ly9uMD{+g28-WEMt!-islpC6&_8W?^E7(YBV6nfl+%da?I;h8yJ7On^n*(E6K`R!;{r{QdWnSfmw1LGB|^k=zdNk`WNPnUWXw~2+0 zrnIoHsQ5S|K;l(2Tt>GaApP{dWt>elEyKT9!xe}IQ609PV^i3v|_9o(*hhi$G zP&I%1r`a!n3OgYENrXq0y9_sA_Tw&ecB&n|UWV_^0;C^;hi1P>klF9>huN<&p??tY z`5hh=jeLYvZ2kDB&u{NrgJ~0>|46>vz+Q48c;NFZmeC{>fpUQXh^BX(g1M=n7|Mgw z2djw6az{Pd17<>o9&>@oM%Xe2vNWExh5d}un87Z|P<0%x zV4Q&f0ar2ps{sAPnCh4|S#TzlfMc>IVI^KPLnnwf=W)7I3gXk&M?7H*k8tN4Cx&SP zPL8UC)HTpI1h-k!2JgLCh7KACP=%H?{KLMt4zbzDeZIA zzC*+;D&Bp`_vUz_C|pWPjS)09MOY0_5r|i1RmW# zKkUG_zxSg5v&8uGXaHK2p>&c!;!nq{@PEJPFA4OIEA4-_w2brZsQ07V`ztLiCI4t? zNm)c=Q{!{l`=XF4b-@^&qB8!?y&{Vc{2v1e;>Wc0OfMTGt&x;j+7PK9nM%_*ehp-` z4!_8O?hw~e3qy;w<%?TI7l9|i+}Tywc3$io4z^^0?=#=5H-1Eo+t7iE8v#Cp*aTDM zF2NN{MeG*q?BtlReX}-umGxUoOBdP2rb7XJdNPjIG__G9;sHj|YG_VI4?dYFKhqTN z%$S_0oW$Yc{aiJWC-0WyoA<(_U^4Bkr#7AWz1UU@*{J=p@wotWhYwpI2hzt?A(Q9%Pn8CpT9{eaT%%NOv!Myl>I9UTui z7}zj_feHTik@}fQOMokHUK|5dVP>?wihe5tPVAzopAnw$&RVi+UUf{5NUx^*b$Cy< zNtf43`Owrgc$_8OE$jiyw);x*z$-pveg=l9x@`V@Z_a0Xlj|pGQdi-fk3&p4*dBKs&)fFL} z8lyOWaU6$RpdH(#GXB<1UnaGT<<8J|`x%0LNt3efCPz~wpP$EjUoa(`@0*15=%4vt zE**v6L8Tq@@ep-{kBFYwl((zRaDGt5R!RB_hQCT{C0F(6^+Ae)F{dH=Dy4wVIu!v{ z9SV|E-R@PgRb){sY`gapvVhGbY3+b!>>wr9Zmy39h&bN-tUbB#vP{Hs1=v$zDY;)$Gw5RCL*=jr1`21#%{GU8YHWFu@}45$C84CX~x@KYR%9lYB+_mtH7GOH>o5s{tC zeP77;I(U`gD@<$zRAfnP^dsZy$%G-qI}y->!ASHoUm7)YO12O&a#BXK<#1l&BxD@~ z_}M&pw;8xn-F!NmJuALih)C$xalMWA?p5VWWO9mzJ`(V0wkph(xC}vCuIpPa2B$3{ zACEwF2d0k{)6xj>*byL5-iQQ?T^J~p>{&6u`V{prtsC>f}Q7<;AsK;$yuX_ck4YM`vn|Cz!u{BB7 ztf^EY9$lFle%;!YL(?G(Vkf`TqRP)rluR z*7qHa+hFXsH230^&sd$O6|>`&%4w1kGw!Cx?K^igo@x(+_YVhc>KSUWt0 zqrQ}rnv!CnPFxRruD7ggv4NVDZu8Qk$&{oNRx$g0Xnjj`XT#J!_^>pKMW3Ob-l;=; zMNuB51|eIHsiR>BX5BiIdnf*cx}ptDnUXlZXDz7_kD$bten!bd8+tJG1XfpO760Z| z*)SuQvVFFl!8}EtRPQE#MMMTwJX&h2zXz3OAx~4a3b@lH?9lNU549}R$l4&Zmz04r4bK@f6&+pomWMc%ABK2{v+{x65gzN86>|GaA_% zlRCSkgldF-!XbC>GRY%z=@sRCn@guk^p_YgMJ{~lpsi1<^O@4p%3=6CFd{wTPB;+z zV6fAf(^IJ_>y5Db6^a3r@?o07nQ)_l2b*8cMKaSw9NpxG+$O=^d8qc5+IW88^V>k6=t7^fG<`gQpRJ=r=AhFIikbTNi|vK`6L z$=Rj*liy@2+p;u8^yI5-$*4!iTWK)u zMjX3Nm6NO#Wjqe?o~grDA7snlc-QCf@mB{nZXdwy4mG1oOSS2j-b5F@t3<_y#y)h+ zBFch3uGJvwm+DwJqt-uTHK*lSeh1$2GSy(rz!#@W;yIF0k~&ZJ-PM#B^&4y{89pe( zM?`Ohb#i?-Tk*IsS$WaxcXiY+Z%`RZh2fpn(I9MV^gd8Dp#Frmjg znad5&9}USxmGUaV>tpT-W+}~RFXV=OL?Iu!5adtWipJ;Df@VCEq5HgSvWvJAAUW=^ zU8a_gnfgtakj!b1%jtU@PbXCj^k7KI_5&z%l*Ro#z)K zh<*v`q~5h6bB#2VPJR1PAuuV5=|r&0Pt;{KXa7iD$0V^vAZV?z5h)Dm*75jz+UG^P z7FV@Amti`Iw8v?MH7uXCkJ9o8F2cELZzPSPS=0F|#Ar#2OIwsmNf5uqrSKP} zd5eoa?0EkaqFv7}uT4L@gfpwNU{Q{~3uP>Z3em9YIn<|pW6I8|lze@UO*dmW9Jr>Z zB7)d1>x?IqSGCLiyFd?oWl#_NO{j^S#z8c@IR)LE`G|Sywx08LdIbDP(cpajf=XS?y_Le-_bwYLt4{J?@dqzj_rdZ>gq~zr zljIF18zWBG($e&DucF=iC9cg@`Rd-}F+Xw>HY-}{Fc|G7 zMC<32t>#w&zTV6VTL|u$^2k<+q?un+dv30F-eW%pCxuI9PjYY-e;br8dY+y)?R_%s zgP~`y@%X7C&ZgvB;-+=xt;We$kmx2s##XBrOlIlNWAC^|2n-TtcvXBCHyK4DTtx~A z4VOuK#+}hQbiSodu=8%IL1}sI-_KoQRirhxr0IUJ87^cE&xom!b6uT2tU20D8$5lF zlpSmuajixN_g!kG zwy9_M?VpqXm4D8}&ibGo6=(@!v*$ygdu}}cQ${}gAApwlB_qdlfEzOy(5r53_b9GQ zMa4wslbk3P4rL!kD_quOQqoPQQ{u?D46avZlzXre8)JE_I5=;B8*P<;-e@}<&MxTu zh+ZT1Oj9H_IaD>)zQKBt-&Ar3=|tI@Ui1y?lcW@0E!bgiQ;Irba)EG(u88|6=#p~2 zDLw4`{SXCx#pOUWcfXwoaVS^!Q7F%{3YN?TX}aW4a3bJZTlxyncZ&Z!@YOxx&`Tv+ z)EomdwBzM&oI#3?SNPX>per*#<9S!KFFyHcP6$oeE(_^on&KyK-3oVE23LEj7Ly6z zzYrICJ`8jn1rjpWVWVOiJ!g1lp*=YH~esKXQE7b_x_0 zZzm^aVjwIIKv@1`KK>q-pZS;;4b)NuKu6nefif3VI#`-AJQ5l40YPLhnxmqCYq=EP z`yDl(2i(g($;m;aysBb38{|G7zB_j-;_4R01@qqh2)p(K=W1{j&NppPSQpNdfYckh zL{$mdNL`X>=(Fi!l?u(ZuvF7o^{XL@n!}K_`5i^(orvUssBPwLANF|_dm{&}U2fqe zcgv3$cy26BoBiBKT!}V0A^d`Ccm>+I!OtQCa?1u66oz;N6%SfJ3Vj$CP!fj-(@ZAs z6yrXN@4$ysAQzYBu}ps6t0-#DgB2qK-uoC6uPleXSgTs6R@}Y7d^5g##p|1$Toe6O zVRfmIcjg;ZEAC?#ji#E{%4nHVPak3G#M=1<2@UZw$QsBH)vlA3g)?&0?_OO#nBez& z9TM7VI!--%FB+?$UL)KuIp|f**18=#rPz)9xQe<(VgqiU zKQF7UvfcqZuYk<^ti68XmL(k(D7C=?r8b0asN7s5r60ZGqR=wBv-NwtKskF?)TWnR zLi-|Eq5fF%1U3^Y8t(i&!;Yt>$}Uq&hD-w)kq1LCBw%?|Oql<~65J~+fgw0Yoy@=p z!|G@n_WQ{tG4734k5D=e1ETG=WUp;5+!crQhG8vlaCOuwxYJA}We`%+Qn8ixvfR&e z_511fh27L`rBA2G!xUC3--@7>*hV?GfzH)3!4`H*l$x){_D@tjQZlU{*v+ zCaJ_F)*rJXUVjT&>}1lF`ryUDmXy)ltCynclQ4|K=fM5Z>gTZ<6d{R3!FFgMLR3J6 z{$t_w_nZa&{pVZsa7Khh)JtGb1yCpPfIDh0>jM_tYd%gUsmlsF)AKidin}Vf-YGT0 z!KaN{0(S_93(eb$E1bJC?w@A^OUR7^>VxSJ+;Q!5*M=nS#{ zIvSf8-iaq8R4InnxtK}LIa2kGrb$D|D>C<4+eZbP{wge7bnOYN4;ZksCW5CNLzcNz zO3lKE+{NlKzD_6iRt+ZYF!HH$JL+GcH!k*Tgh{8{u?7Q`t;)YslUE{4cFrpLLTOwI zB`%5^G$ zpo1dA>aJaC$ieP5qudEn8RQnaWgfjxv$1 za=7NE4O(RL^!wAGQ~J?pp~853Y?^+ZQdw$|RaGkcUZji+=@3Al1=lp?hquP2g`?)M zqq$$A!bkb^X8tV!p}Fks^TVV$$ynntlC-yEWfZSa93^JMect6QP);OPDIfX-Ctz*kVT%sF96oZ2nrbEguA!q@ z5-|*C)Rr3gN`CVOGtIcB^i^(AJQkj}8o-hncEtzBhg=X9YB&fpil=E#0dhm#4{u|G zg0!u~STq3qLV*E6`j5>s|K~jTxsw$~55f5eVEAA896wbWux8HAP|1a)4{@Zg=*q6e zKS4IC5^}#X#9-}Gu~#!f3Ort1ODM<;7JS!9nYyEkX6I~EHH|Xd+MsA*d49p_=Vwp z5AQ#Mw{?oyMx>;CxrAhzSQ(^fE zzg?a#?}gupCyp%fYtk#Q2dWfRK*x9yc-UvwP6Rx{kHubmuyS=zA%VT1g8{BQKOK>s z4lk^c1IeokR4+V6!1KwpG5?TPaayXx2OvtH)&dRV!)Psf0GBFGY=h_9^&+Yxd%C`5 z{et2@X1#7wNStWGeZPHqhXJ@$EB|z<9;UWDIOKxDf-c+$2zy{)iNO2+7uk*D!EB(k zXf4pb+yne5Aq|}?7!R;Pz885Gkx?fwnG_Y(;TT2Hm{cMh3>RW%~&Y90|w&aCDuXHL3Ock)4hl?v3zHF=J`;m_vJxNW;goE-QRb5{bE zdtI}L6j$Igi)|>Xk*L5##CWd~j%WVX6yF87 zuOY{LfMZz03@0FuY>U*Uh*vzaB><4_#c;1M>4=l%xAIV|QVB6&{+AiX@ntt$)9NJ? zt{YyVFVOxMcXK%bWS_chs|Jvc06;oDh+4HuqoB*CB@1J1KIxxG*E9Tn06;n`5YnBF z?t=X&mGu5VI{gu;UanQ#d&mS<@3l7;ba`j6zq(EqDJDZ zi>)d&H&sWlE;MP)d$SA+vc3?}Z^sme^VM(a{f?Wjny+G3b~`I!czgZuj(RE>Pk>fT zfn`3MQac!lkT19O>d>_qLC?QNzIeO@WoQVMhr0+{k6yR_;F6H*<_PY+Nz02y3~*GFd0U9SVq2Y7>E8cL26>{?G{K9U7#=s`z9?@4wB9Qo;B^;_XnPS&?Bz6x$pU#Nca0A z{xt=(if(kRuZpO$R|oUIA!n7zIS*Go0{WDOEl*XE8qyAlgkr%$Fnd1__Q?~@ zlx3*fbr5FukTDIhX=jr?Jt}SD_(b54)uXpH74^hhD{%1^cU(GYk>BqwbFk($d?D-g z+dKDbgjinHxd6$2yZ)N9+fho~&8JWu)#}0xeAAxqMi~cCK*;p; zs?d~G44m;=5*K?*eXVTB)+R{99QNTP>d5G=pmoihD+x%hP}MYt)QukK@)@qKXsLz2 zHTbBAU6iw~b&T*nC4Az+_;OH?yhBz#{7t0$JxD*Z;CH0U%>3Vw4(ku3nRH5)2zOIrMU=s{TPyLuP4Vs&r&kBA04B3B4-ODUFKZ8y}-md4Z@FI zJo&M2P!+w5yU{ z1c$0BU@_odMTWo@gZ22BQJZGfw@x0+{aG`gd&HVFd2o$vvWmN}1Q8IOn~y_IvE@P4 z))S;ELNglc`|Q*=UMA?1f#Dx6S_E6bMN8!WJ(?dMQHa%RsHl^bR4dl`if#C5a6pH~ zsue!a1^yGu=2)zJoU{tyq8$g_IWqmjMZ0b!4ybYG(vfnn$v&iGWaJreV%+pK*vwr@ zoZyK&;B{pHPTE+%LNu~;TN=1-2Kw>6Rwtl~4M>fv2GqE2K#k)E)VKsESBgK8POJNP zlS}4Q5`=VZ*oUHzVwUhKv1xa@z{@C?cG3d_p9ucZ6RCiO)Y z`M#3k`3xD9IxT&q^Zudk4EuM5uXh6c?)XON#p_c$$_0IvW92e5GB>c$PmGHu;}aP= z>Z0Fg6wE{^S&TXtV^#@F-6RXvOMQ_yq=F35BZk_0YQu|LjFA#>-ZtLQ-$!3%xmkMS z#n#^F=vHb`36C(e$GqR=l{VaH#fmmb9rbq4vsVmK)PFnuBTU7ID{|#1YK%bEj<(Au zKdI_>0sJpw8jv#o0n>h8@GoN8?+ZS}G|-aM`{@gR6Vv{6$zS)VUz9h9fNlh)W2Lj(|Uw-u>s}n_=obwX#Xds0m|E-m3(_f8@#pN3 z`=PvXY$_Xs)l!(0Zv#&Ex^8}Nav42m4LtZgcknKa^p|7NWZdw77+RP;MN2lYOS4B? zp5V!j%Kk94Y$LpHNPD3n#BoP*U z2~Em220d=bs!<+vzeHwM`Alp1hWiW!+lQj#^;PQ&Cft4$bEZ)oR<8k9Mj zvktRN(VA(vnt6Sx?a&)cWEg8ZNoJT8tg}b#dJ&%|K5ju;2<)u0hP6W}gwQ4lNWClz z*dCO2V&RZxd54m-Ku}pW5h7C|Q@dk35f9JrQ^q)^t{5oj>9MmaLQ7XS4?C`Zrc{mL zGv!^LMZ$U^^!^~5Z1Iyr*NkYPv#cM#8$}Mf>udX>ulkwFa*!seE?W-w`I(7U2X!d=H2gbFIvEgDNhgzM_A8Kx(hl`SLTLtoU{SD3S_lNuI%l~Hu7j(P@WM_zQ zKz8mSl3|T1qe5+6*I{=}5FcH^W(vFlNMRGXLlcA?# z!cH7Q9SW-v5G!J5GexoD%oWdros3@J*l-Yz@HoA805mslVL}2}(LUuZd|pb6l^V)? zEHwPpVH(!}?1-@T*7Iv%PWPV4qY%ji;pq2V?9UeXKy$h+vp{pY4S<{BKAo^1GxffW zlN2Ml!-&EFV|wZ;9JQV2l9=-MVW@`tzsLe(dYqC>%|Hir?s{3JrWm37yF_+DH-%Q# zQm7>jHTR>dhxJlWRGJ{z{Xv@ByT1%*KvaId@M($*roi2^Pfy$fM-Oe;0&x}&P1CvF zQ2CfMqmb3Ku#Ng==PzJ?x}7g5PB=8Im%NU+i9I%icr)M}!u!F0w>vsO&Vq*og7$=s z`Sdh>eF3Ga7nZ&94jZ~G@mbQ;bX}ukU+==AzIWmax6!S|4+bWa8smjM=N{2y%xxHI z%X57c4*7TUg3mq`Req%XMAA}?`$RC2Ekb!MQ2qp(CfX*hqoyyoPhBE8h-&Gv+DAC$ zh)BZ@xKQ55a0)#QMvjF&#=$b8k16?ZO^FnIaJ+O$YlI12Y!8RcV%16K1B zSptc4?=aQ!VlldN+mJBpWle-X4-25V4ab8tw@_8v(Acehg*9wj%QP(fH9;Fn`w49RN1y~<60R8+A%}wPO z&5d6Ad3BU|&oyR!FfeCR=w8>HL)0z0jjkAyJ`K>^93N_Kpa_xBUztDxsZ9BoVea2V z=x1sJWmM4Fs|z@LApvJEnb;b|%gr!^OXh$OH=MAd=6SsZ@mQ76>m`|mi;+y1#;ep@ z?m+huqX?HBSqg1C_5}X`hHxyTc5<>(p`1FBYc7}}ypE}a;#Uqd`t$~CvM}~`63j4G zh=zez#=8tw$7_kR*PF+JF@+Gp-PqH z^PF|fnhWju3!{Ut#udtPBGGuR&j@Jw(;^B~algnSL3~kj^(KklnnM{cKTv*51v}<` zdG^5m4SK*IPe^h89?<>E1O7Dueo@>U>x~hDV4pn!0i6P&Gxd^2jbiS*8oi*kmPQ@m z;_kwr`$tZr&xN|ATkyFXWINGPDh>gP1tS@1;kcV7Jor%IfG6)1-?(Vhl$;6hqoOtQ1x)XNE6_&Q%B8;m9Vkj!JteV!59t0SNtaE;|G2$=mEO>Uk!A>zPS&Z zu~QJAv&TtNL2Bk>iU(^VY2zCSFJg07AYv9cUv+yIAYNEFwUiqgwKNbY^BV!(BHj+G zOe9-B<4?=L`Ttn^3aF~K?q8A4Lw8F{gXEzb1*D~=Bn70U8>FNgX%IwOP$Z?hyBq25 zc>Cb>UiJTd_y67)&%qeNIeV|Q_RKZcp7S@4`;|Ep`D%rhBKq&!(EXiED)(11sjL?g zR`1DQ$)pVi*#$h1WKs}Q3&Ma8kW5;`!CPlxmeoYR*nRzHmpXk{lX5smG*8Wb!jA$Hu?^`TLAqQ zf&Wt=m9*4)Mld|$zF@Dga*I;?pxEZF#CF0wH;_u&sXAu?^@dV(E!~FdeRqOs_n-l- zY`f+>(k)Ex{`1h8TXV9CS(8JqTdDCU$EWaWK4%iv!Va5vkIi4% zD!zbvhGOb-U$j(IJc+I!g*FK?c;^$b zfo^1M6l|Y3;-f_GJ$ix^f_;ygCWYiy1kSHW-vx3uOeah*>iTc zUDLJZ;Us?prs3^$SgQA9-;WiG$?O9f=h2w-45ctyjZAQMZ$^pa*L+LJC#D5{ckn=R0DFnj6kjTZ_x+S3EfV6rAfuO9Y~}5xUKhdh zBZOsLt26$apL-~V6f^QdD(*+H$Hcwd&dDtXsl3!O%sy!+NZn1yjYf_+RA6nIiCrny zuVK2~=<)nUJQ)7I4{I)vO`S@49#al=2-Z8ewT?kG6Y(iN;%NVyLt8QfJ{0&X%CPYX5P&bDhj}p8f>v<73Yy-)gU@z9d5E0 zsGk*hb~E?r>6#GeB3*YzCFil}0%o&jzkKh-(as1xtdOXTYwxb#zq!!+SWGr`aZ&ow z8aj=1>|&}^Tm(KvFJN~>_T(;q{YSzj*B^>S^j{fb?PP3w7ta5nqw{H~|Jd8CD6|ECNT2sU*0=@q-YLzXOq zlAlXeLO}|KQB*$WTYtR_d&GaKTAZ=Ldq{5UW?x*C`bsepRw zstV=I;-o|))Zv4E6ocWDNs{56Gu^)3lL0pZjbL(0{;V^bDtYU9Sl^w)q0!O^?p8bB zn$MU~G5OsBmD44YFBL?Ys6IE$NFZ9gy8i_Rwam=24lUBpAjT^*swJY?WOGQ>ICkDC zV&k1;)preHDnxa9X<{1&%+_LNGsk&eDqKKQ-$)^fF#}Tu*&)$gpb89>ni_O-#sM{fR z3L_z-YrM4bhetebRgbS{_)nAGHsYz9yiOHzbAR+P#Oav)D>r^`NICb)qQPgBz%+G< z)MBr`x_3CV>eeCWuN3hP1NrArcXo?Lp78219T}Y2M#%fH&~`W<*_J58np}cT&M5U5 zJ6l+ZD=k22t05PAS;O_c!6QhnCY7POu*Kh?Y0u;?6W~YPD;QVL&&_*SgRId=*LFKM zs?9;U$-XQ0b~a)j@#@>>L9tU}3Q1&-Ur(S56}~MJoVBjkP7^&IGE?j!q$8Z0Bg4w8 zB5+G7rh%<(D&LgqI?OvptgdSK(Cp?SvwYm~Obq_fDFu>M1}KZM0bbydxT<|edzEYgd{~buP|NO-!2o{+-Oc*#ZjDP#X~&JZ;FZQwSR%!pv_W!w*Z}=lS0-P(R$W!W3wcd0(-Ux+5x4#15pT; z2-&*@-939V@a%J&5c(z5wpd)`uH}`ZFXQ7E>@4Dxne?KQc62a`F z7TP7Ti{dk3fEf0`RqG)|pre-C?!en|U`d-20O=qLYYGDH9N(vSvUf-F1qjK5_8}yv z0;bg?Q*uN1`v6+{!JxlMe)s5mz^qUG?v|nL&XdVvB|%DV>sWPycMo?8LcDukX<*_w!DbC~BPc-xfEnlz>O+RnpR2O0A{`0Q=QbFPw**hxEdIpsl`GMSld9ZVXv&HpzegMT3cgcsNg8)CA5u{zkM_BLV= z5H`r=TOb{>8w0(<`m6m@0$-EYkG?Wa>c!K2c3o?_+mQTc|My=D>+YNvi=?rUv8}$n zv5}OmwS$eAzKxBUmB}xM+z@vP2LO621Kvyy@Mix#h4;>#{^#L-cWS?8rKzBsl&x!v zq8~L%V70IMvgBxILu(DH;gtggLIqu|qgAe#sk1|NLYD$Y;pIUbCO$hOpRjpR0a6l9s(-xm)XIi4WiuQ9es@gP$Mh_;;$;(n zg|Vvx$ufnUc#}B1A>*Iq9Z;8}ObiJSlqHw)CJTMansm0*!6O_JUzi0n)u{^Rwq6Tu z^Z4KdU4_g`(w9pvG)?pfeOE` z(MR=nBLP5P#KBk71f^W9h#s){I}>1(E3^oiZ>orxZ7IRuYRoA#NnWE$z)vskUIFdY zb*s3z9j1a73mI?w-vIUexliuu`2(kO>1U-gJaKtaGJWZu$8r0N_M+AuxyJv&t+e!j zh*rS2bpsp&u)h9F5d1IP`p4CUDaavY*y7jd7^rvzHVL$7_1 zNYD!+IZXKPSsa_`u{1bukI}Yob415JJ5I|`e{&=#0Eo9CeTZc>AnyEhT_2u5kcDf6YOIdl}e(DizbQw17 zLsP*CQv&%HT$&1t-v`TX-_rwuQ~tbW@SrI(>m!qw)I9J7iSq&2_i$*a`ESGsKet|J zd+TQx$V$GE;RQBiK;Q&y$j;I^u7*2%gRI!??$9UD5D#?f-(Gpl3&QwPXx6lR6vvNF zm2uN+G_6SL--(qua5bk=V#e?ZZb(3zUGCVmXWO@pF7(9;?rSncl!c8&e0VwSM6 zV;Q|Ud8?SUMjl{Zp()L1;vY@p22n3CK)(@_m*{lnAn5_scvZl1pXKF$wn8dq7>cNN zEavGd;}?iGnlmVvMecA6o$HXpUigH4ajO3MK?NRtXtYxQx9Y{mRd(lazei1PhmmUx zfC5u*(7)wJ-O1@c61lAgU`w!Kdq{0~z8@5*j1YeOK_Kigi|NyT)2{4K1=BY7EW)uS z(3p}g=1gd*gtvs(FFp&Vcb@mI*N+}zAi)n|S8T<}A8 zY9}5DM#(G7`xdE?_*%0qxe}9IH6W`qYel86ctgJS+SFLlIfdG~2YoF;Jta6&jq(0d znywFPy>{CZz0Un_q`CX7BH_QAfnb`L6@*S2qvzrprD(aKEZ=R#;+oZZ^sOY*ZAy)n zCJKc0H?S8=F5r?|u;0dBWSl`23Bgx>&R+NTk_~-MLAB1Q-K-^&U~|98KIyHcVc$c9 z+EE$WARDX-^at;HnQ5`M4AOTp*WPA{Kf(|hjx9A_(0Sr%R|_O!jySw%SP+!c)G!>% zpM8sZsz<>rI2MSKH2|7x~BiC_}i&6XVL z44VYEpT16Q9#6JsqcbL?pm1gmUii*w4)r1Ibs=tI3ULhkEsaKSTRycz%#u8^^_^Y)BCyEtH6t-zs}}(hmB4IR(OXI2Pk0F0p+(aft}zfTHUU1Z{aCCPZ6v7{*`dnKhKT97?tQUKIR&A7 z#6wYBko4(JndeuN#|3M$Jpm4iLi`T$3Q4L`O;lRJZu5a<0$v|&KleA-T6CC6ES(%g zGD+HHYB!g^Bno>`=ty`uG5gk;*TTP=@{xIF%ggr++0S366Y0TFr7(PtKr)>b8*Lj} z|7KPMwMvS)gL1GeBvE9nPZxn;IKpP|pys}W%+76PcgbnZhrM+7`e5z@^V_voERA7H znmwtblVw<}lxCj_%M}mTYG-yFlgExVwF2RlB;kVI#I{J(dgzubSZa}#y*#h5x`)9Q zf_W}r@g;HHD64mD{LvvO*i=nC^<&b~RXoCBh5G64nvWd2XlQ}EtwkQEF3;0ayF?d0 zy4qXVe=@TE42Ws|-CF+FU^r1WRqbam3}DRsn?w3#jNgp!Z_rsZSCy)Cv8Mkq5GH=F zsr(Z;YeIO$ZdGL2d0lNJRR$6Wk7VI$!bIl}U2vQr_T0M!UaBGemLWw250sz)FrbhO zsXl7_&=})JNQRU$qM#_}10`=#GW*~(#_gDOO^)b7|7sFWU;JafTEUIu+TMO5aOOFC z8McVHqvZaA70E3H{zcQ+&0m2q`0I~A*m34R1i~*Z>p~;^3{w6KgyUM%XG*=KF^iNU zc;;28LdX6?Abbo7gln^Y34}@h4upXttH=f(NFe;s&5Y~MK=_S3@~3m;d-o!h@84tn zzvjs=b~shbnrIBie-8Cb2*#Xj$+Y)n09ZjTb=K=MD>^*XBsLTgMj75{!CVK3Ds??#qPR!FKW(_Y|2`?}3!b zn)=k*oQ`%q*mJkn)AdX3M2yee)%o_x_vGCwb%jdqsSgSsC-voTJ#VxJ4>G|6>T7yw z0!6nGq$Li+LQLB2_O?~&8dxU%Eo%IgO z*Wx_wv!m-1^TSMV+6TAG`RE=HUi>bz6NoDio<*086s&UNVE3hVEzt?&PE#KqqOP=m zdY!eh)V7m$X}xfe)>j#Cozu=uHdi}(dGc*0>U`B^I5;^#q@{) z-y$#Q!?@dIg1Yf!A&(iaaK#8&yTi$k55#OHmQ3hzBu{|{g%Wz4&&p>l882|yBI=B< zUmKJOI@6E^2o}XiP`MW3>hkg6X;&O3@X$1`_gd-^AVYLqXS3W$JgWZ0YI2= z__g+UF)|l$kl=84auZVYT6D%4-f|a{1X(LU1pP3F+^lVt|1p7OwYkaf(0{K#f+bMU z9?S!9x5vMRY!e^MIk8~EBu*yzjHQNFFZ?i&6eI^B^*|toGr~JJ-q8@?gOg>UbPyA0 zAeyBr;kpUo0$t*c^>KkJx`W7|`ryFm)r>@P>xjdR#96Y~V9$m9JHbGO5DXB}J_t7; z;s|}{ucRLXzuQ5i;wra_n!BjyH?S6hwXkq>Rj2|`1TH=kWVqMAd`Hq13Kz%|d;o|- z+|);C>CTg;-F$9z0FWghFzYfo{|pZU!ew5);gXdYM zk{lRNBl2mC4y5}-D9$emtIzP>oZojheU0#gRs-jhoLI|UjZK03{lsa3__mL#(;oE; zIIr(V(5&dkegM|!z0)Z6HjsxJME@j$8v%3(`4|RdcfdlkoZ%NKAHm&zqn~>Tzo1W@ zw%(ND95gheFlB^C(;m+s`P$CD-W7#Z4WKhU4ox3z@)q$(yEpVHF@zqV-#@oK!xJD~ z#u7pXND$=h#=8pe7(xl)YB40Yf!MU|@rJjodZeRYz5!!8fnMRId~|++yg(7j zQibo1?;ZFwk|pm%bA>_1jepp{OiMr|T z(GauO(#u_JdiG$yJMnH4qr9_SL4e$B(Yk`E4pwlpKo9mJ3W)DiWK%+Rx$9NEc9$5# z4eYt?x)|h!@N2QQrX8k}d5F6TjWVx!Om_IC7r`8pR9vz?+z^e0W zC13A_yYcn{>l}s{cM?$J56Wc#)B@DFQ_Oz3Ye5h28-Qs022N~<+1?o!x7UCpDd)3B zdu?h4(n#<$2JF&uvo_P5`$GQ9Di2%m)zW zCBhG4-+sIEcztAmdjX99{?llHhe^x&s=v4wh?n_$0-8HI1G@9$`2g=TteXXfiGOgI ztE6v#i~hqM1+M?4rMf;)peDdXQAyPid#K$}mGMZw4`LL4@NbxR!6XBar(Qsc?p#BO zD*uMSq=s?ZvnD4h`m)z37@T78{p+r`9ws4PT5V~{?8Ie$=A8gMzE z#u)C*(O$_?qk385RSsYcSRDj4oarJ(_PhkA59Yyu2}>3rP1=HNK;i&@60g;LqmM#L z7>VF4OlAeK>(eY%=J3!7n)wd5H;fb;ef%jEXZv zDSucw2sHpl2~njC3@V6l#spFU>;^UoGeX$`5Np2Dh<8i*!_1mO2o3Bl+~gtCc3kSa zL9CG&U|ZWwz5({B@PPd8-h>oxcifQl)s5dCl2wtI=vgw))lKfS7LRN!_@>?5C6E2*gXaI`eJPNJ z;Pgv)_s>}nE-2ZNIvyb5-X$v03Lq*#CzfZ?35WR za6BiFjF|#G^2EmXuj4si2srGQ`@WF{3-62MbM{JX{U>)}VrpZ#&|a;G_2#p7q9uP3U2R0OR+Sx6ckTkG zsc7jt>;lC`%@ko~5noH9uC=I zO<90qiJWwQJ71Qb)|FoxwnO;BH{g6$0UVU_0Jy;a%lpzl`0`7rIC*zucW?ew_8O#G z*;cvFgxE1up!QWdOVp=ea5VoQ7g$dNylGL9#zPV(pZu~Imn>$H zirbE-+>i!N-v#ArVD5*9ltz93=(9%5N0IZIk3ShS+qP&T!MS1_E zbVJI$g|QRi(JLsePp;sfc zS>mB@(m?Z}*vCs)=ZH1)t%;l1NX#ZGAf~Jh!mD zp1{`X>#|8-^(uHg@N;F)@yH9YZBp=_@RREdDzUB$vBxfZJstzu$KIBGz93T5u0oL9 zK}qc~)PubSZOA~c>KpLEJh?ahbfBpz7FNUrymY)#ve3ZVL*YhfuH(R{yGeyN-V4#? za4zY?gL&q?DL; z1;F{p-~UK}-~MA-p^B-o?Mr>jUtY#QZWRuRyM-7w2#EZDO%3{a>u89yOBt2;R_hD`UiBTE>r! zH=+4!c~ygOhv_)+6f=(%Jqn@Sm~P$R8@5^mr*KQ)Q(5 zWy`+U&Eyh9LCOM0o8Akpdp*M}VvhjI0<%M_4hOE2OxbMK$Fd^Go53u#fnC2;twUIWxy-v3i*WCr zMAg5%`1#3-U(8pkmhu!2w$~j0(Cxg;DF)W20sqdBs4V=8K;D3p2Dxn~*Q64pxza66n9XR#Wenl06inzj}? zEm2>ul9=D%mJIhG*YNL_^VnQp58Q^;e%~%Ps5)=eOP(V-d+$GWgzj$L9e3bT&To1; zL$x18V{XeJPX@<0XXw`fWpA1WEaJR-MuXenR3Ymoa=8c zO(kmq=T3F6uKjxAFCSg!>6O2{@&6*g(w#Lj?`DtTVn)gp#vD?tQCU1;Ym%Rg7TvOz zcUEHh)%OF{ob#&9Y@LR^Q6K7KDip{MivE`pI=_|jCQM|=Pn7VpI-_T+s)Do(A4mLF z*zB$=(yTo$qzo0XtEBX2d1{Ygm@(iWKmH9m&#>=1p?W{|hx}NG&NDM2d4COPcm(`` z1U=^S^Lqx}j_{m220naqdpcO0>2ovWIhiJ#CeICM|@9ZxDQ zuhF^}nUS52@t8Dv8Ec^#p4b`&MaMD=#F>&`Qypm(kie+VW}0euNi+-8@*3)6wshQd z?;bN#D@@7h$T6slh1U*$b-b=oWWmHuJ1tk+mh!Nsr2HHoSMO637D4~;)CoPP;Buo? zA6E()lyQ^ue#%q&zzxO&!NbZeFw z&iBpgYp{a`EOtnUhy74l%Jt&8YjCS^;8WDXs;_v2ld4E2UZNvj?0PWag$pZ2PsK#x z)M8Mk-b+gI99@r;m2UAAi6C*YmPC5$6c7`#v$sEH2h6CS-&M*B67?;D41f; zM+o#hxV_q}ENBsOk38#>SH>0slR;GRee>*Unwvh~({p@2S<*_-Fp4pK zKXwK>lM+T;(mTf#)To#nSh7X;Sszd4K7wL0Isy4fZyur+f>#fGdX5vDJ$5d^xFn1w zk%TZTjHW1zrW*|LI-RBa89zVSO*rcniPhNy!xX4_uJuSL3nBvH)?P8MW+kHik6fbt zSkABrUjcGJv4!hAFaPO$%v#}c!zh{VLG7boh7-x7; zrzR;bR83|YxZ`_5ak4Y6-8j?i&kz#AY2jrmX)qLeRzRS5%^0?b63FRqCQXf;TSoW% zajU4nQcZNCSYbBCoXi8|TYRa7UWL@u+?ISvWX)YaweL)70^GIH=|L-x7N;zXzI%EM zRCnfJeR8EVf)>D_Y!X*}9TuSxhUFKAV@O#!7F1jusq_5)1GSZ>F=a8*{N&^%k>k%F z)P0lu$gXax@p|2BIB6?z?CpIKcHE7`t<)#@1|wl-MMS(LTj_YXVI4`E>3!ICA_tf+!E|2KZ3d6S&*O*< zYiCa35Pb)xG^-SPFL=pS;Cu>_hzT|r>*5OQR$XnM95u-k(d94ka78c`!p1yN7LD09 zQpu*;3@gOPEEQ~Xa}PH|dvn5sq)#ftq{KzRZzPXC#H5$MR+xlU%Gc)R5Z>cvYv8fE z*nV0*3iqtw?V;8DY*&n zl|H7i&%=VNW#3)3{yE2!Z`*WRf)*+FAb6+oy^o<*`e5m^9K$-zSo7-FYh}oBErU*~-1!P`fEj2uo3@#wlAy8_@Bsrw!YlNkrN3jqo z^Ck^C(oZQKNE^%Y3cBW9xU>_MMIzU;l&Fj7QKUMCx!74jrX1b$D;`5+lBT#P6Y(~) zVCp(z6}hJB@LaU87f~-2t33POfy7H}Z0%W*=kC0b;EoiQ_BS6*P)RNJOryrwgdfjG zu8LbWBF_0l$GsCW@ooV{5VUfR_bYCAljW3bLO2*) z6$`}x3vD5hLv-D?SibOlUfsEZDDEQ_Z2_T8j#9|D4^|y)o}@Q2oVIx}-5d<_;1uKD zy!aL{jjyswZn(Nwqh=JGh7jyv{3eDf$!DeXAOW5QSDWCjY^d~Qz4-UY!7*6QUVIq* zR^ObaW7efE+Vt;V@AEmy^}=1?m%Smcc(**;A@g0uvXOqyN11QKpkZ89PHhXdgwj=s zPF2eo{drK-?ZS-?*wWNi3tkS&5^e9#7&Y15bxunSIp7)F`#c^oH4R~YZzf7~1 zkAHo7`Vd-VtB!uoeX127W?Kt^kxpo>akjuLKerN&t2C934xKgp0UaAZ`q44y*SQW1Q zW|h&}mb{)wLHJZ04m1nG|?fK4W(2>HL%5&X8bysJ?} z{{boYcg=kRJSvS=47_gjPV0s&0QD+{G6z7t+K=bW&g^=g&&>ce$4P69OT&o$)aD!% zkVZt4gZBhl7N!ZV=%xJPydKbpMok-t8kpPZ{H(c$8vdu|9u@b2Ll30p-ounWHz*FM zxi7D!-_w!er_CK<#3o7yK>Z>p<__E1PkobL^}EHfm`P#e8Cl@$0(cWmQ|HZ|M_lso zuU}-Awby7GCd>lWvm8*Ch5(k8#8 zY8VeG04R&>=>G|r&IkcaPaU*nfdHlx-dZxftPD{9^eMg1sow{u1*i6@(O9EB*5j7S zC)$ylRE@;|V0w92t|_fuf-%sFh_@-vWB2G6z;p-)q^7}(4M1d24{+hXL5Bk*Ip`68 zb;|5uO>b#zFt#q`6LtiaCz8uAqS@dj9*LXiOnupt8)Q) z`W4ZNBF-7M-q<4R`$xq zwvJ|o#&>bie-5es$in*VE-?`?V_SQ(7iNY)j^eK+Fp#N7G*Y@CrHhdM0e@5&|JxwH z>%y-o_Ez80WHVGmDH<|xVlh7vf9B~8_{`>LM8u%7zY_+nYOyi3<6+p->+wnJy~ixO zYz?`OX;Yx05Md8c z3Ipa))Lb4=2kLe4fKr&YW1wD_D8B)Ip_lDLX#eMVc8jRq=yXd$B4n*rN(NaT{y zKHF%o^SH(F$#ewJY!spon+`y0E{=p;?ZLsX4Qq~@zqaOra3(G}vV05>hB|;derQjI8ovHOD1D49*FpWk;&eFO{R>*)eXNqDiyiz)V#& zr{_0bP6TKTLMJ(PA_kNWa%WOoSoqutc%AQ@FFV_Cq7WL^zcyl{=8MXRBy5z4%gByJ zn;@SYB+Q3}H+r<4Zn>YZd3LRa2!znbw&9fFT1=*!#frb9sbwSz`9A$T;x=pR{zuM& z?=NP}EK;buDdf`0Q2e<{dbzaLCmRPNv8buSeggcbUwYtJRwpu6dvh zY-ZgrIUnTkmDFRJsq!2XIBluz`eABBygWWg6M`WKvTV+f+% zUw|n;K^;$cKd?e@x~qF@AOQRJSx_!WYmZI#Olrt0?$w|JMIi*g6@}bk>nHsI>NpL6 zI%3~}Iy(0A)>TzJ&g7S)nz)B504Xq^ZI^l=wAb1=F7+Y4S;-G^f}rK=R|niBnPr8Y z)xU7M59aUCf~p9rUwxf=*Q_aR&|H6fT zgfmt}5lBKr_b48|^{Nq2gVFpraxxrLNjS+@AzT&cAZlgnMNQkAVyDKrKW9R8zZB7X zR(bJq=PSRb(~XnI=zye^glMFrVI)Nj<@qp$x1UjKu*B07-&1<>M_x{+)J8mT8fEy^ z$7Hq(?BBh zxM@W}2c@ISw(iAjj#8Ml_{rG9V2ChuLMKG{iZAkcxC;BI^g>NFBXQvoR?Nk?n)+%EgL0hG8Fj$69x2CIR0WM&YV;-l#Rm^5yfT4p>{&)j zRYp?3!UsCXXa%FWqx!Lv!>?5Ghsozmkv_%MFiS?b3|;XC1|$kNj5$~gfY(IeGAzZd8kDLU4(G7z&mRtgc3h zgZYja*YC*K6WvGL)W3aX%V&~seWv-8!e7L*@mJ^8A7xVO}ya4@oFZo9v-ERg_*}=fh(ALbx z-ptzS*Zv+nfS>}h`S(9M;J06nA^&9zj$ckBA)~BzsProWW?2>x`9F^I|8uFgN!|UF=w(qD-wRWkYm~f7LHrDJS1Nt>qg2|eb?w<0hu%ki6%rFsOj_Zw zf*n5z3ZPWF&UPTi55R!c$CT5-jwX-^TDr-2&{=u6m-PSS*W7)Q6oY*~VL|Dc5&TmF z&Aq>xTFRE-Gj;iJm^1AHO)bSOAIHLR@FfrnaZM*AO%goZp{)09jmWghn-ZJR?I(co zg-WWSLG`7wHw<&K-UgqaX5XSqTI6|me;(IZo=}ch(YCJ5+GYAszx{ns8kQ8{E%AqT zHq$1F)QXqUbtsWO1~J|*g7YGB@>;(hGBCARryn_xUpwYOQ3WHV`hF81zI8@dY6)S|e$y{{*mz8>m$KBVqDiS@esAQfjoC6h^OA?-U}>YnyNR7+t^%3xz42 zlkGJurkv68u0eM5*wJYeDfsNPm$?yLEUT5);-tsbdbazpB@owrKqt{|`IQ=jA8n|W z76wOz5YpEds^0{0y{4g=;c@7;d?hk?f|Xi&MD350A_>*s?a;ag)zNVK9zCu)MSrA7 zX)OykOOPOI)bPT}i~~pmFWIsyC*me_yUqW~pphN2>6uInI|Hr1%j#LoSRrPrQ1SBZ zm&J#4LD`Zg8IH>Xi&NP+Dw=J&ZwEecWsC()&a%ItC(cmYzMm5orp3g)uj!kU-`Fg{ z)cF|~1^jhJN`(V{fEV`po3pVZe9~%66v?mOb_HCdzlqKBCfqCDoO_Ld>1ODMi0$Vr zsDy9stn+$|TJf}_x_3D9!{OC&Z{NO38g57Cp`N{agwNpY6R4it5Cnh8G`XnURPNFT zNqs8X;ln7V<6ur5Zmm`{l6aj!ivx$Y%c2zb=j2)!qd8s|Tf3n6xU;o?(Zf5x8 z7d?fzrKDYUGdVyA9s_#%e=h{TYpKW`boefnTi}be*f6M8uY@ODd+FXrA-3~M)!b_8 zlQ~TI24_1(&{<8hx|f%E^{2DyRlXZbjElnrSr#MHekolFCez?A>%3?W@IJ=LY<%`i zC&+;PQR=M^lzKb8{2A-r;j3NU;j1bCg|Ei7;%-V$bBC`saglnC}F?qmy%{5eQp&6^{g$16>G?Q4i# zK7TOKcM40I_i5L-*WBYqfDmWywdFGM0CxMvP7j{YPu?(DfKM9zePw1J(Uz%pmPLp&DbXSWJXa((6o)l zf0(4Z11AsBpEH9hrP4Mgf7OsLO<)Zkbn8Qw)&kBTmT|^jFQ^*ZDy<>Y^_Fb~qft+M zVpSc3^oUYl<^$kffqm@r9hhx#q@ir=ijv;F{3%}dU!b!ggol~YG~56X2)F>M4?ptzu()hhJl?Ra8z|I6dFa6 z+RgPTpx>N1;`H^RF&c6+G{zD#m6tI5NN@dRm4wyXgh%*(?=aKzjY;HY-c?%U7dCP& zI*k){vkRs!p0=`A&!O1(Cdyt0=dS7>WN)64uZg@Fb#o31jh@h+kghqLtB7;B&{$+n*q)9&JBvE2k<`Inr=BLnR+=-C)$OS}A-~l$ZiDdm%&bm5M16%rg{b>hH2ysFN6(%X=p?F!Wj_?*T zv?d=hzR1AkQ^zz+)izcEZMJCo<`<$3DAOrLn}ORANN&RzUY*ASe=M&dc~GKP2gn zL$RZKaWWQO-S&ivu58!>V`pJOr14!^+KT^ucJ4QFB`@0Q$I@}oEUEiiku>*W-^6c! zrX&o1|7Hc{M5Du2Ch=*Zk~FkcX7vNlx7EGQ&cxq9L+5Ydy)UKW3)O=qUUs++P# zy|VfmUBpAf(W%-%W@q9w|J|3a=qh@U{tYV>7Vi}7rBS(9?K=~j_ixy`!#`&}ir59S zVoI5%Z)wnGIr#giV{LyBvJc5SE*>~#U|~Us^;7q<{1)1gtVpv1fR!|p%fUr6&opacH{6l-Y2Omt3qoe)`>HG4lBnFt7$uvOYTs|Cl}+rn@a#C znnVmsLv90|XCQ9&8U3JLQqv1c-0yC_S^ZcrW?qy%@*Ha4G!di_q2VdBH-ZW<#v8?n z={U=*TzU4|;?hTRH&j^69vM-ai!hbmv!G#dxhR~yIf8c&k-v@1>k4y!C9L(GuPlZ) zN&(e);`WJ#<__cGS_rh?o6s{b7iN)p7=CYiBN7V-0%kzVrtl6`fEW)pgGcq8Ei~mP z7i0~8V$@5ABnPzxhZll;X9t@~18e{^MVZTM)dJl(^O60P6}jt;+|jem26eN z%5wOw{USou52)Fd`SdDz=}=*sdRxR>K9%DW_}Q86e)_j; zqst#BUMfHv6IJTJ+L+)EqyTM9%7zH)%*@t)>=X!j==@;5g!7B<^gBu3w2Otr-|ZCG zfStli9U0_%gV5jinpPj;WL-@u_C8X*Wb=spKELD@@VTQHa?Au5`+o&Hqg}~9` zuE~dxodR$8hq|Hr1^}d@@S>M;B>U`m_IWs7L}dfc%^Sv|2Tfg_;yLnCPg9I1U`b@l zUg{SV`5O_nvb3vWFR0TW?e@SKR^ZS-i2^Eb`5N1-)_!g83gL;z2}2?@utjtIpS#z8 z;mJRn2nWRhSpY=QootIt^yn35vT2JzevCJ}8~vhhH0IzGbJ=P*)x+pg&nh#U2Z=q( zJ3YK>?^0ax-%2~JKZu(?5Kk{Fsj`=+8+xiXSg65oIEMOc=bm~ooGSBZ|DOM}FlL-R zW`RTYq>OtBPOYc>&=!sRvjKeSF6U{DkrG-8n>exjCpX&)9!?wCf4K^mLz^&RN zEch4>R?)7HvG0jHhh*SlRR$luiKfIcXD2UNE|}dXd?IywR9goMzS!9G6K_m4LI9@} zdy}S~5=O6|>vZu5?ebQ=_x28^d{T#c!~1FtKhb3gRl8N}rf=cM>~^}ClB!yD8fSF|)I`ea-C1rpKzs$}IBd7r(@Ukn!`P zJ%u1JrI0K#`TsBD|91t;H%u01Z}w{lU?Y4|31D#B&yai|+8)G3VY_k~^Bypm+o=UG zxCKr>%!zH=#VKz1tt&aCYUqS0&~8aWAK~}l_RjY?%bOxPGecT_;REej-^u-G*DAu` z1s9z}aw7sMYajP&lpY!m#mur5ikZg}e@uz9{#_T(*%H`_J0(3UgE|PH3qUy+6B717 zcWJWW6zz&1RuZS5AOwz-U%BmC38F1NUwYQgu@oz^ql5UmQRO=+nA^;0D)O%7*J=JE zN2`{?0HUQseIKgfA!4Ai-51QSSzn}C3{&r|63=609e^7l`%M)JQz|7mWxtn(>9odY z8i)>Q%PPW9iV3k|`N%|oZmsG-%dg&VDq6@Lm7#ifZv&Oq=aOGzRbcTxDc9`(pKk*p z>>>!bL_!AGbq%oV$^RF2{iA!Sk&Wg+N1K3M|2nZCfzH;C{I@wAq*5P8$>icRlI@c&eG}GAPYpI^uwo$p zPN>PE_TjB1QY`U2O4Mp>RdU6J;`gU|2F=z(murDL>HLeY@K#Hw-IQ)g~jWTt4UUwG;hFOp&fZhNQ9{)!k7dN;F#S zb;F?gC4zc9>6*k=5EL9Z)mNl!GWh)w(b%P-Z=378f$+{WxTT!&67)eh7&?k7HMyfe zy$@CIv@I!Jt;-HFO;Ef^(pIdvGTdk?DnFn9(n0S}9sJ{T^j94eHM6$+sdkXx|Ijq` zfQyGe-PIqbqyIX}@A~u`ydKNNQ@U6>Dizg-4AehPM_*xWwR5SwUz{U?FW?&fn#em= zZMO#KQ%^arz5(pI_NP=c)i(+cO{D;Rl3yDI^hweb%9#exCw7QF>Bj$+haPk95e?4N z?Oh&v2ApqXbrC+bq_HQY;R-IK;Yw=n{!8Emd-aHT6l%m~I)c(N@4L5PA)D0s4MHZ} zsBi!SxRq{p`_u9K`9ga=!N-qi2i?G~nqNyajze|abu2s?a9E>v4$C|=RTJaGbJIJA zWgg|78I==}6WCka)%usi8u-2M*2_VIHb~zsq+9Vg&Pbr|R;E(k1G?UWE1z(x2}f2) z`(xClI}l08E1DNO_%9{kqAM^fD&+S{=lDH-32h;~~p;{r@(8l@LN^Rz=y_dzYD!O~}Yz*?UHWvPUR;uTWNGBzsh5R#rwK zvLzY)Uhfk*xyp5YzMtQH-{1ba9@pd1>yP)d<9x2;IG)iFv2HezjQTmXEar|$JnX_Y z1BR6(^w$YT6-$4rA#8T**MzSlR-*B{4%k}xG?ZLt$qo36*$)-nMxN=0l72%{^iq=a zcKRJF`Z4xiq4R-(&q}MpQQy7Kw{k6WaIzsHsGHmz&@C4`r!w8*bux7%B>XPdkANDZ zXmXeL($g!JJk~CFo5>UF5_bkI*5MQz+~8A!ulVcFCGcNxON2xJz%4E9WMNwfIDkNZ zzuKj+5we|xQW3+y`um5WaT{9eHjE-x3r`mn>@>(vT`RT^L`SBN#e9`EllP7&B3#7p zO!a0AxG=fwu&^C(HUIMVSNxpBQdAs9usE1`%N?Dl)e*=u%^b&A)t0#A)p2rB2sM?w z^l|9p4+&E69;?974xv`tHfP^sbqjc`g5@RfSao3Heq~!MrAs88ri#4gO6`S<6OK(GWq0T*QNDWUUWv~iy`h;^MOL6UmQ{3 z^v`S#2NTgi;l3YkFyhI*41a(Os;NHvuaOY(gs3TN(AHA~E7=xuo;19{#$jT8mO>wL zo(!X~*LTt!$Xfk$`qp#4>g3Ci^CWcW0dk(KXTGc4wKbA^RTQiW=stx<0q4n5b$I7V zC>n-0lA5+a6rf8)bpI+EaFCGe1TOcu?&r4r&bmJ`L^Sx=%~4(}GUOe|KONdJ(i_OG z5>Ab=G}_13AJZ|MIXPkrvc85dg2FlX+Bo712GrAQF8=fD*8+%*A0@6=kY@DM`=f_0 zBonZ(t@>VOBSD1WWSQbCb;={Nyz${-t}*J>?WH=W3A<1uO4@*-m#E8LGhO`OExP7j zTz&}iB39I!8}cXgBc5Hk>yNvrh7m&>C75uYw>qB)D#^N_lB^PT5#M@^zUHdb_!!*zIYTG zKP=|JO7T#XW_w|tyv(5P1-G=J)+^`Axu(m#7w(4mtg%_vnLpJ;S+Z zbSDX~03$!cWR8yJ>zcy7)yq!>^4yiMz6jH8tQy8lMGWY-C`K}L* zLN7aYj)K?E;gie?jume1Rj>FBmTBhr-z0h~-t?m}xqSa!@_RAG2&~XZ;{mm|0c<^` zxvxt?+xyYnnfOL-#$!jGk#()zE|^#0o3ZMPJbv{b zo|=7B(l+CI!r;k;aht8og{f+3dJ(ST;yIE^F8}$P!V$RO&;mWstNti{A1y~tcsg9nKFZHG#I=~g^>*^u)U&-w;I&$hY~I)%?h030Bg&5yWF%AdkaZHbDUre z89!9KRv80Q`voomkbJAW{}$G_q&+*L>X zsY-k%86Ra}z`kCZoG=|+GaWX&H5@b>7ye{@q|&*`!Y{HR@dm8~Wvj85ztWz%w$w;v~@ z)A5z;isaj#d#$La=(qDlhrRsM*YsO`l)Q+Ubn~Z!zJWxysB-2Vj=NHIkbLsp(tV^QKR7t8Q=$TIyZ5FptIyQ^T z?Gk|~lKuSKO8bsMK;z$iNw`FCK<&w8xPOGcGN5^wmyW$)MQV2oydx$bGBNO~I>qXE+Id8xu8 z7;y}?aFbYsbtOAs;fB!-UG@eGw^3gBg&PzZwso*RXE;e*dU{fAvL0sRxa5uQJ`6|f4clOhTHgpOky6ukCEf0As`t~z(mZGcHK5)W?&b& z9a=zoZGAlk;0JTEkF50@?G>&;!db@5JW>tL(f5`kqaUrTzQcKr9R<%ZLAi3e5ToD%tM*RuD{fE;n%V{Za34w zSi*K*hVO+##>{?Q_4!qfeb_I@PGvFuD#uXi#B%)i%dxZc54yB7Tq7nbq8tQoq&~!* z1#V22#KRUggeNf(7C08&irpk``7@EJKXr2CY+E#(3^7VwYBV8hhpyB)!miZ05|mk2 zflMPtYb97FTLNVok{`WOb*E@Pc7p?TbUt+aFYapgXhHl5M(e;IT4>_9SUku+!h!~k zB6<<{uDkpRs=~D3GtX#=BLyxB0{(=GU0QR#&rErgzxk80OMTXXwO>auHE^nkrx1-g{;`fh>9r&}q^qf9pBOy#e;Z>IDkh>C9)|mpW3iv*T4}4Yd8}#eX5jTcE(CE)}{;=)ml$V^S0aULSvf2Ow)GI1ItMI-u7cWCF*9Fu**DwAH96N# zxu1|x8#+t$HS$CazFdmfZT$;Pl6nIu&ED^O{6GiuAX;wrOOi8J)qJE_OQM>`{lU5y zO%p4@%nv`v;!n_dFT@2Ro^T;;n|$}=Hs{^1m-IpkeaEu;ttdB}{2bQVo1*L1(^{@M zO?1w~JT7*-fBqw=Iij9Agc@TVTU!(Oc`@{txdyx%_n~s+yv^_a@?m@&uE!9t&+7_l z*Abvo(zPNmYC1N35&I>>Du$BEE|dRj(r4}fYHK08>IIj;4BO0gBfiVU zfAQh`p2@$@fCA?o@~=SW9RLH0IRz0gp!A>Fy4?YL%~G&-xvb&p5on&6#6;x_F`&$vv&ARuc$Uc0Z?>X9#qOuEJ$tjjJClKAjFtF z;hmJ025!?9n`%? z6m8bsN8Q)YXW;bWRhOnO)6(QFEq>bYvK~vyW#iCgY_Lbu!ut3HD^Kklda-GGX=q@z z8^_IAadwF+fArfUZ3_xd(upsm+7UkEeVU@mfhwwc6*<2HEq<} zztA!rwbX?tUh5GmeK0m<>C%q0r!y3wQS`_mdOlI*qcw_LSGTZzzu4ze9`mBr-Qd;l zDSeMcC(dO~WO)sglwzEEOqMr^@KyWX7lN10H|aIVYjy-S>gO?ooCd z7HE&s4fZH`>G3$jrk7e=K*Ms1hR6w;7B`JZ+jfpq6o6qdhZuB_Oa3fh;MT11S7%fr?KUiWbMO6C5#1+N?s}0cb)NxyNlK7tps1)V zte%DX`-cD^NAz;XM+FWlVKsN^NO2n%e0DH(9Z9V3eeH;sR754#i)L|9y^ggKUKwsI zug)R)b6wPchB=7J{qDlLz}5C{6q9qBS#jzKrzz;SRDax{?hZX?OzR*ypotL0TQk=~ z{Sph0%`J$XeEV|MLidM^u4I9MsJ0?AZrQ|Mb)u(CAx)auz6N-lNYWW!i0+G0OgL=1 z{)PM?FTQKIZr=LsSinUdjNA9Hh%jIEq9WYOO}h3lUz{WeS2Du7kvRHOShV)7T9vE~ z9&sX>(Rc-vd3D#?75l*nZsCrgnf$A4jexz)a}lzM!8~+8UI;oMe__Ec*phz#fcz`aopin? zKGUg9;M8}|(Ho!fVftyDLO_sl{QAAS<$cKfR>`3`SjGBq*?_r}F6>NDW@CRgUIFTl z#;Ll~5?PIe)U;}-YA(<3YH~o`Np_pH#u`7GIQbYYGUQC(=yWFnpI1xB@ZOaz9JMYH z-{_KulJUVwTyIv;c*6DX=;UPY@nc9PVEmXZtPlQY8exjCk9wuHTX2dnC?-~1jA#g; z&~gJfIl}HfgpYvPY4BXs&f6!>>F#oOT#H48Q5C->75tu^2KAd(kYeL5x&#u+6khsd{Kvokpm15?Ah|%V6-;L%?I#yL@Zuj+) z_u66b$U_TBpHal0&_Xh=wSxyaB~Q^bA-^YP))3)>@2(cN}Jg zyLv(-N)ClWBZ7-MTQ1^hmP-B?{%19IN$njg?s9BHuUshbhe9y!XTGt1ZTl+ecK6ll zJ6M^-LsR(dOme9wsCd1r6Exy4yIN}0dW?ltD}M1l-M;fij6N`fJ3bD+JUa@cBR&K0 zzf2-FCJwub``xA<`m0^-o@WI?V1DC7_V>Sf1R{`($Y)gIJLWrJ7m;+z@9|lv3_}T6 zel68ETu|P{U|w^!&cpFM0sXhH37hesS68173#~2T%a8j^v#_^50;@=$cRAh{QfG!{ zx76BC)Bn|;#w2MIfbuZAN8^x!=sQe7q_?La>iy(lOw$Nc5JgnAEHy8+Jv8Af&^`Yi zP3{cM7v${|UodO633^+{DXdB4g6*)Uifeu!)om7}`WFjGL*wy1J#j z{o=eDAtaE$+Ede}@RrNYyv>hU;WZVZagHiTE_N20y=t)0m;I0(0`l(Y>oPR@!hwyx zK6~ETQdCn=@r{nmlT5t2JNn9PZmY55-?NJ7L4`JvKXW<7c%RgeLo0hiff9B2E(MB% z;K$KiaD5JD)^Wu7;O}ubKm%B>Km?Ymb3Xv*Qk6q}u_zNi%IlJrzti)=`@;iYAH+T) zXONunaHOiCf5?-m|GA3OazuwmM|decKRrS%J0BThg1xr`)sL543$G0aMNTE{3!(a|nANu(q$Ery!g>Dy3=oc#fF!0Ws!WAfBylGFF9U~x?e z1^;_~-K<>`XwR6X8fB5XL%n)}x{*$0g(`kCTnjmoqc{FZ-hs*R^^Sl8A9JAl+Y7QY zTG7tHo=8*jfrK={rUI*T9ngv;x~Ak}w+q(g^jU`=P0Dos$!9jL**g zRM>WRD!e#cHe!BV_cC4?=}_i}{+D>n817(6zo)8$l=$k^`KJ3z`u}PwyaM)*yRH$y zMa5zY-bDq9O3&k_PtbrX^!Wbd?@@t+$)RNm7g2zszASAl6Kt6x_A;&1yq@y%Lt(M{Xop$dOZ5CP_Wo5oiVBNv5=Hzw~PwTwk!I#L)K=;|lCbB<$yig32yv)f#?3um~ zJ6|^Ajq>XPGhH!K6v-nEF;_=4M~4LHy4XXMX+xUgvt;Ppd~T-R=4doKQOH^U(<1Dz zf)dRbO@nSSzc&ukOm4w4w@TJpjj@qV#_A;(r(C*BbS2QBF7RB(C(cLHM77tmO6=eB z#c^Cu54#4aULGGDoZNa@DCIZb<#07?yM781y;q)Susrj&n(&ribKjNsP8?JY0-+P# z!WG+5Bbq;+m_$)-e{4*xyZC3w9Mkpv?W@97Ob7KB6sB2w3-o>PTm@+SL;ZE!gNI>s zcn;=GX7~W55M7V$@$*CU=?~n~dEnTsxy0uI1-$MEDkR(Hm-uTns3@xDekaENzAp;n- z0~qoD&*F0csGzVnfNzZJyY97cwu|A7NOIY9PBgWuBhip zzKrwbeXfng=*G$v7YV83VruIX145Oq+L3YO`wx99&t_bzV18--nq|~##q^QJA}SFF z4!i#F*-?8Fi>%cw%);6TDxMgA#qwH{=;m&FqZ~3t^?Om;Q!i||_r1=OV?i9K z!{?*LdrAE4`s}9Ettp*t_B+%B`3)SCL*n{ms6L^!RAEyoLMC?TUxQkfV+;kiYBwYFt%*xN z2J?G^RWU~UsM6X8#y+mXscD447ygxkz<(T5hQXx3aQ!~?S7*hXTKBkB zBnj9-0+znRT}}4=9i+v7M+xfyl(2Wdql7_`K;gWX{Vxi!-5?$S!d_0$6by?ik(ZH^ zKNIAZuQhNZj^o~vWK3S|z`Z{El9h zmV(|*z5LQ6lPqE#9*#7#PVY~r%bZyx=W{Szc1Q)tP^#?+bAr{@>DcE@&Y8sEnY@v&q;DxTzcN0Io6pwN@Cr|`s6 z*-)I@HD27VL}V=-ac^G}RQS31I5cNG3-_dKpHb3v6&XFkpxY%6gqLqR-ZarBb(d+W z$-0f8I@SCJZ9%8ibIX0sF6Cmyrd&x?@@lcoF7X1vA0KwX@eS+`|q*> zpax}T2k67#8kDakG&HB=>e8NzqsZyh4vbyYzeZpdjHeo?glF_fHF7gKo#67Vv*|TA zzEL)ng7Md5F`O&CqObgP#pOq5G37j?{Xzm$E+^!ovI7!7D{+RO>Z+r z+ia78whs0vE?|!WIuyh)fgWg&Vm+;vxUL7xyI6M3yZV3FtGR+b1%NE>{w^M+wv1H8+5`k}6lWa?&=co?PAUP@p}Eg$%65-Yt%y(6&T$ z{DhYC(3tp`k>uZk0*4WK{yU&`A41r`6#A-~i!_H3FJz5IPa$>se2ngeZ$+tR0Y+{} zHG6~zWO+xbM%a~CIP#p&#L+z${|5C8c{(nV2f91uBbr>(e9qk1f=zsMuG(S0C|xy+ z=RTaT>hzt`Foij9e9af^<=ZXW z{)ob9#?z_N4EZht<~O|`vytQ00c2}k;yz~@l*3wXzWGUK5uc)pX1sJ$V$y+lyRNR} zXSnJY0SfxU$(-VuNjum;aThEiNAksg@I`-Hfx+IJlKM3P6F4TrLrDY=sH_#qqGzc${ui>;@O=Gjb=niNHBi zqBE%AX1YET;&xlaGpH^@x-x@zt)81^1U z$}eDcFr^3-9{o{y@iL;Df@g;RC%MVQUAfA$q*b7=y!-L5CzphxldR~n=pGxJcbPK2 zkmG{MRoEf9N@`aon1Qt}d&%Gqa6h&%&F=Soh-MR+@m*A6#kI&P(4o*%qK#tMh3b3% zR}%Oc7!)4&7rswU0RS}v039=+JPIJV@EkxXC`=QYg842WZ-QAejkKRumWtP~_N9?C zOSLUrX_=a0v4Q0H26NT1m~+M*g&OhgQm3Qe@3IXD>``!kK9ZjCj+jG<5WqN&B@6!CkJp|$58Hib)? z*dWaj>Tjd46ZyG>l*nC|(EHXYON*gn&*a4AgOH%&yZz+Vc8=&5>-W`#l9z?Kb!}g; zeo=|^XcGB|R?KBVwlVm0B(NXjHs>Y1`ktA|?{LMJ*by)tam|AtpuoQFJ^|vOfq`Ba z6q9+epLLEIM<06O&w$Au^gIhT_l@xE{Nn_ZfSqq2?+ghhr(uH0bD(44A}>Bgf(nSo zFz*theMK^AQcarS9`Tq%o2iS99Vn7_J@~?bBKbuh;wy-F%qvYd@Ylu#e==ck>{qBx z{-gBCpMZF*Acd8#e+L&hs6L@<)R~j6g%OWcAmZ^Pq9Uvm8wRD=?!u)Plww6h7J==4 zG~sgXHh_41W_b=G9#`!Vk4K&U3&G@uA`nczE&QEe5(J3hEnvbm1x%({Wq7Mz*V`wU#*4R)Hm ztkIh_{Z~Vssy?D_!$GF~IVVh5JJ9{Fx^3E@nhH{6?{*7s-$7e{Kiv05y5@Ay^#Dnp zAkGL}$w$+^_4mZH*=9;CU*^hGp6rep-O7#iPP@B)SDCivJQHq$W#Wkt2A)PPp1Yj{ zoKrYPP+8`^9PTZDl^g6M!xEg)t(nuR@6BRvPRyg+9UMX!n!=Qj>$0-iy{o*NZ2l8` zIN2Fk=o{!uSQuKuRb|i%PUhyz{{|oMFC50lk&a#-491xLuGojXeP9V?pDwu)C;Ets zj7P=XNC6_|4+3u=v4|%SF&`Tc^C5hkfxLZw;R8FVF-><*vHu<@_WSVm@NpXEQCZo| z4e-I5qW(?;Vz#jP;Ua1=U8^Bo&98e66#Fn{3jq)mJNVWOczdwM=bncY`)tkeSIFKx zp&hDPXnbd(j(um3*&>t2{WJ+u?1$brjoTGKBG2|2OaPfz=ogYE<2Zgu65le@4a1! zG#GwW=-Dj7vXy##n35zT0YXT$URqOTd?PhsHDNsEITA(^!n2<8P6NGN&oFOi)^|NM zBSrUJqq4edMc{aQF&bY$J5H1g9XS&=4cq;cT;Nm2qEB#N2R}8CXYetil_US0;Y5pS zKg(*fY)L=xH2Qi+y+gj;wR*FtF^#;FtZw0z*m-r0k@>1>oLznV@XBYCF^Xx0cpjX# zPnpqi;OG9ajNu5-^GZ%5Eh_y@wMgWNkJI*TSG8zdqnl>Vom!s*sTNOnq63p)CnHn0 zDPyDhIJPIc2)Ibp-q@moY$BaZDC1zhv6XIxYa-YSM2pWVbqGWvoMQ6%AiwN_=Bj5& zIZsBuZ+5g-068zG!adAdk1v7o>Vy+ak#ULZl?A~U#l%lsR7uL#rBM1*v*FSCk`ih% zPT9KRa9vA&(7{d}he~^eQpR`2kcuda#Ok3(?UnMy#gr2K)eVwc&&yw>u!_FG$fy9y zMZ&&8i8QgWB$|)O8RC_z?=lpG#PAOWWTL@u4T4 zVT7*j|4bb*8HO(e4nJ`uu+V0!0c^G~-X&yjA`l%NsqE(Q-%TF>|5ilwcQHJeXDiT0 zm~;ik2jF)~q=spAzV`JYMMTPA=MeGc$UiG0I013ultfl0Hy}=Bp9}h!Y`6Tvzhw>Ez`3=&LtA zYqk&nxJ#V)^W+hVNY00BQAlNH2f%fVpzCl%{`f?IY>w7?AQ}0j1|Lsqw2k-q zp{KHRUE#6{CD%+Pz9{E@AMROwQJLS0*Djya))cQ4@5I!`=tVQ=$w&OrpKnfXRXcv4R>K>5)SlB zI0$|Tb;i9k(rI8CZaRY0JUZ=gTZuahr+)ns?q(#|&scjS2GlJU0ni*H@HzwKH z$0tk{S`jxa_}qo5Q_AEIE5;+KEQJ*;mDdIqhX~W9mqMc$-DQ z@{gRi(Gc%Q(=mscj&V&X3G+xECEBLz-WHfc?Jr!0NzyduBI#B+8&r0GQapx0gL zpIbQwMCNSO&w)7)krd}3!B)xSY-pM5*!ispk`3Mz0pIT=ukO5kts36lG6ttm6+e<> zj#+()TNw!IJLp*G8R$zJm|NO7%h_1k{Y~EuJxH4Ja(F-G9JBg5?!m)Q`c0vHXoI{@ z0mlP{vf@G&kmMz7_IyqH#65{a%tcxDAu! zy@HqIU582XCh`~-0mBu`{e68nv_d9e!F8(n3(>oy0%P#a7Fd1BOZGwx*Ensb2}~o* zh)9UJ2O3FRSR+}nGMu(O=t~YWbC=C4P`qNu4iv1LSmAOZwy;Lh%(AN77}iL}Pn1Ct zi38`IROwq5&WJA&86cTAF`*V4pn%`<8qcL>02J^bpX?X-;dzABq|p*yx514!-j(ad zmu(1)N|GXNy)cK{#^CN%Lh;dX6z#?YSn35>I%f5CTzn4j6ch%dT=)X6D}<*E^;6kY zR|2xKPK)vtD+sYv1eLXf*EcBq7=4FqF_3h}w)KW#g7Zq71)tFT$14rl>4b`1wb2dH zr*Y6LaSeq(#KrY$XESoW2J}EI>Nz_dQqERyy)}RXAQk8^f}iHUI6gV#!6j zp?jvy<_NYU3N4;jh4NOvsa-*Pi%OvwI?VA=KD(LYwruZ|he;LMLdJD2B=UIjnRLWJ-A!?wCJ*c-x@lKNv1_~gjw^)CF7s4+XcJz zo5T@l9W&B|zO=oar8yY>>p{X4Q41U3onQ_vw+<2%^xpF{Lb82i9W&BA=Dp*9Mb!ud zd;i>luFGx48N~5ml`Cl)-Rc|fepn8cWsTi0p=B8sSeBvu`w0y}Cp4ic1QVK~V%rqn zcS6ukx!4m_c4t#a11krq36eianbM3u+SMMVS_v#0joBTsv~oLQX+^IJ)4B$dzmNEh zrPVL3EA#PM*Q(IpRd&o^r%d_VoiY@j4{_^^X8^FEo$@gw&11rI2v?9&+!yA>16&ju zT$Yrq)jue>gmnqy0jW5Wa#!Y>gya*)5|o52PeB;7BTsa;nx0% zB#(!UClQAAY?nX1O{BfpB>s_DrNfeJWAteRVe(MIJPUc8b=>M>UJ??I6A%b?LG|GX zsE+^2LOQkv!j=|>CPu)`iUnpO2fjVr|Am7W^m5zdyn=mri62w{9eU#rFCPXPd@)Ef z_}9_h!QL&Y{|n04-*TW{of``5Tn5WGAo7D5m82Tu1}{_&?l0dK_Lpz}*OalxaG(Z2 zpd@&83{U~kh5*pS{>wleKrV8BivVcO&6On5RHAk&DYjV;I4^0LvFN&d5HpjJ(3Nl8 zsgUp{MnP52w|SMY{;uW6_XlOdj0KZXMu1AoD3u9Dqy`kybw5yeO=@gLnaVk{5=0Q_ z6W?GqkB0{9#SrK4fAOI=VP>>wV_Ytxkgm{w()u;aci6$I0bL_CN8h|~$1d{OGF@AS z$mZ}pqYR79hr|p!tnQrOxx_7z#DH7L!`5~r>L-E}k*gBph~hpmff(ZgR>~gBM1iRc zLKe;5DP%6g4k;hCXe=}q^07i>kQ=#ZuHJca_a4eDV+WN7aUg)0CzNt9plrm2Q3)`J4Z{KJA(Q;R)AIrhcM`=;>(r9 z`v^O(jNe7rk*5wr3ce@=Qwi+a+u+7_-wKC_v8WjuWTqrX41ccm7vS zC7{SO)*^^Nkje#+I>x8r_d!0ukb4-jEFgaPKxfRObaKZjAEo0cA)XM@q^-XuZ!gJ^ zjkYBE0wpQuXFL~vo^EtmFo#YHih4eb(Tzd~`1#EeV)UIN8`c@;{7lY7mZmTMNv8urTr3UVl9Km2)O! z@CUr{Fm8RJx7n{~kdKKTdytreO-n2?8$js501;144LVt3(FpiD4-5E*Q zP4Heua^;2^@AU@v^}BKksKG;c^TACRA+qX?)Ma-&SJwR4o5!?&!Zlfv;PZkXsb7Eo)6Wan#~ze}(4*7* zD8D4=!r=Koa14JNGq^|pj4PT=1i}5e#s3z)EmPScy{%W+Ma%`Hl_PdRi^IymE-1G+ z^y5iKm>&HtOpmSy^yvD(^ymZodi1${Jvy*C{hM77j(e(_z+m3r!D12%bAT&(fhDf^;Z{Czc9(EHA3`SL4SHKD() zxtqLGChcq>II1V_`5asMbkS8jE)8ls;%DuB5qd5ctL`U1#Re|Jty5nLe6M3Sr-d^} zki_a|waAULs%%iT*SxPZh*)u!D}FfgK?Zjy#DU1s?~dQpq+mq`eYG*+tr0$59eD(V zo++1Ai$&QO-py;D;-Z;e%P&{k=g~_Kco-!n31l{!_BaB@@rexv3=i-sa;t7x6e{f0%ieTtfvX zhEiU(WyNL?J1;cC04jFq9$o&PioF=9*w1AClZqWIN6H|3W zgmnVy$l1nGQ&NjG+CRb)v^+Vr;c|Fr1-DCTXy{;0xjW4I|= zv%2ZaI42LH7j>t?uTSu9|_=9@8+h=box}wclH8BuPKL_z7d} z(#Knq#3GS5nBfG(A*kl!8ZQ`Z-aa->h|Xr=Q_^ z%X!w~hhY>Fd2u7&{byLS(}-D+4W4k!k$*u^+Cky|KvcY1WEkwfIlq?l9)-(Ey^QyQ zI-h_Ef%nHB1Idq$&3>6ZP9K|Fp=z>gJQ zd84fDksY|4b+pl9JN~B&cm#ug^YE?E?*D-+|DYE=IkI^7%fD;?!xsTqLq4Vc^g z$@Ts)DXZ-g5GF#TtUTH!-~b6+@9O}o5pul;tVZB^uLN_wFQTd8mV0-K6R;Zf6biPl ziX-%?UNmJQ$e#6=*HxPL!*&Za7EC+IKQKcws``PuGmkPn*Ut@8G&JQNCqYUL(_)pj zT>!kOSL3S4m=)VvU$74!s}|8@TO>G4iZ?&v2;5WXAC~N8tIS>Zly$glRrAAsH(T*E zS@-O_Ltt?4xkETX?huOy?hrhXI|SpjczE8fI|M;BsS2I>}fw~mOxc;&fz6;3PB1DRq!>EcnQMRW}0P)jFt^iL9^+KG<8CXeu6 zZ6B|)3iDVZDNcXqo|o;NB(TXR(|VuRXZ~ZpJD6a+XF?L()YNe@{n~Dpb`r@84=*?O zy0PZ7628aQ1((!I%!spvR4pK4qHp0Vd5PW0s@BY`He@HCg8%yh0S(#WE z9f8)~|Am7W^s=>xiRC`L{$YOck1rpF+2Ll(o06yg{&PrtVkUpVX{Ma_(2=xP!>%5g z-0MTn#{Md4SF3-5lVaOrZwQX00q^_Es|4+rj8={KsESYWMb}cd&{L9Uyy(kJJ9`a1 zqV^K|HE$FnKvg-R^PHPao4JcEPF`1e9&lQ{j71+Iu?|1M9{pB~#T-v5Z+71elOisWsmp{J}MoRldtllRQ+i3o+hIM#oy&#RdV+6_za_VBWPdn~YlZNhYB3sGla`0tv zBf~LXk!YT6J@X#@Lohn4Lzg#BvX0H2NVi;`=?1*J*TQ`5V!F2Eh~?VNB&6ClwsQGy zcU7XzYFJz^nY&d-LF>v`EH;2&=cb(BdgCfm}wx0s1LMn4Q!twS#$s}sJ* zh&)q-CCSA`%}g$FmNbY(-{$PPO!GIzVr~94iqDOF;zX%^=9xJna+1V-6?bY=1Hzc! zwaOx`Fg~~5mLb$8Rm&WEw>hV{zHoD!2-PUU+4bypR$1R*%jlcIeDbLEMrZX{IBD0> zvhW|q7xotVW(LYu`rwSVf`OH#&C#0B#&7KX{(|@)#utBo>M)|<6IV8IAViKlWNUOl z$A{S({UU!=ipIHs(Yv`(E4Zkg0=ZEv+0C!*1R4SBVxwPPdB60+zr8LG(+fk_DzDM`@DlHVbMYP)$NM| zJR2X1@k@6MH%QI(FQylN56l6AfORo6bl)|==WjI>rJ2sAFDy=X%6foIkL_U8hs%i* zPVN7Fv|=EsP{&@Tp}r|Stl@ufRwSoh8Sn+6cmFRmKM zwRNFC;=@vZ5To+pPFK!#A7T1_|3*u19Tpdfn`}xC=`aS z{K50@ZL~sn>XE$55Ij0jD zDRl17=DpK)zPT#vww`}U!#5m^e&KvypcYfY9W383dF^zj+N6WFK|5!(&b;J79?7V@ zU-2aDn^iv6ck6BGyoGJc26@-e;kFGp{McJ# zT^#r5Z!xtianY;u{8zG&MKZ}-dYZD^hK7i^vNFA0?dFhXS^ zAXFBBb(Xp`x!O5rcVMNr_3G-i9nxt`?|Xjm#h_Da=c3O1X#NpG<EU~$BgwEKTablp8EF3o!cHrhVuTfy+a%NGW>qolf(oWp`?>T4y@Pu0tP8ORK)?%m=cXSi*Qb{SjL<9c5M z_Om)i3_>DF7ar~{I7cz*BN#h|a0&WZXg>^=#l~=@AM^m{NZ#B&o{r-|!9DO>?Chyq z9%KD}oW8Yhd;EXyy3zNxLnObTN_kH)!RcXNK~MN``rAgWIoBPhe^>>B>qf~-8%&4f z#VUW77eDxoyjb}_UK~sTCohgC|E`R>?aJ!m<#5T*IyUB>bqg)}B+DO3PH$vta}4P3VJa_OtA4_LAS0 zc4iVv?JF$A9Z(oba>NYS1o@)r$y9F1M}%R#2{I6#Q^^iUrF+djBs+R%GwJ0|cg--$ z$h1D>1k3h>3yCE}5!zc8$^@~Tm7>5Ue4g^$dEgQ*Xpcft)q?7!)W5jVXS-b%R9%-c z7rUBjac!dW6XwD8=_oXg@ekYkk|u^Gz~va;)&+V)L5s0?A05Z@FyMSak4*3mwLruk zUO<0;?+-0d!><;|0-3#CT`c=tiWIQf11%7v*>!&C{Fm0k-uW*d`Ed0c;y29O)Aw2+ zylX)yMnKI1wLrbv%nE%_3$z1kfh3?7DE8zi_pY!w*YC#(pl0#bW)kt%AqcD+I}Ow< z*C90v-oj2}fLM(gGlm6cf;S(lyxQc5O6a*8(L2ctRG?xDCx8+9U_O-AWd#Bkp&sZn z=z$0)2Rb))eOiHjlDQm(gj88%`Xp}fsYq@d;6phtium&PwGB*at zq4$Kvjz?|up^&6Bd8tBbmVY>}cOZygi7W!gyMal|&n|<|zfboT#(#yaL zoOKG*%A?$2^?Pm)!S(ib{E02EDGEZglXkc|%kyua;do$#WmBouIP=Z@BneK$X#YxE zUjN*m?O`nu2FBuxtwZsIB`F*?`Kce{kYll+{JaT9T z33gh};+!OIG-et|;alvocg)Q%mQrVGTpZR!7V~qjSl^Mc1?P;mFPJ721u9U9Oyzui z%N2c5rau^InhefSe_t4&6&)`07yAv=03~qfD-ImaL%Lt{xdV_GQ9rO6u=kUmNWPwU1fpegn1ms za=nN_7_W+;7Lz8hu8@uyc7U#{qt&{bfkR)+6HLVd3seWlF`DXA209lNxgR7=PSf_D zN?6Hga$ML-pKla%n7llPH+kMF$m5b!Z1ZBy3;CIDtYU3ZYr!V}IUbmDG72asL2iMR zlTdD9@iPIvP8`s=tizXOP;dt0=$}CbF#lj4b{IKup+3Nn&mkWeYUuz3V5%?rg3Of= z+^EFr8k`U203Ljg3c&2!xD;u2`O#3E+mw|JNr-sSbVO^}r!cv$+RXG2z<5v#HhhDD zQjz!ChN?`BfI>wV4bP(yJ7p(qWXB=W(5aUZnRQMH`g!G2nh^l}IxecTZ6O_njd+F~o zR@lFC@&b=EnMz(ixwKA)OqqvF*$5hSYgU_{8C;uDfy80RXu%F*+lDr? zxb^DGs5@6ewuTi{?pIq>n=#dD#{v^RIG^LAI66i*34L5(Y-nk5n4<^1aObjLe;p^8IWlN z!C^eI{Y>*r`tRqzR@Ck_h$~x*Jyd?VaLXSh1rZ2oR<&*12D=y@ny`iG@&mmEIR8~y za~9qA9w&ycUa^Y|6wEQ z6ktxb2CQCCzq27o<4KW8T?LLwcYtG(7dUGq=Kc(k-2ZgEcWrVKi(X2BM1VIn*`0gD zKyaaO-M23?NHQ@b3GvO!6&?ls(ONrAsRoA|8ey?qjf|2pqp=$}#nFT}6d6orfYnQ> z?GHGoN+=?3{Eymp!0+Ne2*VD=^Z+FG@~~TypcsQrNoJr4)hKp~7K<|~xMYde&d(89 z8%2>v;xB=bfSh^luBR9y?z-%E6RbPIju8xqFB0V_Csd z#d6mn>G>z>_M0yDtV}O&1}Wdim}sH%R!Fvy{(N6mB4(|t5Bn*j+C7t&i?90DPQ0vk z*9v#pkmt~P@Z;|V*>x_h&w)ceB}{rKB}j+Zi!0QU8CN{6E_OSV(n|y>ee_q$(!bz&~ z`hxY@uPy3E7ucdQf-NfJAGW9yuq|rhp)IOEY>Ub}O(IM8HGKLejzq68yfyNKHkaU2 zphUipGC&BF$o71r)vA9*2w95*2uULS%!Po$c1+`IbjOFd~mqs zsD(HJWFd~eYau=hEW{bW&7)5n=)gj}6lNiQeqz_&6}rR<>|I5XiXaPdhQ*hI+#Yb3 zSfS9w(hr@6);o|`>0japE;R7?5d;n~XMBLR0(s)A>Nrw4vkPr;pnafbZNJX>26D+S zVd7-Htzt7Cw@Hek9{c{#mugSEAnUgzUVNQ_x;r=ZQRtZ8Ck^qQYf;1%ikqs#H(!51 zu}GlT37=2u3dy*i_484LK;E_z*ZYbO%_bzH{BP%@i3xLV;0N<6=DFnPNGMC6ZoX5T z`-bHN2H}>vck2C}Z%Yp4@#q5@juFppsNRz%RxBd3GY!GI(u_`|f{Q_8V_J{b5zsiU zeokBct=}_y`)f0|6R9ZDKO}F~)@^*4XmM_OeClgyRs8*yOrr&f`Uv><> z_fkc(#>#BmMj-R7TZMX$fv37!MX@pI+okF6aJ+=0DEf~-FI)~e$VbqtQ@Miz`*;!o ziSEy2x?lO|AZT!}9!A!o-e)sY47kD)5Tw@V@4Lcw!dzh;cU@seHeseQYpz-DZI@)? zfoV)WYxbR`84;KYu;ne`7NIN({RvsbK85#(`3Z;}+6qN``~)H<0+X1SJ$}M{V+p`d z7@0Xadg}vWXS^W;K>h+e0 z2{*A1!WWsRqOPAT+4WCGpY&mKb$Bpfj|k{=PpSSt=H4!Aubv+ zH!fEr`fxnvm=WDx6f39Gmn7=8rXQ}j*I>CTQLI^g`)oxc-dm|$E;hbIfbp3`9Fs2GVHDa%K_^$I89-y76lZ7+T z210%rj*y;dU-&C@EO)n8(C!LV^50eP&&Te^8R8A5ts8TGmh>)n=(DkhrmJ;voYlqJ z#%ht%;bS)q)X8-9fcd}(>J*R&E~S3*XyyGv4W+~=ocuB)2_?Z!^wmRZTc)!|-^3K@ zpa#hLJ(zQ0qN8JPjd7MiRxxJY1ny>HI@V!ayut5_M}zrewvD0_DKDwn)GBS1)Vh%^ z`1D^A=cIVZE(+GE7*Gfs8I=G>&*0^a`Rl4Z9@rdEx7IPY3u`CBCK2EpRKxXm5M+sGq!LWV0Q>qv-k zi$;g3RaDFkZL#5_y_*b$MNq~iK@1;7os2%N7H5}pZ=Hhr+4j;a`Vn)qbp<+oBME+I ziq!cOE~H-mm^7yT!VU4o1QqEr#xsf20A@#!fCt3?rbvi5gT==*?d*QqnT5Y*SVt?q zJP`oxe%AXHu~>QMdxc^ft+kag`%mt1l*;FAk<+U$$?JB8~B*fHi|bYWK;k z)LdEX91ZNhn5aBiC6h@GJSX#ws(Pm9iuy;@C2R2>mUi;z)-|aPF^uC5VAjw|{E5*@ zwy)NhC6i;4y804_7;(MY|Ex}n}V0bIr9Zw>dqU1=Fm1;num35%W(M*+k zhQRDIz0!>rQpz9Icpx{P7U{nN^c6O1eVSK0#H|XJ-D}p}^(mc=E2el@uTBiu3vUPsw}`PC`NxyBwf-IFd3b3V@^r9me^lB?9V=efy;&6&wHgv9ZKX#30lW_M}; z=P5|qIy-tGEQ6rKqQ;*58s8nJV@DWbARhM5$a>cQdvExE%=$lL*ZSX_SM+p7Gl{$K z=O2dbSW@IV)wHaV_rsF_^+$KAV}oIgm)I@|_|8gLMBLC4i@l&%)|3j!Bnz^DuSIa@ zy9P;R5p`p#otLlzAS$$qs=os9OX_n7S>z(-M+2!ZPCc~$pIHAlF!i@$m@&oup*MtT zgXflq3-yN3^zL8&Sw*bP9-#IM*<(ZGi)EDkeu_y}MMD$t%I5=j1bC=2U z@FWbdrG&N5%AYkeypUd`en+32*BZs|;>U!x3)*7-delPlEH6w@OFmWk>GzzN99#ER zQ==EEWED&dVmR|4n`i&+8wt_nNzW;-33*q}B^l^LLA$08Jpz^c3-QmByw*GwV0dOIP1`Hhe z|3P9V)rk1%4D(S;e{*(>ssTf1-`I1quxw^LV3D@cXgorKo&NtzT_9AYV7`x>5M$vh z0N1~~xBgtEJ(wNn4|~$$uH$ew(T|&AU@J+PkGMu~+sTaEL-!UwbZ;qnY;O%SC@b}# zIs^zCb+CqUMB{t2c+o~%G@~1>&xb!9AZCGdxF{d_2gKV6(tL6#x+{g-F=NQTbd+!^ z_0TFU5$F=T1`1wrOC>JRU~kY#J#NAC8ngC!(Kp_PM?P(6(NrDecEUlXk^f?IHcdgMuruBUQ&I?o!y~xAncLM-)FE}!Isc28`A9T`5?{HC+x zPlN_h;{ekBW|soCYP5f{Rf9@1WQV#9J-PnFFax19dqDDw5QB_YpkW4hXvHe(W?WUi z`Z(uqoQ~jSZ7@jZp6$3pi=VmnqO#Ah)t@a%on!TL`-JJh(zA+9u8-XQWS0T=}RYC@u1WJAY8gMXmwvT6ZPnj zS}*pfWdED{W8Pfua`Sc<|9WhtZMw)q?(36>5wg{N$fZUPr@p~52a z-r#!o?A^x&FxVIybb8Uxsv&d@?`3FMzUI&aCpHnX7vwIT#_R_CNg@--seGe;xKgsV z=c&#YSJUsf;W8bOQ{WZ&>5FmFw>|gxy@w`R>g)|D@5a+^9($>Cmd=*Z=l*;ih^^(1vggzfMTvUSBMR)K0fCiS=0cX!#s{Z# z%Tl4hV2x29`xIv5xJ%8v&QE~3r&{ebCNOe8X5nc0qawcwn0v|@Oc1(OqntWR?TmtU z!sm5#U_X63cG|6?qd=i%;($k_9|uP6d_MRrt+vxD5nf0=nyh#O=N-gt(@sKxH+Jt6 z(yA4VV(n$or;eozJXuAM2||_XZ#Th!UR-$K#U=f}t<)aqV)nbUG^WLj%i1$BQ_HZD z=S7Dn4N190g`3>lb!U0n&g60J(*vFhl`AL9eeF!dSlfXkaScn2)O~YCIa_WM0jg}w z%d=;c$b)gwOK$sjcwlO82fq2nsiooZ_N?|;pXc=$<#T3d6U|nrZQLFbJ7$kw;+8`@ z<(hltXqC$9*TIW(YZWMF<+x1U-e;FP-!8fq3L6;wocbnA$d_*f-njWbpMq%cKB_p@ zRp0eIp&=I%Iw7p4T3mE&BF9b@o&O}M!IEB<31{>=4iF56O(|aN%|buNr5tzaMd4F5 zq@(ApvHJodUZ8CCG3ck5Bl%tn{z-1elSYVTMQ&#M0i`j03xQjt3BEdFvv^2|`p%+b zFP?C}S`a$vx&~S5?$-D3Gs*oY9RL=B+a43iO$nkMV)(9aSP0BFtfq3V*8G{>#xR_S z2ZE%WV#Ve+r`5QUw6%kjo9v{>)(G41m8Kw`5tch!S!^07A;JClWJT1D+m`fYVraL} zq9OrXg1D^l+vVGJGMX{LIO&ce(W7T1oT%}pXY{YZh~76 z9i*s-@{qULNv9{k1h@o{ZEgmUdijm%a#fI`E&+Etf>P8?=$u2|1fWK$D5(RtqvPF^ zz&7{Mu5GTX5c*xZF=nJdBqhn$?#5A{Zs?0z!tD00Nc(HW!0q;03(xXLL#8bGJ9c}x z@SupWD37s5r;n z2@v8*#6{wAefg^fb-x5 zm=n$y`;;?3X7vf(KuPr+PF1e;LXI7)e4I|Juz2o)r`3l3$8)tAIvR}8MLH*_(3|~m zOJrHXC*`6Z-^XUV$9k@oGu*D%>N{m_KewR$ILi5ZMK6UOcBe;^o5AB4~$Q5^t6 z5*Ci&k^;j)X-7L3dxQoMI;J9C$*`v;RhT@xd_k0OWU<8`ysh{e`fH^@F zKr#pBfVj&RSnf~Vps!!Y>QHdkHj_4C2?tkl0Iq+`u=(FMl=a~Hb08-&n@qjU+ z%cf6VW%|*PZkwt+1YzpQjc6R!_g9!*$|LAL_%9P#+K_Q#XBVVLMz8ILO$~F zgTkh|E+ZXyOm;llF98o~O}ZTq z>f>FBzyYkHmxx@uAGs@pK043W6WcHRVRG+Wy8g|1%qAXTotl@i)OTCnGY$`hT<~13 z9_XqafyGK0L9tTt=VK~QjD*YrZeI6AAD~Nr6q2M%bvD(?b67e2j$^z}S|nXKz4TnK z<^s%v8mH;uoVF+nsuqz9sXen=BS`}1$m%gQbV!FZ&d*WxNI_%P6X?=o^}14N1<=)9 zfG(ZGTQWcWB;4%*uv#4cd&-FQHsavh-(GUKCiUSQL54*>-F#wzN3#QnsgEh;eGA0Y2>_ z^6Ef>R3-Y{`1>89ONQlV1gnVY;;x>+GZ@8|7@{F_u~1Z>Q8BPqO!*`$m=qiZQSt&N z@--Tgt(sMQpUP1P*M4|9KyGQjmHOPPFr;)s*!SE*o4zY>AIf88o^d7@1ozsRWee|2U@%=QnYU{+KNFHZQ z)@K)l()PX84{De{yV#A0I!pQxcQWeBw(Vv^TytI{nI(XDpKO|DN z!Y@)JkmBSw1OC~^Tp9JUtbOr~*jWZVs?-g0Y>)hfw3hEzc^O6yX^onHP$9Fa zSM+S}m9IpT@2CR}*Coc8#$@SF;pj{t*A_GKtRnkrQtNmefg$nm>y3V4nc15L*D~bF zduEZaSiS$Ztj+|GGW7`oMdzafmf% zDL%2`A-V}KZ!&^V=<)$HP#*pZ4GTxxn_@#h-78L*w|i$C{@#J5NF1hsm`J&|i-+Bp z3Ea{6z{_MntbH|Bb=Ge;S`8hRSMc1g7vvS}i&k^mO^^aR)?W!yT$h92azP1F+o_rN zDRpo_g49Mgytz~{3J|SkbQ8++_<&tMa9*b-Ba~XMx}&ajMI^_`4cuw;d3shITU3{LmWu5`Z^ zI2hy!6{C7(u^YmJD!>EtzbGXlAi6ApuL1x>z^M(!kfiPaVMUd$^PUmU0{G<2?W`IB zU+b*g47egL7dccaw^UCh-dMC~qPwkhMDfPHGP^a8>Y{vaU!@)!O<&=bN{0UeYjP-e7?jl*TGFl-evyL}6mRzReO`}FHz&g=1aD3h!K0ve*xMNY zE$`NMCul9e=XG#kj_z>a5un;b7sFwhm14&i}hXb=!pnIMvvo~oN19~Cts zB-9ro{gUnaIdoh1NO_~t-cEsw4}8)js!bQ7_1+qmT~J6a#+~y-=Q0@Oq1|Gwp6{8@ ze4RSn=P#VqJG0QhGSvCOPf~DE=ACt4tvY&rn-~f1;6vQ=wLiExaN zADrADe?%iG(6%xR=Zj|S41BpF!-U5t?J<`2Z4A%6b@OC=uUO~P@AHWqQ$H==lnHpR zyR(7OL&XG-pFO+P*SQA(e;)u?f3 zjJg*gdeUiwFAM(W{Q7rD$TnzJ_hkz0T`ABZmDz2cyRbRjJ$&CG`#Y_D?pUauB8)Mo zWdE%@R^#-Q;v{X&K;>(LkimB%GNgD=0*VJ{=EbpZ<|TKFI4Wpi8#eP&`PFH`W?ryP zOKA#Z+oFI@3%Fx}PD?BZW!Ug8O2acZp_&Sq>D=zlCXMmrkG^T!h0DzsCNjkq^-#4t zG{zRacx+tL8&uAjNHgG#t{97`;K+)L14MDUL3qK+i-`4#$^c{lx%hSyw4n z_ThlE4YeeBWKPnaKSwrSq`^D`1Fr$}ew3$i!W zZ&?V8cfG5<{BVwk#^Fwv^H|YQ6twL7p4wY>ba_aQUta5$g`X-XeYMiJa(xp^uyZ7K zD~y)+>DT#Xgh$9hs2nZ}l5uvncY;)L2-gdAf^lu$ub0T-vY@>a_Jd^Ky+ZQP?BHw* z?t%|_2=8|cNi+rS2GDHl65QPYTgV?g)nV<|5$LJ@r?{w{r}}%uxTxbWcY}&vzIE0G zA2>-H39`CMOA&L(=0 zUYc?9Vj|^ddH&^hmTI<{!hOj~<1^zn{6tF@cX2Fu7jrE?6yBk`YB4Nk-28F`hlR&k z6BB!7?4yX&V>A87i=+x^l7Sax?>U%o1SrTDCA>t7P_XEh8?k?o;(?V#f3qBLZe;bo zY>7U)qbo+??ximz#BarkQn#vfkDYJI{hk~W(u^O$7U7qvhGbpC8DD}^DB}HR+&w=C z@tj?j(oDa8)M3)^?ZV(9bP2$9K|0`D{<=oM|B!?K{+T;%p`eTa4CrU2H#Tc_FOb9A zVCZKLfrRgE3IBgTy$TIu)9iT=ley{q!|bhCSe^BlGc@k~bZg4Tib>Ab;dbs!U-T$x zj+qZh#*rL$CXi{HaoZ{{4398aL$ihPJP3P66&B-UP`jPH=;Ch&K|<<`+gmAqTbFV2 zIl_5IH8O&ExGid?kTdYh8bu;rxtO?XKFE3d6(p#!RHli`y5eWe0>cl}A3;~7Ps0p9 z@)SWO zQZN>{XR!>FqvmKsE7%*;8(_cAe}=+gkzMwt;2Vk=8{4_;OL>6GK$(M^yi1Wj{Q5>X z;s7w9?Y!Rz@ZIaYW~?i4|1ICCfxRrY_huoovT5S}+g^$;)-E2E8{Q1yf!I5W0{q$< zfnS^aJC{#zzcz8;*G6+~^I8>U(Xp!VKl`=qm=$m%`n3hY{MrT*aFnn2-@UIC#mFsD z6M)m)^?~GsIq98Yy=f1y2l)cBYD+*Cn=SZ*7eyI=oFqE{copbQ4r{7JD`+j&xdA;K z8Kj2;%XuB+DWHc71}}AJIS<#vdC%`8Z^{{rmyvl0QL0N!UzIz&gKl$yW{z*Yb67>Z)^ia})+3u_QgFmJg9WL{- zCHkJ$DY=y9Nco1IPeV<%msTlIBd3M;X1k`>DA)but;HMS6u4jBEe1=}C0#u!sGonE zTn~%*xj6_MB26x>dIsF&(N^V!F@6#|OyPQ5|AhIY#XmT}-n)%ha{52@XuN7xU(%b z5(&L@;KlY0>4Cemfvj}k&IVx1|@ z*^bu-@-MFsk3YM!Rbpi&fbcE|KLwXIHDQhgyY6h@UYXrMyjP&|kj<)+Vgda8J#gqB z%d>|j5ICd^3r3;+5s>9btEdJoj6 z<{r!lRN4k;NS)Js%^G$m5`UPL3-{5`n}{5RB~XkEyG6OjrQj%YToO>4&Z?gxDtH+CVV{W3h4 zs)qWLYfXA=anpKvI>&6ycP*+>#cca_IW!*T&P?Y?ujzFx!RGcHMgEaa{Z%jDmsD6U zrND38j!4?(n47?N<-I=a$^l>|Y%HN3bbE`I1Z| zzIPA$9q{yLvJzf}`5o*z>vUiOe-Ml_45D$578D-KdGd=1%%(NjSJ+qFY;?MaUh7m> zj2lx|R{M6%TFxFz<3bc0^x0BGy3<$B*lj3G5!aW$GS=6mXK3L2eLxuVMJ{7r6P zV&?ofkajK&lAlH_eMOqYK4ypO4t9{VvD6C9@Ev5Z8O=y#k`1hj<80pX#s*zn0@y*m zhwUICFT~T2A70z%jScM};W@Zq&oXt;8+#S<#s;?)mF!ys-!X)*jj z8{&9|GZZIsboppdUuj`vUlbN7c(?%rdFA(RTIp4{y=%(|gIE+Ab=2@9d@WEVx9G{+6T z$cdJ2NQz9QQ)2@8BEU8_JmdkZ>57dJCz@J9bAcRujR|q9^kL`L^?fCXW zo>j0A%9@uBP#ka8-A+2lWfYyBKcT4q9x)p19{a5i1TLdCfTYRcAerBT`)d@!^pcJDK2p#QnEt?oMyNTj4z*0V)|ZTm#+tcWkO}yz%X5zCwH~ z;I$-v8oZXmhh4R-)gtp4jkkxg>OvZAH<-#dCMyG?w%jH9)7+SWNmJs_ z$J%4LF1YI5{-^|$aM22{@R@7s&)xl|#Xr;2FP$k~{R}hd&BS;2Vg+ta4I}b=0aeT! zIY)cX$y2>m>c@5V9Ume8uI_7mXE9!zyWRH91JC(&{YeJHJB|HmkxFw^w6~AZRnR+# zsxd0EU44HgRzTm!f@%pEi-@V+{Laf9Gm14xu&CTb4kfbF5(3kmGhaH?9|Im&^ z)YexAmy>xyt7sj_QvOkVD5Fh71ep1@wuQV2QodB7(g6m0@X-Sw7qKZkd_V^KrFXV) zHI*?nvUWCC_i%DHwL$0zq0^{nB<}5ASBE=T{rR;0FxuY^BB_$@=VWT`22lRS1h@wU zPy!}E(W95yFeX57)=qlEaltdcF#&X;`SdO)6LCImEFlk=04@3i?j{yfdrSbJ;)XE+ zN>h0x?!~=TlVE~N3dYTG2fwZ+6hr<9c9@P!a-biS1N|Uu^SL*AGlPxZ&V$jLBP@V& z9*o|scSdi7>q3YL$W|Z$xyEnsm=;`Kx|@jtZ9aE1QMiK*A|8XyCp3EdYFu=NPoYq* z^T}_cH>f!D>z#&BKlu0bhCdf)4@>(UMtI|0a;B4UXYX^Yr8bj8SSpF&Vrnnu1({un zz9g9Mhq5P!qn5~(!05r^-tb&B4fdT&Cr4za?i3PtE5!S7QB|@WEyueeNb=;Ws%Q&= zBf8kO9D|q6cgE5ju7S>16ASZf!M5CQwOZa9xTO)7Q^-*B9NO*ZsHp|Kpzj&N^dz|k+{@UVo zJqlcx(y(+jblWknv7gTKE7MiR3RNq*tXs}W-w9nXG2R;1)@66SNVX;uym7AT&UQV` z&1`3k`jEon)0k+GGFy_AJDqIDv4ioLNy_b!kQ zrf^kStPE=-a8@RbcZ8Emboo^9Hx`MVw2*cpBRE z66z$mp2rADHWV}FsdUc>-cmS^r&dPoU>V7*sB>CAybp_mlWw%9_YuF`tg-ztLI`giHTk(P^R0ZcjyoDBbVq?HD!g%IKgOUvoM-j!!&)7 z?bI6f-t}V$J}Kh$bGSw5zEAqc_Y!no!%+dGUEB!&tykE?4Z?Z*5w!0L@->PU*?$G? z#EHYnH#4o!NTLTOxS_Bkq92AaH7BlkU!QPT%#9xqa z2|VF$15Y^H3ZWA+xTpC~_=$^|HcA*r;onfb`017v+!Ia<@`Q`q^@N);tjN#2s!N~W z>_R%BMc2O6@$F1e6x~iPix~-K6}QM3-gCBJp3aB%ONA zX;#jDwuI=}1R87E?R4q%$;5)EJ_4#&yS=)j*q&&E%)1!Y>CIUVA(2Y5bLN6{g_muW zx#nx6&flm(`B|Qy)EL4nKY59f$Z6g!Boz0?U~p`9>%HwfVfQac8fu(Z?)CS^huorO z`g9RZi`F&_=mU@pFND7$M&rbsWqs>OMu%Cj;i~4a{5Yv@;b;FC-?a~~ixvo2$Af*h z!90TKb@Kfv>~wFv^5^$3gvI=}PDj3YZrO0sX4^%G`??w#maE7=1L{9q98Q0>4uNWx z`1a(l@JP{r52<}8?g!P*N)>JxKOl;9P$~)^^KI{r`C#rmF8L~3JBIO!PzZywkJ($v zurcRF=WP(efR7Nu(7!w8JD$TnX1xs?^97)>NIeR=AeZ+VKIQ|@BYJ_T2~~LkhO91$ zAeRUTQ*SrEA-$zIKFq!>Wxf(w1VF_NK$V}A5RiLQU?adP8>9!R>P&WMg7hE)C_U&p zkcz_RC9<19Lv3ahPGeX7`WbHj4BoZHAE$Rp&T`fEHpZ7gV6- z#Mc{8D%TJI)qnV#x355mutIz%F}9-xP4|#WCSrII0(VjeSvx413xd^)1kSv4vC5B3 z<>gc0jv5%dRVLZQd;%R+t9!gOvlQG>9#m~XHfpZ=smLSt>*mpkt9X~}&(*NckOS@K zCkbG1P>5U|KbXm*eZBgjLtOKO!-+>m*jzzB8N?fka}wfvjuW;#1;T6U6}fTeN!mdSlX8EY5Z`J)9d&8hhMDRG z4N_u@Y=;{kT-}FBN{svG0Io6`&_7+WFk!sWpd=jJ|NXNSfwrd)S{SnIPo+Fe+ABN; z9|BM*_~ovPlViEQ*u$0)_|X4@%SsI>2<#k9cb}usd2qLK=)BMFr)U4;Wp&`ZKjLb~ zOkPwK>}4^6y9^5@Jw`L<7B3H($CVh~9eYuU6^#Ggb!iJ`_`87rDCPM{V+PTwM>7hq z)xbdS!tBE)dk!c5n~mxhoody=KreIuK<|jg{b+zIXrLE>h9ULnk;%?Lk1GC5u4tGW ze?w`ktCVy41Nrx2H36S?R0Sf-w#V%5;-7n#dD6J>JjiBUaPMuX8?9R^fCVx9+RIii zNqw=^#j&8OLtYeq*QoS_52h*z1FC{VxT*k3yMwC=NSic!clWZBJA2s)XfIn2-^*%) zz3dEZFZ*x`;`6*K4!3UDL@p1a{=p1mPG8iGsON?DvS&Q4OG8KYmxtPycLjPc{XJLw zS8sBlJcy{$gQgE4lM75AuJgsa&erO+5T$Bl10_tnRglQ+3GPCH>7LWQZ1MB9*&l7B8%}rx#Ie- z$-rf0;qD^zpe^kl-Ir|kFK-rd{fA<1-ODB-NSXUg6s$>nwG%JsX79W*YUrd@UK*_e zTbOLMU4DwaDVCHu3lJJ`>)<{R_s7wT;ALrvre~S~|EW>_;rcNOkE2`okq!C_ZRP{*y3Ft1NiRN_yDX9x0(mvSpwM1YgpJIzL%ggauRRWpo2tN6_-)ki}Ufv0V8vwJF%~V|2P1{<641kA|oRUjD-rT79CiGVD8d0XwT{g{u z2aaqaNl(czJB>N@czs1C_)_Uc%YTWh*>=R$xkoI4xcUc7T>b2qVKxv~gK+~8SGNq~ zy1(6#u^|BiV1Eo`eRhdD_O-=}BBHHvMd={gxEP8ye(4}c++nuTI0GkIyTORoHz@RM07bALJBLR zjVBkZHeLd;JJ{cj*bom+Cjbrg*Wo3vuZ0w0mn%1uT4J)aOPLJvnLj_cm$_kFgy~+K& z?DMYg__n(EbXHA#pKC=mQQ=0XA}M9|D962G>2zP_lIOT+ZwZ4~9$q$LAvwYl!}dZ0 zHQ(lDSaCj9d{fV-9L@)5%{BHn``6t)htJbbetSpVe(t)y2S{X~KTS{3@q-U_PEKn zb-8^l)>YCuJCF`q)1EgmpA2a<=ftYA7*+24##fB1Dz`4R@@X+~#u>jOO|#62Wik-B zE4snm6_p`(MKT$8ag+tQfN@WP@j;bYo&bC@xCD8{n@$#%6F`xEuGJA zY2f6eh4YSUOa{AgTX;<3P2!im8i~lXF>&v?pY!$$xMtEe#hW5YSrm%FHS=bZ!Z86D z%cE^MUAP&FMI9gsg_dY-b}#AGz$QlUHUKIK5!Q*Ze-D)1k{|#@6;YSa&W{qLj5Mbb zu^`q+{wch3_`Lw6)B$miHCaY-OYa3g4ktP-wv=a&-Qo%m+2H~4@(UYZA#8RmI-%M$ zo^_l-$grqH$EF7<`txZKs@Yi2K}{Tdzrg|hfMjV3bgF`DH={(Cj!t*Au zju>BBx_q(n*qf}HS@)ZjFP5H{S~9FNGQi0|g3O)T$M~4n6hCDGGSJ-V4>FpbEyt|I zZ=zS1Ud+y`ug2JpG$GvztM4t4j^PHfe|!3^H&Eo-)mhot zWghbNn^*Js2#3O0DpQUZLXS{n3$R$?(K-$ejjBY`NJq1CThci z2NCD}A&9uZNw5%>k;S5o{gph3O7b=Vh6?-1>dMX+`{KRR>YCAQ1G*ZYgPZ+YMZRPSWeb$XC-7S0d%wX1JtX5W;D`ghb@e%jZ=E_q^CfLV&b~EWLl#{mwgYU0 zB>c_ZJUU&;1acS%S%M=UJ7Xi?tUY(PUz*>#XBGsdRzJs7w9Q`Gw2ibj&$)OS`21qt zU^yCBAiHw(;w^WS+k(eGjNp(`b83aSuGl)ZOsHR2C-%moe|K3&qgz(Uw~b0XFkgl= z%tS8ADw;0tD-VeB4lXX>atVK%Qo@iaS3XhV7qD9LD*d_td5nHL;s)O86)=z^Y|fWR zS5E)AQ09V>SiO9VEkm-xm``Y=G+}9m_)5r}NKktIk?++L6nn3ngW%!*+k0Qq+1%98 z*3@|?h+Edy+0@a@$QZFbgU%d_9W&g;(Z&DqnTJ8j_vpbW$3wP5aGmJ?Tafa!Lfj7R z>O|8!DbilaUu8~Z_xb~1r#hrN zq_=8z^g0b!X=9(r5MI+^AoZXuy0|IDPZdohqh{fB$#1^s$YlQ5WSwO(E+6g>C2!GA z%$Xed#{nDx*Uipe#~Z$q9G1Qk^i7XrrFS7Gb|{W=Dy;Oruj(!I+H*F;*NWw$99QgU zenyX)*K{xkzZt(L?szT4hlWS74vj`WTBkf0UpgyXj!rLU9P7}h zOQYsDY^>yTZEFgpmGEAvlA;KiVV_7a*n^oF_}<_X|N8e=HlCEJiK!!a`Ix{=JjCJQ z#0Ym4bf74nit8@M{>sMt^MU^iu-xyys3vz??m+LMr;OND&O>C6&n|T1W1RPdvgwRQ z7OUa$4le@Yr&z|{qIP9k3Y?z$+=Ds*+Pp>(@dV6$PqH3;ld;QUa5+?X`W;btI&qMV zM}_8}%7eCbUZ*O9OfoU@39uj~VYnNq${8^+nM6m>@Ne|ir=^^xcZX@R_^{uLeX&-Fn>mm(CI>JRQNstlpmQkj(Qk2FgtWNw6a zi?ecAoApN9;zX7e-QBKEz|`a}(w&NKQ%DABbu}Y2E}d4d>ck?MW|n)pm{Qv)-}ns` zTE1kHcOE5SBhQO`Y<-U|V;m`JJqD}4=$q=8>N#u0rsvKa32k=oITvvR$=%X)T(ebK zQq(5RYpGsvS!Pc?EDo2%a5NwmV#e1F;cjSuXP~o`urd{_{jfc_Q;BgV z?07k?mVctSt`Cc=%EKqx1ysG0s@?WC1Y93s2)-C96Cu+T-KLIcQhuh$2DZMj(RUGWBxO^4i6s&{lU(+ z2Bz5uEpni;ZO!^Q?6QImcaHtTQTqY4UrN-F^G_00Ja!$3-U^?43*>kW3wBfiS9;@X z^-%cmL{0$tL`&P;7I3A1azy#hv>@vZ*xdU&A}uHwMhj}xRUg-t7NGf*BMT&|Vz+Rb zRSEBi<6@el||<+Nw;KrT}cF@_*(QialD4eR!o$mI&^KOSX#t?o0t!(DjG zp@Z&8^%>7;S1g3_98{RLKJi*KfTzEQ5C5Ssdr0z%P==87YRP8=LXuf=<_YB|L0i5> zCz!}BBaGZ!6=&$>apLe-D&4M$$6!8ok~7oyUUl!=xRJ-^U7&7%icW{`hl6KZ8T);+ zZd*w%++JjU%DQ*=-dR4des-(;M`MoHM_=wI-qB|)>E8dKs(BE)NWT&v!2G~}PD$fz zvRw4NQobznTG=P$A;U3L^;@wr;hp+igD(>XoY+zlUd0i#b<#`4a#B9aeoADfCTqz- zU8q3f`r!GIm?cVSU3Fp4f|>O3pX(kPv&W~sbYU10wk7lh@sB2ik4kHt`yYzFOR`!s z{qln9k@)BW9-3eR(Hzzk;cW_@k+;=V#P43?_ zgmvm(lK~wXlofq(_l`Q;Dfai8Aso6NRtMfzf&4G;)cT(%Rw&uIr%3khsjCS0RR0u9 zI&@FX@;|S@Pf_|1f--#`A?VJYRnmr?jh#y<0VfgZor1lu#t}?dQp;T<2<>7hHf!w@r6-QCh1*f*+R z3Oy~zxor|zJrkPS4S~5GD{WcrQ1*K;w|h?P-w1ZJvN_p&jLh1=Afd=xuNW4i!sZYh zkc^xWX|H+f<>_qdYgNx>TZIZJOX2QQG!2g%B{Dlej0)sFC13a)7WTk80e7E*#i$%# zkihDJ!XAM8)QAA0`xI28Dg%}|$hi$_1jRt{4^@@@bK&<8w!af(Qp~RGI%{O?&AtXY zLEGT)WMJl-P1~mev4wodFy#_pvu_V4kay=aEo3(MS>j>gvgr&NWF;d1+&BQWGOyOL z*M7xX<;hDd=9+Li+M#fL7mIe4F_k52#h!tLnJ+Agy_}1Y+EtK=+cT7MPd!nTc-_ER zv5A^wBW)jhBaG)GT)bCU*4X>924-$vPpP_-`uLOKo!H_xT*kM7vxq#@2y(ZmMy0-_ z(|VN*Ig3a)e-&gTPE#BJu|!=;6Dytz%ZY;Ky+t2+SdCj7Xf6ROUlp%>h7^>WndMGF z8a2ykD7d53-WIvP=yXc>_6O6DyF86P6*8(bksLj^Oap-{fAo$ ze$;+A?c2_hi2Gulr!sCJ#H8QvH}VrWAx=Mqrh72|oyv>tPWYkj5O z!eD+D?l;0$*EIZY1r}`xpYB1Gp;zc_g+>+s@tT5HW)DPO5nW(dajJ0yc{?C{K{cMA z+eBCqx6j`iiAcDODz*B36fmf|#Qk#Hs~U1bydk$(^J8(MwPwWFW#vSY97DPUBn}TF zB0%ZJSh%Di?x1%oiWU-wvqrJvI))mYDlYKs%z78*c=5^0cx7p~l`V4)y;T)Ii?T(D z;_+w4uT*tVA=8jqenBy`zH9%2?i6j27ADWir}f0vY_pY*$QPal)Q$pdc^X%R{g#NQn&LweEin>e@ zFXa8?k#IR#Ro#57!>qBQflq3*sh!8=T!HQENKpDB<@f3agkgm__`3hYTMG7d5iXRy zTM9Zf&fw~W-Inh^+)@V*Jpe1XHV}DR918nViav~smpypn#TliJtyxzUuS88qM}A51 zS_ho;ARad6IkWaNm;jI-2!6q8AL(I!6W07?Ba$8zPO}2igV~9w30e6{T8Q-UB^)9> za4w^Wa}uHq^X8m;9G8)K@=W1#uw0r8_OhD}lLE%Q7lCmvD=_W_rZwom)yiQD829dS z9^xR*!;W$94(GwLx*{LOc`%qLo4av<^FRu59$>Ckfb)RV1OSP)o5MZQc8-f~L-K`GJPS{^TwHzp_9$s@jXmdllYR87lx6_T; z*QPw9Rz~Y!9m%BVkE3@F|b%9MT!ZldU-^;W#oNv38(3Hl9$i7MDnmugf8$PzNr7&3^=+V z-b>KWlQhrS?A}Xq=E13chcr&%W#4A_A zfxVd?h)4-MXrP^lywpJ?{N)DXkPj-yy^6=-ko$rG=ahT zK9Rak$Re;7tu7lPD{qdSy4D#@IbZyoE;cyher))Q-a_-MsMnOc7u)9N6SK~A<9S6R z^9a7qWM4L(_EE`t$f&xco$&NKF-GaFN&?nb^dsW!7X(EoZ_c!7&B?^Xd^6M~&h8WR z&|xd(lrTD-U-`(g#PUe5-2?vF@N3>APun`x6QB$RR;xE#C8yuvI_Ez<&*&$~%PgBJ zal1q|4}&R_nr4!V;9Z2)LxI`sxi4O)-fq>f$vkj6JB6g&o1HC9P~FHv_~IyToIv0aH-%wEBBy=ymEh6<8!8y^kUUoX9q3iv#a0Y0}R1RMLOZ3xqGIc^rZbGCDyXt3sE)3A_ARvEMDQpu${t+I|Y{WuYY#_rLkuhftV3 z*my;VLGuMa_@pj2#D_IAn+>mvdO=JMTa(u0S}#*&OQeLw>FpalsCs=*L6q_5PYF$} zz*spLM>lt7zN+F*DwoHYj?V)6i^CibxlSV(iV=TuJ$l1h@m#NUY-kZrK?kDb5 z$mJzN(bMI{uibOm5BB=8)<eP2ii!vLXOq{_m*E>zC&l;SPAL{i8 z-!ud} zddFb_cI=KQkOo%1)`=-Na`5WKtClzPesvS7~D z&w+Ebo;1nn9!s28DCU!?$2lf%{3QH3QJZl5C+of$H%3$o?dP;z#X0E8AjLVmqgK1E zKp}_PZS;CCNCS&H!CoXxktK69<>SNLt3;E1&sOIOSLBvS7`*}~%%)v#X`D_)hemRr z6pFYl$_el$$?QXb16BfXz$#IlSv_53DCr={5H!z!-_|nsLu}w#$7-E1h~M2VrCt=p z*T%tS@eyQx?@zFUigIdd^aJEv{jU@f2u0b03!*}z*)v*7?38D`iZfOpdC|qHR@y?XTjoo@1ApAI5mmHOjHIYRRu)2ZHoaS+swZ^TFO3Q1O z(F!k5qt(>Jtn>WxRvy>6b=ycU&Bg#KwiD zEvM&^Pv5a->dU`Hwc#!MiI7xs5HElAHc_xJHnnv^+`mFc#HB_G?tBi9Xi)mOo%Hh}TSog^Qq7 zIgEw@B?LtJDUpJ_P3&zvS<;q>>fZ<0zy2&T$SUq(sD5EVHfN4w`fr26jZcNF#;9V)jt z8PMmIk$}00<+ZPzFTTAQ5`STTnHQOclN&$A8JL?eMKgAB1*%hLcAMN!anSZ!K~re* zUahXdj{G*ebqkP4U!5uw&_@!gnC7DI+LSbg%uPyw6&BH_I8VYa*Ip)hP0j@N+DBp% zVT~=Dh%COKy7FFsGVUuUsxNWa`is4BwH5fDi2c~%Nsi#5vGY95V10smb8OZ+xxn4#%8x<6&a(3$Q%0V zXMPgBL1je{gBS0vQBhTle);#}T@Kd3gZz8pYt&Pae=mL0#I7+ZbwL=gSs2+k(M)lC ztFo3N{iA$06pW<cvD4Of{y7o=E$x_1CWH0zzq7*;a=TGuaRxQNGyR~NGCwJjC0B)uu&ykvB`0MLJQ zi*J2(3O$x_+wYOpDg2mVs`X0bfIv+0?x6)+?oUn&S_V4Lj?-|K)bzF>1+b(_1m??< zMn%g-$!8?C&PHh&@^|P?e-)M?wq2@LLtT_UQ9tpOca%@JvtTC0fU~g+Wt9X{gd2k( zN2x6xN0*>Mp%s*$vY|i7R4K&W*GIU_3|U%094bOY!a)%Im6M=oWNUQI)NzOT^Lvv9 z9oX}giDGw>_E%2ApAS3)Oe76=!El4=Bun$NhV%D&97wxU!l4J z>ClSFCztKuY>+gP{cDPL1+iZ%*@nsS#DDc`K#nH`>(?fdn3kWUCxL$LQ;>_Qh^SMu z3gI0jT&y%hLO(Yk9pVq-r6YOlzR|0Hs*%S*5Th67te_2?6`*mz&zdEMc3a&@!ra;u zVkuT|LzdcYw_0=XP1AH-i-oFUSG4@`dfeem-b z*`~{>bx-st0%rww2eJIfgJpHS2cYlzfvby5NBPxX;D4%p5nO~7Qgys zlIZ$SUi=5*w~yIGUS?y;pl<5KzY@J=I?KD66swWoJcp_Q>9Q zgp|EyWy>BVBr{T>jAVqeSI7#PA@aLk?>BivFoT>pY*& z$FqT9wN7NALc@he{l(8$l$27D*Nq7<33i^OC1Z*Uh_BOh^**yr; z9%wPtcii9q`F#3wvA>qowrhys6zkjLI?%jluQc^9T?3IwE?9VvDg-!%@#WiJK!DRz zsz)B7{X5{400uaH-g)I!@g8X^lI6){fs@W@Oy56#p(((V6@*{xw7KF#EXaI__XIcY zP`BW&A&9yK&s(Sic?%8jyoI!7_!~&f-e0%te@RCN?Tx)LNgfo2dU(<>xI6s0H@o%Z zjR?;Mz!Isz>PH*$!uqsafc$eV9S+ZC2q~DeXdAljY5#-n$JbFu9GDR=^%ek@Tz~;f zq|so&k^uJ84yx{BnpO+Ih!=>juz~%WVzR`pBjW{>G+cmu^`>S1<;xar$ia#+b)cYX zW=-F8FJcfBe?G?2LGiRLp5QhoyVDJ`XR(ZRjYTcvLKW*>0hpk5pr+8)h~%p$lPt_f z{YV@=qk*|CsL`fLk||`7%wUFu8mqrf^YQT?-}0ibXU4<(J(51yLQJ<&PixJ+o&-1j;-;uXKIXFtyFUGINfOY-`<_BO_L zcZ79pjc!}&*y!!6C7j&E-}cr+?|OeOwzrlLr3gSWcM4dD{vSyZy4o)J&9W8f?XeJD zA7%m;A{eoR2)gUlF7jL^SR2^)NLsaMn*~8wXK>YrX5~#m5S9uS=YL8OfQ9Hxs6@5m zQC!f0OPFs4Sq(2e`i^x%#FAjld?I)U?l-YS4Wpq15KE?ah$SFI?#hiq)zj9=o`qHE0DzJpK9sPy+N!cL{lqQoRYBqO{BnV%)7L})EbsiIs<{|i9-rNn#r?Z zl<8Ud*`@|iOW?g!Bx1M?|KW>**OJsb4j@6Ovbj*^#35mj>Ji5`#3{TPCB0s>B0C8r z2m*7nmS1vusWn?=yzhYNDUcu>O?YiU@tJ6bV=PmZE^qPV?NThR8%9i)^D zk&ni8F~>WB+S{md?E^g)=BP~h$7oqp$-EW!inE$Ed<|i*&vDld6APh>+z(S_-*S+M6HSrx6EeGvtxZt$%hoAv)Z%ZIpobu={bK9=7CdxR|H5 z>oL0_tcMLTf3|zr+B?jj#F4T;de{z74;y0sfF3rC`9msT9W{P-Nj*FluIeUuO>qnK zurr_@cF;#9JtlFehkcy9B5?#E;1t@ISpI+{2)OW1Mv1-qvRgg-(OKAd);FbnvN7=k zK$x6*TkmWDWC^c>q}*0ej6-;Q#N4BV3Sw;K!qvp)Dgi2hpqpOxvesd`T%Y&WfbkN8 z-4OEG7NwjUdCxph*Q?T9MuB-63Nr(ix|6d*&E2Ees6P=#qx);;;Diit(C_)Qf9*R!OJ2J-A-PjU z0*6f;{%gs-^@MmL(T!MA3*9)$f#3<(Fb1CRpy7%gPx$YoIZOQWn)e}AHwX-VnM`Qk zD#WGb3=0fK-VF@C8XYcpg#8A3VB`_}^9iI|0w`WpUki@~hCTTL0)rO@i$P#81}rdm z)ai>+^jo$#u>$NV7y@VsCOfE%*X9xgGa*^feNcH9|9ZK4O^=0aP*kl&;86_F9ZWMo zx`VB*AAq$0(;awzCpQHH)VEMza0SF9hU*U2CqZB^XxpI!CNY7%3w9_il^r(vPAm#` zs@I33u$fQ@W!6*ADGg);?)mFcNAF1K(GmI=};}1FrNe4bX#tSC;s*G=XWG zhl|SzoR$tXM~$&7<#re*l_2K+gN=@o8SCvVd{rx~3lFY0L;{9MEG_e-&(c##Qy+9+ zXI%_u$E&eHb)1FB!4<-1@_A&iD)MDNB*~AOUi`L#%%)KKgfUDlMK9=iFA*tY)CScn=MU;|~}%_Br-V|k}8HXQyoOgxY6N(d*a%F`77_SONR=5g7!lXr^} z13bxR*k-Xiv0MCW9Hi9TK2dS-@KP2_oD=Gva|9Q?2TYDDVYL^sziVA?n9D4V@_N2i z>&Co^jf48ra`%d70lqWhbLr3-(RS})uh|t^YHwNlC z>`6D>Nr2cd+ivESNIVJ2w&gm(1L*+>qzgLF3I)>96dmWq|9j`#0p{JSv_$NDpMrJ1 zopLaM(a2DkoV`HrD$EzYT zxGv*^W3j_>R6Y-}9Nz_Jnt}t#_O*)*u!f6OPE-Q5j=KyLPKOK>rEw|U&*}A|k(FnU zpUnp}1+$c)o2ys?Kg2+~X+KcwpsKZ3^cuNsTAj{&oL}8R4%9j;>c=h(>bByeJN2o& z?)?=tw0_r6G3G`@cW70#!B+~NW9QhSKm)w|3_n#pJg+gfP48sED9aXr5EFgx{v5|G z*7Jx1y2%MtfUK0>;g2FUF;1Nf!EOP$(_P>ur+2x2s4@HAWeZYXHOrUxZ7IVRjY-G{ zG&!}}h*dOb3iXJV1c@JD-`g!2t9>PN=$J@e-_{lw9uVF_&=Q#1_INw>a_E?7XNkSV zvgf=Z9wKLXt5^N!m_1pQ6FHCp@K&DWgrRdcq0+elL<9`}mSKvn1 zY(%3gS}HOa6WL|i@|M853Dhb$SiB%p$Y;RH%Lf32mqm4poWvPLVnTyufqZnF@+G#% zguyEZ#?jdMHpm>#X!ykH2h!g%h3@bP;QlRB=+@nqW4PjF?*+bu%7-xz^rXKFi4Ij6 zLI=gd7B;MJ4lkC44UZ7&Zq*nQ6UuHMP%QX$uwp5!I&Ln4(q4pHWGDT-p!bR!LKZNz zCBw(FT981o{L`FhXG;(&1p$KpHH}TW12rk3gLxZz+B)DsXet-399eLWv$QJYZCqAg zylwNmcrJ{pmaX?)IGs3!@-hecsu0lddPo1#S&*2vYQJ6c1jcxKi?|X)$nPiqG-E z<{Rr_yc;PZrUm2tkEG-|-7 zsOEb6d)ms|o15#{+}T$xKjyFe?i?ICiP*o?-l{=7V(5sG&i$7&$X**^M&tm9Sn!Y` zDJVc2B4Pn?sM&Aj&hNJNUUBF)_&2)(vv6ckDU`QO=`bOwfdi{?L$^~C{ zN8%vfB3BrwQ7s3A&o_S{9~Ayo`^*$A z%BAWPgUQ1&(@@t-Zj_VPfQQvKiT=U5p5%JyK!0<4T^3ESVya(VVs`x_)02TeFi(0b z#h9m$8W5lRR)T`#Kf@mJ$;sZfc}$XLb>TjtwuP{{MoS=)_lIOW34p;8mNOB$WP3(k zky!I6_xoGf#r866FJC>7NVL5MNRcQ5Ub6FUU^_>oaQ(7L&~8i}QThI6fQQ zq5}hEUWKt?zpO$|c{x;M{u-8=Dq)vi_awny+1fp6toNNX2S>_6FCPnYt3QWB&@$ST zF+w}Tp~D|g2+RC;?L77rpxS>u+nulO4d{CLzZO2vHjzfag16)eY^pk29Q(rOxnfWQ zD<}q>;5JnkEdfm?jdfr5B({nfvD@j#$i22Y2zW|w*ACaNyT(u;yT*BD27ud{=r|l> zFSCwYH<3Aar~><_U<=502Y>Fa+>c%JM^cpTffOe;}!_hR<9(WkuUHL$hX3g-4ZjrtLpOD z4p2^09Orct`s#A9U}4(LAWYlj&9WMO4mWatG67}*kh}34<*Mi{eslORY|Cj!@(4sk zmO?ptYJ;UGE^iqYE-awI^)gz6XLZuUIcZq4*J z5{_u(WU`K{yFs|PlscC6#lzV1CMrcOX=ltm&hAPYCCH4^6|06oECtXh?rU6}ak=>>5FM6-sL%69y z8&hnBjsjT{{s~jRZ)0|g2N6nA?+}^!9y=$ClpFYbd|4b~s3`B|-h?pqT)^ieRTJqm z#WPmvx(2BdpiXs?LNhFA1v{!4KJ|%Wmv_*DF!etSB0szZnEE$YcRSTuW+G>e6R00F zn28ACe;qEz`1CBA$Z9RD;Yl+;C+*OhwvfkWZWXhjW0T!!OR~IJ*O`@p(X3rey*I$r zQ^GLy7CI3@-Rq!x8~W^%q%Q_XykKllp9dv?u3k=Yr#pF)@BiC952cO-2wIhP8Z#^AGa(B z)(2{*C~pP<_h~WAeR|hwX4`$*^=78-bJt_wKCP`C@5d9*HiWxRSGs?~!XEI`x$Bq- zd9MDUi@O60{c3|kziuc@*@3uvS@qTeY7qL>0}I3RPzThwFu|>X4~eOX^*T|XJd{48 zUBgDLgEfBOS2t*H-YyB8|L5`PpBuefNPFcyB*Fbl&m+VLrGaM93B-S`6gNJ*L*xI6 zc?EDx%OH8rb|LxB`*o%MP`0W`Bgt^L6dLzpK^CD~iYjKV$g8rtQ0Cl5+YV(9`{DSl zUrbywUXdM>u{4u1#BsC^|Bz`)^hEen9*;b`iy8k@O*zJZmUo zR*AJkL_hYLxGi-%?XR(k0p&s!Gw7-@p5A8C`BPK^ef7}_J__y%-@D~*L<9q96&r?SiGAaDo zP5Zk^VLMM%QxU-9dSr2~dM#!ExdEt`Bd~hGgzCjm-orLI4$UGIH@P*_T>vTLl*Mj ztCrs^0i^WyOExGxvN4vvFKxWG$-)KK6xL1S0CEFA#a7O1b6G%c&2V!^F`-{iye&gy;|IuI2+aoEg8`StucUyV4L9^OzzjVJ zFhdWya{P0+q32-~RU?kfqTz-I^+ua)_UABqhUMmxrD0=k$@XqNNnN}%^W6DQx+Rgy z2K2hmXT}bqFfx~PWd59Yb8hT@uH`^iek75>3{yhqXo&b3nNY9;STxiHDuxWK7+ zVCebk3peyQ7^Z)Cp@`uwx`nwk@v@UZ1j^;sZniK;KZa6m80BiRW?B82Zej7g>4^o3 zP8`0ZsoJ~W+{Ae%amg=Siy0nTLh$q0f$xaea6Z(irf8)HU_1z|N$9YG{|kEoZxqVJtAqJQAyzhs zwTH2?F_XCWWJ*F?Q=d!i2z3S^_2{9u=RdY)w|4fOE>dd!`WGJ3(F@_|J6XvI{_MG0 zATEA8HfVE>1IvPqU`4vYMayk&q|uF=^6p1s6`PtgL3AV@p|jw0(f4+4Ecepj&@KZB zD5iAJZ)0FV?6}%n+{EqcqQxRmn$TdzBG(Hk&W>9;lleTd;B+~9D}TBqS`g()&9Pa> zTEm#6GmP(kbkf{O(DF6Ah85pprtEPEuLLFInTao@WVTGQIc^~JLxoXHqjw^kO{T3^ zzxFTtTstvkK`xrXSSIqo`)9lL+q6J;=EYi5Z@0W=7pRJ;PMR-09!ol>hT77HVM#$k zyvCQLd%}X(RZ;tH^w(Q=NRX=&q_JP`-qZG%(V;9~C1ZU@8B1Hl%x-86RTm$+o$@&p zQTlt0ePsi^ZQczczlPk_%Pr496013>ZjC_WSI^7F&ZdR6>C_)7Yvx{Ma+j39?02~b zC9&Qr^_&`iTKyKSwb+Ckv{uTGG`2jd$-g>BZ8Jsf2kKZ5<0~Ge9TtDjxwIm$*^!qI=AW9OXc6Y4XYq-FoBx{*x z54Bs{{HNV|z>G=6CANxjEIg_i`I;loIKr(A+LD*$*mRKS`kz?7zqe$!TgssA3YoMv{c3`+?q{Oz`I@q8-b8vsD%}<#Va@HK#<(R*iTG zwfg&{ITBKtQbwAeD1E?qGd4mryeO^)F-ngBM(O*ilGmig-4*#4N@!c&)S_Vcs@_pZ zE+kCPZsm-PzWtcvsfae6;tD0}GyF~VrKxMQWKT*@%hk0>a=8007N^u@6<>eA%SW8P zhTOscB^FaxPxMb|UHC=f{}?s4X3(i?>q^2k(nr&Zq1I#1R7LoxbnJQR$agEn9(+>7 z1Bd>wLqf^e#?D^HY(JtDT8GoyK!2xNIQ~cL?5!9?sIQ7Se#ic9z%JDHOf*6_;Ldh8 zpoBG_ejYgCfO)iLt!;9X@bZa^M=l@llv6+%IVRs;NLO`5rs+7R7@CZ(T)_yR7*eNl zlF4uLs4s$f^Z}?Cc+R~hxkxD0>p7fIz7y+d+FSxT(QhG}0wIvD*>AKGyDT;sO)J;4 zj${bTYM`k!D-4reh2}O9${1*utRUK(vB*;oo{>eJ0BVIoOuUCs(uvCJJYp#6M4^+* z$MG(P7>rOVv`r{Qg$Sj@0Q&(5rJaCKsu7aR)woE^9j<2yBb4&gTGmT}q!YTOxu%zN zJ%N}8#xzEg>O;1rw!ctz?*P!Yj2J8UK;3|7aL^n&dfv0WyH&GacT;>~>e2ZdvLO30 z0gO4p^yU^s_Lbd^*|G)+Cs)^I8yeiWC}vXSV{L2FZlEI#`beM9M_)L$?8D9sz&Tb7 zWlo>v7@uP)Y#c2;x%|McBda)CB5+-sA+E2EbH0COIbfas!>09xCk7ALhc?Xp-+x1|M0##8&| zaqR+E?EnVbqr81RJCd-p3y#6IYhwnyc#V{#jKxYOxuZy@{8-o97FvQeP+Phf@+nC0 z(F|=|Uz$2K zl+D3?&OM9ls~LzG?>z{YP7_m{@`*Xw1>6W|feUXWJNpaD+b)?`5!BpsBqg}GGBfaV zS6o9#qX~fV?XlKCT=NVP*RZKM0ddWh6y#lC{Ndu7(=c((WYwtCsL@#~hL?S~I6<@BYS#pH-2203ngH|IJZc5wB)}VKJFl=8s+J z?*t-4uMDApS!YMsu%doi+xR)7s)db!5d3bQm^{fhFR{z{{6cmR+7++fd0GqL3)Eak7F=892%9j3YAl_xn{jpG+PClACv* zZpWpyXSqrdHkX&_K5ythcXEvzy!kmHRZpT$Loru5iXaDlg(VoHek<6j4)|qddy%j3P_oAQD>G(4h`yiqX7cE|Z)}cbz9^>*=cP`MiOYH^gWKy|U`BNFT-9 zpET&IqfK>Rb{W^&J!2fe2Sq$%{{4ggRh|YdC-p)_b*E+y&N)WhAB5!&s2*4h5M|K* z&Y95Pa0O#jkTI^O`6(3dSOo59>K_ClUCo7}BfMw-he05GvjfTJ|`eE3se zSLlxB&PkA31ww$Tasju^KSP;X&lGQNwiazJwSW(Oe8+eI;vH==(V?de0QkP$Wn$lk z#XF(_sVD1iCbr3Tykptq4zA$x-vGX!;EqxV;46j*@ZFYrE?zJKOzg~u$&fLwzj+b? zGzIMr8RJ`J=#B=(J09HC{Eyw)tt0O}>|VMibdPoh9sQ?5FA2ZAJAV$y(yjx!^cg4v z2pDtQ zKFUsAgExp}?C{to+wpl#_lV7-YkGmCAz4nRk}71_RfiVieB95G&IfwQv0rlYyS@1Z2_x05ZV873NIY(}|BQkEDa+hgvd1Sb z-}4RS&xs2(X>RsRPUXC)ycaOnS?~Uon(rE-xTl+b?AYzTk+CHaL@*BBPyW*&8+FAU20c96XV*`d1BV{M!3A^8S6X^sj$hTPIckzr93zoKPVbI54omO;+T054*e$@0 zJ&l><ycUKw{2{JOkz=yh%Xw(M5T-B8%+<1^>|O305)KTW2}8CPBMV#ZlI zvL|9)iT$LL=PAWAs9wQ9AIV=MW7o#x?|ofb<&P6JWC4DiSiCcC7ZY*cvyCFh1(05U zs^vK*-RiSpz9q+AP8EQ}Lt;Pf~jyLoTPb=8_YWa(1MhQ;&qE zHcYPso5uxOPnxS`d?*`n@Xl&1tx1z_ArKzB89dJ{#g+b$h~R`0-J8$T1NHaFXA{p! zlD}N>%wrVG8%*oxiL_+nJlAq>_uv`YS1ob}UeS!@h2+I|`}oFo#yVhPbIE~ar-J_e zKOj^U^!GVcdl>CV2{iv#{=U7{hxk}3D8UZnMio)3>#}NnzBVKoH_-ExnNHlU{`>3v z$050wb`ns4?s+jm5lTQ&GQThijZS%plIv*Ixj|A8ath6^s=9J-QqV70QqW_>q##yU zQqWozo>R}qOa8{}1-Fq#gJm!Y7ery$kVTJ=c)6M|DpfQ6K!5IO>C6bGg|ysufk&~~ zj1bHX!iG$|0KvqMsNt6G-~veo0}>x#>BgiRTHHc?6NMk0t%AM1;9PyGOFF zi%bAcE=8mxN7VmUc5k;xb9Y?dAoQW0H^hLLMel-dyz;5bBD`FLly}XOy3(l&=ykU$ z#M6keW{bumU%IZj4Z3tEB%LaqC^2--Ee7I!ttPca_$MuFA3Nnjo zuDm-#w;bG?L99PThF9eVrdbt5xI`bknGkTAr5Suxy+kuLJQ=jm3m zGDbcpwAunq!Q33r^x>s)KpeUH`f}g5(yM&j)4V<(mm_LdPfM-xpG7ASQ+iQ|=05^ z{r+zVRSK<&%QD`-Q>DTO?(^>z{<`YkTHMzH=U`9`K~{+1!{xuRpd5!JK}7td2?mW<17cgTs7tA2OLiJuV|6G0vF zEm((~3f3X_pCg$`h>%x98PlaXZp3$&?cOq$2iX&U(^#wgpR5{l2rd3n!f_DqARFH70r(rA`aM@y`UDM z26+}8j8e}?l9tG*9d0XbI)|C$yr)49?Gb_SEpJGiT?-CE!T*Cj+O4?Y&?*Te2vsi# z0NZ4Z25K*hE=WcLW6!C1?F_GP-z&pOyKErY{xo*os5c12Z5_#%5_+Q-D#nTnXVAuD3i zRo2X^=Ut;+f2>LU6YpXs3>pSa!=LjUgI~LEUd-rjIYV;Ueo8d|7mMr2)ujQ&`#N!@ zQ4Et`kDbJqv2IB8BOy_gNYkeu^QzdVMeHU53496M< zg)gLio$Qw40wJv@#M+9!pT`VLcullyUiXgK+To`6;E%cdk8>AzNY6#Oq;T`p!Ab#c zymQ=FVCN3}%r`6zMJ(+0Xc(Xc76{H4@7yB~7DW7BU~kzpS^%7^$Pcj%&xh>ian`9K zB~IWzd4m5Cx0tbutJ$lJ*+Gw(USWPN*!>CCvV}o&@oe83;E^sS+==9-;=eI zUUgs&dp#l+vVG&K9(yG5$6yIPxz?+&A2wL}W(o#NraOZr!6Ir2PeMy6_c_%bLS|8^ zr^>KIBBAX>qTcV^{EN{=kgK5tay6{Br#PO*G-QBv$N@?LPF8G&$ck9M$%WK4o0KjAu9?J$JTH`WJR=Vc09h8yZt_BKf-R!B_0KJV*u*r;HmiU{n#xL zdl|$8FDVA9iFR#!Gb)#`;TjT}qEhzfU!$lQPR|c^vfb!y?avw=04nVt>b2+E@b111 zA|^|x#o8b!r;4Pjw@G>MG^9%i%}4ExUYhJ|+quXM6<2}Qtu|w=TuOW;lNM|?XH}oT zZkB5@?!>)JBZ(yGDPxr zy*D0UD`GduhEc9WHGYXdn@l|GJ6(J?v}5y{rPz%ZpQe#6|1iAyAWt>;F{j(D>IY4P z1B42Icol&mO|)g!Rqh-z;Dn}0ueZ9<`@*8Hc2Gm1CHxL9O8@=ZwCMwi<6yCzl#Ve- z9J0`{(AB>MKBuK4!ifXz%EXZA;7*kse2)FO(%y2}BU>O&7VwRsVA}7a`&+hZY0L#p zzh=84OOk51uKYZGYVw0;3W;EP^nPrvkQxkPj`mE9${ZVG&K5WjaE=A*ke zxVV#9?D;(jo>>fhbU&eTf&1v3t=u#|!>)WS*6Q|1+d<&t+jCe4$VUhBrG{W$hJ19S z0vN!T3Vd{*VLmz-6?ft4T&^3he*IZUr2D72xC5lvk%hh(OQi{<{@nBBSo zY(+_Mw0O^X|MER~HA?EN*X^71lCrXwMVz0>2|76NWbmkjD?e=8nlL1|ffKoeT24Q#9yCI0@T zA@%Cx>QNUjxtm>Em3uG3{fx%ko;h&vE}jO5IznngoZ-dlw+pSnDC7o=LXD=PfG4-^ z&c4d}=rq8NVC-N=Iy1I)bFl8;expz~j3)=_fXuRNU3)*G2$#l*JwIwg3Uol%n~j35 z>$bd@&pQuLK6X$F`1N^<{EK|w$@{)@E31*hjY1`mQRvx^JW|dIbMdF%$BD}}fo{8) zN~sD;k)%TV#E2w91DfYJJDm9^wj>cL?MMGG3faHG|K-nUOjXm^Bb*^EDw8m_hD<8{ zd`26J#3Qb~T(7u2aO$J$34jfpj1z}+UpsCf44j}nDif)hgp>`V-~i$WKLP(8+i=hx z?bgc;aW zfcq_Y>ZMXB)f}Q$G(;Ri78Gv#s`iY9h-Wub`URml;wM*4s-oKosS9|BeG@#t*oftN=6 z6yAm%W1#fDiTmLE!?scWp>y@?NG5F9KZtB8AB5LVk{(j;9mU0(=1 z^LTI`%QlCNCGuR9;oS92`bEQNKUbeKbu-lWetwR}Z5(D09SthuP5kDDU?AFGUk5h= zrS#2#_EgBo-on&&uZ|m9hyC0W)t#C;q)zv(v#*Yz8Pq#4gTiilM5l|irRRtC&xSiR zsE*p7;3i48hB!|!Cp0GxB+Uo49{YX+q@U>TNk54^!hRkfoJ>&qNeYT*Sa}`+JpH83 z?+i#kiAZdo&&^0Y-ETtG;9O6f3}oCmkawtR=zLlE^+5RGmH-TH9SqJ5#y=qQG2O%O zah!Vr+UQZg+vxHPur~V7zY`M(mQl}yid8FOfB%D+U`O5XxmrOUqk$txD>Mh3 zOmY*0@pp8K@Ck3UNwl_syatPL#FGiym*b<;_aI`z;e*@#`@35^K*W8sh5{r@O0Mvo zTq?ukap`F&GwH~Ve&=MBNjYO0sH%zdwEOwDd!>EkmPNbXlF3WK z8ZKqbZ_jOkHfVcpiv!JVn+ktE2R+=)9YX2i|XkDc}UsX$y&L{*z&dH324&@5;K%>udl zHhCaEoqLfV<BZ zz&Ew+i7m0sY2Z#3Uvw#~!kf`YDU6g<ITUJ- zFAVm(%sooFJaTFh`);)dG1(X`RstqK{o>(ew4wrrsSp-;_KYf~^?gOnUMu7h9F4Y{ z%CS#>FLC!dX=0Xmc;1&fQY_ij6P^8v>}s6fQP`g>PU#6|Ug6Y!k&@#O^{#t^&-U`> zD}jER33dP46Om^|>h;hvLaRCa@u_I&S;PjdR5rh(+ll_Nff%OcCijGHH|HkfyzI+= zM5eJs)ULgeA{>)o`;tBTzWY*j;4AiDYtP1sl%2=fy{bZok6Yk4jQqlQsc0Uap+a(p zGFY?|VOqPtJ`T3kZ8H}I^mMF1-YUYI2U?~Q$x&+OU^&=Uw{Mw!m4c{k=;aT^WRCqS z^Wn7lfwcWAOZE11r<+FDe8JbqE@OB9t~ z!)Mxonc%UITHURxWlklGI|eVA>Ju+gHpRT3@iY}(w&1}9SU405zE41>9r|!vr+r0I zK(+x_EJAm>QxPf^NT)3|XneGQT3w&Q`psi8LQAtY*A@&hwIQM{;WM3(xFJ<;98eFQ ze+$5-=`Lnc>=b+si`5GFo&&{d&Em}nqZg**6+Hv7TD?~gW3`}d!ELg?4>i^fH`eXj z7KD1)>0Ntn;!rx1GzFB`NGthd*IyFi<)VAAQXJTmPHheKuJ2;?8kK(qt?RiTuUxx> zMW3o{D2)$Myf1<{JP8noC%xa#9OCfsdjwv{`9$BVjr?N)BW*V9W_eNOW9p6^<;7J4 z4$0XsdQCzPKhyv@5Izq3rH`9Ni?O3JJZw4@KXby4q!gPcNViW@`aYOx)mc4eZlE`l zu0*|byyT4_y|~DAHYKAPAHtU8_m;FDIlMTvOsBKU_$tXCawDZWcvrNS)Ql`fF{9;a z1z~zFmE4jh#>-w;xlXP`{-L!8^;MM2aCbu28h^;mADuI$OU{#qd2PlWI2OD;TL{cj zXYgGSPnClkVSB%;yq%8Sp12Zdv5if1x1HKKc!vJh#r9SZqBH0*@jV4FqWudo`v4R| zA-I`^48m?^$kKByPSQq4oi2e9EekZFeI$j}>~3^EjSG>lMn>cp{qDQbJO5}1=BTK2j%hZlhpA*k~%0! zYbW#@CaJ>!k~&kEqz>_gvwj-7nYI7zW(IAJXN$rENK$t=4eqa-vs*{rVIKiL1Y~KU z{v;P%vSuU24!e4VR!C$;4v-Z`jPf-yK{Rpv`z}C(8@gUIHB0BXwovil^3UP>?C<96 zv5(7U;tz8|Z3Ashv5GSl1!Z}mZ_x4{JykL;sYU;~a5~MRQB*^9G21TtR>A0e)6A$v z6tyJT6Fss#9@$){Y-{(WjHWt9-?-NF<3+`kUT!9KF|9)uF9U8xTuXW|GbPD@TNE3{ zE}omvXRGYttx}4KcWhK&g!5;A zB^`Xb+Wx-6`VN3Lf8E|f*KRLM1X@k+*#^tbu!r}+yV~DZ+gnSB?YGCoLp7k5wErGT zXH@Vzlx{9%h>+8miGtH8f;^5~)M61mWvFM0KliH^V|=87DZ!f<>b_-z z^ehHiiA;tqrlocV5Ca6#vq1Mv6;Q0IVKG3bK@1QEkaLp+Y)ovF!{GCPVpUd&MnWMk zJb{ZBg8UHqG=R^~h+ugmL23sT2tE(Ezt;fwmoa}rI4sd~vLq_NJhqIg(>OruAse8= zNw-R$VQPAjUhL>|b8`SuDg^CK`UO`P$Ycjeg$_2T{C#f_OQ{MX@zl=2j-<%iC%(6fM87P&xQ>b-;~RaHdK=R$l1bd2e@1&$(0Q z(HA_Xv5arqsJN#nSLNU*fj%*YSQYHo2Ky+fzC9h3A}yM;d)U|t+T(};hGiu zq$gX0`ypB(iHIo~s)qSYEa`AQ29r+s<$)^&Oc z3KXP}YegH2dM%XCO4IQ-&XRE_%ANJva$q19>>BIWvt}cha*dG7W)^^ytG_wg|BYD$-fw_e zWX=7p_MYqmYHyJ3eWc|-)ZUx$+ua_ucaV_)xZQP6l00CXNr0=pU-?preSAZV`B9qy zU=|l)m_=CgZ8k4)ZKkP)tsJ{E#G98@lW4U0Vd&Tm{MiA=5rfi;{>7m~#~hQ0bhDJ+ z(oYa4{m`XOiPKBY)}zy#tXjA4hH|xlYt{PG4)hoM3O?aTu9WIGC$v~(2&63zfwY14 zj@#o4W6Ncrz55fhxL9Yzz!H-VY41E9^fx1hJVLwkNh&u7DyVu;Q2%sq*uU9`6*UMQ zPIWtn6LI#?qrU7K|8E(7IMTHrH7l}zA5Jh-DcuY5q@N3w8n5f7h8($(JZL`!e2-s^ z0hheS42{4UG4&|1A)-rUxk}>YwYUc0a9WAR=_zu~w#q&W4yTzWJC=%9S_{u44Tj54 ze+uwLKP#ry0>=zCx!U%xn*drc~r4(-O`X4Z(3NCyj}D-3|~CA@BW1X z0^7&wk}RV7FF3yOPNOLl0H(H-^YV-H4+4G;_7=!z4Nc6{_D^8C+jnQM*v1Wkq05+&edO4@C_Z z0U1jhL~jwa1}RGW*v_eRu(t?tjlH#_h3GB17fET4Exbqk1A;h#_@@Ghe=b7epFyyJPGAnGL(cOnaU%@*nMOT zNY}wBaqKcy1N;R#kfSZ7}%!n#N(@4=G4Y&!P0XKo-6MM*fYvFwb+&uJ9t}hCs zL5>{8cZTpsVFuO=b3Ld2nCyu$irKMx_pH%M}X8@_?H=!XlU zwFue~EVqZN$3f{FZY@IGk==UP&w~4e1uk<0sZ>G)0PTz0(|f7?Yt$(BLkR6VbUn36 z-qyA`x;P^qP{DM&G2omipmA5xV4eU^`qrRQDKLoO+Py{f{A+O#>loc&gvTaUIc z=^7GQl6{b@-G-h*UsB6UDmDs!QT+32fv?5;xP?=qp8LFBezxVp^{a?)_7N3Zc~*?x zS#gEWR#vMBb#i}So%~ZD0jd)bB|(Hf0<_GAtoZw#X4^mY5q6f@TP=G!ZinQaBKV5_ z?|0nNcPJzEFaW8OCnXUkk|nN_?%s|YmntBL?5B*p`k!>%H2#k$BftK;;|A>t2lD#~ zs6GA9ZG@d&*;6sU$uE8`k+l}5t1fgalrZa2wENOQa)aJDweSz-elWyHCdbW&rWb=( zuUxU?NmsY?K;z`~lOfN4t&TJ+G?Aez-(S1FJn!-TgOa0L#oEO;$6QT+G7$-vnq!ma zq|AJ$n^5+zJ`t%jaY7IMacK1!|BNs^d}Bji+t|DFn0De$w#84d!^_)O(%;6YnP>n) zk0~#A9>LwYbwxBjF+&$)89)TEXf#YA^JsG8-oA)g*P7-RSl?31XLA zE^FI1ev5`UNZ&~F$2U#0xPMzr_VUECY(6oW)T#BUVy6DR81l6fTaP&$EZzkP)vdb{oI`dEhvRtw*GeDWs>ZEL zKF!6S>eqS&NP}}W6)Cr5VNZu_5Sn{cg zV~_)jr}%rCi2;7P5@)@0=}m<)99Bkh2xNm68!dp^6LTY-PUDtpg0j<+p&L zNWssnXGDN0YQ%-^Y28H&q8F@%>AF?xDqhcf%&&61im!vW2!JM=0n%h|F@2BtYR&P}YB7o$Q20>7Bt-!y&`rmHq%7jH55%eM3zDmI2809e(ghGUO* zQ+wh0eVeC6E3A!+90WS2YnA2hoJi!W{DF=Mx= zX{uznyJId&u3XwO1<2=T$t}o;x#B~qG9d&ZUFb337vP3t8E1Ac>!{v|yv2@h8 zk<#Bg)`6CI@=JhX=jC!pf$T2v*8)NP<=bkgOS~*FMdDWyQZSsXzgQK`R#~h9Sg;eJ z!}ql0N!8Q`K!hXg;Zh+qv#2CH%_fgv8$l);fj{EP7+B*_ta~6PzP5!OK6SkOcU|Rq%_zt@`<@sw= zN5R9T20-9zWC?Bv3bszs*n;VD3|)DhrxPOtH2f zyYw%1K-iw17hz%M=_`29RF7N(C^Ljs9yA^^r3%syFJ01}~wF^4AS zC5G#4eG$hZs&Va0_Y3m&elh zn+C4VS#T(bmp9R|-kED^j32S$?-3$rI;%uYNRKfHPb3kHBQ@o!$bEwjDug*(sT-Sq zp7u2bnj|;+Csn!0^nos)fvkj^vvRLem?gf>m*s#8VP~8_;*5R9?nW^mJC}`F&Ty|C z&ss~rE$1^WCzSK;&r5J0BHiJL6`*`*C-o&#%sp;tQOleDN9ytR=Yx0ir#(|&t(Q?S zpN1+VA5@4mPq6IL%g-#Z3h8*m@4ZHogmN#q%r=1cqA>Ek=aie2>aV^fRj_;2#93D$ zKk^d5Ld{~`?U(H@k%RAFGTWci##ncst_E6%rl{%dPMsWl|JuLK-eTGN$|s@y`)LBb z@?jRAomc+X?N@$Ja{{D~hLVBP*4hX+ARfZe%jrxKHi2mVk7w-n94GVSdi(@t(mTfq zEVhvfI!-=dXTFIDaS*?eCQyX~M7D$HJJw)X+E|gVYOOh!_65)L`a!|- z08<48&uajA^cYMYouVtU0uP?AdyDl#d`BJ)s}@Kez5kUD?Mea0NXoydYWDBSZp9$p zzQDUB)56o^=IJNdX1Wx*IJSWL{y7MAUOr!W3l0^53`*9U4V4$5cMB$Jw#KT!*N#>{ zaUE^T?|3??6qm~e!VCm0=$SguubWit!6scFV60;))h!b3T99Kow$W9Bx*S z|K$bWtl%d-m72hfqszyyTW5~Dj0|$VW>@x@%Z=5ucGyaKr^vaCeigY1FCQzqnx6Dn zhKyB}`6(3=`gFlt6b}?42aAsPQw?YUug;slaHd^QxCzC41x$RM6?B*w@mw zHUN_4?w@!|c-Q2Pjc(^h)|DF!Cq%ugV-v{ddipz$*K(A0Yn%~v|L)^Cf?!Pb1YZ`h z&wMZqLB_^X7hvBlZT1Rlphe_*oiFV?S`MZm>{(=Q#q62U=psD?B*g#MJ>@+FkvGK2 z?<8;2RePBQed*WWX&;_g|2q6xiwB5noQy+xZV5)QDwesl1jqN6P=6Nm!03a*v{g^# z4831{Nq!FP6ZN*D^K*V@ zx^V|mJMF6$D`Dr^o(*enAsE}d_EpQlxgv5vg9aFH_EuJVyU5Tgo1^yyc3NWx!(H~S z^569Wl$)6Q!PQW%$p1qU;*DdLUP>+g87EFZXAR(VoDQWFIe{!ZW<%CL$XC?cxpg;!v}?Rs0wJx*Js9zba!nMO?zF7;}$b zOx#bdhBjsL*spJprQq;bk-eLOP%rypMa-Wf{h;RZ30T!WMV_Ld0nNE zqQn)-(SFMKE^CYvLb@4XLpx;N22q*molhY`>SBWV;gh0D6 zIgKqOr_nTY>I2z|7HlaXhKHNh>-e1zPX2*6jwD>kP}PUlwEgcFiF z$`;?2*YWrscOm;JM^t!!ir`Ifx=dO;ub5u^(G~J7LNi4w_-O)+wv)>g4X5pN`YhA& zdeXZk^Y?z|6U?7U`;xNGd(IwRvk-$^4a2wlhVcfU6!9*0uyG9*4W=(*qhqTtr@!xn zfmU(|C=}j##T;y0`*WpzWpl{165bX2fB25!0rM9gXj%!PMM|4lLe362;hH6G$0OW= z;t|S42c_b`A;T=^j!_LRWg4o?BTPlt$TP)`CXK-pvmY-`m(RoO(ZRaB|4Z)}XkR=z zMjHOjxAy10>{bpU-m_byM%`D{Bx|&)wg!);cH&pwcsa;TOzxDIr(ss4;TD_Hy zYiLAyBIe%V($kdGRp6+JdwWzoh3!S4iU%W(OsX-3)~n7HS-E??>X8ASNRHlF(*-qY zK*@<+o22UH?>ru>NJRL4Kqk!+#&}2lJdjeY<{tJ-@6yp#>z^WbTQ)`C$y)l=RITCs zckLYfZvW%U{?)ez?G{!@dECxDP4K{3%t34Jt*5=O9Dcj~%9)Jc0j1pEdMkhMH0`7& zP{EWlnXF^KQxmuyL23dkNKIhWJ3+y(=Oc99<1%qwP{>E%!x37*a z%O0mAT0#|KBS5*!_uT@BI*p-M4lsgh@Vs)Ien6HdYPwApZHALY2W)qYpdMD+Mo@JX zpqv3xv~99z>$<%Pj4XPsj=6lQbgzY=;51|*@P=Cmo&yU(JIq2LAR1r>w-EUF!vn6M zHX3;4z~?fFr(M4}gbYI44tEehTZ9v6JO6LCwS%^3x3u=#*1W0O89vg{fAJQ1*`?>T zR1{crg{HxWWo6JD_nVPSISgIZ6yI+rST2-bFcfv+*h3I_m48B?C_pZby*Kk)(a}bY znuZ90hk@*D8=9X(F@>Bt((Q#F3RM=;BxXbxe)~$L)>bBYX1*Nh(=*>QHYbU(9OHe2X-yZF z3ORnwR?!?Zp=&NeJf4py?=B_MmXVV}fr>|49(%e;X}Ptttnj>~EX{UzCo14wV_VJn zka(AR!JCuG;=)>Q=|H5+iq;h>!?$CTdWbS5tLR0>68{Eq*0JAX%K0UR=TB>mTplHq(c;xl5P=1B_*Um=@b>D z{MP+E!~@%{p7Z;@_x<_L+57A+>tT1d357I6A8lskN`sGUE?%lF=Sv*peXu=q5HLoLw%a8LWJX)TD(35i4<);p@a z?5WtF?#=bg@(t-s2(y{n9OnWfK1+cPJM(LO+B&T%W*_L=^LbIv8>#1)T zr%iO1YmPzs*vQ&Eh|umEYlm2A(`wAZ54TR>Kw?mBX^BN~(r(*gY%VvyV?PxmHZSxj zVm-Ee-y^jAl0;nl*s3dHQt4q}{eEr@`_3SV{?~XK626qN+wuLy{fBVQK^X1KtxtGB zOP-%ReqFrbANd;nyzjp|q1*Ab+c-o@Dn-O^*j?7a+~Icl>b4xu>OfvC=FP_i!58U7 zfic`$-q^=-y&-;6Y>6z7MjzXVnj-T=?%Lt>WbQa$b6)XAHSvc#UvufPb#UxEUyA|f z>;8Bgd6$pKYzefA=J(vNX~I)$&>QIq{D-J9K$KjwOCS$qhvUR8MGSp$cwyAPg2HoinTRQYuJIa&8u#M}T!+NEC`c*WMY9#tZ$9iI9ks3&5zM)w=4J>0g5!|T(U1ogLvxTL=r#los3=!^w3i-vmIk8 zCEKlI9H&92T60z&v%@~V1tQv^bu_dCYe&ZPyy|RA7T-lDTc_M#^`|D2~0`% zSp>yB={xYjyArYopKf3r-?IxJFH-b@uL`{~d+e(CoisTh5dCGE-0SywInWF{=_^fW zKXD#XTHs0TyLAys>?SEiQZ1EP6pMgHa7O*3D4-F*lNiqjp69z}*i&n-e1Jv}|Km(y z6z|oG7tB6C8da`#LL4$crCGa+tqI}h&v^^KD$PEId=EK&yp(KD#MQ{A(mA`VCxhBN z=NJgAeYK)@oIc7qGC>q0cUbI}^_4i0#iCE4bi(IP42QlyX@p`J>ew<9tsOg3g0FR1 z^BMaK-$=nRI_kmmqz-29QtMKO`U2(7g3#Y-YVG#xzU(?qDH_F3DUg)CZ=brske;Ww z+5gFdaVff2H^H(oK3*VRetrU-ctX#&_D%9N9a2_9EMCU1vSSg{J$_n8Dy>!BmXDcx z!>m36{rcCly1ZQNfz?M0DOo~Mup)=YMS@A93KKbEy(E_uS;uQXdB04adg%I@=Id+m z_mg%Ql)?RZeAp*-x#V2xfYnF!{*&o2hJK&@g7|SYtSk}Du%UxGD3-)_0mS`>chWu> zVF&#VJxGd>7aL;w@Bcb_jv=Dw{rsBc#KyThry-6g&ct}-+d)l5|*tTEH+*0bsj){E8;FstD*Dr%nQG?E+AH}Q`QCZjn8tY$X z+6g~IRyBQTglQ6s=Y0A&J~o!@g_jBe{9CB%KPBm)ttmzpesP8xcMtk|6E|7qm}}D| z=RUkp#pLZpnG=2!qm*a59kMLQd0g~n?r8k9vE!R@ckb^b9;k8}+O8qAlIOgclH0`n zsZcK|CDBaMht);vrX25KAG!gyrpe1+Jrq)KJ^S$&Li@?W-t#w7n+a+rG!lkPk}RK_JKS6!fztD!!KMu`q*W0 zD`Dd6K%NJ7(QEa_>@z7c9~@H3&O(hG$`o7Z#QTv}XK_tHH2ga6^|)Uzj4522BF5G9k#9Ko0zRbz?`AKY3T_Y*bd>~nuytmu~7G^!&2w(FQ2zffThltU%cbxNab$^ zrOunIbuA_!@;{*hZ6x+nV*xA;0xSvqmj&7fRS0ZV1XJl?QLfX!d*U?`^?`wrN*HX4 zf;C;{si0i#m=}wdoq7`9jxEXywyWiLwqKHkN!m^MzNryzh$&n%n&t%$qWkCth7NDB zWC};nuoglh8FX);a^LV(6ikzF*XUH?=|YchFNm6@mJ4Mu0S_W|9!nX{x#BuphY-He zO)2-3DzBL9rq6|&!wsv?+dow>B5kEx>HOI+RJ5`hcTudqDC?tE=eWLMU}<>n~e77!zvlh1mv@S2l%q$ocJ6=@f%TEIK2K@?p}fQGxo456UaNAo3wk2S7q-VLN=W2ld6v?!Bnxuc@;+8R zxm~vPq~*v@qwy@dx1%FV2=nj&@OcrhsNXBq4qj1mR)$7)QkKS62s>Elyc;Ylmb*y$ zPk#UHpZ6Oy75x)U{|k9RP{J0~@QQyEIm!^v(jp*}LgogJ;$U2tAjU!1TG?)RC@<&) zWNtvWXKv5|%njWCH7`iqz4Z{;$1^ru9fl?jz$UdwQHlljAP}0U`!pZiyh+&?x(s*H zLEC~k>4>2e6yp3MJs2vFRq9qMq#$ht*VFIi^8Z%ueMEs7IJEThTSWdTa<4o(!wbJN zr&&}*6vb%n1{UhH*}Lm@(vc3tV|R2rS=05;wyN3+B(8i(G^m!CNy2_$+j7qHP2J0M zWx!+Lh?=N*a=QF{jcpI>bz+qOo-4KZUyxG1$71yty3jj;mM=9dsCkQtOx}@WF4C-I zL73BAUHDkpvCC)1P^+(4u^|^I5&DsAD0`jrCCX_R7z)di(&p^9>SaH1u8`@O=x5qX zfp00Jq=6^>^~hve?iwzw&yO#iP)^lx&u#Wj*q^}3`STd=$$>A&%9yEtx;k*x$HsSR`>$PWRP-+e!gqw|puj_*`n|=$ z!LJPc8?ZV+fE09^o)(?kE~NgGn(dx;5KspRr??CbSdV_e&US*>+1h}eU3~_4z~&5# zyeqh-e*<|+qbT7vFho3W3K=54kL?Eio)EALq1?3#(TUwjbbuMT@o&S7+_HC#+@M5< zOqh{df%p3t!@yMDk~0GIdwld>xPadvJVbB3Srec1L8e0y9>7&uG~n+mm>9hI?1NAu zAq%Fhi3}8nvN81$__!qkAGhb8{qm5h{0%&ekk$=`NQHOo@HmuR#%WqvBO4hXDMf@& z4hi+HB%8z;RUKw39|@Vt%c{)Sf*|3<;kF2BU@8v}M)iY&QDM5$gxz4&?!$~zs5lnN z?|Y%^>CYYqzb^GYoWKPIc^voxMK(6&I!_#)fAD2l(iC<-1z;C)F72gu11(K6A4o&# z?;jB#pZOB)y4dW5O;_#_*5xnf@P;(Z=NeWONy4c&7-lt-0)lx5{hP_)T;5XLujYyBuNFMTT!eGy)=0X*g%E06einEKca>gn~sr;eS zc|y$nn}@>9+S5a47eaf^hRG2%QV>)V5N6B{(m~S)K45Y1bo-l+33;#P(y?vyut##! zr+mn{b-R6+9&-otiOjElM`-g7W9j#f#|J;~q4@)JltVGQ;VzJP|AXHA7ZZpB>sey& z2S&fNLxkm`+yL`CxEuVi$UMkPodJ2N4hiboLGpBS;s8bO&O)yyIq+(NOm|?pDF4B$ ziRXDCI$WHMc^Oy4&#jf5@(!+x(9{XAMS{fHnn0Y*{ho7xeZ*L?F1KRV~cQ` zIrT?~!ei_>fokrlAMyB#hZl8M=T0t)Ms=#3uzu*?ajlYqyHi9LWtCDNI2((v1}F?c!toM9VK1_w0IZ02OF!^C#xGPJj`(v5~^78z*>mo8<4ssX@9qiH9PU z&oL92{8rir?F*BWrD;dYE`E4!bd+rh=d0*Fx=oa=z?osH4b8jWKHp&(kUF+M6j-XN z^iaf2)vpJ<3ApV0mLf(PsDeZzQ)qj5Z{_B*Bzk7kTUDv83Mt-k6=YDfmas%yoiy;4 zc+HuLAN;roL*!exK@br^)_1K`Y;Oq>(Bi$6NUVSLR??Lx^W>AzdU z{`08c|2@CE!BhwiOD6uuj1k;S%woaB;(GqkFA(;Qu@EHd;jVj3g|yGm6ajq^yd`Wl z#J##1@c&C=1gL65Jm0g=0O&D*R1}r}t5w^_WqO3Hd_60M-=gHEKm9ll=X_FZ!l^jg zEB9o4d007oyDcuZrv-{2$9*4e_V4X7)hd33(|`MM&-d?Nyn02fR9|7rOVePw5kt$V ztec+9#O#hAJV$f&zTA^OYlKd!8z?W?D9=Zl(9c;kY^Qyo@2A3i;g|?f$%G`UbdK(Pox|J zMbojHl)mUV{^yE13~f<92eeECao@eaeD;O_R-|9gMwL>`fX!>){(6TriAfy;qIBKD zd$GRyisEK^6zcs*F6HFi7sM;g6}EoZn&7LuO(dLn%zDb!t!jhU_iMmd_m>5PhB4?6 zM1Rj0heJoiRNv0d43Yl|ouYp;UVis}`k7=LV5{;~tMK|2L zba2vCzS|jN?-XjbbbFA zje9IhU+H?<@hsNSxixHd3Jk7HG$!#UffuEpzS(M1x_XNFUWZ=BiKuZnL4pZymU37` zMpAJE83`9d*a{Z~?xa9Z31{*R))8;i_gT*tg5kO}G+fVrG+lRj-BN22ytv@Qb&I(U z4R$Q|o#8qP7_JN7PXt%nE!c1!B(%EcAyWsQOz?(QQwAw7q=LNZDR03NT9qXHdSXJP zbwiVoK|-rbc2gCMATj@-gpzxoAi)ABNR-x0T25{vSkOa7Ss!Q&f#el`=8GRJ?LK-A zSdXmOaO9k=z07d7&u_RPfj2t-~Nc{4}^7UVFtVx|seDO6`7jK<`uLtZt2<|C{ z*Jj@TsWZptQmo^Q87oW`+sSizKzmh}ov2SIliQ3SSUA2F(M93#l_vfdzqH`lL07E| zZXqQ7?0j!ntPu2{4qa#YKg0K2fPWt@cKD#*{T+v}hOh<(!*|hLzd5EiNG#e;uV)}_ zh6n~kHZSZ2t|f~ckjKw_(gbf1y^S!GO<4$KQx*fVIdETqvMC|=g)@JjP05x5xzihh zY|8vXJK){Oqz+3*5re0rxC?&u1LpMC1L-MYZKRy_B&I~IMIo$>?0`IefH}Q2c2)UJ z$Nq?zUF*hyKy}!3BbZtxY9|d@qxu3o4LO#_ay=25I?_7E8)_pBDvG3nF0)V;z}mV5ZtX3<}Tem}=K&T23M^vY;P}Pxx|UrvcW^fV)iL|Jskm zJ`ximTA?S}>qU5~R|avQC0#88V|~jhY&mgB-TtXKwaDwyFMbZv*1q$b*Ry-G5z)FD zzsi+Kmv;Fp(M8MKR0`^A`S#NEo#CH5qMs7JC_rO!!t|E#zDX&awU(eI(t$bsT;>)z z9@e+I`}UWlSaKU*Q(?42v)ZLpg_7%x1iH_iF(~PoM(Km{>a%p=68uH}N zaE%~{tsLY@zO!P@|HXJW^K}xQ`O0byeCJ5_eCH;2eCN&p-#KHr?_B%3!v~n}Tv-F# z%x>oEu37!}3ZJ)dk{`4nJ`=-7E@X3mQVp2ZzlWLC7YFM`%<||Ya7L#Mf zf2-j@sL4KX91xxACu|tv-+S|CPoL#%lrgx((|KzBCIv8exrOjcu1oOEcYe%x zlL}Pmxw*NER%Z*!F+)_ZH;l`v)RPf4UEyzI;KBVV-uoEE&DH$vyA|~+f-kGRAtb_? zaH9sDv+Gi5G}2$i#?&FBhSQ0qFr$X~JJ=vyJkqc8wPN=1)wet8;(crx?cZ`5dFu4| z3Z#*c2s0nJ5q&dxl_&CP#<$0smeN)raJ-=2VU=|GiqpfFf{_iLArgo#sG*0j@_U~J z`0WD6$}cJC&~Ya-NxgU9UVoxt?pFxmxI_5a^Pd48C*6GEd?%EC;XMZhPr|(C;631~ z!p2VUq_&A-55P}Z`;p7yLFpIQE@GiFAN2>W+&5va+Nd}8xl0ld%oe?G(6mgBHzm$Xg>=E#ASbdMc?t_XGFR6l! z1g@n&M<)MEt@nZC8zB#FAOc{7>JFlaqz(Gy5~I&5?#4=f6a&`WFX#=12QyxU`hBR( ztoZ4%SRb`zD^!;Bl5a9pLioJDm4p?bC*7u;4=rLVe>z%1UgDguVRXYkZny=log-aM zS>vUOOBZo}o2qSWZnsT-@@VwidOL|HM%b9_56;qxokzyeRy`$m6Ys`=JQ6kb7D##uWK(l`v2xAua} zINXjO(l=ghuM65?*H=glGJmXV>Xv$Ta=h6*C`KhRF4*UKI%a&Dpy!k7B=P>JVK>kk zj8(aiN0c4G!SH;&!r69?g(sBov2Jj1)JmvbCMKGSkaM&DhdTmOkEmo?+w@2<;^p)< zpWh+7b}D%0{?@UxQl~oH9M=*2fy2PZ1YPjnpFi=&p^HJm!0aDw8FbG0U9P5GlyHF) z|1{j&Kj$D;4#;bX-wJ{pAx}&LjtAz7WX{uN{MXbzrZW>5tS#i;ZHETu)t!%A7t~%t zF{)#4gW5{@95WuZV6*T6w|dIN_m!|5A+)8dXsOgMfjQ7em^ly;t*_Y4yC`SggFG&z zI=z*?yRRfWt;GXWe=KSQvZdfD61_Dvk-lVGXm=wtPV@yC(Q$fD5=?LXdw%*LHFfDM zbK*tFV%q@EYWrinY(0n;3hhbszQm@e`RToyLiAO&ZI6-6c}q=*IDTSOu((kU5XYx9 z;ku?B;&|r|hdvjYHN0p6;0TP3Xt53QAU_5`IjW=Z9947RH)jvaQEdyL(mc^=0sQ7z zZG>_=aI5LfJgm3~QlIVQs2(RTOQ`4G*EK<9Nxc49?Qe<# zh$rs-9ctbS}^!c#G(;zfo088C+XuiltOyV~XxhDnxBY2gig5v4a9?e8E= zzAB=aqJELvD3kO00y15gc(c~isl3&XjG zJ**^ngzpVk*V-1UjP;)K->RmQMX4hWD@Gu_h9APs-^|kXe%=v!s{K+yCr%vKf zmHz}m2qzxI(t%e_f6Wx2!3INEdVYXJ4qHM&B=X%Q)H}PgHqa8PD1mVDODAeS=+YVs zN!^e~!Iw}_w4Hc*t3;a@ zSVASx=g;buWvAcJq|I&mcGLGyG+3xWqSNfhp(PX~W%?WH%CAbkkE+88L1e|{n{9F` zqCUV(flb)uBdJ+bWJ3xFwu?vMCn~(4#;e8ATd(vM&uvy|;~VIl)vwS}Y$RJ73oW7WhvJl$Sq`}id69US<*e8}q*);UJKWP! zND%#Mve?mpCyb}g#$ZT&&pG-UO|^J=!p&|uws*thr=qJ8tFS@mWEmm$IR;$%c8Iqp zY-WqQ5Yh6*J64acH@@}T?eH#%*<@wZp|DUQC;!=dlZCajOj3}{$|h(T>q5Ktq|#Y&?(sy*eJV3 z4}S&Dol_3N2k|Nb!6~=|zYKeTtWT$&?FEqC{rSt&?pXFJ_6PHoIkl+Ux z62u`T%IrlG?99u^u22eACdDJuGTFo6i84iaH-81Ok^YjZyV)3+u`WC%a( zj+VZ`^&#JWunM8AaUjd$$xz6KhUlursCf-vnU*2(CeAzB04Cj@b)HG=Mk&QoE0y#V z7BCTpmYAPfI$VU&l7F60#jvNwUUf%=L0^|A9XA~B0HlD*4`{VI>Hv-0aTam<231Ai z1C2U#7ya#|d$+dxm;saSy@zL$TeLB$CHrF(J9htIAwq$-io&j%7XgVpKjpAxFxH7Q zov*0Mmd@cx9M8G!#erq8v9OgoUcTZ{FzJ35FHT6KNxvpMM`21nT_T$kZyTghfSE8L zpBcsyVvQJNl+5n{JcBK_vIH6 z;Ir1klB_Zop`iLK zD>}=lw$X;RA>_rmeud;f5U-Y{@p9OvBU-MoXGPL50WxH z^+!Rpd#tm$+ufR-3KG6w26Eq-WTp!eYcnriA^8*lq)bj#kd*1GJd&W9BY$`U%s}`B zo1+CV5FTC!0jtPv_u;pY$z+f0c+7~J!ur|QCFDF;p4@9gh75%5Xf@&sF9o96o){Qg zZ0Z1ypKJ@2br;akDQ*G>J1ne>cn!v4lQHa4S)9$3v>&B?dVyH%{_2f1&nnKlO*>xD zJy@ONjU^G#B?Lu0{0-UbpVi)n)1fQq9g5C9wX*I}QBnFaU*dCVncCv<%CLDgj6Qxp z0T!-W!F!c14b#P+@Z}|(EG9Q~7a7>JdhYr~pvkztfN~)bSx zz_j{(H%FB^lQH&cbDWa4*X%)r~oYqQnO3Ue9qdbTb#HCD(^^5KsvMp@}d4feSi8}8`;!V}hV+1GNM)86*CAYsn;jVvKo<|(PHa25# zyNO_udKgcCa!-M^%#aTxWYA@P8)0$)oh06M!*#c#`;&Xh;gb$x2(gpPCPo7DYT?Fz z3Yvb=$pJdiaj28yg*v&9(7bKMcX!_QA9Ql3nL#IK3_3X}31BMxp&<~ntqr(9Hmz=+ z{vzQC@*)K^sz4_f4e#V$V~=YNV=r#!s@Q&U*XM)S|{KWGkegXP$^%^4U8ZkJzBr4 zgzsJ(tVxzm&%CL@M;UF_WUKG^l&HWThsnvS_D#~&4$^413*S!_Y4VwO&On6me9n-} zl}w&QfjqM;9QBd~X-@NGilf?|9+gXZTgg2_4wh@x> zA`jh1f7tR^=-b*W+gsV{n;>#pp+lIaY5RAf^M@@D;vol7bD)9S@Q=V?qh$SOy3pbR zAFBrBkpkcHKvQa?M|`KtRJ2Vrz?3=wno>7*Lhql%(;CMTQ9-shW+QS&#@?0(EvYum zcxTJQrN`RA!MU^LA!v^TTb}$LWHR-SyzL3blu$y7#uY#WI;nU{e2AXN4@Sb{fs^p$ ztY8d@0`nM-C zB=y9t$CRW>7_W>yP>#4b)R*=-Q7s%69eE!(4XYZ!qay)obR>U4!rLa87sZNtdiEEn zfogKq>vkv-K+Rt`bs^SdA20`q3Sf}n$XEv?fQqMe1J_0jwLnHnJuOXu7~#euEvDty zvI&M#-c_JL-K9ly4&NE)s=EzVe@6MFXs-|SX4C!0->4nT!ZE_(FeYAsGVLx2w zBtnzbOwrG2(iNfQ_qJZUE=3~}fqXWnP~X7EMB!U3%k|-(WVhT&@xn60QkC#eJrIGi zh?mwZ`%-9ZwV|xF-rpiA^Qogo`s; z3zf(hL7Z@s_3p`fT!xVX3=UN$U#81N9@;%nf@FH0&DtL2C;9i3A3i0+;W~S5nOBZi z2g2jQx)gc{VP=>D%1^phN5?-XKTwJ6{1d`Y0U*tS9`4G2U7~$l9qi+H<1FOR%5BZ> z1v)D?pwoSBOLUCjVvu4A1=&L#BjVm2pBX1-d98*>8qeLpu8iU(xW~?b;XzzR9nJ6- zJ=f`J!i!lV%o4vGI%cuR`R9JFI{IDM(`oVrBIzQPFPKB{b9k!Mhb_%|U#(aVK77(A z;w^>whFYAF-X*VR_nSX}*^mLn7v!5H#ZjB{{mr<#3stsP)O8`B$ALogHS`zlo{O8H+uK5k%j`l%!6`)&aD?*zE} zcV`pm`>=NUKJ#F0(Dwn?yhRh>nl}k|%`07*%>b@>=jq*p&JnnfQmBef9m5Sh9>aSE z#N&~PA>aO&w-em`yS0JbHlBJ-OlrlhpdEwM5Njn^MuS&vtz%KU3ihLb3(9ix2vjU_ zs zD85|&;T3MflkO`+W_&`9qY~;0B4=O;l;o#q(E=l9NqOHkJ0SV-)qV)NPi4YyIu+Ox z{xxqcL%u*NM#Mdwv#L^l(Kv`hbNu?NpppUKC(X*}w?$%_LsSaAe3ibI6kdpVdP_m( z<;D8+d)X7cUgM3S*emnq@!KYweXfMs7m?oKTDiZSIKlcR>62GEg{_zZ10GR`M|#S7 zzO+T{W6Ftf3hNRJzI4N`%rO#a+vBO%JM8%tLrEALm64f07i z4x1tw#D#1x-0aC(nv)Rd9UC#bN;ioxqli9)!9VO!5k9=AncXc>TQf(*<`6oq9=oAq z_lo<&8~B%}{RU$n0;B#NW7lH;XOh8oFE;_Ab?~+lKadP2_eoyd;Ew%E2aTqSXVS$M zw2{@{+mDi+IK*cSB=D~SQ$8`YH6|o5<)f65f2P}01e@~RB1x_4Iff(V^Im9FLE#}= zdvDq+q3H0U8cg8lntiT*_KkQt3z(9B{((u#kZ+}5mYaTqpVqQTmSkLw=H22u6y?HL z!naBn%%-(Q>|WY!Blx*O#Tm16I*tx7_7{SuUlwN{Q@)3C#wP;b$dSG26|KNs9!c~0 zUgTN^Zx@GUi3UsyFJykIWT{?VuH14KolADgAMukY#YGXo)IRkF7nf#+`IgCCK1zMU z$e4~y#Dr$n4;&{D>T2JS*(V<(a=8Fg`@Plp>}|J#w$nLeNQ|KC*GuqGwKL= ztzTB`-HtP=BC>werqAD!p?=BGe(;?D|GA?H=K;NS^edSt4!vU1d7Kk8=_;R?W;}yt z>KzM_E1}_p(AMm?tY}`RCBO|T`|fPt&PFS=A*KHy*J%;s7!n(S_1BEgVRTMdo|O_h z^>;=is+IXrM*9cfpfDGzJ=E5PXS%{ZF&g+acI3!mH2p!1{;N;?%exFZm+q^zezx9xzEru~{UY3?QO0|q z6es^tcHL#Hfs#H8`5VmCB{hSYjlJo3FVNN-C%15=vW#~E$n!n4xnTk1xi-OjELO@L z7Aq3OVucU}Sgf-jMbj_9Sge?&Qu!}gKL8dh={Q{Rj=R2U?9K2o2*cQn#`M<+yL?em z6SCAh0&X!;@IQao(Cqy(MJWG1)?yCqcwmrf_tQK}T965KZ(2)l*c3{@w?TO;|V9Dg4$>hITRxyAHA$(cY`QI$7#9_;-Iaxpdy=7J91vE+_ zou1iqd5cc|+j@Xww7;w>jSsOj5n<^)w5+=P>t&TV+8XsQmR0eVNcZqg^C9^n2^qZ+ zwTPNs@1u0Lw$uRDuz5}1_N$&XzGtRtpaN9LIT9_EM|?njrdKZ~>vp&4k# z4lbi4cQCWeT7uG)@s~f`cH^zohNmebeFzlul|uEy=|Dl#GL>0w95Pfm9d}Ah7tiH7 zeL>>W#+-uct|9JYp_&{L@kHtoU2m|9IJjPGF-}LljZ)9W>-nX%r~1KOUkW0U`{vJ7NaJR$Z-ov$+de(fdZBIYIL-Df&BkD1 zC5=Vtk46u+Z(Un6JTu%bJiYLFEc`+{46*A!oc$^4gKLpb~( z>~;q8vTNAy5*dg^a1Oi0!UYtq+VgcLzth|>ZRqL7Y|S@C6``8g$Xq5VFC?wAkd&z$NzR2 zS11tZd@1gna!%EoIzS{Z@L#UMeqA48K-n4`i&APwW5}!Q>pE2q)bgP~EpP2v4%G5? zKrR0@xOD?HQbG12TrF?9Rd%xiXA?z9d#q&s_StaBI#n#3|At8Z4XlXSA7nrQ=6>=C z@rcwus8%kRaz7xk;W==%N&SDX)js}WB48Obev7`_fEW9waor}1PBTa4G)s{4b0uL% zN8-MBOi~)axX&`bmYEpW(N5ZU==Q|Bw;q?M7TPr5mV6GlVl>*)K@7|&m|~6V9nUyw zcz)Kg{$i+*egg^bPB;zqAl>EJ4lTt|MJsbLla=YuueQFrh#ADZ9dnd;qTfQ)5qK+J zqpRXB4H5rvoO&7>2_t9B}Tgn1Tztqs6 zH>F1kNV;Kzt(Qo1s}`On9Y^Q}*$r6|T+F<%YXM%|>7=9E&htwZvZnooz(RIh)u+|D zy5`EaLGdqUOFb!q{!R1fd3rTz&BNy`UgLJWE88HND-T$nT0)rG-v?hFeC)kHe?M@) zYGq<(pl^Qokp>;8jEQz<_m2B}OdmM#Ak=iNydV;q>?Rgw>$RGnwWSRVB}|%H$AIoI zJvzuM|?*#0_*g&^lrMyN?T*8T&%^6M2dcZ3v`DaHJsgFkTv;rJ*#K+Q2@6+koDfA-@G>ma-D`W#@p*n*+_z4 zUPHQVe2Kd$ftgb3;hVYCTmBy`U2$$w)}mMns)8uAyLfG!0*jfF!fY~E6q|2Ijwz4# zID7_6u<#k8*GaP+cO`LhmBM=`Rj7k|xXc_!c&RZV(s|GmKsx7ulg`atL{3D`5kGjc zYxUx{rV6ZHE;5Q#9ofnAM2?Vqk`fR;Q81Ji2dKv3KUYCU zs|w)k7VPfJLnC3tRhRFu;oFj#6)E42=42yCevzM*M!d{~BNB?E9SMw?V`wwm?rWVT zmu=^Gs`mKS3PpC<5LSY;_3K40%dj4-unQWE^z?$aFf6`fTN8PD&e`#~aNlHUNzhJO z3W!|_3;N_#j^(&!yW#FGJQMVlom9dd1^Yy~6?6f?Z@1V((E5Y+;$J>A!u7L%w?Rjr zE$NEdz1#l&_a$Nt5sp3xH^h}Q12NLM!=&~9F&}iBT_5ze8j;g!VC78t#ov<~%Mx0i z?fan9yDZhW1L@(;SVRjx7D0i=BIovGz5}qa$ZbK0`~)A1gn{K5d@LgKi?N6fG!}tk zZopV12aH7^@*pHVWB@TY&{zZ_4?66QMSue>;Z+1s?(P7tGBY3yHE<@(GYV*Q>beWjOuBsk|UD1Huqa%pz9iA%Lx5jRcmW5oh z`#pVejf{#7^PxaErTLb)jq9bfi0^q-R4j)lV*aa7aw9a84TB4ZnO#iHUuv4OylnZY zC5U`3lk;l3HS@<)cCRkSq+Lg2a0_3<0z#@sjoO}11rpx!%(#-H+e8=Mu|P>5J0&eq zx3$bSb~}ovkgy|9qd{h>dTfwNgx3PQ*naq`6BHdY&!zQ$5^)#jV(W- zOcc~(|2y#h;2MGeyq$%#n5BWam7Rkv;_wkFq|^M3tGkdB`RhXd(;wVaA4{rBGkgu#BdP*DqAJav9`O;_RJ*hh!t{tCw9!w!UC6-e zt!i>LVi>!^hLr@EE}1jjXM^jh#OuqG@k2MCL2V>HN~se~8liHj>s+ZKSg?u0+em1^ zW=LZn(&`V|NI7NDMjr3@WVlt9TM26;#|i8&qu-+$Wkd>yeH0kI+(`QlyW(!wF>dJb z20{nUpNT0W0eVCuZhQLXp*j_9^k&E4;qZ9CG*p@zj{in$%A)juHa*GL&a-vC`v>vC zUyDB;oHKx~wlCoECiLIeXdh-F5%QoyKvv~7OxZx1p3NR{`(tguo8EK`Y(DBVD_BrY zi{IK{EJu8YdFnfw=8ef!f!nqVtKr&fiW#uX&yo5O!a7l*I2(705BCP}^s>$qJT1aS z<-a0?zj;z|CD30s&f*Q}O%X?DzS|EPf~KAQ>lqXM#w}H3@6%8ttJ1P5wUbo6q^k{8 zdfb&4F;Q^bAKmv_s(VHCPx-|s_uCx0K<;n_hZb7T#BEb7Li_>b2!qtCj9oEnSH(Q? z2`z4GlIM(5Jg=_QK2MWsDPFMT#?R&KeC?v2(7Nh!o9)k&bf-?<VT?J z)pm@JCvdxX;bxG0&u|}Y7E%AtkW{Yvjmj1TZ;A(puDAdGVjillj_V`NO+p;a(ESLYxrynEJ(6#~&^x;c{juXyDn$uW!0wFB zRO0ei0y$&3#a3r&V0Xs2Yj?J1)FgeEC@OFs7U$-o>s>3Utp?)UAbZ<$qUgZhcKO<* zv#FVh=*u|Ce6kr=V0ZQ-QSiz(#gbp`2hO-^>ibkzn?BMH4aTfkj}OXi_St{F-gI$1 zU1&iIRsFrn=)yW=AV|4qAlM5G1o6Re@}yK&BYZen_R>R}12&wLv(eIVKJ&C@Dt2TkA*1nl<(p!Cg(~}S}I4T+LPWi5Z&~kJ1@De=F*W_ zn%0r3(-%4PsP#gweCMmkM#hJ)KVzxXFAz7~%(XC9T*2`u)}&$NAjU+0%6RHpO5h8? zoW~Ajwwlc8o0$`w#IAk2mcl@gY;@)ZR$HVLny*U7iGVy|v@XL-8v!}C;~b3}5p4zXHqj!c|o)`<)S5No6#nlJjiks2{65ZrwYWLQ^l zKo7T;hm3QTw_d-q)Wo?3d$@4|N!LA9Ya_RzFc2^r2@e?c-_fB^eBce8J)emLcd^)= z|C6#%&fYx_!VEe@{bGv(q!U7ucv@D_`63PbYgLrdo4JB@!*g~ZR%%d)2Y0dHt9|XU zxQ5^u0~Lo>WdH-(u$6(^?GH9}zpC^;pnPElodmvcgHDo=80}td*$B2*%}K%9Q{in@ z&j`WR`WhEVvUYneUC(D1^XSo~#nDe3BoqZp-c8vVinJwuEFp`hX>q=IWg`Jca%Inq zZdMJ3+RnKnc5FolXD<0nEfO)&V)Qm_EN|zsOm>7+an+eVG%V^29<*yahSvBHFTyBASkgYEFr#8K zjfTFy&*j~8%?rWGmvRw`tAz%aw2Mg-Ly+emd|y}1f386;@Im<4(V-s8ugMKo)aCDm z$}pdeJf3J9#w+4nyS1wAel#xN$4i?owJB@sZ3GH%+#xLe=U*7%m)HJP1|7?Me<^#n zbrk!LQH5~qL3|x}sr5e~Vs9{nNhbeV=5=p3B7WR-0b@JZ1dv2b{)Hs61S5&O-Xn>? z4ViXiUN#c^bQvG012I8j)p2%?FXBgukdwKwtX>0?7)M+iX?SAQ$c1|qO(1ILKt#Ov zVlE&D8yck@+sO*SY1B6bkb{l($-#2C2;^YMBnDz< z{U$2}s#5Xj01pJO9{^r|Xz+glFN7-X1MT2+gh95Y0X>fiOR=32O#eepcXVFp0Gn(P zKzy7);wOscQlpz3hX`5|7Y(tiB4{`{^pyzK*w={kQ<9#7$ar`0_nNF-oR2QwWI!wS zzCW~#5;=;ei(%%N-{dh!*AzJ7Yh`tcn)UHT_7x&&RC1pE} z(^SR{oA>bv&w7haCu#Amsib9Vv=f);POWpg|4?1-U0VvSlSDq=P_o+Wf4_QcfLEMP ztN_*^D{S{;G70ddhONk88zo%;Asf_)<$uK&5$0W zjuOpZ(V7^UQbQm!^hN~4tp7pGQk963+WyXMoVV%BnHaGJH{{#3_S57j9y?JXZl|^l z4CcB52?6`#wji`NJ0XkLLeVOapsN<5=A|n%ZAYTERkNd!^xY5I+0#ho0F9(POe2X* zdOqK7hgpvgG3$dMX1zBXVAj(DX8jkrr5F9Y9G!Q2H^RF8!G@0 ztRDL?aZqT#2@Ip%@i+a$f6&X4THcdCBi+{!pkRp22z<;q^MS$b8_~^GPRyIcWg8$N zr}2JRZN?GbDX^f_^*_l21QgOR&i3kO&aH1DHC={-_j1@x6l671D!>g98$H5lRr>KesR{nLnfOzN!?)nR|nG^JW7?@tQr!f8Wt%*TU;vFf7lvt!%v2lKp^1=I*oDrAL zynryZ2bsln2r`twVGckBr0eto$e_=zc=+Hh*}&6v<`Z=B0c3zIQkf(c-}6v5)w3)L zry3eC8ML6P4+4-0gF%K6K*k0J8O}2%pV)WAC|jpLHjy+!kO^H%?&ozwfDBX`2|q>& z$N&)Xw*7-j=oh8gM-QAXMeu47q9Cr&%bu92jVfWZoI3Sp>3Q?X>7Lz721Jf_x9eS( zYmSW_cC7#`;4bD(3iO+%b&w6<(q%BCP_(T)x4}?)vqs_k1ExY;-hLsG$G0(?m+s~H z7cM9oDUus{lXt3rw~rsPu+AD2GX*|?Upj=V++20d6kKR$i5`q9`CzQ{d!_sQ_}*zz zRvGZ>5&tAQ7NKc|^Q>{gM*{^E8vFsQ2(c6;M*E{*rNzFv~l?>f*f! zE94;~MND@aIfS6!e_9oDfE`O?GZO@FzPzeTUb zQ%Ye*oheHFQEf^p4MBk?&eIs0I7v800rd)lyAwBRF)jTduhI6y9}}(S^74}SUo}1t ze7Op2Fgjs27&=MWy~c0f6Fnc`#8?Q93`_CyV|n4nBsa~P;Q+DhpW`JkO{zt$v`hzP zXg|oD1=9yh4d*BCw3?5#m|xTh>rS0}dB0;$4LvlL?^`PVPr|BiWG;&ucTW>(21%Ed z9-&63S4cS%;0@&Z>{IV5Ci6E(XdZ;F5pm>sr%}50J2BP{-Y>Cnbr!$Gw-T(cgkAn^ZX=kD*yM_fQ85>A!tYF-r z7mO0cyyKY(UtB?+nXmv~xMyam&^KVcJ_cMbI1?Zy6l%O8{$=sb(#|bN^>rjsYEQPW ztaLKTPf9-mC#h~vwtxOPK{n&AY+t;P0?78~WJCR#=N~-~FHm?IPR^dtAy@}RqSrn@_c>T zy1}MYLq}-(0zJ(WEcnuOPz;DAP2=I<#!PvJl!CDc*n zVssbqItu~Gm#X}1#w-vV8;u2Oy=L=J?bsZ8OP-qWRxi?43UXWGRF^AA zR|}wI>_3OU{i81X*f|{j=6LVzKg*`VVOO{=gUWA_coy&r`WxhoemiBQvjV7D@IfEJ>95X1S)NUU*g- z&EJKu*&)SFINa!jEkpDq?d0o(toxT^mh>5eD258Nidl#CPu2|MkWg``(d9Th*u5XO z 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�ykm){))~ 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 c7F%!l?QowwXyr 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

^3Q_tOCG9sVBkamn!RJ(R>aNNOkt3YI z5kGl;P(}*nPIF^=88Op#r@48-Dh3-R9H;6Z+lN)>$oKwMH2qiEKbjc=2gTL@!+ZU& zO4`5O>&GYa6*jo+9&y`-Eue~9+He+8Q*`E#U(Cxb<;~LjXWjrYd!=(8tFPiY=I1$Zlh%(luW}JAG#=BKxrSDnIX)E;my8r>iwf zwLwR%r7+fLzewU^jw2{h;Rlg(se*^V#oq2~iCp>|j(&)@C6;U0{z&08fqE-~m>QUp zeu*Cm2Z8s%-ZZy2W^ga=#ffoJW|anFI2nr{Lu9lOmlySEE|lNO<8(&xY;$?MchYFB z&=#aK_I9pY8ze5gu(g9w52GOsv_InM6(0^TNl8#vyaw+2R}gU`?$H>WKOSn%_n0ta z7kxMz=X7$Zs*>I!yy{ac_&TKqHEg?aGdVZboRAM_ z8{|I+!CJP7S<{do#QRN)ov%(`(&>2x<#r)fy$pPHI5R{5q#-4~Rlb97NGb<;50!AX_sH|;(3K%jq zC*KV~0SG_J1P_SH`iw^<{@t6l(G=L{=?4yCnD<78m_z@{ybG@x#0_urTZMf&tCxjd1uPI{=6n(n)69F(4S8xgFkwF*Pmww z>K*9MYejAlw-~Ky2+_lqF`y<$nj7H3e>kai$=lO+ew*+z|ojzxKO&2dxZwN1R?YQ185eSC;pG zt(N|^+@~!F9-?`nej|BlMPjwv`cUc;b9sVefl`qVY6>d7fck}!jHY;3dDiJX1Ks|4 zF?FOd$x9y7K0<)oGW@_+&oPsyBroQL@qS_WIa+JrrC6MpcILiXXslb)`%q@_uA!U~ z__VP)e+uln%ZJ`!FgVSx8c!|vFo}wx1TF2lF&QFd6Wiq7!&E{EOhJ7Uj(Ixf0-j=78MSfWx;mw$$^sfifaBoi_$F5t{8s z8)w^N&n7P|lRec19Mc&}=R2QgEu$oiEs2M@6;F326uB#RxrxGbruK;3sF#*lC?sy*J-M-nC`(a1s0KOBFWw$uT8*4Ak2cV+`- z^G&lz#N1E}g^B?!?-;{ zbju@KtU1tC_4mL_(ArGIDnkErPzA6y_nY{Co$+l@2`J0Id0v=n#1{{6_+=RuWkL1U z?L&RRq@1+EJKKFX0_0sP{+V}qezFhAmU1FT38?I_wVTtA$pMvJG?TJVfIn0UJ3yfm z=oRDrt|@R<=r_*$jJ0JX_6A{$cqf9-$eu^t!wFkv1AF}KFlGjVq<)4PDI#_Ng2}L( zzE@nRL?v^2%CUaX9Kfk~8Ho&VDjWb#Md%%n%6aOM;KH2j~ zW)!+Nkurg0uoSEy3NKSM-zP8vXy%c4Jn98C^PH-xrMJrZHs4(ojA1QieQn&0Rp`l5 zzU5EK1Hf6~M44O8v?b8YOJdt0(B%X8G}$iLRbW^$+hSK;@%_&oQuwV=mEqETr4M%Dj|w)QUhO70X@E`^Su8JEz& zpLGvBpz~MG^vxffX};d7Rc|M2#e+R^Y1|e$iB4ejJ>DY z3c|4tIi%`7t@Py;L8PJf!bnkYdbk&qPT>=R;dRqhx{KbX(4lj^*UzA9hk z6H5Cuz(b1xPtDG(8IU*e3WE(+J0_(lnwqgV$4c^?upawyf8knH8XxSi923^Oy`5OW za$F6)xp(0x$;YG~{Y2I1cc(}xyxiG;JK~SzHx__^v;XXf4=nXBRS%5rFhORykLRfi zQ(0P0+cDKY5p;j{@^U(^L8Ch@(CE&-pMQ1cO^uBW*%eRwW2&%9cvA%3cMmAqA4JN3 z_B=+|+FnTwp_{QE1{s;?uAWAf5_lmAhYv*Xmx@g=NjNmy0__WQsnq`^IAVs&rcB)HFW87EBb+T)AV~#%b|KUg*HSC7)0Qre!Vc>1D2=4%{F=$ z+m%>tz0F^X`?|CXUyDb+Z=jNtVoMOfx)k#lVoz4WPLJWpel1NEvIN12hN3gW>v;4g z-K>xgXy)02nt9(5V|Tu0u0?*kZRV)~qdSGCX>9`H_eOUn?-PL0U1Pud_v+jl^0-o9 zbaxn`3mV;VUU(CgLK{kA`{&>f`@ge#+Lw3~)*e6pTGDVB$w#yrIN`6VnwPB<&E1{w zC7jF}dqe`{8i-$1cBBa5p2Ce+0h2rV&*8U|I~wv5O~|{+ow&<8B1XYx})wn@z0 z1hCT7$v){fCjid)7JTW5`Bj(qCU^b6U-S2cwV=mkLgzgC=T;h?zYA-B?)2|mK~@@X zAw`gtCKVP0oaM2#OGN$yI6M1`H~!X21A@~4R+>_fm8Kl9(nMrAfUGnWfRzS>qyoWd z{s&f?hqrK=Z>bKqnK%_dCXNmOrvV4xG^ua=y#Y9lPe?3FXl4jTF*~5F-Rw!e95iD+ ztoZM|a|Rr<#QdvQ4u=0f=8do7^SKvw30j;X!c@9{&Yc7n=f5fXi=7x= zn!i!#oNjAgr{b=E@6lI9ayB#n1nA$p$zs}3^kI6^(ue~6`(&lFmG2XLvcl-fwyfWz zQs}-o`arB2X$j*{zr0@H=c@(SvD})clau*r`vtAY&ndw{mr8qSVUHlgmU}Gt*#qtz^%SLT2$fgRzLE>Tk(L;#hb>GquKr9%cl}H7Z7F|+7|L@ zbW2u0w9k9efkc|e%4EE+lz-0akr%UG5iqIUR8I3(WKmLKaQWbUUcOh%nr_e${Ppex^ol|cM=gDXFu~DH^Mm^ zCx5op9e1*@Y-Qsf#o|9u@%KfwpvRd!i~J1-4bR_2wZEM01qZN$p8nfL-meu8^zRdm z-##J(xnng!?$~L-9V;Agk*m;sOT7Q!-i|ls znO3`q>g)F~Za=w`hajxH!d)Zp-Go^0PBy5K_wUm%{)Ica)Bxg62HbHctN-Fo{x3nZ zptZSfZL|1|v;E&hweriXXkHRiK1IckeSsXDTFdyK4w^hwO`&&ES&e^0+eTPblgXhC ziM!$U0?JzL%VR@SAlVlC=cGREF4?woL|HLfUl3M~X>nE5h@#+o?hVUcgfkY>!;$WL@*T8FYguvy4k*ep*+G*zlUz@P)cW}jEkrR$CB2MJ8mclt*{TUT&9 zM{tI+{~Xji1LVd*rii6E(za8ZRtL5Ut#rI^ShmR0gFTrFnXam&gVIK60}pwn{vu4* zDY!$|pOq-pr~PqZmB=cK~}bUFFl!o55p%He2;_w#O%F zSVb*2w{>oC+2OSBU<)(f|2rd7%D&6HD90pn5QxSusLD= z{7-g`uDrlKcFpCOu78b?NV&m=8o;nH1P4qs!(TdrwYyDk^cIpxZo};7p%Gb{(5o8M zj21a_)yLlcVVrxy4|!{x!;gT>ZI&fGiRUvPGR8Mg!#YTQ5ii%KpsmC%nc3U{78& z{DjvWpgBUb--p*UhXu!u#nUqkZ{5{NGiD1h9h1mqu%opnECG?CS3XCO_P9$kt zE&N4vJ$Q}E@U?2rhHYw(11snBi+I?t^+24ph_?{E(eWrK&iX^d))hx ztBzNA?7GA|^j~e9C|)E!d&>(r=X6YU$ARts>mV4v#6c$eDZ4J3CWI~=u-zlKL1$%| zD*HR6#=~1jBBVBEm}L7z!W4WF;MQjy;^0hg`7{HBVPFnMOG3Llk3c7@Pf-mfQO8>P ziW7&CJ*iuT?LY-UbOG?1wE&1tx^oTy(Iq_)-G59h2*uYfGWJ>xwA+7!R?hUmuL4qU z{U~pg#jB=!e5c3^lz+*nG8!OHCQ1yN)6{KxX`XQc5RniMBg(yd{ z&*5c!k5Y@&TEM36C|d?#<@-;Gs^lEc( zCGL54yq&1@fm}685yn}`x@z>WZ(3aQ93cr*kpCKHViiizB#9#8J~2GvfQBU}?7qC% z!p^JGZa0#pl)#CbcJhV3ronX)h`rMSV()@(MY)1-9^L~73cHt&*4yDDh&Op<94Y{1 zo)RQCDOIP{`PT&&3@FY0#P{^Vs~W<0!@CVK!m7%f-ciAb<-+&FJO&wHEtMiNy2V=) z`5M_7MQ!@GC*oagXUM7<^jx4Cx?8#`0Lygt#hN9_X0z4I6IS-dH^65&g7 za1fonG9)PlxK%R3&$5U8k-354op)=0#8{Xl#RG8?^7o|5!sD^#rVb-X?@dhwwXop)c93wj*IK_=O6RQ}&ZxxY^A?{Ibh zE(Yf(VE&$aPWEr^xu*ZmiT%IZ^8IhOeEu~;09W@j1_y>XjP$RGeZ(MW%fC&@0Ji-7 zH8LcebhAzMjzCXOD;a!5DF+n1_Da_``K46 zksE*#e^*0@9A1q_lF*)>txYSS^wAy$8{*8uZ9A`~Ku&T4zkZ3ae|JqXx;E%@7B&b$ zNx=>9Ycd7^e$9XFo&&9o+SNtIKUd=O{3^bsrT z1O2?`B@fzXSIz=TG{lDGLK&JQVQ#CQ0u5SD$i2357mp}sxu{kO)Xxj4YrpH~krbL@ zF<_cPgg_)9UoI3a!Xn?8y}tT{CF;FekXOR7{B8j42Sz0Xos`LNwtu}Onpqn=AkK?k zxhKx!o(9BuxI0d;6fKe{A$CDoo{d9Z6_iAgGi*cGz*wI(=#ZMq;u}S2^@m>Vp6C1r zg)cUChCmbh%O15UooxnxDTk$-N$;%i+lhUh9;{U(Ty)Uw#6B$HExT#$(w8hwilGj| za__r-UMzqN$Q1zkdC9=lp0`xLZ9xA4AjN0AmEtd?si$i}^}or!`v2{Aj|}8vVBY3q!0`(r5#L7R+@AA+XdDk4 zSMGS&^uJ|Yq5v|T|0}oqF(BpszskAXDrkUMPwy50kx*}&;wX5gUT zBDa*S8$DEH4w1kdqzjkBZwC#U-OUz%n^zk$sg0Or&f9NhHC;*kz<%!L>f5uL^y&^) zclz<}g5Nsw0yyYDf(0OzgDOUb1>e5{kV^Rz08(i(y&FKYi*%CK_=(T;2SBZ|lAd{b zN2|M~Rzc9mz0L+j;}9PMp?6-uNq<+JN&};~WqY4m{)@OBm7j&}BwFw+3JRaAt%NOM z(8C=;6{m<5YZ{K=8VGA)y7;QYOiUZlNnaL|R~*N@?~$_RQzps{QjD_q&?|9q@8e42u?t9wZv(Q+^SO8H zGY>!Xs0If@G6ecAa~Ef>@9A~^1GRr&nG1T{zBM!NKM%>^`MWar7sU=5Zcc`Zi2lFf z)z#XiTFBMT&YtAC?AD$0j|kX^J!KK8$l2`K(DZg!;>J%kWz%vE5M1Ulrdp^1=66#D zA_jlW??BAy7v4XWxscfDa>@?C{O)GpX-mjEl{;l_K)R0Nuz744>Hw{fOot+Fpdn^N zI_Ya_aNwvP;h*7nYrLaC#E7)zns-AfUP&tk@#+A+#no_!!qhAZ$HQA*T{pkEiy&%# zb2cvBr)(axELRveXXoqbQf4}D$V?ky*_VEh8DR)IzD=S(`4&nbzQvy>{U<}?w|oo0 zdB+bp?*P6<@+&_3gr9s1rPnBI!R8>o#lM{NK}$nYkb(3YSNvavxs9O4UM3bN_#M-o|qhV^k!uOHx z8x^RV-;>1x8N>m^pS#(Zfr4Lh~= zI)PwgNAMz*DNeW;U4@gEN!>2Seq~GTF-NJYDEaWfJq$=r z;s;*hJqh5|f5SQX?F}i?OtWx>E?WR-%Xe*w1#S7o7D#(9lDyBj_-em~!A_spYPkXD zeA_5pP50(hmf~bsa?zG4!m8Yp&uO#9Za^b zfQJ5b(O%X=vd=Fr!%EUB(+xq&+$kUp52VbchQCe2>rP1v=y)DG>aPkYa}Pc4D|10h z6Yd|g_!|xVU!{6~v*46iZ^n=$JW3>}3|)YwD0cxVbER_0FLtTz#;l(;4h47fpCmi% zR=Lg3iJUt`xc&6t(Es7V*}|Hb?iE5;E@EFWe?zyw;tk!`$Q!^cD|eB9vXFSb?I5_e z1e)7ZCt#=rMqz^H_Md^dJ$}IL+}`n11YeRI{!uyDlS6)0zieEEt8-VcT=kES9tdGh zST4Z!z9iweJce4PMWP^_d*>8uQjCEwtO}tfV|EeuVKg{Mn%l2Yyc?VMBw9n77x$wsxGY(%bSVB6Tz-TJI}Rccal4sV{k0UR zdRW1Ociw6jVfyZmj&3XkhvljDgagABy8pT5L3Tmq{)kGnY@G`%FW6* zLF~uovSs-WJ@L=M{gWOsd+T-N0AO&xYYqzx?l&H#%k=&n+~0M1^MS8I&s27TG@#&k z0@&jJ_oB^T1$Fn1!0Mm?| zX;;;yqj+zJ7|XunO4<><6wwJPCb}j>L9>XZ^z4hu-V=*v%0E7Jp!C8wofYP}I9vCyl*f((U?`$P@j#Y%h$u7S4R>z^8O zw{m@^fq3o?$E2<_1K{OQm}JMxR4m(Dh^nM8YE*|V=Xy!f0ryO_oz%&{$ml^U^k}4h zL4^Sf%q#^O?9u;PR{PhieJe@NW?C|~bslG8S8;ErnR%eMD6Ca*Y4~_z-P({hhSYhW zp#TSlX^;&)6jPEuc}u_U0-G)ly`QUc6iTVFQ-W+FRe6J^xl-Tk|)PX#cB#( zj}9uh^yk#M=_dW?=f;s}ikj1lfONBSy!mA0eA8a{YRHUuwUyvn{3^2K(M`1M@>1{m zwBVeI;KR^Y7pt`O1xp)@M1=>G%vo;5IXCiNE|KXeQyCMs*oFZ(`x8FD0pu7(R#a ze!Of)EMcteqcqWUHi<1beO-n2aqo%N^$FnNF%_J@zC79g5ezxkDu&*>$&xbPVj0h* zrlE=4+NxCCF(b1GJ9f0aad5d5GAj=K%A~}#t?Tu>jWvq}fwtT{$u3#191{8K1+W`i z6(^0wtB3jZKQ8FKPZ{#MKjoHiaC@)zO9=9N&6$ii*WbLVeEYt9%sgULsJFzzWG1Ob zkkA!dVchMhfP2n~g5_je%vxTKSdD?I=`|)A~2MN96Q5h|V)KZ(LKm zX4`i~xpH?hkha?2sArGD{b)z|WZFMJhJ`rtys0ASX5ypi{`<XC%;Y~)pF>Z3r z$L?M!swFh9Hrj12R%h$aS0RqHQUC27qxH&nYV0O@U zVx$FxUr`OLa==^MMe1?D^9}bvOi{DF8}VKx}Y(G zLR#>07M71PdB1_Q-&Nu9K|={wvRj+miqq1E<#-*&vFQ^F4g^lCxS~t22DV~+!sX=0 zF38LTM1!cMIsRa!$uDDV2sOP62Xahoh;i(wa_pT+o|BH{QpK`XSvWfSIuYh?G7uu? zT)+OoA+?&m^h`fdO?bB^=MtU3WOlB_d^?i14%@iKNUAaVt(U8hGm1U`8|~dRQ7?ZE z>1@N<-6cN`$pVRf=+C3v)zoc+oa;n7ru$3rN$p~tb1QDKkWc&lM|PD2Ud%?_WErD| z$x){e3wZlsVa9epN@^|9%bG9PJEczcHYt0*M;W?euKKp~ZGM`Y_O^1*sLil(*4rCd zIe#OiBFlqUoCR5*oiZ}#M@XXAp<9Am4lj+JQTU0eGM~gC88>DG}pogx*a#>*3l%DH7Ko zaC$hz`~s(IgWs~$N&3#M@_o&iMA>cfSBYwlhES-2m9gYU1DtYrz2Y`1jKS2)8oFw7 zlU<5NWr(Z6F(M1aylc;)GKPbte6&=A^bpT`z8+R>VR>~3HDxK-48Ql9IBaC(H~Da~ zet;tGwf>U4VG83#cYuyom%!uGX*RGtO?~6Jz<$2Uy-b`i`10c~Wr92TUX#JXK3WW< znuvove1~qZuj=rr#v83CUyx1Z&NIcx3$EpcA*{U+PH`&{M0FP>nXLfNkN-HO_sDDFpaTEOY zM!{y=rVFgd!tb5ii~5E0qNVbo&IzVw;0-64()+R<6Aui=C5Kd3-C4d+LexdQ*4Jpe|HxGh*#$ zIemoM&o6j8-w!6ZKZ1%V<}PF1ox>rTxfoSHTa)t&QTObu{X8o$b39!&%NHz8-AZ_1 z?U5ZYoeWF%z5|s^kYndEayppmk9E-cLBucPZEHR4WDCLMCRF<6LHLAu{U3|8O~jw= z#V@V>Qrp*zbgCm%e5-jr9}6u%$ZW;yG$I+*hh5rxttl9lUu30-)D$Iw2Z z86SRW@idl^U6O3Dw(|33g5n^7xAoVB522!tjpJv080xVbpg|O8JXgEBR&~Oi&HI#gI+37*k_;l`TNSAz-oB;Vf? z#B1{<3P2i&}qOPU@SFZTaD3Q)ZB%d_WGVhkTcM1zKgc1tw?| z_iL!sfw$-Sp**AGgLFfj>d;wZHIi%34kmur4=1ZKlYBJ;ay?L419Ew3F*fzS)&>FO zwr^)!GTajCw)BS!+q!_adD5~ZvqQad^1OP!Z+ni1gNx2&&XJ{79xB@2hvY@pj!&t2 zk->|cJZ<#M^UX~UnXXT4)!wpU{Wua}!%4#p73TqU2h=c8G`#Cy-|Rajsy!{J9&s8C zHpa``G;1tQ^dbOr#=zoM`w-o~MXj4>ab!xQWHTUDdNB@_d*F zx5{tUR5yYxP(@NTerc4AO|FU$0UsOwdld7hJ_q@C1A8YXj6?hF+?E;IYO~^!^p$uGE0l`AWFuznY*xQUd{ryAOPo#p zwHgxVbCE!c8}vlhciHU+Wz0`k`_$g5Dq1S*)pQjP8DuBCk_t1>5lfG0_0P}Ql2^jc zi!T{0HEMM)>-zD7Jkv|PSWIHqmt?saW8Cw)X|zvoFY;i(xd<)TlITPv@!APq?(?C1 z*_Te$gMFlNJOnfKkN~r0#+G$<0$8ci0Lu8Yo|m~vlZxr3J|>VD;oxSN7`=lqnnE{W zfz>K|5dz4mANqAGcNB#JfWIe_bSa8xdcXZh+0q25Cc|KlDUbFxBW&SZhM9~c2bk3i zM))-qqSNOPGLd3K$oMm)piNY04oMC)E8I}=l#gJ8j-e(3PZljqX-8Cn557Q+nmNYKtmai=!gA*F@uqz#(V3USD#xvj8cCOf|r2_J$&j_4V!2|}$uzFd~tq-zw+MNC*= z`Os!7%Mi)zm;5W*yO;J056;HS>oLV-`OHlK38S|0VGscQ{F&Hy(*Czms$ zuo5A`{qzbN6^0|yM1Xan>IvEQ^C*}sKlA>#=0tJgBzR!Mjvq_}*cQwsU`A+pHuO3; zNUgqkm_Ill5K?9o(nK8U35I#>Lz^KCyhfsVD@$(85K=#$dAO$?=JED~P}vSrP@pX2 zP#g2`S^%Wn7cg@sNp=##J?bZ9$ZW{61kzc960i*%a#?39>5z5KjzTZXiKLg-d|%kD zYZRy9&qYF~MH#_TA5Qwol=jYwZ>Xmo*3%UDoSA;+;?Fc;vj$<|8aQ;aKA@tVPJ#Qo zza{)aGAvNX&!@J=tEI>JAR(zwWTj+%CA&Dc@I(?ejQ@=REFvvkFMr)PE-&2F52p>v zh{-*{;GPu($;Y0acs`Gn9eF2foDK~i+jIqgeo7z1l)6LrW%IFC`KyPDJy5OQ?n^%p z$B>vt*Da)bYcUXVbl|Q`4eTkHd$k|^aB@9Tp{7*4CYIc5)jiANa`HHmRreU!opb8G zpXAZzR&b__+QdUo>9R~cHb=8M3!?9X<0Q}hu8j!67F;SA?^iM2Dl$@-GSD`mF zqewOR276YaFZF5D7X82?xg?(^O&_{}lgi;RfM=@eNQ zhgyo+p*gTVq+p}K`k4C(A&GH>aFF(9NN)OaoR@+{X1%)oF&|SA9+mv}yrkAwxP4RO zi+P;y`@eD3?$`hPV-nmzP9iIaw%vfW`QYB91klLaT-s0z?2Y)-9JJjCO`q-tMd-bl z@!AVyD&Sjfb+-j8!OeC#9xwB+Ftzq1>`9?D2AxFIC#LkD*WpP%1szH>+` ziF&2R%I<-dPGQ@YjsVQuzft>aMc!4N)+8LU;(A0z&erD6lWs92mIE<06!2vl`B$_LID-b;#`rPgv50%@r_WvcXmm* zC}td&^G9)Fl8KS9h9%_y;L8Y!np8rQCHx880usJVNaLFwrdZ zr#gb-pAeHxj3C4dZLs!wzFhd|aNNQH$0=lm`*9^Q7>=vepDU7Akv)YR^kyP*?ne|B z@!SH7L5_v1;R-P6YbajSK;eR^5TtrS2=Tu|U`3_Pqufob;MT0Ye3y~l&vCBUkfmD0 zm(|E|@Yy%GZ}P!#Q8d(uYyl;oP`Ch25goSW8*`yvPgdZa1>no{1wXZt^kY`b13T*% z1#{y51bl;>>}FnAIvl)gp7CWOM#zAtFt{Uf^-(dwOM%RT!MEMHv+jOD230@>PKAN$ccG9fa` z$ihh_8p<4?jviHcbd@V$_5Y}(CBp7CaqTdV(1b;#G@piX6HNg(Tj6mXX`}E*0(0Tr z>p<2)355>jv03YppXNB z{SEc~PFENH!4{t^D^R1pgKn_Jq{XzNv6L>mJ}g+I`N-x_J6=1;L8ZarM*8@1;+H!- zQr4%i!-pTl^-ou;U;1#$H=!7VeSpab*UE~zxT=4T5IOde1EO9K^`!{D5q=!kYgvkl zivaU;S&E_y2c56L3m%v97~w~9S$`0>Ub)ew2klBwejoHEe(o{iSy2fmjT~NC=y4}O z1#WuC(VOF_*&cSWQfSDc6iVjb=B{?%0skGKhc|p>ajd-K=rNCHIpiyzgc0AeVbK!GCPyuja_L$;TOIvuHkwY*(<#7=Fxo;ZS)X&^#eyo zi0D(!w8uuHXL3DRllJd2vDBC&qQzEp5d@10Y}8U#aU{05=*!_V*bFmytK$zymY=Co zN~d~3=bsPj86rh=H|T$oilzap!+Ev~MVO>WAqfUI$#Cf$I7R--ByYm8WumnHl)dhJ zdzfzTn6bv|Yl+UD^P_>K4vIwbSU zdMZ@Pm4+S&73eG}6du#^5|66~#ih9iE0DmX_i&d;d3lDFg7pTm9x@lW`n0J(>xIk1 z`(l!z&OUT;kzlb#q?4|!4t4GQaeKG0U5eKPOSLwkP(0(4yB=aUDruUojg8uP##9BF~=J%?hg@wA-KR3S7O}k~(fW`FWA&f<>rUiVAMR%qSIZ9xz5;Hmx#QQqKlfJwz zt}lyY+j5CxZJ|pql-gusF&U*MgHKFXQ^yb1j+muKXe84edB@7gQ8R?y2MK36ue?w<0#!WrLs%q)G()z4mYy6l#E&fjI4&!;)hu`RscxdwBYE}ak2Y>$^+;(FYD zIE_U--!j~vSB{rVIrun#PKez&*Nj-r1KZ(kmxPhb5XW#h>zs6(_f5M{|7rJ&1AVbEA7v;auyac*N)2 zZZ2kal0?&E453iGvICx^C>(n~fSXb;B140&A4eHF-LL=*L( zdQMS@I$zhaQcs)*=XoIyJ71R==qxmtEHMbb?S>-nTYG-|SeIn(#!3m?+iH(u@0u@0 zcQN?*v5M=H5&K}xL;iDNCLIeYh?DxQh3mpLbN}FkiH8J7&AkE;;M3CJgHs{mXmF8J zeqc1EZnY&@pvL@jjm zH0ry`&XHYpZeS8yM^{a4;;O&o7JGa1}=`uDQWAiA_Mil(a zQoaS~Pn&p@$GmbTejnrNY)M(8u-MTs*J+#MWQW zig%h2sIxlhjT>vLZ&|sYJmQ=jC90GRIwI?1XyFpBap!KUmQ3Q)qr>D<$^W+hEcP8X z->kOmQ_RgS%@2&&me2U97`ptQIdH|t=BXE|YUt`_NT_^$`E_lLXg__1(-FQHp+Hyl zBQc|OFf;y_Mn|@dJb#76XA}8v=e}@pec!+^!qTqIYcfeR>NqLA@qX2D(U=tCNz78h zGTqVy`OwYz=!p2Lp&V!t*j~eOG9Xj0dM%-~SUdUoTVYbd30Jz4h1e`pdad!URV!`s zF8Q`tXZo61iBiBxR=R`3bIKo0(+8Fm7Vurz9&07qUkt^@_A(vSC!g2f$f!oTM!Hf& zy0)x`&5A&xP5Vkl7T6m13(YV)LSt8_E~wMuqDgQHH8NvThFDZu_hVk#y4OSnNn>bw zgX2QHO!p((zrY7;W@e@A@U5I9jo#Ds&{ssmd~Ae(At815vgpcdR>b86dt;BWXVLxv z3kz_MBriAMY>NMNM0T#6N&yk#ygK-g$Eq+F<|*mfwFX*z}~QQ6Zw5 zt^3Pn_p&sJef?nYW-Ej`6t;w~*f|({(Wh`Rf3VPYkG3U8W4@>M(_uHn0e<=maJZ5r zB;b%`c#>!&`=!ei33gL_qAuson`PyJ=Wmb`I29jZU=FRy$74VuOe;!8^6m4k$ZH=| zJ!t;`76P^;={upe10^&9MlQV562lMq@QO_)wmYSYyS_Tl4G!BsC|!Rsqwo-3{Zpfe z|6%C(Lob6*ldnrz)VT2bSR-vYD7P5gAuuc=BT3ztoL(hYGFvs{^J!M!C-mB~=Lr&3$p*m2={xd+p<4S~A@hCAR40Tl2(_*jKs! zO8F}(ib*jX1}Sk*8-b>QB{>FNh{|immD%igOPnWK($8eP!e%!hU48Wl(aOV4y7O}m zW;fh`BsK4A}n~k<@ZE2PgG<{ne-{Et(~^kEPA{M!BY6u z#kGDe8bi&Lq#1b)=aBs<@}i&csf3zJpdOMp*ynW1;-+1e+NoY=H=Qlwf=fLIm&e{0 zyBk;a*9R2)pe^~j^SE)^HI+(?{Tm8q|K$>f{uf2F)jCTYPAb4pRD?mRF>Yh?RG2%4~K67DO>?=B^bVtaf$zn ztFz3L<|q4l2CqlrnaW0NXJg&n>vCtIh9)8>SdZDqPcHfls%&gNiS7?y zd?n(mT=m;G)hj-sfY9YM;)|v5p7*LKi7~U^#wGREqiWwRdyqLy#je-mDaU(|2_=w7 z0$MB9e3-z4&2P4K&QBjHu^+VdjH|QjNiP_ld_)S##Vr8)a-n(L@Xj$O7@JU%!{hD%qhhFq}AXTB|{yEJ9dpP}LQ$2-ZqH(xu&@6z;U852AhhT-RImI42$+EI!- z4E9tgi4pqLi9RU*0fh7yYY{9>kC!jgYU~!3~n0vki?WYLS@(f80OgQzk$D&0; zx2(W=H#Op@(IS?wB67z6Vec)Vs@&SPQM$XNq@=q;y1PR_knV1z8%b%T8>A&fNGl=<-u<2Z{qNrA{Ns$DF&u+%&AHZd&+DFdUmB6xV9?pp8emrswWwf; z(%Y%LS#-yCvQE@5(tWAn0zU7z7rZ~Tis)!n*Edo!o~|^BOsCEBflfx8=zLr*I^# zM-k!%Ms(TNDw?C>HR2Yj@71sPmDUSF(ChnwegV$heWI_#wzf*1zQA@Q_1P+8A@7jo zT8YkBJJO=#!wK<@?+DZq|N2y+86mxjV0l)T2)s7lvstxCUyE!~)@|kmc zi~phIPHQQn3NS`|+35DU_eMNctzmc1t=E*-&IQ5vdb=NL+Gj!;p-1#V+EA7l*-+g? zGD5t^>5A;J7RmZEF|+DdmtcP!!jFDCIY^qj>`Y=$Ngu8t4ikn8J^C&daiKFMs4@qQ zLy?3cOQ#03PC+EJ@bH6(b|$C`*r2Qd1i>fIjzriyg3VE){KjPRafBYk^xzAx2f4%r zUNv+O?xTz@A^(uEsL%{iJuOdn7H{8|9cJW(ABW`t*|^%yUb8590p=j&c*jW+xpmT` z!{Pv6_$4+gLl?WB1W7zcK*vKZj-9!k^^H_mb3UPt``LKS%4i6IU=iR*`dHn@d2N-d z9BZFt2y>A6NYk$2Yyy+PM1;|FSnR>c!KRI&CsQBPN;90m*%?LpW*g!2s-0=d*I+xr_*x*@%~FghuXb3K%RQNo;Zuo9rU z13J1?9e4q5`$ejxIf0kqk8^=bQdQ~vFfiXa;3>ieO<`tH+vXS1^2p~FMu2V^tn^s> zQsB^NoSF6XW_aU^O*EhH_owW~*Sa0MnLMG@!FLNf6q{el`@ma`l+k@yF2IkjO8O84 z@mG3myZMNqk?%UbI~%xgnc$9M_*DM^;V|idfkMeZqmclbQ%3dwIIfv zB^R9Rik9QuVuk8D`9)u(*lO7Hu>th+-K=oGSK;jlXtR&xQ8mXEoVv&q`%Ik-VX_W= zX#v#=A&A_4YZZ&_!^g53rWJz8=Dq{$T7*M#R;g-q>yr`bxDiZc>gBxm{U}Oq(qB3F zsk+1lupmHS+&<(uT&#$94JoqbGa=ZeA<#kQ#s)XQ4#XBh9%_Uw>oXuah%xG^A6}Ed zd^H>tdaF1tWZC%=8t(S<*ukwsM&t%PtHNnY8-4W=4}Ke4+c*wXJ2vD!Aj!i?SI-?0 zITkQTMn_?bGY##)(W3=~GZrRITumKt@S>lji@Pc?xkqL(JbKsy#^R%E^5LFYEHXIl z02%LrbZfYl@x7oWcC%Oup&PyP?%Ow|>W(U?Yv&<$ zQtlY1v2Kn3ie|wG#Zo^xcR|K|kuV7+E|&?>Jv5kPl@$9f$nURlP;v6@xn9>i zPX_&ebTkbXP4Kucg_5j`Gad2F9s5kBsh6^QOpzZXUsrRq7=80BuMm?(<*sU!j`QW-59{)Mr; z(8Fb42TN4N=`N3t8q2U>Ldi(V3|~P&eUYDs)c8o#js^SpbwhgfGID^@cSA0)ja_T` zgDPicwF$RL$74XB)4rx}!+6z`1l%e7Q#1r-Mp@pBkKZ_CRWF|gD(U9yM+Sghw^4qE z1)<ofSWYd$7zGUlDTRBfk{xH-MTq0>MI>qnVK@))+h|_(DEK?e@RY+o zm^m|0%tyDdkSc{0!+*jJS0Iw#83TicVqI-dGP{|s9%wW2QGAp>ff-RN%z-6Jj=(Lg za3m#U5*FpPV=VY=yb-<-@vHHI7iaEi5--s$2d&0Dgcw3ig?QTfP)og# zucuuP2JBL2Lvyuf<||#@X8UcgVfC6s1v*$)KIB^SEKQ7^cto!E*G<`Kbe`Q@e3Cgo zy|(dms<~cko!Fa~U|cA3>pkZx?byFMxt`SvU*BlFsMR6PvQ`VeZ4lUb)Fgh`v2nF{ ztmk@*>HbDJLQmtI!BCWZ>A-PjWnLodI@<0Y-~5$b%cAXh#L9s zBFwecTj}{|`lgb-#ouPCx%z3aPP%?@M2%sOLR~ROC52Eub$k$Ft3vfjgfp&SAioKp zQ2+kN24boaW~q)DOtbHjc}4Y++;gQ~VS-y1!$NGPHa5hCen2KzDuNVwNi#t@TKtVd zB4(1*gAs{m>>1JQWjyG>A7zE{+tR5|3u4a3)R|Kx3i($l>tRPw%#}N$ zZFDJFegYjUk?-%8iL6n^O@~d!5W?=KsXQY~8fAl@;)-6A+n$PTtj$yi4%9C7l$lTV z?DNVNO%@~^uNxT`tOadQ;y*UwA@1Hj-qE=9=B-@gE?sVPzco9AK6_Sc zE!s!*C0#>ZLzJj#SvOEgJzp=<2W&E1#ua&+Q_#jeu`Swm`w_hRhDj{N{ONgCJJ)|FV-l2MxJPmF|lbZVo&9Dn-zRc*|S#M z8!&B=#4-x@-OqDfN0HGdX~@?HFrqJMN0=l8{o0i%2#|a-W&|?KoGX1qFB=Cx)wa{fp-Xyfp8%2j}F26c2?Sc~9jyFh~bktA|atg(zdUuGs0FRt>gtAq-a~35>?O84E z2w0tHhBfbn%h7J_GG$`g*tE6EVcm~+xvNAqixTQG5|XCo>WsOVzhV>m-MRyt%~5!L zKf(TpyVj1R&>>zXU)M06cDb&j_+N`!0*hMuTG*;INN4m?s=qS{RaKAmVfhMf9Qsh* z)%>1xi#rKCSFu@EZ}c8Sni~8gT!q&ng`F>8lyJAzg4>zmUJV4Swz!hYH!zzTAOmMu zn6ubEa9NF3OdH7pEHFob1NTXEZ9Zp|+=I~}8+;uDlF^Zr?=KeaAsoC#w-CcWE2n2z ze)6tL%{@8BuNG#Bf<2dbWU4UMBF}o%gBf{`BF17%4$>W7z9cz&tUZiP>xl(pzere! z(t|OQO$&RrWi`NVM6v{9%aP{5oN+11Knudp;dFV~9vrAzg=Wd}5A0a9BsHvjwPUtUliHjwhNY_AIM$PgaGfGAJF{V8P*RPzmg*Ha z9&@PJY?r6L>xIhEmU@jl4#p}RPmc*axAcms5_Hgu4mgFWaYPtkIQ-;?$Y-HGxEPj7 zl*qTLcOXLl@e&c>C0NvEujBFOOU7N5ClPzn@xwy4Mh_kezf3^H+?}<%X*6y@n$3F0 z=vCYlq^Ih8*?)WUZAQZPTIy23mXo3Bk_B}+asai|tbe&u_tzTgU)vni)ZzcnVhp@u z#?8CS7|6DGF1dQ?{;i++BgylMpl1CN=jSbHwN1Oyx!*{DF`A&(VwG|6pDO}%pqU## zrjk0$e(f|VvcdsEW30s%$a4iI_2kyb|?e5xN#%o_i7^mQQ)GtjZG;GQ~|0q#`r32Tb zq{gtJ#m_N)m_#_pV*C@uRqR_qx$~&ic%c{FF5^YLI+Y*hh|Dl2 zkMYju+o`Go4e$}M8Iq@k_d@2s5Lv1EOFU?|{X%RfOc1wzNr_Uy8ktT48>KL(ijJ_`I(2A^Zaj+@kE+xX;3_o9>Qax?huxy~kXrc;a zX;f3jH4~_%_&Yj4o=$^6lUoNMgHAvm^nXbfKjl!mv91CJK@obD@IFrL?b=my+*mjU z1sycSb?#U~ZQlygHLIw1;@nuASPXSXxX6WEf?Q6zdsqvHS`ws4&vzi^i_ryQAPM+kA0S` zrGulgDYzz*IfRl;m57$9C6A83o}n$R91P>9wA3^xXKW=td@=}#aX3nz%#m~FQ)Llc zWkiFnTrK$L#Up%5e0WEW;}Cb|CDQu-+G|Dmrw>EH#M#Zx(MrkD&e_h$&ic*+1+7uf zaqXc9JWQ$oR^9x*#;@w;?%)(PtT%m2I`6Pf4ALm?3{JtXxmc7OHt9IsUAWBHm~(1v zyssu`Mf5%?v_gIKuvdkUp%QP}9Q}fgp!~|c@zsvtSi%tDff_Ib-NGCgg8r71f*ZCZ zWeJ7`j8;y@^#ayn3IDSyG|U5abyk_kk6+XRo}>4Nsby1nW-Keq@;+!B4vL#LACe>` z@7`?^U29yp9&#ccy5g{<33vezn{`ZU-W*Kd5B6`Z((XoF4HhQ44{y<>wnqq~ptfK4 zAQlIMaA|;U*%ys_`dX`mU(5WV(X2Nr*xcaV52eT2gCA%WSb$p4-0`CU9e&wQtbu2ZTI zmiM6CO`z!IC$PBpsRH8?m>Jqa}8BGJD-0RSx0~LfJ^OO4u0P}zdLh=Hbi>RQzv6(O31n4w9wG7 zM1l4}0jbOMP7<&cE#kNwue#peh_BA^3Xq% z_&j>*a_zS>M)k#-oW_boUv@CWe7_qiAaY(9ZYy5fhQ!u0ucvFL1z^du?BOa%v9r^w zGijDJGVMFjKG99{Oc47J{jq2cA7Vw0bVZjK7buP0jJJNqZOV8s+N2@tY(d75ik35u z=~!ksPw!BffL%_O)p$GmMoc`~Xe;kjIlxVL3w9QZMuvraJ}sErSfSju@1D!yM5$lg z)Hz+OAela_HeyVVF>{5CGThD!VGkKK9sORJV=|^T4>hR7H8MNu6i?f}SA8511NV+v*8G)y%;&j(I?!H-So9HX%#tO}W(lVy6+;!SwxNxKaYvoYHLhSrv@t)YQ@-BkuX^UhYq0N_x1AjNR{Qd&32mz&C|wEn-UQlL!=%+bWy)WXS}$(4mk-oVzt%*4@&iG@kU#Kz9q zMAgOK-pwn&206rk|P^ zNxdhf?1mv^M|(pJ%cy(aMfS(yY(v?!2 zRDhwCr+Szy9g0(1er4-j_3cZV9G<1(CGGHcAf@VQ^IfTi>;Os?!Sx~(#4J$-(IKUd z9f=X|D3Gx9K+Fjsi#&W{=05ciMvN;Z#h7!u!5jwuNT>37bIU%8*FH+W-iiiUWX}Zo zLPnH}peH^`K-;_~!%^SGKn$#;NGeMrZ)hgwxE-BzelQelea*`yY?&O=nMa8+jaCo6 z2}$8QxuL}=WJ%W*0efX^0xq@+cQq;? zAVhC!y;eX#2ylRn{XY}XPqq41T^A%CZ>nX%nC%BSBDu<0Y9Z}VUVh@lV=;6(67dzf zGprn4x3*3421Z^f`dLY5b5071`!j=<1*WhKahS|QxUvQZ^D({nIS5p$g=XxwBdci0 z+-=HS@4!Pwmh6edRZ=7z0>+Lb>zM7GpP!`Y%q^s6c`Wp>(d16$Q%}Q!gVV~Vv40R0 z!>(b$f$x(HiZ&eApTp0HQkeKk?iO|;5%sysK*c@CblqDkj@>mLRTEZCLX_qQLP_{P#o0LlW%;NCazlU<^63G z@%K^lzhnQ;$zc91_W#fU;;tsP&T@8UPQNLGl`J`M3E-^p1Ij?^e|FaX%gVoKhuA;5 zWD_qy!>C251OAj+?)#9+mMT-%R&BSJPZ!7(-U4KjPG;{Ku1<1~Uq)rF_ViiZ;wi#2 zfGZXN9kLPdK!CP3hoXjni0w7I?k)yI!blI=AcwWRw8NOX5G2)lWr{7{h}2ju|cZJm8j8Owxj$ zOoOW3RTUQc{upVU8FH<(^gzk8+j+5keV4 z8rJa4J0R+UL`cg9Op4hngdUNBpDj2*W7r^$I=_DmKX5!af&M});;3Nyvm3(GPPAmv z2?$1xmL=$`4NGH`PVm~QG1tYR?GIT6o}QKK{Fy%oJJI}hTmHG@p=x5};%MRg^zKFZ z9d!?WTSNR$pZD);2)j7j*%&xm7>SxVI$M}p7#TR5h}$~aSzFrx5WE9F&=%)mOEIc| zIOPENDgRwt{97DKT?HmO$wAaw!WXDuK@e*DC%jy5>vZ5;>ZzX z%(&hLjfj4l{t&!TV^g6U=vEIn?iP>WPH!~FE*yU6aI1u#!`l{%B_VBVLCW$PaD9To zEMI(MgOKCqy$VEv3+%6giHL37h{Py85~#&85_1E19^>EA92m*+Qf!o^&}`(kJU5NW z@fXC+ZD&5%54=I^*Bea&h#n_^e)TBK4|$>X>~LHPh))f2YrEr%NSIzMJPmD0W^Ype zqhEatZ7-?}KaCy2#Bg}6t<>~+=IIsR&$jjGa^j>YJ5bxY6}uaMD|CK1957p^Dx1}8 z#X4p0EH|hb(7lRY7MR3OCOA30d7j~bLN6&~>WCm}h*?$#(TaGe$^`b-^Uu$fDV$yy z>x_&vv=!NIo*@5pe?SsM%Bc?h0!WY!8VpSF?~>q8be5~xSj{q{-3UziGS3JUs*Jpz z#lRh_&tWN(f0i6o6`lL>o@5$5-d1{95xq+0Avs5VB8LDc%g!T7L-vY$VuCs`P~xk5*vSknw$=uP zK-FVbBGkp8j?sf8XT6?UtJPGiOn(>aHVm|a#ETd|U0Lw50{UbX`=AfVOQPVJSDL(^ z+jVa%ZWAh2WPs8%gq$oNzJ!plV=qYxZT+t78xRwg53J(Ahr~v zc_W##B!YbRX!409R6{@5?X2b$BhuOP`CEtAHWjmrTSVisV9MKN1U?a0A)BX`uX;aa zum;fi#(vba@6JuTJ~bA|@Zk;<8Q~@WT1xFm|CYQVVF2}kjgf{9%@AH+y%T}aHRF~_ zaR--x{42y#zFveX`v+Yxo6h!UshP-I7PkzTiM2IWNxb0V#|6bI`Le3WCS?To^7MNW z0~G==7553k;-0E3_(J-ho;kCXhUnONqtsbWz4l~%YI`Ekb8*eyka{wB*)zWR2nnFOg)R?t<^YI^}9OVY)AEVuKTSG3Lr;> z>1)f*xfNz)e6*1hY3}2{oqcUNSl4;`qK9`EQ&3b(ME#!QVd0Z=2nv)%mvFELx#7fKOpS!|MJG zPwu~L_upt+3~FqI0t^UP6g9OUvq31QVr^b3b+&TBlyExRHTl%w4}xZc(3lBhP>H?S zV@=UWymEfm8y}Hm{LpPUy-Z4k@EnyhuMCVY{vEZJmX1{4PMN$ksUIF=u(*sL{%APy ztuRbb`-WOzr@8KpvQAyB3+e!@)9V|sQ`j6qq(I49 zcWG^exSBU)NO-RAROIkG$a~@&HDIU|~Om4Gz<1U0pGZ$A(oFnSkKB zpsLOfL#nhQNNgbzM$FuFbI$+N61-KI9KK&)51QAhm&o4Ah1g}z#0HG$HvVHo_Z`MP zkPOEbiv33b*<}NAeEd(y@Ta~_RFsVXtf3af8`vHXwGV_)=uomd)kLn)bnfWng+>Hh zoN;myWH)XE?T-vld5i2`>~n0I=BXp6z0i!?p^3*N3X9T4qVM9}RiWmo^^MJ^^76W` zluhw=R0iX0;nBoXw^FgNH`?u~$WOVKmd)x-U6P_dJ1nv$!)wD5lBorcJBJS?X_GeR zLqiw5i2pFNMiP+xn4p! zg|6ld+*q=hn#kO#^9-9L#cyLd36kl4+C{%Z{U1QzU4ol$+x@fX`<(#im&rW;7k&RZ z`am-DRI61O`{&U23r~)sywy7)w6};~P^(WhGs;L3MA~1;7l&#v2izkqOJkXiGc|F; zpk49hqSNFU65Turd8+3G=W*>iHD(;QCY2I?5IW_Q<=<&tstb-B+Rhbs5)^uVAE7q? zjkff=;p>k?`}5k$d*vFhOcnVu4=xy<)G*4L&DW!9^$?arqQIBTSk6$H6O^Obj^w5y zlyw`~(4r0Z_qW#*h+f|Rn!SgJtk}VR^*MgJVQ$=dLnrD?=R&t_T;l65&E*!v6IO0RQTcK5g@c6J`U3EbYK?|6SW{Mz!N)4+PsDpwwn zcJOg9z|MpM@U+0H;8HYn2E89UoB0s}gL=ulymRp_1XhGVFHsT>3V~e@smP%-JR8wB zg^gd8mTe*_92N^djhU20&o>_;MjF=tbpD}*OQbhBzW@%ix(39@7PQ*q&Fm3g2YB74 zfY%*ZO46IcIG4BCb!zL0K~UTVy<9;HCxn;uxCl*ZfXQ<~>%()^e7`}~A+;*3>XWgr zzPe467sv@MFl>#V-}s54=Qt^GW2u?Sv4>bVpivkzfLNMjw+{{)t8q@&34vyq)|?08 zXFuk|Avc5>U6tg2d7H^4?wQg~zaEz~04?CgyJ`2+;RZ=?hs&@2D{vjz0Xavlzuy@A zX$tnow_8H6poQ!Q?4ubzH=LRg*)5)}9f^3W`6wiCX@E z#fy}y#Vq(~7vA@<-mJkwEHM%fydHRyCumX2tZP`uSEV5+1^F*LMkb^$QIYm<>-Rv$ zNE{Aa#IN;LI1uS2x$QAMIlVD>zn}SmEmfhI>@_pGHhufUq$-;3F4{STcH0Cf9EW3= zN7*cEnf>lWr#cAjHpt+|p|WrN;x)!YQy+bO6(vdyHzWz@&){?MfT<=0z3m)Xn++B zZC*p$*p5r$65&hJ00I?=u@`CpPQE4Pkwan|D{v_&*S)CQsh;5g?Bt_?1BdnT8R+w- z8*$U!PQ!#M?Dnvt?6_a|-tI>Yt#E9S=LYS_t;|nr3*+(!EnhfTxd4gz0#e23Z{!Bi znV4L5-^dM6?9H@9;Z$H@b>~tjv#6v*IQoT@dsMndR5w4Wk5aeWk&L_GT68njX&Uig5Agk252;JJzeMW8S zJ(E=wOe^vtY{j#zwEI~q%E9>Fs(xMf7zCpLZm zsOLQ@zGJ8APzVe=jIw1|8t#cULN=!iWBw8xCpy;5+rGs8@HB`ryFi!weSu$grPtb{ zSIj&qcZ!PNUlvY}%WVn6z%7$ohP#TaJ%nx+Yj;)@QIwo)m>u95YA@;L2h2j&fY@*gi`lE?Bvzw>8*z3h=-kpoA zuksNy@wmHli3oT{(DmA5?ggtg-6O6UcIJC1kSbN;)(Wc%Im7bO*HvthD*`??837gf zp^^Jd_>*_;eB&cCMAAlMDpMAO8}RN0ZywLy3Cs`x&;w-mudhGP`Tib(7FU&(zY}K$ zEmWRRF9u5U@BkS8^PKO$UFcW1Dgxrig*j+ia)aaNs=F~6Et|!OR+T-S&hkzs7t}mwyC$Lp1!jPQ%9h|96h>-QTzF74-id$ z2@m9a!+@Oc2q@=kR)>)eIWA`}ir|M3A9w$j6j{f}yQGa-MV%t=eSR~*LWDM)E(Pu3 zJcQ@-s#-Od3CQ^}T3!M<-|dSG#%*WFR^khRR3;-j^e$sFjQxd)r$iU?!oD-J4{@HF zG&8Ra$H$n;tuIvVil5G&k&lQ3z|K8ZLz7_YO~N~{ct)O(_ec4R)@1oMDUj7Ew&g$3 zZhXJMzsIZAH_&(vQyh6}xmmvR7e{d>TmhdXi2@AM!SY zku@iY+}@O(q3wzz=6twI%CUW_b#6vSZHcNH9L8RK%>Js{=%#GvEORs(!kpt!9im2a+~xYHngj} zzD}E*tn@*B-J3#@f|)BjzANU!AdvBj*KwFHjFM4XLW|FBPLP(e7J?8F;PZ;wfKaV5 zqig3;>WAVoMjX;tsp$~R_qQs0j*KgjT4aH`tX+I{$iL-DaB^}xp?8AXa|t#7TKOgpF+K{&K}$f96_@CN|%eJ z$CXPrdlFC)3PSn#@-1-VXt6%QJ6e6^l`PZ%MC5kQYuoj1S{x*B zJ|pL(_kf5VLj8B6z5iT9KegyvRb{(0W;CDY3Ag%H{Bbiwlr%|{3^}TSV-%`VZ!AmH zcZe5QK(8*iay>; z1W)ded<`AJ_t|xP;9hF7f(iOh8~5sN?l(NBOpA1FWZI_++fY#}oTBf_gj|qC%YG5U z{KVCPx6G6l@>)=JS%Q#Q-80F<`T0ylxC*U}Xv=cgmKS6^6USqX%eQq#MZw`uDeJqF z4oX8l&Y-(w3NG7*keeGksERGo*SK18$t@`no;F|tu^pWONx zzcKr~@z7PdnYBHi*%H1~$JwMhrHqatI0A>$f04)hB$z@lMP``ln73rauRWnsp1)C> zz8@)BW@3F*^RhJh=uy(KGvldo-udyxdqIL2{UumB)zDHov4Ac@h|HM_~x%G0}DAtX)zO5X|X%z*zZLJ{J@I;z69_0llF79J4vj& zbvU4<{VHc*B!NRL1n3#*|8(hJl+KSr98duO8zrfqjA(I?NOq{kzfw|NKT=XC-wOb` zQoj`dTmz($+&}?2R0Odt2bB9~`8D@X3*`Q9zUBUlAtGW+ zR)E~UqhKwTsu*G}`-^EH88tG(_{@S`w$sCWDTgAz`}~UZDAb<|m`UM5#KpsK{_axfb-NI+n8rG*psl{;q7eZdkI>5;d)Z)4o53Yk)AImJuR;< zxy2DK=pp5?Wl3cf%LgZ4n|w?9)8@5ILSTpo4G1qwDW$Ls*B5jOC&au494u+Z;`k0= z3e8aRWApZ-tB@zO)piDr6$OU8l(yaSgsYDz`uDeBRBMy*`cxP#wse-9-Zg@8N0Cc1ULWg+&?Gd|#is9NU`b6N+Mu!< z1j%5yKaKMv>tj1F{n(Uc9r(=ZKx5~NIX52ahLP{!E(6l;L1LdVQX`r-x?iJtJ}sDT zE`)z?|GQAf<%llm;HdmQfZS!k}|ckDlL0~LfMf?wY_h7VRRrb{6N^GOKdd> z=SN<+AzuNdlGaLC&o&3T_n5#VryIx%HztMezNjY!#W`eB7e`NlwkNh1h2Ls#Hf=ZW z#yLPos{u!|=YI=^|4w56hr)2=KZ4=+z&FTc>CYs2Cg9G(3gNNa>LCn0*cljY%rEi%qo{=dne@%zU^z?d`Q6rG$LCCXa^u zy9LimJC~X^-&UUn8ODuA%rIDUn*NH*;jDs{xHuh$Q0Qs88`Jwl`6M6A%yZ z)6ke=q3xb9u}p@R^c=7!?$orV@G-54NmpE%MmG&z;Lbt`ybzI_;=4rg?;@2eT0D9~ z&u5SNrFB}3YfV+%!Jp-%_?Za7O06;uh4_H0yg+ZSX^z^!M5pP5ntO%z9P(DT8{F~n z_LdiyRrRzv5u>;B<&MO*_~xMpYMv542D+gK=|sc=e6~d$Q;siGM`XvA`x^d38E79CAYmUlk|t+xn@Wn0|pxf%3Z{iscNnrH4gBibLxZh zFSD~BbQc0?jM=5vVkVSmhV3PTHf*qTJq!xS?OY&JpCzQ@%4~2a>2ikF!ddz4RhTVZkV;{i^ z0(ahwT=?`8I<`G*O2MwW_08?TCZ7hw1dR~?*og@1Ox46jA=ozB^`T}o{6uAiLph4g zPdMSGs>;gaIiJ@aW9P7za2n9<+)JE2!p}3Gva2i-CQKsfS{K%#_7`TttbF{c!CE=P z4rzau18;r%y1*iY?B0^{uFn!ZM+<9d+_u!`KK3amvdNp}Q?{8`u2i+9hzeF%#o3&v z`ZmbW_hKj(?~hO3B)H(qj4^11Xk+cOMsQ3fX}daYG#v9d9(7W{d7-JSaZD>u9loyr zoLkYORmak@?i3J<7qR|SbWBtB^W$*#ELrq>f)OQNZ}H(0Ky$+k5e&i2etG}9h^?$6Ylw~?}SpG3|*+1&zntAd{t zWKz6APU)`>C_Jl~6V54g?JHWlnszV}$tgODI%m7~WqT`{aesZ+4=TCj#Nv#z*6IGj zwkeacY*w3pSZ$1NcY!l}?C$3N*ZOop>Q>r&BS*(?j-N%GoSEJ4MRD0nA&30B`E+#f z=;B0E=X!9>W_1`Zj^uM>@pInWgw;R2q zkq-(Vf~?cOo&xyg?f$a*ueYNzs8Jz!QThV4KeL!XlnjN1)MzOX1`}u9Ke?jG$fZDc zCV({LcJCpx_Rj3vbKd@jO;F7gP$@1AREn3>v90R>RENCVIYq_~k3D?5SaK+qG!gR1 z-@J%Gg28+}B;bRV<+>$`P(|0OsH_Wf#$$MXNh04&0I~+%iY+B6)O~f;U z$5L)up^175$sURnEX*ymOo9-ijGNslyGb$G5Nj?N|5OE-D*(*-cr1Y%h<|4^rS+YuUwycx%(cU%aL@zvamC z9X&C*g-V_cK~ty0(K=CTzp0&zKyZWwT;jD6N}lGja%k_CV4x_q;!^_|FYF&hsp1un z=s-C#eqG;4SJqJJE{gJIw%=T0ki449;Ac93Q_uj&Oy+Mm4R`NGVZ;C-wBUV_Tj9Fs zWgK*^A|YOU|4@`^gU6DOl^#tf$9-yjLx4s3#4`H%c?(y^oMcjYsI^I7437>D92Yr3 zni8}FSqYuZhI1Sws}Zhewi0;&8Vvs z>mxsGdT8}w9%TPX8GV8PODI^6Zd^*0^};OIq?cdStYw+!TF=gNR%8;GRo}a-SaMtP9NakJ|JGXLo1$=zavC6fS7rzqv!e zFZN^~VElS zvejK@&1w#LA4%hB?p7y=S_f^8ex&?5{2M|p8YA`66YC`Lc1NqL8Mdi*{mgpblfpgf zoV7bnKjCl6_0O5aet-5qeik!uGB>m{a5TOX2?VWbz#6Ctat}alb7Ft_p#0ZWf7N|= zDrNxZ9K0B)m+lDD~7-gMgo8I%DXMg%cGrvAbF z*u?^3ek8JEmVk|ICohL$$e{Dua%H^JLI)C7bU_W-Mgn)DtAWKwfsR`yK~Qg&3(TbtO*eU&tu**~nUzg;v&iApYH zIyFUxb5?l_ck^tUE76qQ%8@{~v++6#LU_nyku-{mO-`0_`gxm;2F{eT<=5@gg~eIp zcCU(iv|BED2G zAQ!Yvh&gySXn=q?a2VA8gTwG&w)qvxcV`SZXV;swHw4jq3XHfrV}Q~0u=ROvZ%C8f z`57-)(WcL-=SvzZBFd!a6}r6eB{E*xK9|OM;<$a*wJ33*c334RHqle<3UNU{{jTtw59C*cq8zq9I+w!r3w|T$a-!D zUU(BdfFCD^1Uh1Ycw5GJX%{o7pn)TPIAa$4dqD$`BV}3eDCqQ0j&T9vZ9NPYjvb{l zYXywSO6lugkneM#@V>D00Od#t95Fw*GX&r8&;5(KUHjg}+xKBS39%`vJE(@A<>4>fI0W$#SzbKD9@X7_r#|)+P36Vo%?;$md{3 zym-9Oce&7P*0heL7|8~W^p->xZ=YTwIwpvAj54W#&KJY@6=Fsw^y$ZAmioAj4>)jf z3$XIeiw(j2)k7I`5k2~>=>xv7p2Kq^C3wvtSY+f6bhQq>^L1b~Z_V^qj9~KDW}zj{ z(%gM?hG4wtW1C>lhi+#~v@*}%G3K#9kVRUyexGLBQSZxd3fLRWVql@b?3bh3PlI-SHb9apB@a8nPO+ zLBhl_e1v4ub^EX_@vZ;-7U(~(ojO@x@Y&ornX9yg<@k^y8OA0yS+X0XP9czCaJiN% zj-{YmixLkiMo_{85Qq5#aVOR?_9$v>?Z`ihhep~sCW`QpB(@t36L1s1=TOmr94hL= z56_c;Y+5NOo0bW*w&k`gqACgEem(COKc0NABK8e%Z(QDyc)6z_2b3F;egoXoZ-C=H zYyJap2Y#Oa6>y~R!)Q2 z5+GcpROmE-v!cHjZ!AoA@%D#xDYBR&_S}#@99B^y0@u8J3Ba3G%|!M!sdNNcOOt$i zxOg8!4cp=#Us<#+KWi_yIj)#i$zfs77^NDSAiPUqfv6|EC3DCgt>kj(<46RW6K_b2 zxOUX2lhy`xKF*>0^O$aH3LCwL=87|n?XwY(Qlt{aFGUxx7(S|qO28k{~QrjHnv!(V}~Kv>+ykMlsBg^Kiu@S8RW8#$YI!L%+h z9|~sOI5@)7Fho8G3RuPFsd_kg@27k5d*jw$_r!kOG=F-IZ0`xO3w94NZ* z*8&QEWuIR$_e)9Zjk$WT3QaH+iW&*XUS%18nS`ftWz|667%X|+?V1K$A6CEWdIv*k%kW?)?55-4sgyzElC9qQw<@);yp*Dp$Fy~0H zg#xAf0goM20A$^!pKoC)5vJTgEOP*!`xqGdu>2(XVt6DvOu$N|$D{jP3Bd}>UHDl5 z^U>Y|L817`ITdoAY241HCdUv#sqn2`sK!z=V%g_j~`F`amn3en1MHt>m-smyep>074$5a z<*&?s)kXnaa&}G~$6enqxx{tkj5>h-`1RWu>y8WLhCbHj7{Fv5AkGHr7V0aY%hM5m z^VvZX%!{AqoC73R0$@(*u`Jpq3{jpyrBKEj zTimelO4F^l*=ev_#_ZWF_FcYx>S;zYLzUGFhdcL*9@ke(Ay_R)xlFzUUlG{}xaLsp zu(vx|+g?%jHz|^I&-11d&O1K#G|aJj9b410vt@F_J>7ki6#cb*Ur8vyIH73Z3aogT z)b;ie^VTDHtl~68?cVyqP2FJ5W!s3ZS&!MnR+Fn$??*a*aN=kpq#EYik-WZ>Vg6P|{Js0VudomEc>+6#f8y>Ryy@=tH-WZ!zn;$f19pF- zY599!(_Pb2O(|W=p3xxu>ryVf@o{^y3gd`BgGFhC*42LAr|RXs*|*mN{aXzH>PmXG zgR0i^9#6^zRAXf&E%Hs9PPkcp)_o-XId%B_2BS=b&C_k|DlXuKV)3cg<%3kvHshRc3u? zUPsYGSQo_bsGe3Meu$Rm<(|`DK*tn5u>ODYg2IR|$uv4k{6A?Ry5I>%w8ICfgOo{r+m?|6q zv)3jHIq0_Ubq?OIx0(dZHX5K_$SB8lZ@=!f{$x{*Q*GSL+#UabwExA&45P)c?bh8N zvyJ>19-$8f8h@>&jN9?-+Bt@krv5-fO{)cA;b>X@WIO~^pI4EB^rhWjqk~TiMQAflf$%N~q%ysIW+B{;9Yvf`~8udFXnv?zIuMcYP(L~0p483b? z`z>h;lAw0)dO9eMmJN90f1@vVw~Z+(R$dXf=0f(#uR^6y&9&jX0;x!a$lISQh26to z-9g!X?|RRzh??cbZC1jZ#C)#TRNyS-JmcE>O*UV9`8YK$tyPc!dA&c0WB#L^QS;HT z0Vj+y{DHlR_wgTIs4Z*ODSl!`Ra^^*5VifnSDei>%=gK~bMksv-HnLQtxAB%>p2Xj zqrkQpuaBHY8WY0Offj<9{#59k@ULL|iIVZQ&@x9^>62Sl^6fQa!D{+iJgJdz z;^NRXsPnB*XvG%-^9OLGwHKgjmd%k4ClJ?}F$XkXcuh$uM7ktyVVh>UPQ&(n7Qd=+ zMST%h{Zv6Bey=!VG^cni@T%ATf$42vfXan7*yUuQPN9`nVAd(r?!@Fbzu+GSIs2V} z%|8fo_TT)+{|oYe4CGwLLCm@ z30e1x`&^>&y3-j!GF!fOocixc25c7kya3+#)_da=lp5e2%&$WZLpvXn=Zm_KXZ6q~ zDMGUb1-Bms)h<}GFx)@Pu!|Dl!vx9ABu!sshX{gPFZiik12F&#Yx#8!BH|qvT>c- zFLt7UzAr8RdwebbXIr$ObFw(~%s35z9SczG^EckF9Cx7?Cu}#%j1;^N{goKb?gRak zq4Lm-Br*mZech1!PDW^inOvLPI;>}MGx}4$S@{DBX)wp~SYNi@O5O_a`yZI-We9gV zY?Y0~o9dDD@~4FVFZSL#tjlbBAEvuIl@<_?E@_Z%q`N`7K?J0w8zrR?kVd*Yq!C0? zKtURm643W~Ku6>|GiT2Eo%7%8bo!eIvcjhG#TK;~nhGXxj zE3`kteC}KpXd&j+{ZFV+ve9S%NiGTq%Yays7S(0bV?BhcshE%Yo= zhG>W_KF@wl?whpl%5(I+dTo_Qi!Va9R=gd*@3rWCl$yVBmy(XZG$Ablp9{5Z>%$w8 zG4{4VCnS+VYbyiD4!?UcW++a`?*gPH85F_spu5#*Rt%6OV9&pFUlV7GdoAvTKS(AF?Y5ZdyV~H^eEQ^Lse=qSe1@|# zG>O!>_|25_OSKv@Fg-!A(iZ~`pAD7oh#f3k44*;IYTj>6EJ9clX7$p-mOA7&KJ*Bn zieLVz;jC8rpaYZ~ostdWuYv81wNLQvB+sWXZQPUo41I^p#+UdkPFrU+NIjuXMwcm* zd!T~&q1s(*!@})Ale^t^y>dA3U*UW`vOmXs7lzXM$jPKE{q4*G@Spt zNjc}$P2%I2-6DW(o}h+U1Mu#JEUa>9;=RbIV(9XqGvmt9VON{PEX@fR~r@f z`AN#m_U;z7ic%Ht)qXxpba=05!)}@t*=6c`qdhQe73*N52g>wA)xvPAFy_I;@f*4t zO9kjJDpZeHlf!qO+lnI!w&cD!S>$4l&Z5K&OKcHRw+iVw$D!5MwwF$&B4ZKgIrR!L z6e<-XEnRwZ(86>l*qzihlq!v>shWm_fz5=C>}!R5IlOi}&o&Vp3L^%=LV({rsE6n}oam*{&$R-=SZ%P|R?i@FkEb3hvE zZ>ErFyh@VGh{TTcMywhtiYCCgc~A0dJ@$OPGiGGVQkyyst&`l$b}ik_cG>T*PwaO; zBmYVR{)dp}x(4Y}x@A>4;Dz`v_e{C|2GakcXSy-Ne=hIza9h14IN5lxqjP`MTmCQ}PVNOeVCR+9_c401|t zi-$Py0M%rcEZ7*NFDn^NXK(k0p4jrom~ax+0%}>PbD6j|wid3PF83`S*23#DB5C#eD^M;J4A*VPyCpoTc1<2fW9Z zWQFyAL{^|ydkm5liU6{LFi2Lwkp~J~KIGThvUghfN<gh(q*m{n#esZq;pShyMRLqe+Ml@t^Z3_03%4G(Q_%A|_`zrLJg=L^wE?AhNPi~klD`W1N0XIgH$k`;Zn*pP{MQuNqevhDDgQcvdHJ`jt~u7k(fG z5r#Gno8QA@ZN_^z>r-&@fUuAK=UwNy=L5zG96gJe+`Y`v(r<=*f-=jAjt($r^&cXL zlTwkncv=sqAW<%^V9C`>;;Vn(-mi$5nnsIpF2mK{Su)_fA(wn#18dDdGefG=b6#yr zPMxy|S}e0n9v(&ntBSl^ncd|*bL$u$qhc9;E6T$(=eMs4^_uoG|d9DIDY5=KS2<09iy3HKU)KyOF zSMrD)?~yPj7i@@)7QD@EHcO>WpBj}iuq7ntXuF-QXY8@3v;-|YBV*J~yhpw)l6h0o z3oD5_858SSVE0m}W1Yi@OhV2n9*)@7O(Hulr_Y~9gpS%jEN|BeCLPr?mD)KaX#LpjJ7smrfVdny z0;!m_(TP}KCJEa2{1>;wzosS72tE!FDG(#~g~pW((L&P+uOzn(C!G#L0<=zzGaiU~ z&CJ=YOi!1(BEK0d^DO_z|ex`#(nr^x|SgAUI@^ z!r~!tX;Ra^T?nq~_;yLEI*5m;*4@+!#ms_LB6@vn;mBugVcx03QEo)K;z=7siqx19 z?5DSeDpDHtvD8u&GuOlpcV~Mt#J_F8p5R0~-QokhT?YfTC`>gpS5Rf;M*_3FO$a3^$~6jr0!*jf6> z%}oE-293*r+7@bamG)CR@VfCUdYCvfbx1(;#Nq!Pf%1RJEBQr9=t^jlzfjqtY7|xB z$9kaTyk`Ot0k4FGcB8XngftVeVXi7r5@E*{8M1=dn2&aR+}Z5gcPr0lB^w-gcr9#n z?iTcMo@ZZxo1r1g`G_q|qH?PF8aZbwKi-Sydg3qe)K1@EFqrVOJ;#Gr`FiKYxX2awT2RkG4R?YtgM zPJ1atJEitJbnn&UcR8uglCiu+5fy0Pla7(A5IHpLHnF;+3x1%8`koVi@b2T4d){>! z3wmHP`iF!b6@@FO5x9=`5lbjIx^owRALqZd&Tj}CRRB7opzzOyPS=Mh?TSU6tS1lc zM`0>Fc9r|XoDF2&tsCLBoYK}?*UoEsD||kDU-Uz#3wEvAN`VI8+7)M+C{F)L5u0>VG3fbb8(s2?Ew z^Js#{d)>rbtR|_>gmYhqJs9VtL{RJ-v;9rzDbcX0oVX`g62g|acVVLeS*^t(!M-z) zAyhga$Q(KgdI{`q<#fdWtky-m?^OxxHt$_*w3Mg5;R08*{MA?zURe%6`6nGv{)sRK zsR!Sf>;lk!B#P>fJ{?`quutHEl+` zEvepV3by{7)N$3l(zG#9M6TW3ov_k{+y->U1~+gEs~73nNfO2z`sO-~tu?JU%*|M& zio?_9NgoprYT-viwlNHFM@?c_$!gg*J%-5>vYSDev8=Q$_mNguW(pgY*)A&U-GPj< zandhaSZ7^$kONEB7ZDEIwkNwS(=<7MuU9nYW>>O8o}m@DMZHtRgU6DERdX4YR8QC8 zOzGGpz2r-)GEZ2Skc&B4U2*~ukO@3n?d#led!(}GEbn+0s}%62my%Dd^b@2Bhgmr` zvcl9^RbZ7pByYe>nqKxHXw`EPq*f-cz@<|DV$AiGYf+Zks!Ymxk#m~=1N1qb4P+pH z-%o-OuXJ_0|5l zV#Tl3{$~1UT@RW0=S<+gaUcHU2mNj7-}agqa3Bz)2N(!M0|x@hFoT~(v+N4{_gxMI zme-Fl*|cGFxVe!MFdi1T9i8fbb31yomGRMIfcrqiIpp1Ia9lpnrXV0ER{A$i&rG^;>w zj}jtO(@4RP8X6Xz*Jy~s&Uvih1c+t=8aZq1`W%U%b<7>@x+X*tGF7oPD4a;x1Rm^S z?LVwzK8~3=U0BCFLT1!Z(iug*u#V9Htz$xeSjVK72nqw%G3=mq455GvAWZ)27zf{j zQ?z$0-M}96?+I4?#e48;`$>xtL#<&&gTS2OP zjm{n0Lb6xRqr^9lymunqY8Z`zhQgjvx{1Y5&PER*m?ABStz$RTzkCk4|1h%#CXhA8 zkCGwmGa*brg&VIb@39%Nn3lgALss101aUE+VAd8RVNC~g`e&SYGbUtVo%l|A7?%Vn z4Gqfx>!!D5-LUl$orM8JU#Ip2EHX__#!!~iBxR{Ak0pa02H1`VF@;>&eTc@tjf@E# z= zgqBl@wJLwIFn3?Ls&*|R%Cp6-rvZ+1DVRx)LJ=jW50gm}KY$gvPpXcsNc?3!^u1BcGMNyFVmgbU+`iPG=hTg8Ooyfmi7^Jge- z=Y`XzLu4o+^^4@bk7;fvQOk+D0Y$W}f8=C8R=AYu(ajcrtcc~XZ$_=(NSyiJe4OaZ zsNkkogQ$$>!TpbNG94LC4OgaCZUavYcu0Tzx&?goSE;b0rJ=Qyt+T14nW3@i)mgLa zi_rb^MXrvvfXj3YV%UPpf1sVn->EfT`&q7!uIPgN!l0d}$2W;e3dpua9hk_EUzvcj zV#s#VJd*I$ImJI`#qPSTe(_M4Z(aqx6DvNBgWic&G{Typfb4C$b=5OCY~o@+ZXJ!o zoAgxd@FYkjxwNQ*uz6;aKWX%^LV;3!KWOwX0UCXwG(e*V8y}ciJV4{ay_Aj5!t$0F zSMoLQ#QBqXz?5k@(TFInSgG+Y@$JSVs3Sw}w;GIq{9ij+RAd0VF})ia|Es*=GL^7?y1tOvY98)jZygifeOl=auxs})+n<*Q}aw;8Dvb}gfOmqG?=Oi6J zy1JF)TOUISTgO1ZN$!xkVyfvhE`OZK)CIY)I$S?ygSP!PKrS48NLht_NiO8=$Om}N zSDZq?@X%{=^ECm{4FW>+cboVB3C}MSxkM_Uw}Bk_Snpsn9_gBmk)@TLOn5XBo#bAN zd~1>0Gvs2A+!}C+!s-T7j=b$`JVs2Ge9bcJkLw!%fkNj z1=S|ymNFsLn&w?ApM7V5ZgBfXrNao}SHn_bwi#-b275RjYo!Do`yyc(*VGaT_Q$2G zLq?2~?-y=n7gl#iP%%EHzkg@b4@ue3 zltaFQ&xLEy<>eiG8aki)aioDK0m@YV8&Bi+BjBn!106AR1R6^c^N85bWbCRs1Mh`8 z!>3Di2JayX=~RfcqC9LzCc(4}!h;cGoT1eD>!p>HtEH8#OD`M6tECm7I|r0jOw1i0 zjgJih@?lOF@?ktb<-^=?k81!QzbYIh5l*$e?UFR+#`K6Yc)P8tXmc9ru-Q7Kiquc- zbLg|R^ENU@l(@BIvjjMlX9cb$jv_!^MUe4bP2vuy&|m`8Re=6n=0RIUwcIW-t(Uyn z#F3Uz){_w)S`tKhHX5Rys<$Cn6?nDnf}f~e9=dC4B7b!T27uG`0WZJmOBM5uPT0E8 z3l($z1%vQvR)48}YQ{9|N1LvZR|b^9&{WCyR}BI$DkKmZmVdq-{d!GvmCDilm@($0 zj^UL_QE`n)QpGf7#o*!L9ROc98b!$hanWNpZAmgthtU+Ko%x2NcSSY>N`Y$kWT_l1 z+o<`dwRjPbpJ1!a?RIo5lTeKYjAFu2POFuRiO^byGCPU*U!e* z#{Q~r-{or$e*Szv!V|1Gf*Su!|LF6-z44>NKPAb(i*_WTwJ|zzKRt#%xEQxs%#9Cr z7P=^Pd_Pihp0;mlI{a*-rw^Ki-?73J1IXX1m26B%dzL4IF%gMv?q=D8+{vIOc`{Zq zWIDJxhlA3rQ$IyI(G(4p%a$*sSru>z0G^2fAk7N$Oem5;X;w7eE`K#(+9D2^wxFyD z{)jC%4qEkt7a!xDr z)|L`sq~dN(GljK&h326dNEQ{|o@RMq`h*H68wQYO4Wbfw#iTd2g>?p}tb5DRXUfV~ z601ZxntSm+RXA7L*k-Gfq!uu2k%#w21<=itmC^ks?2wqp^^i$w+NiK3(8RObZiN$N zPaNs|)Mgtafx=fw2O(J-|4*#K^_8?GeSn~Np+i70{G-79df&Iy7VO>u+MJ~m-yuCb z#i-~+jlGC4sG_CAB=h-S;_j#VYe`$L=wMhZ`8-bx5E3zv-N<>+0Y%5-0l2 zu^5w7BfN>4G_z^Vj%bUh1hGDojQ131eh&%Z8PrIoj@ScGDpuvsMRxHJm|*e|$9h(c z^YfhVOCNsUwo0&4(jVD@d{z)hAGD>XfNsY9z8nGx zo-gvO^<5v@8T4Vh9({&vA2T7L5_MPDH-9Sa6Bt2HUZBoK(gG7s?S=kU<&@8#Wg+NkegHkt7fQKzdEG(=!T0dx*DpR$ojK_lhiskzdwPHdZwr#9H0IyH4 z^3F${))5Zb!$O;sH+C~}=ar{l7ru^I$7S^^zRp3q_4vV@aDctx10N?Gwu!moMD~$v zaioQS^(sgEhZCWr#D>Z>#S6I^W7|9yQT>tbb5E6h2qpLkZ^J41*MPX||Us%l4$=TBO!iDdu1}M01Wpue5fM%e|07U*q zVdP(~`rB^yQ~vYPhnEb81JE86ek@9N(HbE!hyKwTIrCfwCN{rTH(azvx=9Puxx%nY zf!%D5(1A&?$(#Q{mIr$>`{)D0TY8_-*=d~N-5COvVzo6SWo?FYb1;NZ#owDO^YkKP2i{A61gkmpWk}HVtoEIa0&s>Olbv}W?rj)x zEM>fgsWQys3SyjLvpxN3!y$>g6W(8Jx5}cD>yzQZgm6H4>aim;^%X zS5EbJpFpvKQcE~-^!FMW0I8+AFg%7~yR`xePxx`wAO4@q1fc(?`6kMUo*A=jT~45z z?{GxJ)lq3MX#MuG&98yIY#j)k$UoZC{`^(=wbK>HTpIGaW&UBv+l9o$C;}E$W-8&{ zRppd}4p^TQIS_c=#~nNtJbAXwT%zguZe!6GkmBpK-&>+<7ZY+ccoQ>$_UQvz0iLru zb%1Y6x;a@6e1b`;wA${y7*mXmp>Kt)=SQ-pY3r@1A-nGE4#6^0VPyqIAt!Xt9h3cD zJP{R1e@gx&xl2eOP(3fDF)`!(TYc2S2-w>xN&AyH517BSXWn}90B$uA%>qr(knz1} zv-;_6iv~8cEgl7(n@$EU+vs4e;<6ff8+ca0>DK{2+prqhqT{YPpAkYFS)Oi0SX|ZAU<> z60gr}dm9f9d2?(lo}_wU@IX5k7Y;oGYKJd24_p8qI3PUc0eC#I5RZpr<9&v6^xz#GOM+S6v#@uJ?EVBNj4l3; zd`7lV&HzJ$jc)%Zn=hB!AF zj7SLji5u#u(h5|oPZ?7tcg8X37PDd4Rl(E#jkkV6I->V&mnn_ylwu+bItphbBzV96 zfRKKsK{Sfs95~xu1!pBfQa#*Bzh)9qWZA{*m{I&KOegT+DAwjHAsaBZxyLLb$m zVGga!sdKuH3@}FR6Ug>$K)lm{IQ>oM>DqR78KYllNQ-Gh0tClE7oIX}(hfN)dIe!P z-FTraQP;Q56|lPaZj}@dk95$*!}32Ke;(xOcs)?9sO_$5dSB^Qajjo)yFhzR&}REe z0y`7o(~K8z;@Xf7INOI<59&%np_IGmw^4fB_pR)x>(p*a`mI)eXrE#5gGs>|c)dsd zf!%JflbYquJrtJ?WwLXz@r-n+s^wuD=xED9v8S)_A~R6mV603rN7KdKP z=&#g!E721db8xfP!Rvd0O_Sg+2rvM7{~zx^@C7CC&!5*a)GQsHT@0<|Oie5euT=D} zFF^gz7Pwl&0GD7mG7bSX?F9hv{Po@Ax1Zr!{o#qB}=Bl z-^u0sZ9ekg@ZCa-hu8T!U&cetO6KZE&PB;-8GsGQ2QCTDkqn)V z0A$D)<^_Lb$dEvWTrqx;ArD_<$R>Ye$RHCtlDA{Hcr$*D23yK3J3Wj-QgLC+^Tp1| zcHB;#MfDTy5M~7F!@9UC{1^F9HDvq2K}UhZf6lPjvyU|iB+ z%7XlXxQqd|J$L?TXn!H4OGOtHMDfzE_+EDZCVoHJd*55a)UgNzO70ky6I*_7ymD`c zb?z?M^gOnWHwj@mv}~w5N_A3DXp!r{g4gX5c%SpW3p4mmWIbLx${DrXg2Ttf0SxXK zRD8Dn<761hT{_Dbg1tko$Wf+EmK9A1Dp{t*8f$z0L3)JyWAIqpGO;ATIJOjpClb*HW;-{f9i&FW zZKOc?Y4?{aT0(kru`qO-8z-}Iy^kAP@VknIF>dw26~GB7oT|t-4I3p*@pnH9$aq07 zlO&`e)vXIf)U(k{!XmeGi~6~OOz&j&&Gr)EJ}uh;n@PxVIB%b-w;tSYLcI^wN3q3? zg(Iv+pF7%ZB{yuwe(@QwIOdpn)}6Gl{yBxM|GjV5qoc)oJaa4Nh^;Hf-G2zxtNH@q z5(y7pUf9+B8&JKb9q{{Y7U{()W~xkh#tk!eUv6|gX^)?!MxP%BTY?K84-Np!iGzxd zhSn!*Y8-dtF0=zkrY$h#p@@rb?KuNe6BF?xB)j*4#=RxjxNrK+vFB&w{-+|?4^n%we{Eg&0%WA+R^E}mjTG|KH=Q>;nH-O7* zBa0rv{*t65Tb|?U3XjrxH8dc+x(MOMDZ5Td_cWSyj7_&0kX`y&XI!03E2>xV<05-w zL(q{v19eenbm%RRB(zJ;If()4j6mxig`or%-;V{YGIHnDl$ zgK$%_9xoHh&*NF+=tO2dCYcK2tvJQSWJY+5fS1MJqtytd@ECAj#}7Sm^0u5Q@noTV z^OE_6GOEUFJTk0xMbdQF!rbFJC{>-rc;5LW^OS@GwhI1{S5f3q*o3e1GxT704oM%q z78tP9q-QOMcsU0-i1>*mi2p3l<-U@jywF)ORhr27g!S5(WK>UiJX#x-ibxQNTjpH2 zuH+-k5}c6!KFgOZVtl5hGG+9)Lv!R4YNJfFgo%A{<=FG zl5(`G9FL|6ll-j04^s?Rbhfyad95CvvZ&)!$+9t+e2g`FhtF0>>aJc-<;G(|FFig= z*N;;CMkVJ7%YeFSPTs3E^g6EMFFu0=$Eb7c#DW|Ww%k2ReDU(0Ffo1vqEH&C zoqO16p&0Ll?PqV8PKlH!eoC>sl34cjejXRa$Zq%^d4fBO@){%%wt>D@#Ym~ThDxIUu_Sl**XDwR8Bve*Pb@gNRSiE zbPUQ+_n+CjeuXE*fJ{O#r#<>dj=*X$;i`+iPY#JF*N@i@r z#M5FsUE>Wn+Ce@yyR4Sh9h}x5%I?C&H+QkFdoo^Lve00GOIC!g7RfzCO;FBpEtZ$J zvE(JJ7k?0N$=X?yj1fg1cL7pKHU|mYWr7wuOK&@_XBhwsE!j~@W)(@lK5c;O_n?S6 zVQ_=`Z{W?C@t>WHzs|+t*dO;Pz;!1po4uOWFD`>ylN5$@g1p+C-$F%7Ua9lDt#a-I z2Q0gXBs*SDk==@?o-qpa8cU6ZIo`9UnK#$5c;aSpxU>>x21k{aSuP|ekrafHP4dwa z3DdBoamQxOH~AeK1v+&F(kvqmF%mVEVdDDPcen z5u9aC$DLGe?uU!X3Gda85RNPM0!u|apY=A4&(YIrjEZ924qo-B$f6CIZ(oqxSMRhJ zA4u5mqIvhqnI`O8NA{D-DVEM{|9V2}z-!BFbB1#dcy0NBCq(uaPw4meR3A(hx_*!> zPN9|9I!)SJ;Sp)Hj4mfUhxLFp zfQwJSmc`@rWs8p}-@@|&l12U>=A`vM%}JqNu)N>gy)Y;3Az~0;PyS&}8ji^rGG;*I zsj_$)=_)Q;lysX@s5$s!bY?4Z5G_Ga^G!H6i*nh!q1@C!O~8#y9%pVyye+QAffuL= zB;3291MAV|{OQIcE=$*$m`+JpCImMrm}$Rc>7ildd5xkdV}N7fc*(JNd*c4)Ej4IN zO2t~g$9pNdOo9xGF6V=y%ll}x-GT+Vat|&!7VsAw3#WUoq_SK9RdS#cw@x1GLUcJr zP#oY`Pyrl^A;Le5r!LFRUhr9L_^Q`SDCexAUJ0`kv0~9srVE{oonIy>R?kvXCstx#pYiddU{aIb zXY7lsSk=%MA|O|E-Jz(d$cn_1K^D_n!~z@DYPKepfRezaEX>{6^&s!qHn1RnHy zU{bMSVv-h``pVO1DWMF=Pj}@8<)HS8ak9uM$P^M5zN3wGi0w29ezP;y?Nt zwM9QI!nu3hCZfB&Dg1LTk|Z!MS42K?&;TtQX1z;l5EUQg0L`|DTVO`Fjx z-e{jZRI3fCC`qDi+*zKLVW8ISFP_!Vb zRuiU-s;V=Lt(M-#npvoK)e#00k-z}0@)k;V+Za0-Lf=Nh?%}<`j4nl9u z`cTWW7T3)sc`hvs2lt|+!;-o(g#MjZ^LHf1<|b1b$q zQBC81^_mhrR!K3ZSdwOg;7DrTVm>h`K|+#CL=c^pK&GgXZi<8{QYNH$j>yLS7&-$N z{ygqsySqRUZuPv<_}e~rv3jVbO~K|+%{w;u)^|(<$-$BXxw@H@4|I#3zU9-mP%Q{x zII;F#NQpSOazCK<`@I%`_j?ePP0cNxoE83GP zbs*Hlbc~#tSP-@iyG^49;q|5Kgsu=FCW}7}fa3q3>Ykt9co0>IhHV~Xt2(7Q`Rdr- zY|i5GjgAlfgl9zXz%c|3$alVKt8Jb5CEp3j{%m6N%f&qRDjdp%1tLMhX$j18O3)1N zP9$%SicAAV{kT{xYBZM!;E~NobZW6V+;}KI@-R*#l$ktGsj<#;b?C_N6aDT{WFQ}l z9^uM-Li7jOgzY}3Yz{lQ^w1xC0lGH8ei!ZiV#DsL8ZCf$+b=_ayAz&E+``VPm4=cFujj1~msCSS5C!*X ze7fi7G$$vwRr5~oFY>svyR_i+nX;lvNM{CeubCb&&vMA7L&T`>LL~@g*BmWj zXJJOj2kUq?IgW5u=Wt2!wG4jjiw)AvLWsDV2VwHG(nQJ022b2_V=~ET;`OBZ1~*Yr z;G@d9$4&%kSs{$8U#ARjJZk<9(+A3QwJ4KmBq8eZ4J)VouL%O!$n?(7HQmWtkQC}vZ(;Y3p~o^974#Ab#?+I-<9uzD%( z+2DooJ!wi{;`#GXXL!fiR)bOa1FGu5hVNGzMc3hatrdL@MymILKez-aGn2~2@2){I zo}9M(CnS0QHmrZP*5AMmCh_%}juFmmNB96)3VL(Aqwf#bZLla%T=Elk`WLW6!Z!CS zQJqSfdUfnf1Hdl5{bY>rjPMQuBjg>JDdh>cWhj;LO1ewu(Mu1?WkE^kDUIhu%mkLn z$x24|w}Y`Bg<44EK=I#QBZ*?%id~b(mf{qeN4OVF;j;qYi%z5G=~bn53%I068shA1 z4n1v{-D8VcJ% zl*p1)@9E(~MCI>wyRRlB!s`i}`Dz0i3S%FGxFP@z1x`Ri;WIIBtcl$Z*m13JM(%~- ze06h}$Jx3ES6PKu<;b*Kw{X|zs!uuqJEOU>3~~T=5&-P3^(6j5tgk>T7K9eSe}-)V zpjFJSeVh9*hZ{!NOEDN-UfiOTql=onFVuLmA*E{Wf#@8}=lIjrZMW|$6+HaHuJ3Qh zD2sN8*+c8YDPYhbjfH%uriAeFWt9%DDL7B)$dzQ?OW{brUE{hd|0H(R{1=3&l2 zp~DWX;%Cwk@6a^#auuKA8n2oQCe39gN_6c+yp{@GdF&#FPL~!Pmq#4;KlnR%25bS&^SvX`P?3WM{VPhYGK?=%=!@hRrfuC0G$APl64jX^xZmfw6<=k} z55BIOOuGwWC;b%yphL1+xCH}@!Z5awqK>E#ynfmCgAoNz!7u~%*G){+-0+1-i*R(1 z4`k`9zh4M(ilV|%y6Cb1`aB~6_r)4;WO8h@YlMU~Q_Y$9! ztm-dhcd>5Mwm(}D-?O!2Fy}SS%yGzHHrSxVd*st-SCF~KXnQH~E)Ph& zn@+>>KQ)YkiID(f9=wub*?!fCiXY6!mmq)<~QUzOW*CsC!v%z}&P;Ck-`rn9L_1u4zt2 z%_1J^J3C%%je{qIpMw{kN%K%kXOljW$+pUQM|3@x{AG1$Qf=%?C0+%*g`b(~MuVm5y2tVE9#as- z=gq6tW~ysAxMuNw^#NMiISD%hnWd47v+0jN_fTbHWpZWFXVvGrs_X+U8f|l8^z+OS z{mU~)JYQNS0_AAe5uWCnDw(XifJz6%$&FCJ z3K2hCkvaKzi!}QUZ#j;k2vWAYn_J{+@PNbO@b$yT?LRnt(y!%w&|uET2s$J|jhwDxR7stPYqKPiWu?V!>KKz6 zN9IL-n!`tr1w%6~60-C6o;MWlF+R^nYQ{|`lZAmHk7JpByW$8Nn(P;*9vv&bi-s8| zZTOID zGe2j8pI2?gTpO3@GW@pT+nW<7!@Qb8>}zk!+SR!|E;k!&g~ zo%m2v3sn=>OhT0N`25B5f`D{W`poZ!^ijjC2|YfnZ!|ZFb%md^-TRQ6{gp|(M$gn! z_sqWRGWq*;z>pe{ru>|IrufU4{Em&QQ~fklU%29>5wIT8WX^V9Z=SBcw9?Awc~9HdqplwPL6yBDIJ+<@s|zUk@Y;W7f<;xY=rMgT5FRRWrm zli&o@@F$%E_}@y%R`t_A2)BqdE`FDUTkH$MZ4AW>UfzZly&AKFaLE!u3$3NM!dk?L zni;cvT~4l(U)0>t-UT!KGEJblwmq`{WiTY|O~K9V$A$Ul{s?Z4%=%X)_rVoMM;uCj z?u|nK;fj9~e8eg&kc$#<1I#Qww01dgh7cQHWEMLYnMLBAhSLa+^z(IBMXyvx23JaUUOm>p%w$vK#<-s+ z%MMssU{L=O_|B{F_%uLMWuWOQ8XUT*{j9{QKx3#A6%hD7%gQ;?O%=T7nbgkk9vEPU z6>z(IRR{@;(x+lgR%BpfoCWdK^Wp#Fe)I5M<{ zZx!B5L2YrX^iBKEP+}DUT(mJSr*mt4*TTDRiI&LR;r}Aa;E|jol{$Y*=7zZ84ZQ7V z2vm3+d|7!J8dYf}OR6NXn{YFm?Z33Ov4K;-_USeX^wGIX>vClf3u5yEYLF9G8e7G?$IRz= zLLn}w3njsYTWv7>Up7S-4^-9c9SUE@Oe|-9P*!-AKkOTcA>1Kqo0sqLd_x>=;m*b){ z>(YPtz&O9H@!WAsb{alk*UkLM6UOWS}r!%+`yj^!87)pS}|g19#cs9A;_9 zFvO68Ef+dE7{!j9GD%oPjrPtSe2A8!6zd ztcFcDDbXBEAvroi964f-bDZ7!dDJM$8O$fZPR3A#V9LURd`HB%aC*`UhW$lQ{XxcU zr@^6eCh^kXTxKL0XBP=}T%44m+t6ST$j6}s`h--vlzYcSS2r#kU=+Wm_8qitK!jZA zKF|WX4;D>hj<@K0c^8SkuOzb9y;rsQJeDs5>OS~I;!L|T&rK+o`-LDok^%{Z)Mrm_ zpC9uH#i_u2f-dP*%Ox-*lQ$kch6He92jGVO9|ZIlM!Xa+3eH~mXXxZ#X{Bz5uEkZ* zBdz;W2yhc-HWjN|E5~v(7=NFewXu=n8dPy~Y~~I-=f^{9VGrDwUJ>^^-aGSiu*{?# z_3HJYN4MGyMSw?NOf6hQq<5aL<~oKog71zpS|BU!{h}&=V#(V#G+a`W|LAqQ5lQ2o znEigWZ%Bbvb`Sjmr%-*`+{aH0Noi-=d$tMnHqU(r7&&i5(1_%l62`xXF%TDc$)0Fa zw3ATMESiJ-u7;z!UHJ3CMw5B6PK>s!4$4$-RH4w#ai12AGvkKCX=3CtG#S4e-8j#O zoFmp4BtG0wMIGg{W~1IXdeXf)B1su}k0Lg@;tck$kwNu$4^qt7-o{4E($M@W*%1td zP>wI!Pjp-x3I81(S628PA=i3+;-p4?zaiw(DGBVSTp(nJeKq~`%}(Y=%`h^6uLU5a z>OyBP8}cDio|DzCIUgk;v4;&x?1dxC%9Y9>4*5QysTIBuZUBaOh-$mPD*Crc>Z*rh zWmgEsFB*#>1BNYq^5)0Y*=g8w4@COldR-I|5cf&!o-}6epn3I(hMCSP0S5~pv^%dc z<;KR(OmEOSVu&=mSkf@|J|MA&C~)Z6WB02E1BOM?x`qk{ zKu9ovkiV|&0h`v9uv|q6Fzd)n(2V>o7=u4DCorTou9g*N!k^;CEJ3E%Op{SuY^NdN z=?=|Yeay>bmHm~IrRmh?m~Lyu^Z~dG>SOIux!59gL0MvzOB?a}lLmpebohK(vi$I0 zjA+aa?IOR05SPd-jZ>fhk~aM5%^-W4Zq&|4b~8gv_#J*slomU(ft30o#rrgB@2Vk7 zNjGccpY}PP*$oCWd2mxe$5~l3(0`I@N;gr=5<|z{xhI|5SJsgo{iY_2Q~o<}(veWj zHQ~YM^#{74grqEU>}JOe8RK}hSe_a89KNAP)w!t-ONcfg5V5X(QW=3H5Jn`QM{#P| zXP9CzdxL+pJf51t!E#3b7f?um=Lulrk6%Q8W_H%y? z3c6EhIJQn0!wz`V?o0cynl}-D(EzVh69$-3Km*)EH3XQ!lz{$1@cQZG;;_501*AK9 zZDJNH0YHkEffLh$thqf&rU~15hR5lIm+DJ4| z)xQY2>^gzSxxxm5$> zmxX2MC8Qh;Tar0}FvPXzDAF+`dgSKP1IE4d1VoibDuC`}E}%OJq+8{m59(PibSL{v z_?)kU;xh;ez&Q*Ag)ZP6c5(rVEKw<-34RHR&{?q`ph(L~lQc{OL2KYmLP_yU3k{5$IoM zF-j4>(ya0k)6`5`qz-y)wgX^e#Z2v-R@po{Afk0}Et0F3P0aRr+Fm= zrJHhZ?#ydMAHF5FD3pK1JH91ij$eH6LTx0m?Op%d_Xka5ysuosG9`N`5ZC4|a-qvi ziu4)`uC>aq?DoJDG*wo)l170aEuohS`iX>VGtU3_qrZdUw|l3c5a8=|$y$<|a9mvC zPU(~@qnuI940W?3dGSth!S#sP%JmRrgIt0^>k1ff{xulBU4WtBPr%?mwCnX3V1NOn zdL%GAsklPjJk34A8tfaLY3>#QCfs^ND{YB@tTOK5=&NkA8h(HwXaHR^m4Vau9@jCi ziZAe`Una{b_dTpaO{7riM4{wVUVS^FA02^i(R}DjRb@y}Rrx?V4EhfF)?=_EFuM}O z_395*W!`v`g&#FdyIz~0HBCA|RoM)zX#%RsEpFeg)HK0(G`vJ40KuROfZ?wz%s)bT z6%V68g$$#60si!+NVSBNmV@W6R2c#^moVndJV}evxrii5tS*XgJ2DTfEbSZeR~k;e z-5#y>z%PYH-lutKP!NkJpNNL|fvAFH5MQwS%mZHS*f-yeSsaHs7%Jk;2N<8nbE6ie z11^W{qUw+2PM4?p$U^ic*;CsYbadD-QF=b1d<+{g8sK*ypX-R+<9vtqt!bxNi?9rv zxuCo09<^5uODv3I{F>xs!$BfRq7y*n+x zjs>!7cp&?`?fssssjc(X+zI@&f4^YL&rAAW-z#;WvUV zvV&GUS&;igS(&ISrNN2MXOq!is?3Q2I3eDV9hC$$8WcK4HK#Z?Y)NGW!r<37z~xFJ z-ce-D{Xl1iiV`s$Ocy)y+7U>b04W+1ucl8Z*k?$}bF75u{K%5j?+YP9DCO@B9e3R> zMr#b3g{nEeTT?ZFYNrMG|LBQ0sNwjmX~Z@K7L?${CWL<{uaWY5o;xBK{5jv^j^i`a zh>TZGfy3wXCl|tImsK$^B12)7W6=NdV(}{?S8?(CIg#s0;Q3CJ6hQ^RMQZrSeD_@) z)>sYjYLTa{9xL}bJ~j38+`zQ1e$3%W5>p`d%aQ)JsB9IHI^PPB)4q-P1>06cyIKzj ztH1#BXp1z zH`HpUmBhX|UclXHC|Ervu{N~dP`quoR!J3%g!?eb9j%~>eDzbH;=ZS>S9)f!drEuTZN<19iK>&6o89}Vm@7BF3eGW$*ql}=1`ByZk zc@8k+r;CJxOs(5vUHiXXXhr=hFyhk-KDrM)N(s3CL;AbA-`kp)x-&g+vaBvgo5*dXgtahIoQ*0CR?#{#Y%`bDGtMg|* zRZm-d61Ei+!F4f;p*z06Qh!eev5&aJt!8&t1}&7RtqTLg63JMSkiM?Y{B|vN5pHK_ z$mPcnvSGyFR(vugEB*d(!WrY^sfY%zP@%}3t#{u$_*d$oQo~*|v4uMg ziHfUK^_oU0xLPu&zlB9Z>Wv>{j1uxfs6)v#C?7O_z7`diXOMO`w{{l4jpB1ZI!$GP zJa^ztm#jz?0ZrG%`-O${s!v+?1Ky;ZR%X-TMy857bS3r^Q7IV}0L&FZhyA9+(}H#s|S5`#-r z$CIAs9#=J*O^7Oddt`a=EgV1K<70flQeOJPQvTJ?*8as@&X3kUJu^W;VJy(vKfGw| z%U`tiaTdVt3b7oSCVCwj5}7!(IkT95<|-P$xu4p`i`-qxSipk1sd9GDVl&FG5AX>b z4#$V{D5C}@*Xz8Tx60;i6oAR~x2;9+S#n92Q#kToMFUAq##i_18Y;sYz2Rl z50l}!|LN#QHeamq$d)2bjH;${>2eY#yKluF`nQfGs0>v6iG#IZm9uXluDoDwrE-ta zAs*Y=B~#to$}XO2*(xW3zjsu6M5&U`%H7?$^@-?YRBDUG!mEXVuhRHnvkKByzQ`{$ z*z~3vS8@CFE2NM_06%|2a^8@YntnD1J08yFX9% zzXrp=fI$*%dmW7<P8 zP+>8JOW{~Wju$#}$QL?uChiksOn|gWrjah78XEv}(DV)B0N%Kz8DQ!!C4%=qP&9TA zzs61UyF-LVhO(Ne5#asfq^d<5wy5L_4f$R-$7ABxn_Y z1Pv5L-adS&OAHi6;+suaH$521)Wp_MaL`~9=&&QywKne|S|ZObKA&CU!`*__u%VbNFxuuzx;GcGJ zyf+G+_T6r?<61N!o8|L=RS}?0JIbpfxX4uo86Ih*f9H<>Ct`i282RmPBkz_hUA&KT zi*dL7{y)~fDasZl+cIt2&Xcxn+qTVZhH|lnEy&nD1fBPq5 zkFg`xj=AQVYpz4+(r7t}{DG?D>oXdVOZ{HSs>H{aos3wSJ9}X$R;IR}Whw;C9tnc} zP{7gw=oC$agK%<+$$WS%y5BxSSU4y=J-pM>*<-sH$j_-(zr{+UN6YTJnO{a@ex87D zYO8{x!cX*6*=hwlouGKdW1q-~$Sx$@v(B~AtS>P1Bc;4F4gM_^B>K14>qo_O znX>_huduij4cGb|<;8}e$p2J`B^>=xh{0T%fZZoa{f8p`UnjCySSJ71Bl3Ue)cp+mH*CYqxi-iU`0*i#Z^j9Y3()B~yv3vdneaZen-*U1)&^JsJoUk?g zFX+p}i4{%Pa6Yya^#}Xz_jCQhzH|dV+p2lmS&olTURNi!Dx7jhsoynjE3!O8X8KNn zRH2&gLaC&GX!Y5NAt&*2SPtnOXwu$bkPYKftv>@B<}S~@uNT{Inr7RsY5`;6v_=Tt zd{|z@Tpt@3z}ikTL6%a-c&n~h@63>Cp2<@X7KL0?61?#R(zCIQ)yI)in3Y)nmKOfI z>xEw9XYp0D>bVi7O*vldD_GG9*VD5+0Oy`~@%A2P2<8B9Q#a zyUAlRJBGP*kj2G~0kTmfVf(TUc==OWGN*k$)jAP-2e7>$PpT$Mxr$eC5E|Te%(ba2 zR&+T#x@d;3LLlidc^ZX>UHaLxT$prM(v}VTuBhns)lWYHu3@*)n@S^a=7kwAyXSAl zYJdISV$1xQG=JJ&3|#*hYyaOa-`{T0pF8lcfrG|1v5}`p~z`qBB zKJ;Gq3cc-A_U^I>|l)Ymr z0%x1Ly-VExO^bSLH}W?%_qX3#(JaZXmLjjqrsU`9*a$bT6w>D~he1-&Qf%V5l9#Gq_OA&{>P~F4dy`9`7HznC0!Fj%+!tkm4)Ce za0)q#HhX|U-d8SuKP7LNvRjr_8R3Qdoc17_7+Lmv2eqjYQB4CAgFhx$xvy_DXwH_U zUtjBYxsQb|07%1F9DW3VYI)!_Bk6zKe_L>mHqeOmFMs}Hr3 zb$-yXQ~#r7e?*=z0uQ%{!!~_GyslJ0MX*N58+^ttx8Z&30VTUzf08Z}F^^Qngw&UR zBP8OWShQ(7CS7Y^Iw=xBHi`%PTVoSRyap~)joNNKw&4Mn2mNMm8yYtFd1FZY$~i-W zz>^u;1b|v^92DfQkrTXQ=0_n-y4gx!8-zo#ocXFH#n@6rw8_b4;Rbpu(epyDIZXsy z@(0f9)U0^i(u)MwEEa(tRN-|7bm?;vAVro!J&dAil*5RzM&wle6B2njmLE-`OXlfQ z&08d%Ilm$&>!y!|)p^f8t$^uC$JDs`1ZCRude_;uupXjf-8<-^6D7;>(;iE01Q~J^ zPw^Q+DE*SY{>QPGeK zz|4iiUZo98{Ljx+apWTIkgEu)Xp)~i)CFCd@A>DYgLKFCyV8#HY{ki7`p7RR!Roo? zL1Wae|B}^ROE+ ziOgOHqGA}S?1z}{6-O;Div+3iUdonOy0(Tvu)sI0{L)GN?1vg1%%Yi|s`J*ZK!wUb z)o0V@P@MTgiAiVpzaK7Ep# zsgthP)dj2hm5knrv}aNPMr^D1QZLK_q4UPia{m$n_>H`J^sH@80T;YmkUd?8hCA<| zz&T_H`Z5XA9fE56)32yE0pDrhhb7c?+-Oi-lL%b@6Bb1x2E1;g2Yol-{2S)eCdPZ? zxCU$z>%iF*p8lh77<8Zu(}sQ~T&O@=KO6+LJN&EGrH$gzs2Y(o0H!G{BaD)L)oouC zKXEMzG1nTR!a|)d_dsC6sLa-Wa}2tBg?CZDoJ=pY`>6|SgEZ8-aPz?=+3czG z!JzR5QzksTg;Ay_Wg`6gy^K8}A4BIUyK3=X@Jc9c+-&Xx zY0vfs?~x^bATlK;;Sr@z{OCfXFnJU?w;1xqbzP-qcjL}MgYu~(PF*9*QIrp^DSx8t z`V_k}!8+`_OHF_$)M~rqydOCIJ^-q>j(}qv)*5mcVtEa;>X_22HE1RAv3rvt)9WgV zgOf~!-ggUpq~2eo!4OK_I>Wj{QC>&VJkP1xYj z@yx93Q%X?2M%)1sU6$#cuttdVyIs~&hVq%VDEz<0xUZB5Xn@b-WP)(}83-rk)LL<# zT8uqrjP25Y;Y}Y|-pX%E%h>jJEQ#yeGCaA;s*Ju+EM7_K~yP?4=86wAM zufqK1CN~Ls6uV z+Uss)r%NEpX;CG*^VV>x_~wQm|^JW*A@xjRw6W~5l=M< zL1$dt%1F(EV)mlY%W+TRkaHi(=uu@0Z5^aMxVntBBha&Ei4haY6Ic}P>Zn$a+5ZkS07bP3zzZYW7G z4=Ct5&yF`JCX$wN7yRTTP+p|`W1Vw1-2Ie^oIg6F>Fdlv=7`0+%3|lSq`HFGkzbJ`THsB?wL*!c}N27!Ig0 z>W4D)f#$3yu9&nYyVI=;E4qUSqBZAT(7xn&lP(wV9T?~VG~nhm93p*r{Slc(IqwS8 zjXV8frM(>l3WzFA7%YJLq}hF$t4J_WK(i`dy;*}X*Ze>mX2$72$v5K9#Y-d#Sd-s5 z;v)B5IBe5eo}%fH!G*d)b~zui-A~keV0z#>#`Wt!2m`b|)p<$G&7=v!8s{o-`fA~s zd5W2UcdN3yM=H4ktkG=azgQ_MnY~CR8l{m|9aT1?AfWxVY-OMERSkBy*rK z))YuWbb}8!DxN-65S+WOjuVtQpApw>^)}JICXZ^H;d=zH_~G^a>U;2b26CxPq%f6V zz8;5Dm9;DN^1A}xUV(OISBgTT>wn|K=vC!t!mZs zqnV%IP7+z#BlMQaA7LRSS}%nx@0USB8#+6{dPQhZg+hkIlz=b%#F<%gqv!xL4_(`s zqxhML6$y73YUbdd5078ISusSvZI#zRlC@mcjgyGE1jr(-oGZ>HMEy6B`X2vGwUv!FDQVWZ{ z>TD5@CaG7TURf?wi%yq5u7|lk`k^&p6?x^K^&Q1qk&-IoLEFe&euo}i04(oeW+{Tr z6~ng-{O0D+&lfSlNT7{)c_HzBRd5bR3NG{FvtsmAq;z7Xypb9lyT^I0jDlXazdD^a zh=MDIMLq#VxRB5P5o~=jZ|h<91cfx9#TaOTHd1+OTgAy(Ql{nm0kJ20ntzO+1sl?LG( zw(Z&NUEW^N32i+;ZpH9UApga2c#C6^>yizva_dsc6M%YP>|K+PvnN z?y6KQJHO6AAcn2=1Cc@7R`{Sn4V0eAo{N*BRp~&Tn%i02r?Gx!Bzp?ox@D#vu$sVW z-?+)y6k2Tte_e-|P3Bf1zW>Lph1oYx(LxJlJNYXl>M$ZqIYr!L*@}tjY5!J4x$|Ry zXdZKqFL)dzI0ry2Jvin~3-S1Fk-lYIbIu7Xy@zA6s}1zdK#IY_MeVX?CUZgu@_b7OoB*yN3JhhDLB5D$H17uWA?yUQQVbn6a0As(Guoo)#_6;|ZPf^LuDMtmtM z2VpTJtwBE6_M7z$+#WN>WtS2avs#%_5;EXDF0D|(XDmf6tJ68B729cMlxccH)x?iL zJ#EYL(;(6Yi{2oGMTn9>Bq{l~Drr1$0#M#x;;v0J@q`)ngrjZ6aS~?Ot zC+|%sraB=IH2wwI_y{zZ8`twMLOL;8A0akv<*VA}Uc4XlUAQUtYq9#Fu}VBb{B~q& zESp{gEOv~*AEJi!o{kAK`Uki>Mi~bTQ!J(WI}-!ELDOmQbqJ5$t1C`%8#rXM67oC6pe?eHbSowT${Zp=_>ssOq$KDmPztHh$53~-k) zzY4y)LIZ<0=?zV1+`+JKvF1YiX%30K#kIzZq;pwX9zC2Sk(EZD_igtd2VGb0CvS<4 z*+pcKcg5b#a8byV7zaD61L9$m1UZe1H1#HM09~_x-sY!GC?>JA7q7Vxh6Mos6ukh@ zU?a`-x;~G|uEb1w$DAP)k>s^osKxKE60PIc?de4&{*1r+d5NhX z1H!KY9<6v}F{G4eL@x!T2k%4?Yt9F(8<|T>QawEo{eN*~GTd=vC+8K~a`1Q3m<~o% z3-2GPZE@Bf$s=Fe3iT_lTP5qaT&8E$r3IFhND`@Cqy$RfEH<2sB+e(5=G6yzj}C#X zpW36V=&OF4;M{M}rIc1IyE4jYYLath6(Wz;Y$Zpu^ROFMZq#D$%7(Ya zFBRzoBG^4}Z7Zy2^IxYn*pydXr_K7@2KDRSMJG>c<>$(3YOnHvu0m^txJG}hyu|cEg~xh zdRSV94CFM$oV0x)4!I3N&DuG>xKfS6c=+lc=~UB){#0+Ak6js{{la3DzSF~v2qZ6X z(SV`?58o+JaEgon&(bjxY=9L&%q_q_4W@nAGFvXO{da_|C>AlD3^}1%80-!xFSbZ; z0-U$fAPN|v4vgWS)>$uF<`Qa`HW)k#&x!2u}#e>|Fhv2zzX8cx_82|hbvpYRY99uk0gv!aKBZ1rt>;+ z_8`%cNA5YS1wa!4$&SwR_Fyaex1kCVo-U+81TD!K$%2HFh9rbNP8`jvi{pR`Pb$|) zA1Hr*L26_@F2IE&zg*g_+1>2)Mtn<0a^?Z7!Idz4v@~idyaYrz1eIF2n;Z(T4K&QW zKx8+z$$>+%MZ4V}I$eKVDrwrfi?=B{DXSbo_wU)@0G@c`Kq{&nsnsNr+?5l}CeWq` z)wz7@m#XjYbo$&pln5rwRr_S`m#3hD%ELm2idfmGqhK$DeB`h=DScPHICn;2_kJLwO#|iJ4 z45D^XMcQK*PR-WEeUWVe?Fp0w$T0Ar!{g@M^}cSD8};lZ{OuTR$t{Tw$>%x5JOIxe z;Qk$Mie4ak37oMGOf^b_;Wjy* z4P?Y0egW(lbT}{#QUX}PD4;6tE?q5_6$KMVxv2ruT4!3BfC{5_?hO-@?$!Wj#&V{wk+kuNuGy@me{6z?;^ahuFk|K&lC7!&;9M>ALxBDst->rLcB*vX>-$CB6Vyigc-Z!ndN#LP1~| zRh%vQ3*o%>v*OFo~n(T1Q2)fC;%5& z3eefFpx2^AYr`4VN$oQ)ZGqnjn0W(2r?ucn*Ng#xD^`*E&; z$b&m&bWne+ABdk~1%8t~9e2YF)QNbO%N}(Lu|rgC9^wK-5N8hA<`G zpCpuSKw2)RnCN>7{SLal#tYn(ber3KGt5x*OaX$+>jB{3P8=SE&3Bfcn>OuxB>EvD zYeiG~+9iVkQNZo@(~paH6K@yJG-DfPjFv2KnDPRV!h*Z3{X_bRw-G1nXONP3EGy_~ z78sk*tyR#$K!h|+>C4*%*iwpQyp;`9`4TtI+k4!*3xyHa)JBJ8)wb&r3)ATwACbulEe%pT$fhQM`I> zwCvs_CjlVV%msqRk>bq&A9bJrc$56IFmtq-2tB)Z3}I)JGoa`Ru`B2jlUAleH`ohp-*=axTMMHPmQAGsC{jo|u3M~{dI$oN zqR@@2r-W23Etz&VL%@`sQ~NlIL|k0&y3Cr~{5`rH=ohZ$nC@;y zd(W3&xe<}T@VQ>q4GxgpIi782+d`BDYAa2(^Zf+ zSxJE4%U8}sZp~~&5uG11EX3EA#Ij!Qc@OR~6w zb$XZS>ki!)TpMJcj`AslKu~__n5g;SWzJa3z2$Wn+uq{^Nm0=%kriCIM$YJxLVcI(`mM-P4nf{fFBcw2V;pl)>T~ha{9%b3qV9km`sR5c+ zm}SkD`A63hEY=j{&1eGUx_WPQ3P~yJsWIpRr)_AG z_-qmLw~7aaBFjD8S@X~5PG_l^Kt90-orHVD7mW?YK@Tp8$qzth=1TmyldL~EbS84z zb&EnZ6zBl7uz~Gm15*R{LEXjCG~ZVObRqEUa0G1b8$9zhytS&Z-*OW@ziki5X`h8R zK~svZK6T}n>35lcC^XOSUl&}M0}I(u(Tide#ou;7%|N?57Tz}B*HT!7&U6v3;8DeC zKo(Dr{5Sy$QzLLU#ZME9E^O-_BxS$qc#o@QbC8(V_`Y+Lni6&WH1269nz{ymV;}4g zhYZr1d1LWNh?yWhBu(0pU=0>CnikR$`3oamJsH1E5s%5!D^HQ0sRfKX+bVJ(; zlbVks#Rw9StKClxp>50Q70&yU4rHlk6MCeno(D4mKWZu?rijZ7NLUBm1bXBQA(Euc zsYiZ0=KPs++M8F8xFfa|rZ0d{G-gk)m^#nZR8!FnPF>*yt<$`*&UUL=x&Hzx~g&>l_hER$-S2~bVn6~RK_Y> zP*#!V`PI5+R@PyKE~2CNnLJdX5WhXyd+}_+uX1>7&8#Y!dgwJ5}MUx z`SW{QM-dz1%V&5DA2K}9;@}6l3Hee>3ECzshZLBQijvYjlT0ORw;P;W?P`42B^|E! zHkE5JOLIY>?{A0-cPh>ov7B4gr3fq5cGU#|?QC`3Bnr7t>wv6_h^q56<=;-I%Ci7s z+dnkjlPJ~Wvt4mUfxvIh?44Qh#1=1h*Qw=MRNOOl<-;906=Y8%GVZZ)VVt~Y=KC{u zI*#qSHvl`JlvBUcLP9Bw!P>uV=d7TE{3f@_ldd{mKYOqAg*-o8zBRJ$B;`VN)|J9t>O4n1(8- zBxz9w40o6Tg{QR43dgaYMifXSWT@%T;hIeqh{GrG3xkOM*&HEx8t7oHkY-;8K!UfM zHoxjTX(r%|9>=@)o`CcNtj5?)>;*Dh}WvpEU(jl$^w3*|?PbamzyAjn=&WjM~V zlHlfNk)>f-C8@8fPSg& z(oWBs>Dcle3sKGrnh5V?WIL-MSXJ05wS>!Umh<(iYa2DnHdU~mkNm8axFB4{ z4&s94Icc)}tNSdf)Y6SLMC;Q-1z2PCC`5DP#lyD6FTp+DCTiMWznbAIsik29`2!5q za_pzuW+NH-b^V=HIK3-qMOaMhM-bvm45W!yJ1kr|McEC3)gS858SICQ^T4>6aYo(v zMG*@18UZ~PuC#l%#5#;H7aA={`xy3x`#dTPt)f71hm=K3*hBDvYF50>a|T$vPuF%u z99D19>{qEwr~?@n>v{(SD|VwsSa4Y8+av9>Wsfa_&OA>ay5cfW1=4)p-j)fVr29oca<~Dw>Wm26YfjBy6d?L zIc9XEKLtd>P|oP(m@|i;GMLYWE7*`Me3B+H8G1t`?dAr)v?CSe=tk4%BB*z|6AqyX zCuorsmvHD$YH?9Pm-D5%?-#l+xAK)yrjo017Y6_`OV?sVaVseu@?DoDb247zd67{4 zpu*chR0FfH4W5(x%mRviyR(OvPQK2qMbjLT-5TsYof)4BZ4w40#nx za(v}r%MB|6ijlEIPI(EKMu>1k$`L&pCxHOK2AJrVQS0oL3?(n8MJ#QQ~lSY*;y z`9c6vy!z3o!|QqYM|I9mK9<{Nzv+-UU|pB~jJ{E>1?gL+?khbC7T>$~rDli?OSfWI z2qdG&^-_&KgLNz`f#FJAA1yGRi_GAatr-8fI0x;(9}t(^X>WB`DRgK)G9<*#)H*q~ zf=8Vu4tQmo6w?bMm?u`B4cI;Nr_Z3fY%R;A0R+k0X*)nJ1MC5&5-HY#>JP@^1nPme zLhaKoO*M3~w3kI>pYp)g{zYvE0s(W5IVW$;aaYC+_X9=NPb=ABB)nYH7~zEhor^zu zpNr+ZT)tTq;`>*Iyyc4&QQvr1x7zos+zB6gPv4qJ7h0gQcc6341=C0W*dMEdU__qz zIC|UzU$P1_$0r>+n3GHH1GaRm{%(M=jT}hnIUS2K#o-@aa&13l4AHLBhXJ$NW7H*a zV4{7M=Br(kg$r=50H7h}{B0#wxxOe>WrO#sCPftS&P=%Fr=Jl-Xd@AyDquA3NS1G1 zw$1RV`13SutuAx}RwT!skj1Cux|Z`&7u3F?s$*DebVU zwTr{g$xbE|kf!jnSkyUH>TWzj?Irp_;+4}&n9JEgUgFy3l~UUF2{9AdK|H7>1k)j{ zm&upH*DB^T22)~{wpHg&{SFX43d1!($9l`xU$Q-6R$fS5T^CwM0Ja_y+zW+YPl>64 znbJ>o9ML)=CRo0No8Aqe&7Ui|Ik_M3i(LttiO$#~K_7D=Z9OhkFpC(@M8nl#O20L; zb)Fl(4FC(DuC8l%t>aYr4oE%%NHvmF1n{O*=o^ns6{Gb#Nzv>H{LceTt{(WqNS8%+ zZ^I<*iI3g-`4HK>H-T&&w|*bIgOW=^SDWv0494)bpw&%^SFbi5z+a=$PyO{NaY1DJ zchRUwkG z!=sK0{^p$xE7Y1Ot~>iq(P0}P2KRSjJkZ3mUDB(alHv~(m+R()`bhI6zBhB?P_x%J z?4vrU-3;j2qDcjp3Qo^HS&oXhGJiod68#dy@ocpXvEEVBLGjP>6)wKq zExi+qQ4+(oM=15hA^YlVEfE&u8kNI+{Dwr`sP)ga7mSC%-n_GSTwn|i=oj_E{D$@Z z(1IwLu%=Fmx;#q4;1eyUmep$;(-5t7KAvjz=tXKF29dS{jpu1n!&nel&KhsO*1?RG^(|oFctpl$2 z`eNBzDw9a4uWdEhD5QjFsyY0|m~hN~s`EVt->tJ|ExR8!tLZK{-|Js9R|}axchCGe zICmm0B?YXc>oaZ6%*LCsuVG_>0i#4qaBcpq(j!IcNGu%Q+|3=!Q@=uS?vWYtdCzSU zJ>|+xyV2%i3vS}>%iqP@-SAd6gReLycLf?u$)64?)Oi=$X%H2ipW|>6>$*Eb`($8i z<1uTaQ&T>M&b8S==RS`}(n}JzSL4CQLTl~ie9N((Abhl`OIyd*Nu)-uLQCy%Sh>;X89!y55lmY3fP)*tJ}Mm zN;yp!%qXNrE|hrZ%{CJ2IhZQ6oUjvXlcc5BdneF+Ej~UxNKT5`P4s?+@d$RSA)*Ok zT=CqEDtYURB3MW)&H+!|1h+d>N{mFUMF3Fx9X>!i!v!wH>1r=DIS z*ZmqP-?C*;#frp?VoAMNO^j&cSGtOu&vbcyt6oZNmf{L~#m%jfjgC?UIF&wHj2yYi zfU(z?mFr1Cufl~6f85Kv=8g1Kg_%nB^eM&Iw~^sc;q)J@$Te4xHZpjLqq4>< zoRLX{ZL@vCTEIY>_pc?0p2O2B70o>Yy>v&FO;uZlLO0W|nE^CZYBZX>v)qv)Zdnl` zr5gs8Dh-7uaCxa2Rl?Q33ZhrLNoTMF!(=pzd(og4%shn>Z(+NNo>2L zbt|jIG5uWJ8*r%56m#^DAH-yWvyCUjQX_yZ#tVx$pR~~9np^-TAW=ock9@oW1aWo{ ze~}XaDXkU05e(avwm&?cDB4b?@X(t@F8)*;KpGRRXau9pJ%?sEcB&4VfSIscPVX;T zvCeA3>QnM$XYOvEIf+!i(aAIZFk3ZJddfMZT+M4jr-YHQlN= zFV4Y@@&L=`+b#RmwOtN-npmNN)EH%1b82iJKrtEPT|&nrfv)WI?3!^pPu*8xfia58 z!H2W#fH4!hp2}s~N+`DNl2HhnkOCino=1h%Hr;~kyCJ)5tTln(y4+#UrAy%JtJCt@ zJ8!mgV!7JJgEwbq55ZszT(>pIXX(mi^V^t(>mF<_US}1IVYYs-3><#DOPn0MIi)d8wqz zgNOt>R%ciZ-+!wX#T6#~L-xTMcuXa(#$-i5&!!pax^V-be*~(D287=K@WL%E11rA< z)9H>iPYVK>OnG&p>4$9l;`q<^qSI-JXVSf4Wi=kcfqUx-I$zw>9tue4U2jO|Y9m!O%` zMn7}=B*j`exCZyhKG$*wENpOX5*I4818knO&>8K#YtD&|s^>g)hPsY%S6S*eH2?~& z6%srJJARBNmr-F3;`Z~6EaEC$sI@a26bQZM29324(rtO2nqVp8SJI3py+wbDhW%-U zkY7~Mu9N7>bI^1aY3Zj4yPt>1WtP#)EhAkSN7%V>b;Q;?(98k|ezrAo_IA0ahHPuf z+z;s3I5S0fJAr>l+d$^PEU%-;$gqzROhQC>gE&1j?Zt^{+TG=%Fo9n4jLKh?dG|v9 zs(ZiaToTiow+r^^?B0gH!O))3G}uaqD|TLlK4V6q-d2*ousp{PpAKrp$2H_enT{OH z?~zG!P?FU%#*tf^af5N4zAnVmt~&p+;2$)#VCv1(XYRBnt#V?{mPP7OX7&2S8lPd!LWTf^t1X)L~W(VP;a}?*-XcLkdr9#a$a$ z8{CTRvzb^?_U8gM(Y@tKQPrBwUwj+fg(r_rM2A^;dYDLQcaOG>RXv*?6@2_%t(-NMoxqfU;`~%OE6EtTMN(VNY-M2Y5n5h+-RTsgIQ>@1Iy&a)a zV{{TE3r4ps%XL#oB2BZ~mx2?D$^GS+qJjfIBRH2ixmtVsLz{Qcmk(hj?1_622np9a zL$28|6i+Qsvwj7Q9&XZ8iaa^glUe;1bueeUx4*I&624NcnMd8vke+ml2zwXwXW)m< z7D47lU0&Q!f0r2EdGkgNoBrLLu2^CK7rx`F{_!5OT=2Di{oP}P1wtE-(MgANdG-_! za|AQ5(`}~kRzV}vJFO&N(QJ%`0(V!;xXD`7m}z@EbV41G9BNr#SRHYFCrVqVqKrG<>P?9!-zY2P!%q>YP&-l&!H<@=P=+-jpe(Mv?_GG`p` zkx?YG0r(`8F`5nFPAFkVSGT1@j%H(J71@)p$$W3%`+mnQ9^YUr)spO>0*LO4rNPZz zG#wdw>@P7)5YV!V2cfU=^>Ov$A_v#HAve z+~difzhkQ8lOv}NV(o3z-VO(554p<%@dg+ecfpJ`|9FVOjD`y7j93@_|#}@yv34q!gOEp^FJUZVadzAi5rZUiMgb_<|1c`29&G`}R z3>F(MMaFE{AAReld0+zj`U5)8$^$$S2EnybrMw#;B$Vn^2yUkfC&W%|eXy0TEmVx^a!;X| z$68b)k$Rw)vdl83Ym`r|a*iWjfZg8t=WikQ9<1NdgJo+Gj%r`AQi!k$l=vt|x!S?; z?gvvuufDk>Cb)G}VP7PO6c@i9`RAZFK%k;wG?BT?4!)WZ&@g! zb{TG_t7?R`!L@APK@#aJJcI{R2T4>a6jiy)vqg4)G<93DMyW}-2)_^if_QFVM8*9A zQFi7^n1eD78tgh>`>il^p16RLF9K0bTxnwb_(Vof*%*!=bDp@gW`%K#s}vjb2q}fY zebqjzumn`$@r*35LgO@ET=k~9q`2Pz_nAGbDXJ^BA){N@R!4W%)}22>-K2W+ej1^w zG9dp3bEwu_;l}39M3uPso*Pg!tEd@VvdmO}*YsGKsZKS&+VbboTu?W$qLMQ@U)OS{ zd@sJNMwPfYkP|R$magSauQu|Mz|j)4>urND@tJPzIqBT@c%_hm{ZaYu$XVQnTOlX=biqDz zbS@Xg4%dk_`Gyw}ci@ab)ku+O!>N&f@$PbJJ>Q#MfrlPlHZ=>%0iSXpE4iw^c`vL| zdt7V^xD@JRPVPWhy(9EaD3Pju*BqdC-{$1stJ8o<3Kr!hMPfV{4EK2K?Avt{=ig5- z^;ty60E!vo^EUn+6flo3LIP$Wx%b(_1{JDLeRMN`^FfouT*70AJ2t=6W*%w0x5W-9 z+8IoavZf~t*lvIq1B^Dd&P|t0>$03XjVTbB+&1?TT6Bt)ctDzAuM4n>+dq#a&WvZ} z~#iB$(!Yv%~QF0f|WHfkY!Qx5umf=lz&JSNt`0N9u{8rw~ zD}E95Cp(IR5>o5g&vP(gAj+rras)t7+hs-;`>a;|JQ_$SF@d_$L{Mp)o21Kw(D-3^ zWXv#!d8d#JJ!HGzRJgp61HRKi5*aPYtc}IX%dtKMi=NVtHh6JHaXB|uf~b1KeX1@ib}I78@iED5VDa1 z1ZOes$=Xfbu8l^HzJJObKG#?2g412D5bSrs4rPQ}FniHHc4(HZ5+yq8-zI}`=UeI0 z&?(_WU77J@=;;9K!@5l<8-hHy8AH! z7j;|Wk^f?kj)miJ%v9W-JPmLf$rtY|8s+tq)+-~|MvP}_Z~`Ay4ee2r7o8wlkR3sV zaMCFKH0Yvm$|{s&jgA-{&WcTVbY7wVdpZGypVTJ)b3?wcpgwVb+a;$e6S4W`_1nRo z8bht50T?Pg$pYcbbbJQbN{4Epf#Moet zYy5mRbXGK(WZ92JZ_XSUC3cy)fi=$GIWOcM)jr_>pg-hLoJqNM9nE^;`8FE8EQ~3k z6yTPV+WR0i8DTt#)II@lWpR9ARv*#dh&O@Cv5MDeW@dkejKh$m)JVoul!X z*;1aYPSITG`+JRpxP9RHE0L{<_oaq7rzoGP12hY!pSXJqrVNo2DuQq+r>UX`4nVDc* zDHtQL{60OH#W!VEDg5Ocr~M5`pykFO!j4)<> z{(YmMEMzr3()K6HK9XB%Gt`sRd#db5c_>R{mjShz55lpAdQLj1%_|X9$eS;F$hJG-8o{po(cuHuh zo$=}|xBv3O`^tg}b&}rli8CtZPQo-MzgC|1tC0m2Rm*-Ww}Zfp(8JBm$;r7$ajr4B zaBN#kPTHgC!2#)-BQL%i z3QBcAysMw`(kkl+S3Ntqv^gp8ydtAW$S7eZ$y*;M7prbU&%nx5%+4T~etU#|UL7)? zW`o_62*5nN<0R+0^Nu0T&<#onKd&O7Q?sHgz|0gia3TYfjEla?+cg9=3b{R2&^@hd zz}BHX%Blm7$;+EPjFd}>{Mb&zHcSAjmz3BrK)(qHK#mc55R)h+3a`lR}JPYIJk@Sv&E(8GL&YKq(=B&OcA(h4mRu#XnImw?CelGla z9Q=Zpsh5F-jMn<33JWZ5V;Ow67s3o@V23r_^@~t2;-1vvtSNIv(#2n8sh|mkaJWRr z^aW-^%t`>WxBrDhio&yXkEWJ@5qWJ0!${DCAe=(d8b@lh%I)l_?iNw_t7v<{6%K;2 z{=yvG*>nQyojp;8=NkT%q|Ot0dwamok=h`V(Oz2^+gEa(KzQ3mNTPt2)*5*ru;(*e zVP2|OpdK?Gu#8L&O4#oT32?I+gA?A-Do^0myOa;^&0&l9$t&)>tA78ck>deado&xq z$}V-IRbh-sLum`yYyaREOHNX}-<9WbzIpqg?8L|U;!3X}?pl=2#LbLtj zXm0WlmKFfD-{LOyk-?`6Ud>v89n#u$Mn)c}O$Z6b+X!K)4=4V(CJH2&8O4oR`~Co& z!%qYdk1;*Ols)j?_BPBY&He{)+yzh52tiuT7dJO`Y%Yx7fZyE^A!1_J=SF2<-G2b^ zPFHzsKGuUH##QZI^0VFz)wQqs9@Su;2nK6W@X+sNaOCSA{24s_^Yj(wc`fdyO{LIO z)NlnZ$GEfe2;lu)vVs1oD_)F(B z3Wz#}%34)}R+wQOp}H82PaLT;X1^3ya%*FF_^x6F+pIvC6d2Hp{6jX^mUyEDY^Ssz zQUvLO19b{)>fO`s8I1g-r)NN;DDn5&B#unbTtUevX*PKRj`s_sUC5#F;HHt3UHWjG zMDpbFQf#u)o9euzW$W&n2!hVTd7?O*q(9`({W5{`ow$I_Oymy9pP*DnFi%x$P=MOL zxYU=LK*Y~ORYk8H+9f@f!($PBdd(O{?;&O@78UcJetm$qdM85XrSU#2>fsr!@9JU$ z-!9r|%t`>|hgHW-Z_FOICQf5FWSopNH+|dG_X`L5eMy1SBFT=PMRTkpC9F`z0SC>C-{0kYddJ3Ic^wm!ox z(?BT`dYR#WmvGci&3ACR&Q9|r>JtE-32HlUbO6-9(SaJizr7p1OsRUGHHcNRrioy^ zr7ywaYgE?bO$A5RWHU)Fgw-T$X(d#EPit$jZes7HXrCf+OGG$a7Ik2NXO4Pw#~>>= zoNTVoK_-AD?)g4a9r70O870_ftp`$@W{vvlADQDT3-V!V>4TN*z(f&&dw(|Mo}EL3 zHkR5`|3!q~rOUity&>vQwq`>J;fbvcw95`sfg0e3-EhSD?(Vem?rOL%XQe)KcumKU zL5S#j2C_34%!bE;pU;_pMaAbcT~itzJe8uxPq^6=Ggb0qWE?2#QB3|~EEWw!Unz-a zKh_6HcNW$_eU-^)-xs;qbtk1ha&Bi`JUXut*4Sk(Xl0)3$42xs&?gq;PX#=fEc-W& zq<&}5$5sJnYq8YbgZU~PSK*kCDKl&8O;7F;n(Amx(MdWgesw9ITO~xfj~A`t^#sl` zx3MxyvYUPN{a1>Isg@dI@YHFU`Ps&n9 z>d={}!D6p*`UjVrnaVB2DgtYSGb7l~MM)V0e~ik0VqZpo&y3a3C?h+l&(VW2T-i<= zaniL8Emsi+y&6j+VdtlT*Ho6s7>Lp9M-Aynq3muYX$4)I41(K&prZI?JJ!qv8dyYQqtT z+kUK90uE@utQsVw9|j6Oza0U77&VeW>t%Fq+#q`%#9Ru|ZCmfos%K6QdALV@+?jS$DS zIi$A4nLwFbfUj0U-@zUU_>ACroFnd7*2`2Pr>n~p8_9r=BG8G>Xli*i?J*$8eEZ#vNr+P+WeP}rUjl>{ z_|qX%O$8{0Xa2|l7c>PbwSU1@k2+fM>x|VJ8nw1jBt5^GhIEkJmh{QkilD_JzNTnA|5ZIbl`RG+Ex8cUKKQ1u*clbU0L9ACj^jM;Ga(l{1_M-k>G5v-x`;n%&QM!Zep()Z zLZGw0&e_|wJ(b!&X3AXv*X*x1L={X7;c1LNB4HaBBYlp~p$d;j80Q^eFgszW&Tmmi zwi0I2BZq9GgRC<{_IYD~AU0m8DGO;p(G0e`32AV}+Vn&Gwn6~HqQKZFwW0+G40N zg(Aw9C=mZ*za@qrI?2$1vPh8!ABxvnMy0|K|6#<(w31eo^uk}NV6&A^L*`L^RPxJGXG- z151$&-F`|HbHS-_|1kD7q(M=hPN`NJv}btyftV^Qo@NCw4<0)%Qrz{};Pvt`RAKA3 zj>afk<-sbOufesb{nxaOv(&r^g82?}!+u*|7pveuX=sZ6k*it(tjmg$@S+916 zLKOVg)L`!}uxJOu-3Cv~#1d99j5on?bQsC+icA4SiIl8$Fn9Rovd+yA;B15P%s94} zQ1842*o6?~YROoG3?q#Wj-XTC6UB`f5*!H7+mxjgct8qrkt1=4@WiQ%RVrmDgx(+~ z-AV}B8Qzmp{!<(bE5maxBGu^-p zL6-D&Rvho(&VegQaPMR0@M8q;{R^s-|fiAi1nrZS@Q&_1*y%)JB-s`$1454`x zZ>=Eqw&KYuR6(|((AbK~kzw#lKnp6P6kss~CWON(qx6Yo&|_LE0FIZgmDPRw)Jc%~ z>>xAQj6KogkL=w6MK?Lzoa#0Jj3}4b;NO@)R|~5zQ=6E*)<+r+>|k;e;(~`x!U&>c zb3i|2_RH4ULwBlR2^;Kf)Ylw(;F;X~Z)ug$L9Lj=9uBEQ#Y(dvCGKI!#nP`>PKCvG zM%Y?p%3U1NjTRwY_ximVubP~Per5$tDeUMa5Z6s^y92$03Gw$!d2BI;punDHv>|h$ zClZ_977=3zeZ`(zp-Tl73vJgp?jMs(X*nh*g%#8hVV!y&dl?t;fiCw_5m*4r{E=Fk zu=z?Uflge!Gp=zzCHD0=JZpjR06e-h8DYugTsS%&G@-DtKn`Z*RVEiUxK}{OZ=mja zZJ+62Qg-Rli9U9aLPmkMFHXvFb5a1v9;1Fo1gH)^UT=!Qcq%S5UWm$;``y2W@XU71 z%+XWdJL3egC?P|iqjrg7(O*}w3%|Go6rL`vFBdK7MY)!-g@Y={%pB$dNdAG|kXz>v2d= zK7}uuMj8Qe>p-h&M`BH{rI*lT@#WfP+FH0NQ-}1`Z3OquvGTChh0Z9aY-}~s=Qztm zOMVxbb+J-VsTKV|)8h?vYv;-#|G4EsWB#iX<1s&5)4pKY`fb56KiJ0YH#*tcmJ9cG z$Vcvrl{(4CbEh9#6W?9R2mI{0AFY!<;J6;Gso#3mLEd`K|Czr<{hk-kGUzLc`^Yru zqnqw(xp?wJzIf_2?ju{RgO0JIee+!bdGkH_2i~dKoch6M7xcmBcCk$I=GwqiW7_w@ zp7q_hmI4>pE&{NtJ?)Wc#|%in^JkhEW_`4eB|Wem$-QY`w6A3nAiqlky{$=qFxgMPy69wclI1e|GT+Hyi+;dIXGF$Qb3WMeFZ0O_ z`C>WLntj|)cUZ=H^=k7Q483fZ{NKKF|7pI-*6X9!Zc@Ct-ux8{|D7wHPM6~2d7iFNK(QSA8aq-j;onlG*R)bmVI~!`<2LkNoNdL#Qe+s16C6PXs$pHOjUJqBJKM$lk8(C1bv!K{ z6`8eC6F4@kX2bv=&=u^vG+4r44N}gYEA=uYE7qrKf24>`uA+wUM>O~bj4Z8$C<4J} zW(lqQsQsll-MJaRLVEIR%8Bnf1B#X~a0~gPhwfi^(DvjVDc`oy5C!~_#fQ4*9b0{h z*g_{nbr2mG82z@uO3?aFM}F_N()E_JqK%pqPCaCu5+P~Z>}NIfqb=TAZ9W#)Cc;;% z74V-(zVpZ)GCYOH)zp){^eRH5`_>=a1ssrfv_hrAl(q^5)6S)|6 ze%^Hb9l6V%k5V=9iO%2(rOcCnr?(LU!ipef=I)Ck0lAebq{~T2s+6xO)Nsh+qI?oL zCiuz}6Qboz7h^)52*NAgC-==KN(0Fz{1DkS@_yy#v9~cMENzG(8V4umQQ+?#)|mV@ zJl@~B`7h5b5r-o5rN_QWrxd|iCwj$!G4;kMwIJKM>r$lBZ`Yzbc~<977w%JqP3EW! zC49@P(^;|kwLZs@AlbU!4; zilko)_o_#D70_AvTb2M}yLX4Ia~p0;8YT>h>a|y^HsrboYiNNu^c^PxooRc%%&)Yv z)>~Wt=nrggGBGJPUKj?KfvSBC$7SZE2UeTOc(u6hNdDAC${}zO7;dP@b9o zNd7sFA}4PX4aCMKSlx1?K`=e+SWItqKAr+A^ZRl?zToj0v0{dIV;a%!HKGeTY4Ayh z?`X1s){a0FR9EsX=#rV69i0iJPMRCE1FP+AGLDX*G^8^|dPA**=$1F>Rt)Oux|lyr zw^W53mfppe?eZFg*sAF>nMZ_B5DaQ{H$fCiOxM@PIq-OMZ$s$!bmwMvq`RQ5*3L`g zd@i2~+kz~LV|ld~!mGwAQd|lsl>{=_bm6pZ>z(nk%iN7DxukU@@EtlB5p?jDuj!U9 z0vbA7kMjD|X+6>wa4M?L9q~l$T-&Ft5LV=Q!m|`{L!pFBNxfEP>aW4%c*R zHY_X`RM4D6XqPZB-J5)Ct65bP7c;uq3@n$C;OW`?DvA@W4uR$Qd}=(GQZQXn!R2Yt z&engRmVco+I{D`ov#9WY$3z9)v!Pwa{(9CH392j3<{SWRM*hWeFa0IbI|SOKhV9%F zEHkB21=Vdzw0G?;FjVKcXeKLZte>EinyXCSGhAM*OdcPk%cCi&aHS;empfOggy1$N zrggE~v825xQ&_Z0sT5)~?pv5OI++(J`~6MzSAOS$CeTTib zoya-;C5Z;lDM!$6Lcf9%n%^=O8dMZk;=N_aCL z1a2sQ_f`pma&>AwG4i-WvNpz1v05T%Lw!T@1)L$CoCe`vbbfk7h zdmYW*GTK_JcM-;wu&m77XzW)(yv$DCW+)dK8SBhVE=)ewpu00Xu=wN2cj7tf>U?WP|fGD-$VgWb|Xh>M@)}hVaHa zE~+?jDFNt~p?$R|yh6zGM0#kHq`@n-ljU%ZAePyA(ce!r4!wmjo(mpe;GO0) zy8(6GOH`|$0VycaM9o|ZSPINvgNbcCO>9|Z#fu&;QnOVBjYs&sapEG~jTS?b#kU4^ zj)6PC&#*9>L1@CqH#8ugWKrvyTE`AdE?kA-DLMni}Rlp%2i?9En zgJr_ooKl`UKJF`4j5zUSxCf~uQtRO^bad4F!PGB68w42{GMr%$4yfqCeFMV;tLWcYWYc#S8*Wkf)KbH z0&$>pa@^xj)GvM&(Eu)^S(^+upik1EgON-Qy#r-KQVQpg;0l5conMCI1>$U=75Pm# zVz7BoAjsS`*jH5qlmS-Q_ zR7*A{Q2rVUSOrFcAa);z2(ZHGpZz?}q8rtmR3vZD76{`Yr5K`y0>F1@4+OwBX0vc+ zkRrp^f3gcupkX)zmfg7*=+`xXn{YPKYmSEO#Ge_t?>E3=z*Z7^Bm`Dl5sc|Q;+YJY z)I|Un`u^+eBfX43#E5(RBK~Ld_Jq~SpKf~5fkJ=X zcnGkt2n+k$Ng9|s@Fs2Jq3J}h51cNccp-zziyt8^*2Uhe zrwLWt^o!z(_wmE!*axqyFs(uKdw$b?oL5O(s}C6rgdJ_{&H3aWN5JAqTjaMl)o*63 z3x170@ZAwwQX8cay!GAQT+Yi;Rzg$*4F+*A5f6A;`V<8pd_47BoMSOg0+N!0cq#mqp+x8p03BG^=U={DhCXk<5?8_^NcQ z3!8uFIW8TrBH)f@p>`?5tF*-DMQB$kc54}_w-$}OPlWAtns+-^n?y`ENVPhXS4(Wj z>!2;jXQ+v;f}Ebi9yO05kok8D_wq^lmTg)z9u&9HJli*ZM*POCN@@_~SwcFhWS$mX zGSlX-%k6J$cNB5TAI-#T*2gG|61w!Y22lh6YvR+nBMgA#wp#rIDZKf#JO$=x`mwi& z6%TfIla8S&f|&(yMfXUU%%7BX zL`->h^^@D|jc4a0!N({Ucpuh?1&ch${fN$oMGeI2a!P2L3rlAo{Q=MQyv;qYp5JNi zE$5K74G5(Jn#zfFy6$=2!gRF8PH$iHVbudMiFCplaqBI z967vcI)!G-G%!>9+Qg_@AO#S!VrDFt*vs^8<9?4A_QP^sY1x@T#Dk{zviZ@d7I~C6 z;5j`W*q!S*o6E$Eg^UkD{%+!n`T0{jx`T=h$rV`Jm18)Z8XWf5 zjTS103;O+UAn;$Uc^NHuqDqE$jE#!E8cpDLHCZO$;_^bq$hlqO?4X*0+OH6ejaNT7(V82d>>^oqC%^4Npz?J?cNwCne3JdZB)f$R3 zQc2A&uYdQ3>KAjtZ@;LgrzjswJ%+d0;A&%6%tlDx5Ku4rPynyGj(I4<}>CM@L(G1ILkr!slUVVmyC zMT7Hu7)FmvQys4OpHdw)Nggl8D5)Vjs`v|tpAG8ra*uXwkijcj_FZy#dCPj4O_GnP zi;H6(D6YH!bncbbFy%Q}>}FeB^3yLX(8SAE7Wn!S1yQInEb7_C;5B1r&$23j`kx1bno%7yV1MNyG}?&;gAWp3U0l4agu#*omE$p&)e8`A#W;TgLm7QpIp;hJEl)dH<--=mb-0-7 zi+~Di1;EtP5tu+1b~RK#@JH->fE~RcLhBQVrmvS3w>Qj&oNC+q#zu|6hqFqA8L;&8@ zx3)Cz+0+wm@P?O{F{(1`BKMK+8#2TGFLKLUMWAN_D%!$PEITCpd=2=lfS8AC467S5 z_)~imYd7}afAX&e(du)uNc($52y$)I>dY8u=G!)EQO{PHv1jYIJnORjT$M<+1*VZ| z#K`_sBY56>@T+*aHP{V*Xc1{6_)Zks{{jY9>qdSv3jvgtU{`sya0FL1-(t~Re7o#0 zSwrQ^=3JsE{w#z}?Tm2*5e}y^j-@Ww1oKM{uBNc&S2`E3drYVID7m`vkuo8nV@NsZ z<{n;e?!IQx>U}RqIci|h8YNH^1m=XhKYE2avqXFWa^}Pbacu4sG(>*{5)+8PHZ;@H z3{x_+LSALM>*@??Pdau>kF_QFJ%Dqwf{a;AdEJns4n9>Qg|GABr}#ref!KcL1vC<* z5n~iC4ITr)zL>=G=Os8thjb3=-SXxgCa5SGlCDyyL)G5(Rw!&J946y<{u*U ziI@XnV%N+f4%)=+g%E7a#4C#seqj)o79i><12vNnc9tOg!XWt8f6YJNruAPl@1NP6 z$-l5~vu_@vmLe#gnfO_Q`1ysfeRKA&Ezd;!EJFN@Nz`6}sG|tdHy*R2jx{iY@Ey-V z6mi4GB+Q|yfbkuM(Z&i!9d(G)L{ls60f({LRWoJ8!Oc)jnYt;LIIM-K>U%*z2akUt*+)vZi`z_>SZqio! zJ-L%(2|)UrUtp2vryPRTJycVWVt8^4EaVrgXvdR2fHD0|K%|F?SON<8)7^K={*Ih zwfsHH@oNZ@{2QH#+$>k0lx<+LM2?}Am(MBa6tsk^mWdq0lb!zn`Sy(-)3B6dxN`_v zBEMiKx4M@K|KZe=Rcs|VL@u-SM23xxkja&2OaU`W?#QmhZxrw zSF@03|NE>{P=;onft7F25y-Fqj&u9(asH;Pl~=!=o$nfxaulNW57oza0sb;I|EHuM z{~>A2lSA+v`7sN*Ij&(o+ac-SCdVMv`9{_hSno8LB@Q^g*9KQkeLvgu*{`y|GfKcf z(}*26*Z;)B1Ybl{z!l5@s#L@ZXcf1eOFchW2=Iaw5|~gJUFA4n_4LFFafw(0y1~>S z0Eo)am_%*IBW&ZXcMzyX1-;A{s@?f8$ZMQ_bGP8!ZYmIVm>H%e6AL&|M4a&;d+vM2_${HK# z@@xcUmydF~tC8;0yESwcJ`!Pu0lGU3cQ4jt2q)8JYdvdJ44XJo(`B1*=x9+*(>872 z*s7fP!=!U*^ZQT^lMdhh_u)R14&Q3!MCgr^d=CdRK7F)iz8U1lYH`-+s2!GRyQSSl zsb*MKP3)#k%C4EWG5fk{`|9e-lpLlVp8ds`MPn2BXxG~9et1{6pmW}Q?#$O9#=W4ZF+trx++4Y20F1S?NB=BAYXN2i`84wC zx{nS*im8S%zYB4Qv)g~X{}!lG6+7Wpm{bd{@+ld%PayIO>@I?|g_s?mzM;MVbtxod zxRpl+A*Oul6~;yb5Hn==HF8tPX5cn_vyXrd0&=GF<09#&s`6iI?ra!yY6pyyMJsyuJP~Q79jg@ao%sp zG5CUT27RtI^&YpEWQ4DPwNYtQ6{f&nZKyhK35?K(xGGFR|DcVaA0#rl63I)^T zMMFD`yOwRkEM0f>!QcdWUG#0ubgO-1A6@^84BG)qIhutx%?C2C#42DGACPHiC09qk z9$|wTfE^A2HV4jYy;v3CmmC1kb;qVqHfy2(EMr(0pg%54Z^BRe;_2KCN#W@L5k z6Bo_8({PCyKZ!e1k1T+(h@Phl!P4CuTbmd(xwi|MrxvKvwlwibmVdOI=hs8iJ49s3 z9$C(5P6v_MnBM)mNE>e*tr#S;=3f1NiOMax%@3=Tx|xKdg_(l)pE`xqB7pwX-Mscl z3#wY>;Zg z^g=yVY0A9g2G8P#i@(Znu?0+T<1n@vD7C9Mz5_90FL&#V10!$}#QboMH2saZ{AF;X zEmf=FFH_0!K|rKh@-*g-J!49T`1ZE2WmB(c7!L#_c)L2eEwT!Wv!bJ0ZT~06XPAr=P+AQ+EDI7nK zPH6$3KxPlBVS*@R6Vb7YCav+P%Vq5?+`pbaFXLYQKwYD+@ZH_PwrAW<>G`*K|13Vqb5HZTepcMc=lGw!D<9|e8hzdW zd@1`ocbK@~6BYRR(0}SuTO6udY%t=~r8HS2q z`SGvu&+!)lzrkhA`lZm5%_DcJUNbd8%te8l7~$DrBp#m$4&$S6%tUu*&g?thfVdfL z3H!!_^IVGR(aaVJ_tOsX*YbrC`7vJ9WxXDO!%m-TQ0e$q^NOUQX*lP{$>Mep%d)DA z&j%H}oU_3;=^K0-Q)Ms)> z?m9PpqPsZ*=}`Q*Rf5m-=vU>ZGqi}*<|=ci3){$Qgzu^H>wWz&Z)Rx>Bi7JZ?@7cl zR$T;_=N1o)xO>+Z^%1W}_8%mMhw>e)*I@T=hw!Y=`60i#MfWPP7>~v=xdTK<1N$atH zAZ~zv)B-%wM4(~Wf*#gIvP!|#0!8yW}A<2RE+0qEI&Z+pp*j{v2A`>vcE49DhGANpy- zugZuIHNhESa(CsrQhIl}$wuOY?b+DcB~b+0F!uT?Z987jv)kCq%ngrBeX$Ya9}OG? zl)h&S6YR5^U;e#sCXAM@*-IO^1L-BSm0p%DdqWD8y zeDZL!3+1P_j}yJiXU2>APTMyi@8Q~b@Q$uD$ordw4f)251)wmtfh9+nxuqM}ko?;n z3&CwLM)z|xXhB{ibs+y(9vi$2mss;q&Jb`i39+wHb*I$=rA4bCjv z5z}*}+e1sp$Z>KX(3!n>?6yNWrVPVV-`G92f9Z;^)K0)i#>=kL8 zUsqt3UD3s-F}GUMX8D=0uc6X53vH_AsH@?MEh#I4BaL6eGS}?#Bb`!BhpDxEkNpJ` z%7X>_ihjGOG8=!ztx_*OBVM1Kc_!{g_C_adtQYS@p4kylLNE1!j=TU9hn=drCBx-q z8I<`Lc@h)P&DoW)Eo$w|qMgTS8+<@c7Qzh&Br9a+3NEN7c*jr{ z0*?!V4PqeJ{U2NL+vbE|gA^>Iw8ID4UJlvu1|J|JTyaFO!3Bx87P?*$te5=j(h3*U zw-mBd2NxtObp2DX-WB1!h782t8NmiA=nD65r0s9C`(I~|3xX9c2)yp9$N^AL90+}g z5IOt>A%rEgpB$kwMFcKT8E8TEwIWCTmL^!B1q(l$5kg!=nZV^p7f2wuzu&*1DZg+y za{gku{=q67^;4RDW0lAMVoScU)C&|4IclY$1l823oDNnQVuB}&Otc_|x*d~&3ll6* zLS<=|gb?RYW^ma?rHTk#BQkFSD-~7gryL`HX`}w3H7ealVgBwOO=+eDF}Nma`Y$N7 zpoTi*f@4$$nV`oB3iDsu5t%Vcv%d-^|0+Ob#w|;?LIglXXat@q!ls?s^X3-CV*C%;jDE0%7F4-tPxWfu1z**G8k2lLtd%R~_I(uD)~K;{NX{wFX>k@kTt0!88R75okU> zP?N6Q5}6WwwvDHc5tka=Gs}wtb58D2u^k3D+>4Gp1@7^6#r+ll3mQO)r@ zpE=6!)G@`3W_D}*KFvcl`*YwEv&XP(AtHR98UEn~M2h4>=w%PyElE(BCj}3_e-ARA zwBH|x8h!=f91}W#FW!f(bWjs$*2rB1f{Kbay@V-Y8=~kxW6f<$AD;I8A~jls!;oG|G?NbZ^QQqCLPuw%cJoZdC=xVx{uuFJ?&ky-IuU zF8Q86Wh=ODwRke&uHyEyald`n&Hc@Ijufd9z%&K?Az#!n%?uB514I}5Ofrjs_?BD^ ziy3tnP8iU5P#JmY3nODxQGgstI>(4PaUwnDylGsIk$E&Mg`dvW&}1~SMZ<~?V@B+y z=@Up5@(g%PpK+BiqfFrS4im=w0+0jdi;(rsR$O?4whBkCg$a5pTA@C-R28wRcEGU) z8zXEOz#y2To`sZ;25+F_i7|H25_J*FbW+2tjKZVADxyLvwlP5V1Hs{aqUwc>enlPh^{4j#5_{nLD zf62<`VXgP8ESlH`A2V&5*@|KfI^L>iAJ4Cp%JfRXi2rVN3)|9LlI}=AY_x>O2<1EH z@`Fky%$%}JH*{pC>4Z8exWs-3*#q}vkiXMop+yqj8_q12c@<3YbMLf2!S70yimqV9 zwIpKejfcN>zR^k#pf&Yc1fd!WM)z48=>Zx zO>5WD7BBu1dH0KsILmW2={nIovstaUU*;wh-9d_}HWYNK2vYTccqrRgsneTkG%EIz z)e-O=`E@M5*gWg7%Bhe*qd*+BRfjVZo<<;hq&PQ}TTbcSyQTH^|pR2$hjlwR_3V!D0P zvs}&4Q4a;`!1NSd5z^ljptc} zZGUC{3@>tygv#eK5y*pd61a9ddy-M1EoDthhFY*xGAWKUzoo1Q-# zqAM`rJ~1LZ*?Sz%1fGo-=jzhkwBhJzXtrb)c@R(mX~DCrIbrre@)>xNt5Ev@&V}wLyL_$T zV;xsH>alD)0z0|nqZPXveKuz6Cr;QR#|*W(C`#GPcj)rje{bQ%NaQ?l%egp8kt&Z-8{lM70-%`3)ktIk4SZB zHwkw6-QGS+VGZuJU7NaLwQf8+xho5oH`Ozmj~R8hkFQ+gnN&oMM3>zKgVvAz)_6ji z>3g>?PHu11@RjMhjUGfsMteR{iwk3WHR--#S4K;0cXU1_$5FS`r*0EHVU6&_h*PZ7 z)213DYmXPITllrWM4@+8v)aqA%B%Keg{@Qgm)*k?bwF&wR?SfSu!kKnmoos1)^!`J zr=szOlx}7n2BdjYj!A~ko@?AN^>jV6y~wA*2+YxrP74wIDyeaoMyK$^|KkMhU-zf=B?L80yG3+M$SBo@gSZ?@n2@U&Vt2*lzSqB zf7v%P9mUv0IPh%)vTQ|S_`@wCJV{GQ{pq#A&)%a zUY>J#kK{}bVNC(nBSfoejR>$9U_+V}aCPWz`VHwlNT`YXtu)qWn0J~tL)VE}E0TIO zJoy`5>S8wH8s%Rx4HZmh90Nid177dE>!Vle4q)K?TDF6QLfAxeI7}@yR8qYZkx6MG z!aG8uNN899;SV`gR`pY<=Dt0{nmz1FdrI3><}ExeR8=2LNNz93>dP#9=NS3v3^Ndv zf1ed67toO_+zC9S6qx~>!@4Hh_XR!l*MhZ6g1j?YVH?*SjK==(zeB9}#VH^JT4(Z2 zGFbiggi-29VCF@A8UntDoLD@({(ZC&vl73T;DcZ6+C9xsH;FVKI@7aX;g2=JIUfvgV zJp80RinQ)fY;lfeN0$4w=o=85L0VLnVLIMJVfoO+t^ohc|xA%LI%_jrqssNnAxDv&f{M)D{pIBW>oVu3ngF+G}q znDI-Pn@G~qc|ZK$zwoc~R_uCr2AFBns8Iba*vlJlvQTz zKI6lot7*nl2yBaJ(^}hU=k#b(o-JGePS><(b>j{}SND>rd$Ph4C7dBG9Rc7z(Bn3Q zXi=3w_nl6P^u5rxPj!LTlBdnobOt znxl?x)l)~6m?g?w1ZD=p038|E)St|no8;qGEutwLA+@QX@h&qdxttcP2Q~VQ13M;F zem27Ed#2~?WVZDo$sUFqp5jB(kGM8a*?zXdqR|;TYa860?qacDD%&@2S-#2ZuS5Y= zB{`qkP1E=mtTj|Dg|*+uafPMa;=0~;p{tZ1o->Is2A11h0}9+9wARBl-RhQ#FmQP< zXq5o*QSe5$q_rTr*W=-b^7OL50W-Ld4=iG7DXwHKGMbKjo)gBkbpW+t;J0v$oKmh2 zQj&l6y$&`F8LTeTr|jU3F21sOHkO#;BTjOGG?jynvGJ3yw~MUX8fGcepO-c481jlA zHNRz?I$=9n9I1Ud|CmxSy^$Yhqbu@=UMXd-onh%Yk8O~-@+yK^h`tZBP?pz1a+bfY z$|u-C98;}N)HNpa`LrEC1djCUKgBvSm?kvy|u8x1=flyuutcx0|%tkWF5gT9@Pd*2Jr}^QU=n`#>z*SEV)ko`0 zt=h2`p>U!t^Tbu7iAm*A1A`gap;!Ts>ll%u=0)PxZ~D{Ur!G~fy`=;9sEF$FzxOE1 zq->#SXEkS}PjkY$x%U)Ff?AXwPl*fDdg!=E7Klqp)=zbFHZE&TVh>kS(HCt6Y_g#u zpQ3k|C2#`)1@!QPa#{8r(F(kDmS4oE=L%HjwJbg#rv;ltnIB`7PQk~Moj+K0z|+ya z3PHs0t6&_VdJ9CbAM43v(y8Y(d5KzS9LG59MQ08eB*dMv<##x^*B6dBl-1((GWJWG zPUjw1LB(wF&1JRO%+ttp$03m%ByD+{e%t zW2hl}WpL5p)Cf-lhU!seefxBBm&}^*IW%n-Tc}eohl_3Ko2|JI< z9cv*uUTb*vv7OI7U5+I9ZZUyLE&E%;oM9}4UBQ6hnuW(qG^?+)06@a=D47SB3za=W zRb#bE=xjmKwxWQ$|2Fu3Vb11V)Tf2~^G1iSwp{Nf^1ba9SpUgt*Bg7dNBjGr{GoCv z5V+Shv(rK>26Z-UGiHG@N2f%6vS*OtbC!JSN{vA8@~s2z_c|G`Cz!E@X%#4nXb0FP z;6Hz`HWpSrI^!Ch3}tdBRQOHJU%3OX$4q$4QiLfHsnsD*Xn2#;gTYHeN>U82G9%~k zQJU`jo?e^Sfa{RON(eilshP^Y*Gqa$K#ov)uOBfOB;}DOj5ReDBbkU5me;sgN6v#7 zI_F(BWyzSI?puDQ?cF5NUt2hB7cIU$gKV-6vT~<`1{g=cGKNeXagF6eV*)O^oGo;^ z32FjK0Y@s&O_jG)#JJfRDR=19t*d-iu&3mSNXa#?qqQ9-!yRr><(Hb~^}cd+sfrMC zm*w=;ZN+Q0$$0NHz&a_DHyhXvTh{`<%4d|e*kw}I2F{5t_nMh03L??+ob+J*iH06W z#8Lt=xwK_K#*-F7e?g2YdDIh|#I<6Vb=jlM3G@xZ?5}!}yF)2z<}1J@5wI~J!QLPq z0XIcvIgK`_vmGG(B%31YdIPDW5S?uTpIk#cQyIRKDLtb`zXLwxEJF3t&12-+abuH)2N<>0!-I2lyYRN+mXqpxvPYhdO zz3FNU^Y(Z;W49{T7H>HqJXo8Op3s6gkd-uTpz9WqDa7) z;mH-LX4Je-lQIcnF9?txG?KJ)%5>KX&q-w|7rW4P;$;w|q+!OJHPYg#M`J zc>9evpi_&_5y;v`{R&~LkD{$bLIT%3P*l_pFouM{0?9}-TV&a_iWBd&hiyh8vyd37zGIR2TD7YgJDROyYa?^J$`!f7paaCYmt|9jR2U8O2G4Ap_Niu z^O7|e%Yz)SMIhAIlw8V)vcDr#S;zlbRWPSoX(2oPA*Bmw6{hilSq~3w8!>x8m=sGQwR`?0ta5cdT*6T%7$-4*c5P)eat z^1)P2wt@7)iS4ePk3DN{)!NA%v8ud4%sOzPgSW3oH7o-pPupp6Ojd@_%UOs2={mL$ zGGAEC375Sqr3^=-orI&AmSYhF#|V{2B>w96IvrX}d20@lR%wJL;{%RQz^23r7ZLJ< z_sYkn%M<`~)iSqLL-5lVA$#Ym>6>a-FgGQK(HPcB1|C+ss&Ki)B6`jQ2%u3Ai`%Ue zeM^gl%lg!C0X{5JKw%_Ew~{Z11BW0)8uMri#d#I;X=DY8-8%x-G; z_*vC2H4v(D_21mW$`5IeQYB|J6sqP^63gygLLusa?-!IXJ9?>6rCn#l&RAZE$4 zZmJxFo+1a~V3DKCh>ID5HXQN2!FFZ^0;|0WG61EuD4ARW#GUvk(?eX260ZvVpe??X zCjb19M9HQMBS)95-_k3;`s8qtkJkj=C&-);W45inUs#{4pcJqjzUT3Ka=`7BbEg4^ z4#GYgHC1DepcJm9?!@LrX~p7tL_3K!HIe10R#WmKo0yRHQKNVJbW!vW_y4-lBitgE z!(0J7kB@lJQZKd3&)*&x?sMRY+L27)Toyz3#a#ng(CjTM76yp>(Pvfj+4Zwpo&^p|BJGBjLt1++Js{} zIk9cqwr%6Ywr$(CZ6_zTZQD-1JkL98);IHS_MfYEb$4~`>bkLdS6BTzIEymCr0Y!H zG_Y+8eaOJJb?6hS-V;88m>EU~1r&4N7Si?yAVlr6Qu%=*;{kbvF^JZm-J-un*(~K+ zV#Al=MTiM1ZVngH_9MC5o6BK+vB6JydiURgWB^jfu)6`1{>>I|pS&(arQm(??k}j` z4jCs?D(tzd5RX#JqU5#?S&HYO=pOO>oi2uJ=1Hb_sm~s1O8mf)P6n$776Tk_=2xt- zT`!kR)sWwbL;2i~uy1I-o&g@VJ-0!R9-DA{bWhPCy!RnF+6hU4DLNLB#3S{)SBU|u z^9N$kORnTYP%BeA*&Lwq*rTY&E(^DOg=nk>9W!k?YQ>36OmYVAMb*z}%~NBl!=1Sc zHHIi_XE=I8DMi2hfI(=;hmVujVA%L*dMc1UktB1_%WS{xQ{bf4)9dmDTtr!-7{}z= zMlVp0J<&Yl7~`a~*MCBK1NBLb=pvjYCbck4SS6^$b{}(W4@5McdU4^v3;S2tMG+me;+pn zsP@@r>2%i_0fm(SyaZ@UAI&!W79uZU9;EXTh;hz1hw8t6iKIhDyqug<%{UKw4sU#c zH5wXLT#nt_OzJ@JLQq6u!8AWx58{3n&TsSl>7?>N+a(uhN+!_O%(kErC|&dP7SN}Q z27!njK62XbT_kZmsGws*U;Da5AXE(q4eSaQAi@xPTrtGQBB;#Muse{`$9fHh7BK;! zt2@Csve_;mU}Ovr-`PHlHAOiBUzjjsu_CY_WbQ2I6RRp!X!zder8KZqK|pyeESUA6 zhBwqe+&_UHalgmAk_GaTEFNbu^OBGcZ`no7vXm!>(B?{~-0hUg@)C?!S|k*$AS1>t z4gwB`93%jPOrF|D=wF~imX>a}!Y-9?)ykiMko5tm>z~7CLKmp{zVk#@?~Zm4;KS6{ z6A_Q1*;xEg`&m@1j6BO&;|!=)SKt}tfwzTN2&|t|1!7_BCP{L5qtb=pCy@#>L^BZi zK??$h@)aW}ox2HxDe_r)=kGX2>UuE>Nw=fAsh<&2QB~OE_+vH-%k5A9ioL3Dt}~Pf zdI&dn@6}-#!k%Xbz#hAkDh{r&gGJDK;p~rMjF#t7BlQeH3+O8i!-BfjNk`0V>*zS^ z^~K^wd3r5nn`fVH1GeP{kfnG?Y2AJ|Cd?hBAFj)nxszQ#Ay0QT4au;ZkZrZ)N8ztR z%jY^g-o1IGwM*R~UsVa}dt3B%K(5hYq4k?Mp{cYs7&pf2t1wz_WrGGY73VB|-E>lZ z;(CloO6|bC7e7ax&+w*rQ)&|YL;4)G-NA7|(;(v3xmM${n$(wPHU`r4>E)J*W;rU8 z^in=;nE%7q0)Tp_Ob$^=hqO2GBl7GP~%6Zac z#%DGqKciMMuum2|E7ZYAYgt8e_$U*HvQR)p86f+-Ajd3vPg-8KD)I77LSz3v@LV|n zt#=bwXJdLc_z^q^x3_N&{1Q(A9rlkK^_o5IXszJt6My!20FD=!GcYe3fI6E9;+qhX zw9T|#hGB5T&fNmnRXc(7E8q|x-P2<3K*3j@TjR-?GHcXBb#~IypgVHYl}ial&5#0# zXPMb?N}6I>HS#f%w|@ly9=c4cyfEh#`ehk@fFr9Ey>v)7!MkeR{3vp3ATRiJh|#f) z_IZSqcx)|tDD53xuY4E>O}gS!1`7ZiRsc1^XmrVgZ>I@Dk? zDwF3T=A#UBYpS`q&aH&Y^QO?L$5D-n6ycrxMLD;p)8e4(fS-^HO!4)_ zltl|*^6A%9rM;bf$tCw>EMTAG_dAl#M$}>4j5I1O_|$1N>w3N`2R>r(0`ro<1hzUi(+3sh(~s<)&isTr++y zy)%9HRzwd5b0h9r3izMzk-hc5-|g=&j%)iqN8r6aZUV1*`R00mKuh>oGhv;p3q?Jj zU}-(?_T=(j^+aZGdvn;Z?k#KA(7n7@lwC#HN^Z^$M&Qp|_?dgW9qYVdka~X;;(wl$ zF3atZ@~H~m+{o!{D)ViC?pzI~*7p8cI8k}Eb-cnB4v_c;XtgVXmwjQv-fL0c+k zZ7MJGY<7c;e!6UAAtU`TR`h3bc##~N4yv4NaE~3x$O!DWz!GAUX4-H8wuOx#ZpD@e z_dnWzZC(>kDx$ZV2u?r~Rt4+4bJN{b?K6rn6v=uH?&a z8Sz+7_|J251@R`rDA5mIF13$cTAZJ6Lmz>Wa)zdcT#LqAjf!tlW6iRa zVm+}V^K6fW%6YaaAAW%rfJ~3lP|#)3R#)qt>YFb&{C;ohaG^205c?=Uv-R8j)0PB4l&uBZ}^UV-$_Z||oZ zo7C1b<3R0ku^$VA315IqDAbA~My_R^K4G#HYtqdtk*?^wYN*pQ4j(|ZFxa)DOsCGh z%#bo=lzX)1RM`J1=Ibm3YH7F{;VgtX+Yt{Vr4cuk*N6bkfk4g25>Sjg`5o%oXb^f| zbw`fr^zw%b`>VJiafX2_rSek=pIT=?b}G{+EFK5)Gf!S55Jsd|!Y@iiUqZ<_69xplyYNLs`M_eh?v>ff0C^FtR_;$<1j zDwXFV@AO|0q%ZGq%OvVMF9`p()@BcbODN^V6T(pwX(d^cw;TN!?l~@wh%RcW`Uqc4 zL@FhDd;p;rPFHJ~|J!vFa62)S{*y0?;;7pDUJG=HR6(6esueH4UaYD?Dbz|>FONe7 zEuws(8^@WfModqdsu}MTi~J9=SV_dxS&foqJOtm~iYJp%Ndnk*MXo|zW5~y8NS738 zo$y&nh(Nwz+l=iTo^lXT)t+emNdI>a6y2teJPN2J`W6ieRCCM#cr~W}#kUOs1pTjs z;unNg8kvpz4`95X`o#uQM(lysWZJ(dlYKuL)4wWB0`O9p$_v-M<7uk9wN&u7CTYqK zA3PlNt3m1}7mJ>#vfVGcdk)VH^$p?BlvK zA9HD*R((R?eU(0|O^|!rH+GE5%giz@gj>FHJ^SN|7#+@*yvA?3QHxo;LbU=47Ittz zc{ltk@$Fsm8)-vVbwR1Ve~0*a1{m_TY!PA$7g^4pvX2RFHsh&<^teo#SZ+?<)N&;i z6FF8mr7aMW6h>azsYT4j(N(PX*&%j&|b58baIBL`6c$RF#!{m@kqAnImN28E(p+hYTXrxiA{PP9Z%Qt`#(ej%i z2Qk|AEQ2&$y}xu8h&ph=f|BV=A_vAq>sjq_2rc;&Szrh|3}kp2T3FT&;Zvj)>P+XM zM$IKU;2rAyI0HNikpUr-A8@X<%e=$bxq9ZJ!KVHsxhMq8)#B$-y=*nptwL7=y~LQm zs5EA67LinJE zZA*h9xYj@VuRf|uTu7s@?*eMwsieEa*Mf(cVaVcTa(L32YQSv*us*X?C+>+tKwRk1 z-}6mkK7i)FeP3E4OouT5<%aI!UEHXDGm-v z8SJ;Sj}MmRCrp#^?3sB?hw!J^fH%ZligzYKa@u- znBxa3tF!F5mO=F3LfTGjCfOasL0R&jTj243Ha4{W1n`sav~{SLtn~)p>@%qUo_BVA z#G4WU>w^4eFdY{313=^PG=X{DqXW%_QF$MED|Z9MuB&_hQw&P^w^2-Xl7u1t!~^h zs_kmL9b~5wIXQ!r{(>rc%o90@ntl;8nTfz<9slM|z|_Gw{XTapgKk$kW5Rrq@VN8hxr#{qvpn$-{FMtw46r>baW$%*lIv-@^CzB{qf#ZS%xEumh za6sM+J+|PA6G1>tK`IVL99kg%ufFF@fPsV_u|%B%MVfG5No_5#6EA1GAIIij>PSk= zFlr=CY#OJ{tgIOccc>v9Mw;mKm*;U%9!w5w>g5CGG^hGy; zX=9mG>$+GW8Y>Jr5=nU^phOIcWdQ*tijxw;mBcK8;x(l=^39?+ax22e*DF1G zWqv?rmuG*LSU9MtbQk(2iYPuLMt)~iY`4ObBhgxk?a`RO8OP*i&?JOn{P=9qm}*d3 z5o>bryfGCL)M8$PxOkK5EAN4x{?T=Gkli@IOZu{L*;GE)ccbAxvrX8u1d#s_eBIjdmuz0XQ3y;Q6q_sn4A zlIw6xFJ5<=N%T={aHhx!TLnW+P6S<(s@q2>UHGNTBW@-|$&76h#aZqqu1aqT9Licq{fXn&;&z+@9zE-xeU|Os`UyhGs^PHq zks*K8u>4&-h(66lg`UCg2uLPUPaOj)zqFk5Ukg~REU1V-zlHMAcke3Q1_z?S!kOPq z^LKrubZUnHPRI{gh^E*bcwTI?st$Fr1#}R^Zf?M?uK>7B*T~d_idw>vFPiXD|G>;% zHFclXOBHPHfMyt2=K~B+L^jT&XD6-cfTWhT2708XS8QwX6>kTnd3v(GidQ&ZKUWhK zcTAU!sEU|a(L3oR4R%=ROyxyS^%ko2RqAin}Lgnz?)4z zBV{6u{`05;7Okcmepk$?rZYjTYMC2&&3!7VTMBG^Dy@>KW+T{K_E5&9QKsDg!%f*8 zSQ)6|t{nG*Y+s&6rY2%*b!+6!Tym)kaPqjQo9Ak`?p^d84&K_j+J4)kuf}h*q>#-@ za5>AG?IvB^z`D7fWQGicP!0PMHoj2Lx*6cHP+q{sDqh2jX=L4YQzM&+U~6LCHlj>v zIan>_uDdo`(orQ|a*-2lRZ+(JpU1$$T2sagu8)^tZ78R0GbYM(0BMMqx$slKTKm1p zu{K^HRJZ;m5{Qn>MOo9`&ATZq70j`glpCiEMm&^Il`o@(UP!;3 zY1mD{(qFvNiJH2a#J`-`0EgcEAHnX|+ewn@)(4q)d>1kXmEdLz48c#Jp<@3VErUZvkKoCgZA2Tt>fh=v!Fvt@p7kHzklQ#vLWurKipC z39=!*yA;|{tCp8(60#3;#!VAy#eWLZthL>g7roWtlcz6OwZjaiRWuYe*mWnIjJPKa0~5uiA14c9zb`dO z!~Mog+dUqX2d<14KG()sF~?nh%qH4s)}p%8kYwtf_%X#tLQ+T!0*Z54O#ktI9;EF9mnb4;ERm)d z&0J=!SNH4vx-zT>=yrP4n2Ahy3Eu9I|Ec&x3TOyiT1zXiDClGPS)w1p!xEj&%9K%! zcRRAJvWaPp+e`hor^G%Us`7r`^s810k>L*%ZMzKSo@F$ubQZZmJ|jgcNXCPmVtzTX z>mo7EwE%R%dzAWQy~dDH=n#Xw_b9#IzlnlJ!eJ`&%oZ-?!z(bz61v-RLAQ{@*cMzF z%7%x2o;st5{m?XMxXP*EcS@g2Le@C`63Ibtz zuZdy@%AmO@q-I&d?<-1xw#wnW5Mwmbvtyxqo~q|UN>{Y@U;9!^MXCFHCPo=-^C zSg;gwHyL%jq)+QA1u}ja z{#h4%XAGXz#j3qSOKZ@f$>j9hdbiKwoCQ;2Mi?%Al>Jh?8=!2WWs`carCP7i*colQ z52OrfD+IKnRvzPX*cJ<(I-Zonq*YS*>YTvsARk_i&><|YJ&A&7!znTw4??y>gLStD zT;lRRfr08|SG)O`2ZR$~U@WCr3Kc#MoM=q!jUjO|bEIc?OxR3C|gcaEV_bs(>Qj;QDH>)%n=f zXfYhhlCfjcC-9BOf}-x70h|0|>P~e^P>>oRE)E*0IlnQ!Ee^SclzamM6blJ1Cp+rk z`Magj;)RidgywZpZ6XBu+KFS&UWZgXV9!w6RQfR;5lCeDiDBd@K( zk-WnqxdBs~IxE%)j2G70M(d;v?W^ROjxj9;*(Qpl=aW;U2*cJzq! zQ+mRJ`Ht^!Nt^UFP~+6QwVp(02=UU#&UAd!awUPG97FQi^D9r7vO%AMDpjMfH)C=P zUX9Fs^Bee314gY37qk2VZmYJr?92O-)Jau2;?hLjfO#)NK(gE#J{ErlIl`mfmhHj# zocEZ6>wO-UEtsx=+?$S27@2G;%t-UBWj+q2lyHQ#=5(S6grN1Gz!uco%LS=^D;2Ug_s0$#sP(Dm!H7VeyGVcM_4Xl9peaP$3zh* z0Z`drs*s^j$);jhDZ?7oOP5)&XP&tSKqAJTU1=f9t0~JGWQ`@Z30DMw^iEi|=3$D& z{{>;-l?*~k_7j9$l@u@D7{SF!Bo3P*;NaEuXsnypT!g}$wgh9UeZ?gvaKE7RjG2IQ zf{>h`h@DMNDtIG8j6Wv?eKdh6$3PnHMd=_rQ&zc%pK{I6r=5oHVwG1Oei@=>84ClI zA7$z70GVp6AXAq@S@OMoQ~x0~`sv?3-hQ9H#%3HR?QE&l^wOf?S~!lNMLb#VzThzE zZ;sgAS}WQ9qv^+`J$Fu^O_}kd{^a}@0w644YH1XR?#(U0HN0C9t*_7__UTNb1MYP% zfLur|;t6DMUZ<2^-2L@TqJD(g7Fahva*@I!SR?;<0lX!Bh2lj*HvpwX9ojgEvS$Qj zebveRQ2B2ac5X(^%UNF>3)_;%SiI2u`5v=wf7b&R$pipUe{oXh85QUIqcM?M0(_~b zEUPcWtP`L1H7Q-r@O`E3=eEZlt(S(ON{MmLa6sznU7R@Eq!9<+Wc>{xEq_FZT)!=U_yGf$^;L=Qf_1c}&uo(Az#JJs0`pMP5 zoX#YH;?9agXcj3`veKrbdxk9LsE{tyZe<@V=P1Vl@wP}uj&LbU7LMV-YX^3ifq77Z-Hip%N*YJl(6rJqgR+MPk7cNS4mKG*wTI0xKUZ zG_qY0u0Z_bX%}8fVtrJlkzQ9Ff-}Vc&3}k>!>J&3nSECvd{IrXjGz4Akma)c#?ZUW z{{+~zz5ealIuQu>z;EOkW)QiGdE^SdQE z&DIHzD2xVo@AA@tt z;Lz|<{Ng=flG*v%wf=S%eZ0K~BQvpEZ;;$cZfH@Pr_|J5{v~t#0VPnPRpao!odo&d z#H8|H;Ls$~>60Lkckn#+GEh}r!2y8+fN+?nD#f}OL--*F@B5<&QRJf9lj0N4ck1yR zc3qLAKy`k&DqgV?KKRF|CBpGq4tsZsr|qlIFmKsY7SW))^$nfro?Q)XJ8%o;pAWuV z-mi^Dx!ms?yq~ulIotwLRXaNSgNZ5HtR;A^)KYkTtp({-u#jZFPXyKESflAI`Z!H% zrHP7^^S`i_Ee74&OoQ+IBhsCPN}Q6UYVzCl;n4;XO?O7C^F<%!N;HNKCa(=nN*b^| zf+C|tv;v*qZnv<00ahjzOMqs79tHc2$t(uD$Ex13pnBOD z*Ll;&>aiq8yc3$uK7W7zoTkPQy`u9>@>{+UzrHn{<=`BvROajTjhFC zm-{xSn=dCQ-u#6LZfL^K2WK$+IMNHQk)P&I2#iw4>gC8Exl;}XzcLPfrW zW|-a_+irJ^z{)JddRJe!t#%%h*oTo>=?;P|(FY9B=w)kDl%(K88=jP+R6{ibO_ne( z!0-I7`;ktY6?R#bJJ+vb-R#t;>Mfnfq&;g|xmYB>hAjMED#0E+Ylmzh8GorS1)jl~ zY|R#%TsefxLDI^AGA$KzY%?6efl6aDphDJh{2q{i|GdCy+vP5h8a;ptkBvIOzVdil zU^A>F9I2KhkxM4f(N_F`Hsvlo3tM1{mBR;O?Q+O&#%A7F4D{+EZov*av!)D$aXJyq zW>CK8yu;Dkg?m~!O|@PvRcIhZ41;j?4)emI(A0CRI4gmK;LmpzCjvY972_OresX}* zuK$68ix9sr6o*qN>$CN!TI{M_u$YRTxc(=C)k! z)g}%y*Z_)foWio~40UZw-XYz6<5jK)9=@A2gkq}CBy}^uPz_(d;j8=8sg4)YZ8qck zdGz{Nw#OO)L9ZZ7SpzD%4Jt*lx{* z#pkU6g9W?y^9WR$3vq~~K?OGRJaiL*DkNIzg6Sc>9CotuTavVE3b5-h=P;dJ#LnDD zJ)=0hwn(J~s|wQbTQzasHfQ zBVP_|ujthR2&D~tHWjWrw}ryYg{b-~@30^Q?I2Np0~e+I0TvvSmkdZ^C_3m#jXg|G z{Z#$usueXKX2r94kyB3)G`*Mv0EAfp9%rvYyg1Tqoy?LRv(i=_UivHU9bEPf@}J+b zwIp>IcU}M;PH)}&cIaba&76Lwy2qXeCLxPxMJjo{RwX%i2Zci%Ph(-_95O{xhG~x* z!e_82w?*$yxyrMh9Ykdu0VPURM#Vefg3g)m-4-R;;k>p>>l*YX?uHIwR10xY2nz^Q zZx$h;!tbpSQkpn|3lu)Zg9;)9hzcFw)4(jaKz|{{f(%fOvgZ42m%#M8tv;c2djis9 zzT}6+Br-XBY)bNVO|n4D0!GdAzFMq7oo1)kYhvVrJ7JE3Zbc!?}peuKA9Ovf*%N8;)zOb|lqdT*gJ za%Kw0%szLZpM1v&_k8)nh(9+gV0+A2p|T}C=$5huD-dK^%4dy6ZOzX4fX4}N-x4=T z?K^LFWt75t1;TROnDJqrt7OC5%&x#{rkGhcM4D0X6bStC&FS~U!;OUP+IuWxX4tu3yYWQ>DYils|cP0pZ<2EE%tyJt&=?+!oI*ej}HV zzC06!`6M>Avctc{f!WQ`2Twj`l1T!UpmcJF^ijQs`FXRxEnU0azq&N&zqP>+ZW1;Q zxsYz{JCV1kv%G5tH8u-o*M6QI%;Gs3xALI!W|zla7AaAz%{Fe5CV|RGv3LJ4Ic)VT z8#0YFIZ|S&UV&v;l0Mn!m$RSjI?;QbBiz&q|FgSi>l6{W5ai*mL)yjNk3Z0kIkA8{ z=6zCMl1}AKw~TO>J9D-TG$@zGv?fLxP8Y12gRxD%`}1}E>0*jzGu^Pn58u4!8`JES ziO!9A7%{Sv;qC&R(%uh#C@`fn8T?%)c!@SWxFg?Kdia=Rvc(C`Hn_cTq*a4L;I(p~ z?M6KiXo*J%c5<}P0zQt${WZ-&-+IG6%nOwgp=SxZN!<6(O%60?HZ`FW#y2&UYi(&H0ugDy%&jcR~_P~(!jdyDmEKzi-dS%rWkzWqvPMGWQbZ@nvfFFKMCH*v>2-Ur!K9pI>PqwpKJtI)z_h5B!bh=U2^U0Lx+5DwU_6x zoZ1wF$iX@1tG90H*_{HPVcBd18=&A`8hpzW^A>0|qVm^D*2HS2e=TWf(RnQ`?Ppf0 z9=7C)gXJZ~zsm?MgS|jX)5uyhdrA-OwJ)p3#OV4Vt{IlR-8CWX;)&sq$36eAl8%d! znk8U?lHl&I4=ahh)ELo;T+S)*NWi{8VnDuN(oso*vf5$FfEjy|iLEfHhiKnxlXFRP^a~DOkYhKkOl`#qSO8f%ciU_!P0d^4@=w8e zZe4O#1v;8-0JA)|2MXAEA~^;!+rI^UJs~m2fR;(gJ?$M>c1fE1y08sw1ZvuQkfnNq zXT%@rXtBfgH$Y$5ttqK>wtLSfnYdh%9?l^)dFecLu|)!|zX$w8W+s({^{}^45yedO z_+{!}IU1z#BLC6qlN?c~tL_sRd=&;6*|sa159;Iv z;pyMXsP8}dGz!CO6gVaUur}*V@F5E?vwB-S;c?+#_U-vygrdRDa(Y|DO)Vju401?%HkjWcdQaMsX zAK#xZO~|HA5bMv^!cH{lNFCo}r6+{3wxv;7t|l1r=-(z32P%2wygQTF`Ajd|WnEpZDTIQ9=(^l?_|1t=jT#4mXqO=O_e zJZ7=Az;3*_71iztFum5oXSOV48*dmcMSp92m-=F>&RoUO$v~;nR9h*!5;{?RjS5CD z^?pxe2z)-&LDHA*;lW5&_qSf+vpS=S`Ksx4KWc?(Ah$EI>);@Azy~fm*RE0oTb>WG z2~rAApyr8+f34kM)6%7tnpUZ(4@_b9-%4##`qzYA(y-I8tJxpNjsWw<7&4!e_2nySfZOlnRp4^nFz{`ge9UnvnH*Y6iLr|2|>QY+#G>d>TeqUP&}p6UWT zYUoPepAa9q@=!kqxK8ycmQ_yWGi3qaKMM^ZiRx{ zzRv`_2=q1=bBRVCP_AN&IL)-`YxaKygU7~z? zXO}V5r1EMQ`~JbmVC#D2!xgv*mw-Cp~n#H`8km|G4JGUr&ebL$}b44!zSIVw>v)m=Yia z6K_ee`q_wn{YsGXL4|ZsrO~&~2fZo_>_RS147tn{ziZ41n-=+Kd5)Kdy#$2uqk-?* zHDI@owh!9qz}41P(>1zK577eAGQkFrqW@W=a=P9fX$#b-rQP_SrE~F!UgqW3qE)Gb z_*yp9fYyLsE739wkoG>dp|IBXxA5<9tfcPZ0fsq@U2XKQ48De=X`yzK3er4vv6*US z$y&d~|7lg@?{+IHP8G39myg`6sp+HEoe0wGx*iaOG2mM1j5eq7bN$O<3aCx72-M~n z*+5gc1P0>?wIWt|+wfYAVsW>z1ezgY-7Fuuj#=hiwQ#1@tyS}~4&*xH_u=*i8o6nb zkJ{cDr@mVG!A;}$!dh#GY}RyL0s}m!GbfVT)gf zSz6aJ*r??LV8tUf9MT%Ds&3q}UA5_a?kjLnC=;=^UbJbw?i2i_gD=-za8_HJ+jLMY z>^obwT3)PLffcpBx=YEu4{7M7>LUed+&X)|OcXlF7Ykg#k#y54y+<||;vT(_M401H z`%wEjQJK`ye@#Sx?enOA_iMlXUrk5W51Yei{#YP(0>|GBe>LYBVRrKVL2XBE=W5)r z^w%O>1ZriqYwg^#RQRO}S{yyiP)kV!X=GPgJd+M$P^*4vbyrer%e&v^{nn2+P3TRe zeAG6}4W4lgG3e!Ax{3t}OpE9I@17>%;y`m`rao!~iQrFecc-O=))*?imv6cyFNq> zY=r&`m%(f`ER+tLr-9uss;PAv`2C_f+J}MuFRB9K)PLdQnJu4E&}>P{19a}74%#}( ze{ybP0srDH=L&wHrK5aX#~R6?m81M*gn4p*8wYvR)=lbOD+jsHmQ{v93kSKW&Q(_a zFIwnWScoY`(Q2xx8CH-?L4fZ@v5Hin&L0MN>C4~DX3fS~iy#ka@IrOzOh zuICb6pq-37MC56*K`SY_OZHXbUNb4VF3xp4K?^ClAfYs3ga~=22HO$@$o9HORRC=v@{LcaMs>7@<#Vm-Iu{6 z5@=mnDAvUnn$MhcDa-kb#{Gr)@~zxuzV z7$wXHtUHfNXb90daH@&)-#>KU_YMgRQN_t#43QdoDH%o>6Z@3|_+a&)=eO*=+lE>Vi1YAe$&Cy+Fr3;KLufTimK>AZ^d1{p%tkx&MZYWBqk(NUXGfa?5`x41;<1A@_Jc!vcHWi+nQ z!8y-6o;x$mAYFKxJFgqoJkC&=-t02u<}T8=r&znh-@;=}-XtlMxU_)<_8CdWi=cp?}tpAmKq5a3o)j>%% zn@p^P`*3oy7Lp6p^Ct#e06=qQwx$ua#i#woDWiMAJt>mL{zr@&=QTgK~ zJq*48&6J)twz^uUon*%3AGd)Ml$ZkD6)5zPdu3wxbC){3++M%n6m#b0dx1B@-WeIv zTuSyrXBNC%deUkfv>z8TOb{&&-cu4-ve&&M4z81ut@B z;l}&$KCzbf^%hUhg^xqecKR?WrO$cl;9_T5GA6UO>4tXp_->tGZ1jNVPm#a*P-sk8 z3h+Fp9g@vy&C~F^U+GzCD|cU&JwJI|f|c7@&I4acI@VZ7Pa8x1=Wio>h*zsVEq@Ma6Qa@n9OiH8;3NhE`p>~mz;;h9qKxHmszM<%6iRJLt-n`hek zcesUU!{8-_Z+%KJ&;kHb%MdLpem-*4Q4cWIgUFlQ&Vk@uM!o z+guXPZ0{Ae3!UB9=x6(jmzm-_E}TZ}ve(;%ScR2vz(rp|=i?~)^~SDr^`ty3E!vWF zaepTYPqWVN`uTFDpF~=B9_&pE9&FPO!B-8Mz(q%xlvtq&k)14`s%2qiQ`xP#FsBKu z(bslX=PlTJY<%}xF?54mmfWK01}gArB&=|F`wwpeO+%bHanJoSd3)Z+}3D&yt z^>umjqv``%j>pRqq0-dpxgH?n&F-BCq7WC+(UJh)xF0c>-x#wf@8+ILFfZlTf~$Kl ze^NGM4gcpqMMukje)8Egj83(ZjT^j7+H!Ul6NBunSUlTq<>7ihW&9SK_NiJwA*R*- zIhk{i`DMq+LkqXBgG=Z0$}vgIi+KboHow8*7wO2nY+qlwGi8nx++Te-qR`i>HlsI8 z=L1^0Wz)v8FQ?A8=&T~PlNUkZgv9!yE~>-_jN$c?Vd(%1)wuF&`3@2 z9Msm@?iNa-OX!jpE=GqU9IY#PclS?%o7jIPC?e6hQT6vz5#QMuz1Z7bN=kJ7{#b$6 z#tn4_ZjJQUQ<2;Sv?5`52_oG{{a*s~4F1mnADI80QF0&DmW16cn0TA*|Cr$jECOx! zSLrUp>pcG79v;O-y4OGDzjLK6Ms7>mJxWS+ZvrYq!s#-Uqje|mo;veA!Tr`b>y8a9 zRO7!6wpFrwg%a=i;I=QKWp^Pd(!E^<`;VRzf3!&0U5bfyQ}1}!`?S{Hv)$bH#s7zO zs~QlfCcb|ZPL#a6nw;R)uk|aQAUu^UMmfMp?SE^ko5QXM`Tw`g|C@l~P5yphG0I;n z{syo8=4qzG^?ypu zu}|Axiad<0Nc=~GgJS1#Om-d;yw z_`(PH=?|7h@;!Y2v|@=wHiBy3*FtnugLmrQq|YTLvUgaMu{E}z{j=(n!%uISNnd8E zd=N7(Y$jXU>QC(MX?=etp2^zp*m?XbRrmgK=<}u=Dt`sKlG=dw{B# zsyzMY0wWgu6TdG&O|<&uM`zVhA`d6!`6wEfRB%6bz17fX{@1-0fe@Eq$+S)*+}6}Jx> zzHYwm98wjYQ?yG#$Jr=2?nm_a>N_Pq7aoXbnO>a26CZDq)$Vo#TzpD8_~5Sz<1eao?(855xGR3MY-R`h9})s`m+SjCVr5k_1vxTD zBIBhwe;&$b!qe)VPx9hWR1Ey734kiM3$CmjRr_4NE4H<)F^|XUr zVxNb~190B`%^JXh#n0xH9`r8*Ho8U|y}!{k@WhlZIH=&$n07Ex166kL#`K<5g3+IU zgmko;!qq41j9P9OLPxBzaS4Db)z;%au&kS*1;7zQ*IPP(jvurlQGQ~JSCTY;=Dput>+xgtYY;AnTw%?JA+u3VZD0}Nv@Q01HRgU!~dH*YEXlj56Q`+*m13n z(s=s|kum-aJAL?U+6qZT|r zl#e&2L+A1aN3vQ>qut6Gn?&P%B0o;DyPT~VL-VL(s^1UCX&M(a?2guJ|3Ht(q@XOw!_@lt)6X-4P`Kk6#G)D z!PEwrsxhaY0G|-o9IP$RGsHYZt{RJRehF4QGO5tw8GyBHPbAmaaQk^m^^No}_b@1eEG(5BfVg-TQf5^+o@s*9K-$tpn%-QC=Qc#RmI{(iowYr}(2jFUGDVp09tjexjO zf*9=3C(Whzyv$uV`2s=CI&GD{Gq_L>J2kq}0pqCuaX^~XlyN!z7;7Wb_EKfALYr0N z`f(McodsOA6v>j`TDI4bdB$ngy1;tz18wrlwUAbGb? zyRmZe!p^QjLh+#_o<_@m-4Bq}yO|@-#xYDr&l;|H1KVIhEt6=Bb>}J?7$>qj7%laQ zRt>hYg2mnR@sK#ihAsO3)zl*5C;R-;n3ZqsUOy$&uJyreOgU=0*~xo7s>XrC?3>#U zknt;t10l)*LXuAb4zv*4e_k$$sGnR%-Mrlx`2S<=8=!P&x;5Ljb-MesZM#p~wr$%u zZQHi(K5g5!ZF~Cr{{P=(LYUpv@B4aQjIKcHjVp?(rXqH60&8&c zG$L=UX3VMGqm&rQ%ml3bp`#{#c>!a3`8+Cb?_$E|F{F|d_r?i~#noAtu)c#iy?c{b zxQ{#KOA`GT3%4LgH!dUgg!Kc=*@JJ&v4_j??O#=sO+=Ibs@l#a(DrxLf1a>UGZjPg z?^XYjKE_xu_Lp?6te;xAe@VZMIKFiqwI}+fYv-KLX&{+0i2f%D%j z712&UVtO$@Pi-9~%p_LEALm7WBNo3eU~B%%oJ@P#=o>gO@qU3PC+i`gwbvv|njF|U zjW|7ol&ja62+K(C9;4NAqg&i3yDYww(oW&&;&lPlSoJ!>V)eY&#I`<_R`)>XxE&u&Rac2LmqIV`$;k?GIWS363{wENh6^T_{9%Kyi;_=pTKR3EJQ|f0^W>#}I60`}y(3pv z>fb+gsbqSF7-x-LSg9$1MKKxG)XP=*h!mR$b**sQq! z71i2~vMdf%wVS7!P50rP17^6K&MEa|=PTpALWkcGa;AeQ?0(>nrF_Q2I0>TUhYef< zwo~Bx0N&4~*uwJe%1~&{p>~au%Fu9iNG+P<#s0vm0Bdwdi``#KtySpK7Q4IiA2j~( zw(xu7f^T!z1{hP-hI(f{59R;tZ^aj&N}!9Rf--b{RQ=|Dr9Zmmy6wbOtDqX7Yt+q@ zS{OnC;{0kqPru&TClf|!Ic2)nxj_4kIVENPORZ5gfoJ?T>O;Jsoi7J2c zRs1?nYGDScQL5QMY7PQuf@;#RuKw9w(tDgVzDVVa>f9XAXv|;E*G`n#Gy@A86Z^p<^{a0+}pdj;7_GWsn>I=FSZC=viF`xMRg_QmWByEuRU+5 z0o&Glv4OX<7?=)ErvVwR1_`RRt=tQw@{4~FxW$DR;$_dlJ8LamFlXbot=(?xOuOTy zFi5YAmVj~P6v=dLMhWBNMr2<_g{JpAXu|Bcq>To&5iq>w&=%pd7BJiwFCpn}{>k7; zJdd*dP4B#TsWK}?SH>nVXzW;!qJF*wz6!1`UervZYGFZZ_+08&j%@z*9V(Xk`Jq-Y zm}`p)m6fZgE%z7A@$!Pp`igrr{WPYhEK&qjuHpEg67U6@ztJ%M2_+Y7laM&!;BtFa z3waq0kn{PJ`;Y5$<3tD$t;YUU&Qz#;jGNqZckZPVMUhJY!UrV} z=tU8oy4eL*ROg{I8+r-;!d5RVb5ietm42G$H#!=j`?RL@jgG=-v103dqoXh?DjK@q=qQXTdb(bxE_ViCqsc~% zl0X$*xLR|YZcJcB!6mx(&8hPebS?zy^o2jUq>*!LOt_}r2KDeSWj+H1NyA&i&nOjvFlUMulxK~`dGvM^637FUqY?Tzb}sl_EPENYeOY# zfVLE-h6U<0Y@F0ph(Ib`OoMYSP*XG<6Ne)}|eZIsPi==#^VN1Tnc$-AmI|Rhpj+i=`^F+EZ*ufK$Mp9km15=>5v7zWs#eB~WEV%C z3*7mYMRcAgW1q7&tfLH_9~}r1{uj7a<#&G3p{h+*UC)=z-ZIchunlps7FTfl@sXqT ztv)}-`Oer^Q4K0>+sT{DXG0yl!}Di)8dGsn#Y*_sCHnE|ES*pD9ZNhX>QJ$TZyP~M0dha1hGw6cI5yR_flHAviI!#&fp`JZ>=#WuS2N~Fe*E=B{`$?mQvAx{uo49xS`d)`Kf3rjfT_u+8 zT{MwISmE0SR$^daGrqgn94&TT*upk(+h8r?;jwcGzq0e4mO0gHVKD*S^HCl=i0I5D z&g)c`^2nszd&TH;m0ruG&RXr6I~DclcKDd7`Jf*E<}`N6d9PgdbuT&v(Nb4<+S(VC z3%4m(W`}J;i8@JJTRm|~+wHmkRhmp}(P0(mU$ZbU_PJx3%x^7N?QswhC zKqLGTrxfjnBrQ)cay$wt2aDe{(EB^Y=#VdIZHDvF#^>p=_0gEWWHR4cWW9arsac%y zoq?)-F;=2WY~mA(KzWTA(uO4x>QqBYX9u*&$rLdiLvhZ1;HhI1mgWJ|l&$$EZD^!m z;y_gwrH_fsB&dg*i1~cwF!5e#hPCwN*&5lOw#mU)l8EZrTRy(;^rJ}v<%@}AUvFKf zaQdGbm@X1-a}*IAeaH@_cVrs7=QmR+NkazT{?GmO(+zqT@~UghTXStzP|v%NhdT>p zGTytpjPBeST&K}@f?RvUq9c+C^^T(FH5ZPF$x67rfj6A~F&+8I*{~LVdxLYU7b~`| zbndA*Bbz#OOslVXXLn=yIqRjt!5|KbK{6=<2X$$1m5!<3DmapNqFX+SJSM-hI&WiI zmU%x%Hc$X=!;S$j=EOe4*qpj-dNpOYNx~p7CJwsxi4)n|;K!#NarUW)<8@3GvQngQ zylddxiWS&z6wWhEFh?7dw2>;JO3&5#KDhQPwM5z7!Z|1%TW4iI6j?NtAWo zq((j zX6btbhJtJ9#3fE>^uOc(TGR>82?Y7Ij;1c5h*@-_F`5}DppsXJ#CY7Ljy~amIutfv zAHI0tqwxxKyoSbAYt;(OGM+2Yezc}+3hVzmvupZ0m?^18!2`X8bp=JPcVUM{MAV_! z<(Jf)$O?^gilAAsH(KNR2nyg^+%?%{&`v*NnV{b>N=>g*xGG?KV1+Lmy@*hikv@(O z&25Iwno)_zyIp@XxosZ60%+=fpba=O{sjui)iC{QrYBC$L;AMOrmJ$7WJMx?H@Q*) zJeb+$X2fY@B$-c*9vWx~8s6nZ`ht|G!;0f6UMC23s4!4oq)3UM7I%^gp3WcR^h?*Y zu;nOfgu3(C2UsC7rxLIg)sm(6$Lo+TfUl-uDdNelkMp0qrNpenmB31tETWj`2xT2f z(8zd`goOoVz#U>Uo>C51lQe6nW`^t7nkThoww7|T!3Z+f73T%P7jI+>^?IJjbf5|{ zZYCZ462tsV5Is^}ciW}I=hHO_c7`S~bo)YB#*QXkJGf17u25gPjbDD zf6AJ867ISuqKniMSFs;sexQ(sJ26;{(nXaA$Cws%-DZRa9k$M-U{AQ@!>*gEST|U( zu0~>CLjR5554-ONaab4_s{QjAi8qjaDw>j2%sf`6)IP=bAi@=^BkH#TR#pEXRTd6k zF$iNy&)xBlAj%O3eR|TQt9~rD+NuoICFu%m(nS%{MN(GErwvo<%^e2Y)@NFWTb;xG zuJI9{)c7w3(k~k`Dqu+8xLvWNd7by>Mr1$4w2RM#7NdKHP)h?a>b7c z>)?J4Ny*dBc<0|*3??|1^d-MCZ1D5GUQtG8_T%JdC52S|$3sgFc#ZVo!g8FBB(IYnqEfea^TPd3hHvPFF49Is@%E7 zXrB$)b~MU0Db(^={4_3PBn*VUuRQlbh9K=ADI=KSAZn_el<|5DCf*Fpp+1r@3nXEB zK&({nFo~XFJYAg_#tKnqxR__%e_P|k@R3@$g@7{ikBzngY8S(QNMYX`GK0SXQn&(Z zHZtpPf9RZND?hg_7yO!X`wTGhJW%Jl14h%n=#56VXb>fcF%#X@OeQx=MpOmjx0xR0 zC@-JN)`&F`cfqH9xB%!->MgT`q9>Kfvze6*Ll7~C$_TLWw7 zpIL1&Udg&D5W52GEmTr?021X|>JvMvuD_^20s&?A6$np#jk{^K>S zC15$;+#5OZiL~ZoEF)~}^7x%2rAc*V9E&{Mi(oXLmNIm8UhDi!QrD2rt)G!#lXMqc z@EsM=N2-4d;RY}CSw`^BQZZ5q+G7dHV+qS+iST2I@?(kdV~O))Nzh|SlCh!$qrFCv zdYT;d#6OP83NaUEBh1Z&8yjT)v0gTnCO!VQ6<3y;J4fA}ukqfO>zBg6@0*_hF3bX# z6;|6OHL-h8)-s#$mgO6p6q}VXibbBgC8SaRHp2*Kc$o?aUm|;+YZ~Woj!2{ng{)iw z=x(Q-7v8ON3tYt=rtZY|Ww_kLNu3Zj=n*Kfil3M3>PM-EFLa{{Qm>NZ@bb{6xFK__ zL550p{m@BKU&Mhiz(KL71d%ZX1++?=A*+A>RU^IeHGFRbSP6y+rq&QeINzE6urGuX zfvim&m2dwlg-Dq)v{^>B9(Ew%PjmLO{^C~RDaZh}dBSH>A%%mKU?Cw+wsH%FzfQaL z%9GY_`Al0c!Ee~1^b^(0YbM+Y>%*%|uCycy`pInGT;Xw<=Zi2Q!_EqCaUFOKbwM*f z+Uk7N`Uer+4Mze+sJK53>JXr3;PWbzNlYiS3*$w7MyJE`R;|ltb5Oky0u$Yf{h|ZT5PX80LXT zLb#nQJ;=yGR0zAS(@OW}jsW&F#P#cIJ6cOCOTn*dMnqq;HDZ?30*_i4l+cICc0Os; zh14u}y9dI!?%{~J1M>Uc%`y@1!Ic3P6PNrZgiSX@fJ0w6!7h>=3!(&?HTtq}PHp=T zyYo;J^qV6B>glPdd}>#U2y~BW&Ah3%zGnuMl5Q~d<_qxAJB7Id4&=~Np-u->%y~Mx z{FVJwre*NhjqH|4To*TRwJ z;K$ZcrL@~Uf&kT^zGC74S$V+S$@%0`fnrqJ#tc1ac|m&%C77l{=0Iww7D5xXW%ITT zy39RFbi&9Ha-ar=J*PA%gsN~MrA=5%RT5fxzhWj&hn*JkF=hRmL2SUh5p ziIOz(1?800<3;Ys2fJyK9);zbD_3o!?nhvoRpNB$j|nEjgZf?DV$8$*(edyK9{G}M z@;BiSQ-^t!dcupRkSU-!HmTjP{nfMsRF#PX?{t>zVLn}q#k+gAz+pAizNU+eXYnM^h_S~WMJqVUaEQ9r%oCcLi%`h%S!j9VQVhxXh(QRzX z1t(%pu|X&3L4PnEm36p`VT)JHCAt|QMh>4kXP=IXGKXG#>uUAxaoM#}tT-r&kYG(R zqV+>{#OotjMm&+pkcP~nN!N{B%RREKj;G!Lm#pb_)x`ES=)xRedjHSr1Lr?oUl;Fg z9cAr^dTvAy3)F7am)+%SQeH;zo*6=13wVQ!Uu|DI<)T~K$qSTtnkr788Z)9TT;Aror;AmrSL~H+#BQqlhS|e*(Q(Gf_GaCmhBL@dP z6Qh69+-RKXb?9{HX#Wy{^34q5ZxI)hDy`&z008(v0046TzeJcC=@}Z?JJ6Ur*jQV| z^2_wnp$uISc?K7mP((->BEUIWy3(iBkb%<_I?7^JOK32eKVMb>=L@~LyIp;JUc5DD zU!awtXBD#J<~l4YnyQtta+$0Da7>;hzkD|*jj#a~Ls6|15B4KiU+@$Mgs?6I3O)}g zfuKA%!yAUGAp)&hL}G#4@EktX8SYf+1*|9&A4%nGd(%gWK-^-m3dqE<zi>Z5Z(%ld1%CVJUc1}F(b7~^=}B%H2+ zh@rdXI%rDJM%-!5lbE)6KJMK2nc=;yo58TboUx$$cyf8V)~pxnSesp5_AfaMs)e&)`-1$*^mBx#m1=s9a zt-QE=x(+W0haj{V05Lml)wNAq!Ga!k`Batl@H7K3`ZJyoVUDexMU|8LoVdz!jD?IHp3 zuzk*50>&ymKU`x$G$4_3Is<}0pkr*D^E}u|NQm}Lz6gA{0Bzm>pf{!!fv;9*r}DH4e02B6}la8}lA+tk`u% z%}n|X7$?N)#6E-bY?wB^`jm-B?gSTE{$q^+ST)kNO>yKyQsTygbvW^F!Pxb>b#=oeDNnGwSu1WyqC@5XjNH`uYWd$W2kpe`+5&|j{u5r#;w z>5u}lI~5U$%8cy_!fN0Q&yWox4k$j*cXakt!10UVZqp9hbg9u_j`Q_ZNFs$mS)s5s z^@pUGb>=20vw%!dKrj%Vk!SEP-UwNY0e+M>Ky{u&X_2(K9W0HE^$pUV3B$SpIMoM6 za<@bA?0TsxPw@RPf0|Z%`Px?iSX!KxpIbAxJXmT@EO9&?C17$%=o|`;S9BX!h2Mz| zpj*|dN8;lSkAVHjSI7LPoGT4sd3N?(9p8cerK|tybj*Ufx=By~09PCU0KWfmr~gYi zU#M-^V2L33L??Xd2?nl;qpTFjcu_csMy4%8#P8>p<{el^t-V@5wY8f_mcL(RuDoq` z>vpp_DGtaO^B$f(t*xxI`eg9}zgm274bsK2TxOkE>g`iGS7zrZefe&VoJ8~9OS^Nk z4Y~PG_K1Qk^#;(%!buqy2)Tx`rW{iV9dKN`&x2x^?G-4av52{oS2EhCal-6G%IXLG zK_=o3dS5l9!S8McVDNXjSOV!Z9xQ*6 z+U^AU=2l^BUrb=OiR)pZ<5z?FLVR^#+5u5~^0s|T!}6?cXf)m>HX#~eJ|mO0U26N- zF?wdXt5<)@WyuacmVNV=@4RHT7e8H}AksDObtz#INWtI_$7UAlGjuFn-MY+8E z_hc`SX=wKdT8%yIRU`de4Pyqsofb<;}K%I|VY7gBi_6QgHNiK+>>g-PJwhRNJ$_^ibw#fS{(Y?Wf16v09u zmAZfR{5ktV{Xt2%;g9+UUAR*Hp|tjoQ;`yxTDfS|Ek1sUbA3L%+6Z|IqF5Ahf;a07 zry3suvJ50KN7?4&E^AMVFS)XF@9af0EVVVHV?w!WGsLLfD9a{UdxXg;Rt)$4N1{pldVJu)7ywPq02YK|MSiGOwk|&!$X*G^F zD{wc$YM6QCWQQqSu)J4CQi4Emb0p5gy(%E4nQKE>rF_65+1c#^A%=o+DelBFztX zKYDdE5f;3Zj1nW0J$45!`}1O!c{(T?HZ+pgV%~U5P}5MBk(TN-8J|_67JC$f!@t7t z1cZ!ignyCq;tas5q0SUGqr6dgiECKLX{ORVpg!bpCCB<^W^mw;uiC4A9Yd zpz%_p`5J9vZsI0bd$%wi58SBLoNM(F!ANpqVo&SsMB0vpq&oyMCx}&-#F#qlvPFAKYUKsrC}>7_*4AxQ-f5~x*cBdsm_jhnPXVccIm2^@kD($`!0=#tlR5o+!VjDs!crdRbYIasm0L-N)WP3(^jh}tt z{YCckDRp8*Y>((>Q(AV*Wrf?&!~g+b$EDa)K*i_%-v;_0Asx-^H-tk$8Rcd2?pIV6j@GnpO8x(!!6EBfC~?ZB4 zP+YR6P({0|5(8<#4S(*pgFHnjUrh}cT15}<^S}g^w2n3BI))^>RMh8zX!eaeNMzJk zvf&|$O{>Lu*2D(XJ$r|4j-NsQW&8i?_kw)G!Za`dfK_q;0KxyKe*c&KUr5ujSz|%y z-h#g8#9@G0_MH^<=dq$4J8xiCCKbkUf$x)@o?SU4h{X~kwhQ)t+K8>QJc_1Txs5p- ziFF;?ix%0uDe=+i0(#|qeSq34ZMc(GF@YvDad5e3#7X?>KDilL%a)Fok=X&>BtFK0 z5ppDyggF|`9f@dw;QlipXhKf$1jYl$2_RsVF+bX?kmf$iK}g!#hXM906tj*<6WRm# zsv)!n*hCCSd)%Kt{19z#awffSf&)$3ah*Vb<*^-5T|&Idb}$S*b1ik4maF^y1yB zkpkNj#XKn<&N`@kD9|hk7ae&AuWO0m#GE;?{%5p$>%^0c+SWv*o@*>R@SkG63K-2# zYEDahyVzo6rsO$BMgzuZyiPnQ!dZ(nAn&&$9e5p`+y$}D1|-~4yx1{}6SVh7c)bM0 z`h2DMYMZQrTj^nty$jhYvs=d?;cMU&_fl~Z6VS*%2rD$}6u7(`@x2kkZ5imf`nti6 zSb|B!&Gfm7B% zG>lHPK&^!c_M8YGftFOXb#z&0XJFe7Cov!gU`QZh`Fju#q}$j92S`lF^e0k7)Kf_2UkJ4t`^zN;mR)==7Aqd4N#651AnY4 zo{kmB$Wj6P8s^)m2Z1HQIX0o`OQ(%{)IXD#>+yChCf1~cP*y;9V~+aU&{U22k&6{e zhoDYas@^CqP;F(@>BVZCkJ=Hh9OQ`j?ZOFPjA(aR`b4G45dqXrK_tX4qUO`dxcU!k zJC-(Lo@^;@`x`}g;GouawRJX{1-%^OgOLRyxfYr!Q!yrX^y|o`O!K#f5=~v=bWB#z z#=w~gfM+yIFnO%_fGdEZICyro^fE*+T`YWVWil5LTqWM4GjqG+VNbzVhQ`5_Z2oqf?ZGNM>?5?B=-Ry^)8rFc~K zdfi!h0yufzlS@HTDCU+=_8cg$(=|B4*bv|iZ-`LYuaN%$2w?>h_`yXwh17dwi_Ui= z-$Ij5;fEeczK$^{wWNk{C*lhxQRSytKK(kHxAXmppc$Wq(I$iP0{KHyJrxQaz6`=%)+|YNzMd@~@hEn9q2Hl1EUvUwS_>g033^Ppm1_t3|S|{d!ym&75xJ z`n2h2$(rl)B?XsNW*0iJeN;Ak#N*-!^lTI=!kGC9NK%${@3(ufN(ch;&h zC+%B8Qs=n>svVyaJ76Xa&~rrIW>)t_a=-yg|^Mbm2Erd>Hm35LI;`j$~ zj3H-7ddG3RmjJ$(VK;F@({n_yc?8w=zKws8pl60_lsX8wt@-~@mgya`;0de#PVq!= zPKb1C4b)c<(xAXJjpuof#AM!yV%uP%LYtawq`LM1JNBUP*h!BGd*y(+HwsnSa;ZMQ zkHRI%6AsAyn7mZIxG{Kj>}~SZzuElAjE_dEGp}oEgPc zG_JSCbIC@r?a3gl498HW0ao|Y7r?&&j358Sm!bPVw|!=kGXE92_=_9&RPfBdK^I*A z18)D>Z}}T^2EXQn+{!(1Td2+LL4ghgu# z4*w80AXfW)gKeTvl9wO}NlAElALyx1Ng8}>O^6YzGfTAUy(qO|6cZEYx=;*u?nm?Y z+^I;oSTAII8Ys{FA^vn&fw8>8;X~^uq7JJ%2EVVYd)M~8acpXUlQty9vs!15EcYn4 z09*5NpsO+zD>(QjT;Me0uT0(0BdIj7#j>>(f0KnlXOg$Mq+CAAhst*cYE~=ni;3Oc z0p@>$7C*ABut&_l9haT$|LC~<)!mOg!l)s%0022QfB^p&j_AJ+-oMN)%ICW0h+xY7s)SrUJyHSB`oh4S=oWOB0RK@wFtAGEfGW%4;D;&p1sN}Gs<`%@h`cn*Tp`RULA8FDf15To8$3c?a+de(J zVY9gbNN-MjzNTLHJoKF60v|TXGC)nZj5P;_kq3+es6RbmH2izpF>ewKgNh|7d-ybsS3?+1vOwQ|m>CErkVv3O@lyzTj`Kk; zN6>~=5%v`5>vILUEXx-pO1h7kaT@LZ$Wb3j{nTk<1ofM?1d5nK&obPVF6Mr~OlW2< zo;8!kYT}cHp@#A}Oj@zzktqmqm^fl$Ob;&o0eTaPeZmYp_uqeIz0z6ZMDL^VapHa}8U*(kw5pvbrxf-<9Hw z9_7@Lpkg$1!?8=RkFH}GVP=iuTe6HQ&$U6iAD)ZJBQ?YXX^%om$qPwFw4nhjic;MS z&zk+dcGE068321_cL(Z1*f8FE&W{rdkmzJ?P|tKX$LA>AbAmY7Vv8Igm+BBX?U$#V=dWFyU(0zy}R;aPHXlR98F8W zUW~cRJi=~V7>RyH%J)I`bc?_14+In% zm#fF*5EU^gM}&I`7CG{khlS4uSbR>00!O*!)5nYmeT~r!`1PF|+u4M_dDg|^h zO)}=hbKA}f+4$wMyF@Ibr=X^NdrY3rOOXmE1m(Bh&jQcI1#zfL2hv*+41`21&gq(O zTY#qR+nY5bBZRe52+A&umP{axa;n##*+qvi*z5e;dc88mtbV;7`8ua3?u);||lohDUN?cVDvX+sAN&jlH{v~tXxTT`2LZhlPL2jf<*74@kE_O&lK zZrgo9!yh%dMMnQnT@kwH6-LCwEvVFYnoPn~d15H){vlU%a;J$Tam>@L{nfG|ZJVc> z5xI39_cOzu(GRsI*Y;Aslj%zHn2hrCm)#*6=q}$bq|2khAP~q4PR>ACGeJo#|T;Sv9r1|$BJ}f@~x(2Ruq`3;B#(X zR){t)Cgspaajjmqt`vXgu0#}n+D(?knwe&VWn-b@vYo_)a2U-NB;y)Zq(Dwe$`Mm} zizh&3iwps^O4|XI1))haAZsCa=W?FpNU`j(8tn|$h2NcRaW}YBQIckB2t7nq?E)S2 zKxp?(WT6Z}HMLUjHTJxdREDUY38q0bXYGL@<&VA-ynALA2`!u}i10mkZCD2V^MS|Q z`JFvO8fWSGAyk~+*>JYWJ*r4@h2_&_EWkqb`Zg9$jrTh#hz*&*RtP)=&SX`5^Z+I* zM2lsYMA#r3yo7C-`K2SclMJAVANn#YoV6vzcvAc!izk511ZRW~;+S7_84{fi%Ym4{ z0E9F?NzEZU1XL_K*8_IK?35^bN;G$tlYu&pqf`Pky)I%uACXwPGJb_?Sy4y*{@D02ZG-H%pkB^H%9 zZ_b+h`l#QekE7co`4ET@$Z^t>B6$&H)3I*9@@QugASTRts`=3fXX=wvwHE6KJEY_z z>ayE!hZq~vF$LOV&RzSD zLuMJcmOCU{d#|D(^Vcsno71C-sxs~2z1__=z1mim;$+T$*Oa={Trmn&vo2@rW0W;W z83hpYjVvp{C*kPr=_=WqqSIx{dxgBn6x3x;=JID@kzr-?6*OSyKGdgS;2K=K3dJ2C z71=q5u^Rq534bQZqoSs$;~M~8w>2F4VcRg{0E>N87x(FrmaDLMFG3Dqc)4Cn%z6`; ze-Y;4t2Wscg|F&lE-?1J_>6$KW+?{;K-XchvWJ-Rw=&GY#)Au@S1Sm_vKTn=n~A8f z3`mLa<@locDJPPGbi9-qS(DPiQ;xVYzK>lXR0m^1k2)rz|C~o|b@Z}=(1&XWXgS){ zp&#!nr~_9qLBm&(Z{^IfkvzQkT$%vR<}&?IV_kui9lcEh!3lLHSeVS@)q}?_?>p`g zED_@vSn_#>SR_JSfK2(2o+rPdqzFq82#sQM>z0gm7@yV?V>ygkErD|DL$K8ODF2H-(k3pn3r&AYc7A6xAvMH0|Sk_dD=#SD%Ne&S~f&gXVF# z81aT`kF6>3je5jsi?q6+jH|&Zfqh`A4+}>+Ui}ouE@XR~uF5fXv{nbbI4n<^sL)rD z6+t!TcHr7(u8(8AuM|$vpI)!_Sn46boLA)L1zTRi-jTQC z@Fex~iTp!qzjy$`g-*@0$j{?g5^ifZQ>dN5==*!!>bKXou|P6So>8FB;8SH|)n;*M zCc}Dm8i$yY?5QEOK8OqKXalw)dE@YYcZ=X(8;e0&wIOBE5Itoq#HQj;mi=5+J z(I*u(yJzq?jDCr_kejL|-1fqIJz;$^Cm9P@N5vMARtQeYgx;}eMb=7SRd!xJ-L=WD zm4^=nYkyseG=*Mjj7W=c>}dB0zgO3A4i)<%;sPT??^{k1wq-ISuNw!|)v?S!zvR5` zBrVqK#SFL#7o9QBtVX5_Fh#AKOetVW0eTd4Jjhh4rr!EeFQ&nRfyD>M@{1GaK;Uav6%nyT0s88Ve|y-_GtWM90!!Jo_f z8(?xn-hJ*o{%%I$?Ye8)J#rbidt}+&E_9blOFOz=yMV@6d=B5&#yutKfdt$flqiV> z4f#Dl_dLxCO8Z$$f+7kHF@p-yNPgcZL(4*78?n+XN)(m$qFH6C8(3iwsitD1HshTV zL1mBqt2e3WPOuodKqa|(_?31(&DIokjJ4(>g_8j9d2|{3mqjw zwN;08`k5%^xN>{D7}PimvQ8%*YawrFMGJ>Fb?8l=W>-vgAU!v4$_^WfkeYvTr z%tU=cV}Ap&$fY9(jLAOi3u4-US^SVx4>5Jrn$t>n^^qhx9eg=kA*<@Utx^*V?3(Z{ zq%5unT|k|&ZV66#?nD`AQ=QC@O*l}Wm-hHsJcI#U6+GgqD&u;StspZ-6lTZ7pcirt z?y>a}RQNF`H7I-vxBIXeDPpgy&qWgVktwe-%|z_?x8mKV^}mP+awFzf0b{;yym;hzqYQH`jn)s=AN!4j?AOoC6cak zjPcC+O=%|C#7`$v!w7}_yh34Adp!;ma1;4dQ1>F6t)~0caLpecdyW~*(i+fihvV$c zwZ`$PVn=0zg1f%23!E#noK@WOc$p|0sa#ETT6Dl0Dm>$b7^* zToJ1!FJtzP0qk%3XEcgdcZb7k=8oQXGNM6!H=nVid|Y)DIz3@?;}hc&BX7GuC*f&a zAp~3XXJz;Yk*>O1kFPp1PfZ?jpAke{BTVeckvM~=;??6D328)3s)hHP)1M#C)~WZ- zxZ@I;M(7GCSBu1z6#y&UmpkD^o1IP@qYQ6(FD?HYBAV{i#DR0G}yQ4r_5>n@i%p zU6?G>sF|^!Cu54em?C4}oaeR%;_8Hsa0Rsgp^l?p$2)-pvy;I&rTBN^l|mcw(`%}Q z+*lm1%vyxxY0sI&^p`9Lcdjap)`YCZFMVA9Y&R6oKJ#?H!NZqm9iHd zq{3%)xGYh0_(t-?=E~-shb+FOydCkkwm2v}+Qh(KgJ|RmOx>+|Fem&NAaJxy2(QN~ zO(rm2pOVDXAF^BsM+V_kt;l4*Hbh{E=b!K>w-2^n=4~l?<~Ellbq`-kY6@AJmbNh` z86-N}C02C5qVgR$ia(c)RLU;jWVlrTUf{Be-9(R5iuzUt9)PB8g}vKFxo%>yY5HKgMFilyaOC6 zcWZ$P#9+@WY2U^&PXqR$n|azoklB}?!6EkIM^b!RJgki}6C&G96KaAN^}HJ2z5Psi zwPjdTz<`FrhJ(Wrp(GBG$vX!;QZWH|omt7Hn@Xg7bu^}ew6XnQpwtfFET>#EGoZv+ zs;aTe^crYRq}l{kr{<^9de61wH*Gmx;_sN)an`Yl_$qaxCEtQ5v| zM)%V)P~1?Jv)vBrKE+r&NrVgbCo~lRm#d2>@f1_uJXq1eH## z-~e%KtIV>MGE{UMtt|JbT@rQ;JA(ezv!?JoRbz(I=Zs89kL}m*vm;C(WYvD$A8i~? zmofal3a#>kkCX04;njmYvpT`^FBqZKy#K}7J4AO9c73~H$N9&$opfy5wr$&1$2K~) zZQHhOJ30LfKE3Ch!TYUMlN!_>+*NDc_1jg~wP#&K3(nY!l}Gbdp}9YZF3U+AO6<8v zo9TUIGKs}=w+CGtsb+@XfE?ed6Vaayal?LYq9`Px5Vt0 zyAAQX^?U4R1+!X;oTMURarrNjykb+TF`=MHVJZtAh}?jjc~rEH++YM67iR z8zMDd=c^k`hUdN~h+T;paNBkaBZ95x1wUjVg!t(Sxz;n^_DI9jDmu9oNTay|S^$1) zJ_u|G#oTgNH~dj?O_U52-PS z=M$3=4^cHLh|lLw_ECeo*@YlDmf~d*P`)1PUZK8FbQn>rVuXDvGQ_cT`a`?>Oir zbp(;jjv9)cMamyT#;Rz|ur`2+8pGKj9B6qZ{}e9{7{cIdOzIBGI4gxGulq0INLJO` z1CX67{FJXT`bmZ_5VwusKyT6L&43ZH{C0L_KVWpqTzNpKyRmDB(~AcaG8DyDi0E?_R61H1D;kMTZZCG&%ki_BLs3dNJIe zt)QkknM3KooC_OHSCx20AtWp*)t|$*?xeDSymYu-`>IHLlYZUgt1>nUdYjc@ab9~p zjY9q5wd1T*u`%Xgg8yemQWOoQXbiMz`}m;8*vx>lYV)hU}~^C9}KnIw7^ zMZjo9%k$Iydrm3g4_lfI-$|p1U1KF(_`n5~vSpjbA>iY@+HHx%mY#RMJ3mstQTw6+ z*_LAOL9!Y()lK&h5Ien=4Z*Yuc|5!LfK^0!IFLf4lb^0yCB7JwtyfD@%+}kV&g;o6 zgK=IZ>RaDAy(MqHfKAi=aj+lO8Ii_1g_FC4>3Aw;#wAnxKzUK^+5)oCg|*8Vi`^t* zIj~oo5emCCIFL-{Bz6K(QyHtuOw>!A#ylx1S=h44>oP_vCEw>#Cs$*t1T}0IFGu?5 zW~h8kb*L}~?t8JiWrFz_2H?7b+nS&MB3dcyYw7L2d$BxHBzFuJCVadS;`@ zgiF+3(!JzIe?I6;YPoT0V2YIAM(L%%vAu7Y`gEr9nTjv08sl|?I%;(0nhLfE=F~6k z(?a?-Lb_htY4jHPKkl5l89<14<)g4PKQ^5(*aOVVC}~;4KIhAB%(jiJ}fG{_^QFn z2~|vCH=ifQbUlI~{^@yYh1BL(j(T-P?0Z2Jac6f5)E95qW8 zgOLhT>0iQfCzw^smeCfwWm%S);Ob*z{^WX#$AOV6W#tpRxn?!LOQG(Y&0K;X2=9vr zFVK&)5xLdiAUC=hP%7!e3vacu7)tw`(rD{UAhl60l4F8)12j9{47M%80SCYvz4Q&L zrE?=k{Z_IWj!)KP}kRHe7!G?PB!=STyNu5{!-ml9ZV-6`#5+qW`b;7=n(UO*F2 zI~-Fy|MK?;wBN0MK`Y_63X0bSc_iIkoxrrJN1cX4-jB0woAJc3GyGsv*eS7WuWMEpIum9Us}~OVZI_+-8qUxDMbq( z(_XZdM92jY&E=&+gbCgI<6>UwWF|!}>_SNJs7_4Tfl_IgAZ8p9@8=l;?a>T*1z?k~T8>;9QOiO@b7 zn|RyDSA*Fck*&*NZsbxB^o70#5gr0%?8GUbA{7`_(}ackjdT{4VcfvbQ{F z5aCu%newxnDHFesBDas0pbs9gxnCf?IC`K)0^@jx>O-&46|m1uAAx6C5S(v{Qx$lR z8rQ4=l52DsH%~w_&DyL5&sG^asdV%1HnYS`jKrt&+6X~hCcS9EZIo1Ku?XvnEEm;a zjqwFgP2#S>KiqiSylXnle*kwUYY6V}Y2*?L1zSaS?{-K$@xohd{SIyW19=sgWaVD7 zl3*9Nz}E*odhyqL`rrGscU}fO?{@>fkPPU)PCbs){*-eQItygKzqiye@k(-PV>}|K#UVL|NX?P*);4k(E<~^w!8Om~sk8U@mkna?+jv&Z0Td ztlZ=z$nUXWj_d)-SYF&%UUD$krJPL5)KhH06^geN)3Z#52LB$-K$0 zOB*tin)T{ni*5=bBi{1Y3D_(>Pa0hdZwQg@TpyKbt(1?4h4s*e<~6#^DqDj4g_Y&W z{iy9>h0@1Y3m{M|{*z3Tol&4iI12t%gZl*k+C3mw=f9%G+ncq(u++WQcka>!P_b2<+>%qv-Br>=ns6a zz!}Ao&TYrH>%Z3`^ge(Ox5KOO$!If2^mG_KA^h<6qz9bvgsI$zNZ0|}k>zugaB4XH zlxc9{3PHNaaeZBPi8c1RvQCUH<68$er-xTKGp%<|rKHJlv>jjUr;N3-`?yCN`^9 zF3W$W88B*DU`^@}(Xdr9pLb@{({n|aLA@}Fiqgl-69$ysr673ZtW-FmeYHVL>>YKV zOLzL*TL6P1q`5v-zz0LQgrOdF&sPYvb}R+wf>CTph^LUuX3VIw#7}kx;|dF?G8z^4 zYH2pih+NVzVSH8n#t*P+IvrO+`w)LuDK{ggOXhT_@|Qg24k-Are}l$&tjpbBuPxxet5 zL6i_)p=D`~RILvkhUNO7CbHvc*4K^evt%vqgbbLhx^4jM3%i)}pw~xl1#0r@P~=}E zaaKP>+af7Dc32T}!6d!@?V1|Y1p7l0q_trpWEw-TV&q-q9tBTj+_l_F_F}iSYu}m0 z$zO|O`7@RwH^m+H@ctG%hgc)R0l00)WSg5!Z-x^f(Xih7nXD4&o>0GJpurYbXQLcHW1seHERRDEOo zu{YalwTRiLJV7rguQ%QXrT>yQ`tLqWtfh{9GDGk7_W=kR+BD$!t?5aBYT0w`$NV|F zL5hG#7XO(WCYR1nPX~k1PDaNc3Ybxeyk==Mlfwx7${p=Vc*D#0XybLF0*8=qc#P-z zCwRUB6bJmir#`@UIe8Pt6CRBo?>spr{8*ODH0Gk2US|s#LI?;UKA1RG>P0DRtSx?L zio@s__YP8hvk3U)yNCo~!uY&TV1hf4k(L>uA}{;@F{L%0B6u!F|ET35M|BW~b{bucD? z7gLT}yX7BGYaJ+%`YHQqW4aQdZ@}MXw9gz%^4fw-zdFa3r>iavMxU3*?6wxNo9X@Z zIFz0~TH;>W!N_%;rmw9?yHKVZ1rl{lJ|Lt?|JV)=f+v4V zW1!WJhyfN=l#xtxT@#o(c3lM1-kdq|TpyKmZ@~guK^Xfdd66~2I{4+}?&h5x_I}sS zND>f!zPv}X<{CNk<}sV-5d2I#*VwqW@yPZWU4g7@gE-sFi8GwvTQ~)J_pcHGvvO4p zn-hFhm#(%tT{K7MiN!=Mo-2c5F)RMUPu#4d^t=HDCX)l_>Hu}&;$s}7&r{ZKD$U2k z0%wk!FTEb0bkOU)p{=7c@Aph?m00n!u9FGB;fQwp>D^cg1^D5`8y}%Kd?GuyjgT25 zy8tcndz^C5YH70#FFjkklkEcTwm*e>k~g@vdnk6@z}9Jv8Vzpj!xXzBB-LPIE9aG4 zy$;!X;V&C$!XdK*rUO|PBzmM5FnnF;btDX1B@APkG$GhO0g2lBf{4ywM6N7r=JjNO zxU*|k5<~O|MReEKk!beKL4Jygj6jM~ACcM@dRq~K@DEsCa@_9{{+QrWEJf|``xVjl}l%p%gS=3WE`F!N`U?E&9&(?_CxU1RSh!)yH%nCSqb7nMo)D$$ zg`C^wus-FKhOK*kkL;faHV#1auUjl7&ZnnB<-Yw}LCV~utf|o*28`<5;u#0U-Ifwv z7w8p|&GD-v=P!hfBx+35L+06_c*kWipvgzN;s*5cPqw_Ty-63+W)wjY>f#ZO61>_n-YOX>-yI@Y1mKwqL>0@OH?Ewpt(v(}E5j*=6rKwvW&n^_e_x(}BW2Jt{ zS&dq@;uJ5A{IJX65yu>E)lxaztFi5YI7gwybok-!^`{}{tU$4Jfpb#83$AA} z)<~o#4?O$CXtS*L4D^GfF>7f?OROjUYDLO@mlysfK3Paiw&OO|;ZBzK)h*Xw)%?FwP4aK5(VOwm`jfW(#>Qi;m7|bmW`XF~k&dzi!+z z#p$in?_GICWr4%`e)FqEp$&57svDyXUqey58+wJ-KnPdCg~k?alT_(z3J}@UZ`6e9 zc(5Z#Mc#yjUrHux#^U~!FB=tBRRLL$YW+zFgWdc~m!Hk{ zBvD7_xn|P~^XZ0z>J@l0=Bl0&=sqzNbN#CQ5em+|H%Gof>D$Tr>stxuS24q6iwdr> zB*||AMLTznfxkHm6!K3>2=A^7yghCLDg-%#Arj$Reg%2*cftzq`Bs(u>#kX_S8gi; zkM&NDv1;J4OWDL5m?MU6_z|$~f+*f_yANO9fO?qP4rGhBefn8u&$x|oXQLI!ZF@KOCg zz?q4=31J5zmOK#wA$6%&34$5O3h5&FM-nk3KbmF;GKqk$TkZZ+EDkxC(vH*ud0d-| z11Uk=l^jokFU*=eY_~Zzi`b3s53&xwl?4edXXzu>@qp!` zx2j>dy^HY|S_X!w7OQ?wpg?e%44w7zgYsr+9B4ERn58}*HSCa^$V#IveQuUQ6^OPl z4^28dehZe|aQcduGC)|2hzh4UKAheNav*Z!f+>_BUv5KRmG>ZzBrpo=c`Xdo37aTx zJb?G+uRbk>W$H_9J5stI8lTw3D!{yo`Hu>ZU0VIxqXn^qA)P=Kdx;4#!n1?|-#fFX zS=AdzO)Rf`wV9*sUOsHw zFZ(bPB^Tk@x_iS`P4+@ehfk!aQBQ=X>fB^;1#{K%*q4sZPA?YgsGtf|ElJD%bovPM zt;uo$_VUeUWP9$WeC>7)|2_2>auOf3wD__FvZU(60tfnP9~fW)EJT~&di4>1&*_9>3NV|G8(AJM`*e6@#BMD(_tjDFO z8)m#!l}W?^{oTCFbO27R|DZ6{wadXtY1`%wMuEat)q=Kpl~?wZ1J#!DkgegFlgIIo zEf-nWHfajw_PqdD^4`TP50{-%EJ#v}?0RxW=XCt(^>M;()@$JLYNpcxN-`0woIDEW z)|L=-NCkGgNbA~lnJM(CuN&Kf?0a7+$GkFUV9&WZHz9rfWZh}YWGxJ8 zxEjeSX~)mVBkIp0d`j_7FN0_OcSgP!)A&~=lo?0?5pmCL>r79z_wm)I`tGMhi1?yq zn9N+U5N102cwd+U-HMH@>kr-K3+7>8;3=F9-w?H7R;gW$%5Mx_o z&t?N$;Q;8mg3vj-DVj<`sGxM@fGxalc2UNm~IuymCmQRWzk(_dY(~ ze!hE*&xsr3Ln4j9u-|*2u-}g(>Vkq(bAOk)EsZ-ZlSBAz-N{N=nSqFL>F?ya>h-!-CmBerBCv0cDGHiKCZ z>U-m%<`avb^-|t{_v#~7lw`o4BRgHS(WD_@jb%g5gGhSk2{$4!X#$qIUSFqGQMNwA zEDq5c$)?A^XNuj5Fh0=$aD@7MK@fc{AbeZjpGjlOP~+lYvD4R}d6c-ebjApiD<5S> z1g(YgZ`f!ZBBy^`e+w-4B+F0R-lB?x1#?*W_FRH*GT&*>43Y=h2vbCR@U?w1KRNJf z&u1YC+Wa$FA9&jyJ<>hxzRNXIAu)FkcgJ5QxJpmxzm2d~=>`{ZSZ$*BsQ!$(ZvM<- zgfvEKABbmU^#|%crm*E2NDzdTUnjo+7I$E{!T4w16{fuI++n9#(B+fA{#^V2J%!?xXY_uhuld&P;B@44lia)_$#$gj87 zdJ8?+8x;baG4}oQN}!sskW>F-G?xDlMq{s&xDoY#FdAqeR8kdyxvxKyUL&-5IxEnk zSEnE7v<5NiGReoL4veJf99>ZV(<|}m|3AGFN{zmg*)hx|11!(%Q)CMoNTyzw{xW=t z31-!gEE|W@Zv530rwP>Ls1Irva=VapFx37nuTtC6{ouwTJ1ae_%trhF;Lu1BdH9sM>A^OvY5jnrF zqlb~1Tm|$Tr8uM~hsR)#DBDsn-V6!u8b?8Szn zhj1rRHGKDq)Hu*b4950VpKgSUPU4IU)wVyso=RsQZ5u`J5dMh@#AejH zkRvgQ5G3je93$`qctK|!cg~%PvHv;`GP9Cg66$x{3oVVbG1`TOy$1-hcWLrGn4P^< zTqKn$I&q2`|Ds9!5NWJMjfP*1i|ml}>tOswc9J|T)Eo+6L8bZ|)D;t&8S+z$be#Pr zl|s@h76n%lH>Q|z!hXu~j-lY?9H4~MA#01dPG2U3YBaEq zHSZ+0cVl=w=}k&`7+43y!UA9A4>!@K@!pZ6_EvhyE|=51!B z{KRl#9KQ5YgtMU%Uaw-PdIuX?EC3h&vb(P@z;W8>EUmj%|@-~#*&(&r?cH643ET=7yLh>Gy+&R5}NFr2VN$4Zl*%CP z<{x?xtbB?BRw|{#c3(>06~*CN0z@3Ky=+3)+z4VI(YYUUJn9G!nlU-H8@`#f4U{Uz01iU-~T`FKv*6WDX&1>TN^b3~_4>@xo&h%(?0djYn!p zrmK|b&i$bl{)3qGpq=}l<*S{?It0#Ax2Zn%dv?_C4kldUNw_?7lfGHL6YG3dh^45T zhDF$e>T-%kI)M`FM$0SZTuCkXtQ=l3N?HWOfLd^3-8|~DDiGFwOIS*AiYJXEd)5t9 z<>~)$ljo%DflKLMO?~blP{WPZx71{1vCtP3gEleik4|69gPYxndES4PI6j>t@KQx6 zeAFO)9)im1UrTq~!y{(TCNa(ij>pxd@ClbWq-6>%nUg_&$2>M+S-MIoWd_I##TJ(3 z+y%q4o0Ojvm%|GmBB4A>EsW>HC~IwCpM?b7Z?18KP;+5C3y+jF^qgFB`j(SAh*GWb zLFz%o=NJ4YQPgq;;Vc(}2sK-IFTq3fTFzoP<%nxDv&625$X_{w@^KZlbLd7A_c3MR zIeF$Zjb=Dlw~j@Et2SnUbR&G+G7)sW16g0pai=zUAixXspq)sZOJ^)1TMyA4LTElY zv0uYMTHf|eh-GlWbnlT2T{y_ag%M-`w{M2NhJ zJfNMEUh9wIw91pL2U$AQ`7o4-luA!vhXYhP7L|(ihqpO`>vZA*>*)@P6Mmr&cESV( zGx-VMAM1o|k=rK8SytO+`RC%8im|tZ&jKq9cf-^Zic3W7G)^F(@XzWW&azG$x8Owd zsYN0~fAyI-*3dT=4bCa=VC*5z(&!3OT(~kl88j#Q(0vz>rb1mjVgY3R?8fQz_DK(ZQ^hT7yZoy1*;@j zgcgR)QAY8BhOQHO)eq#v(hzdn^(e0Q4 zgi)qM+xil2K?sLH`kH5Uc|*sSn;h6>@5QRmO~A@PBalTwlt@%%XhA%7cI%%Zbe8jt z_szBNJ-aNE2mWyxbc$ktwQQ|KvFE5T_QMJ9;xzc5-86ilm|_Gshm5FV`>>uw4b}xW zcs?QT39{hok0o2U+uO4dj^xdhJYQL4rpy^@LdXq8W%}Gxgc(haH)kE(n3}36PG_A} zEzhXh_FM(-28dWSDyLB+?c<JAfyMKGba(2=Ud-QLBPc@r+AJliqojz}&2{tMh zO+hJA*~;3~bX%q82_JAAiV@hgbR}L2E*Gl?O)1#s)P@#2?qLbXna|Z!q&I|-Yu2oD zkfeoHJ~olwmz3Ldz{H%qzT0v1%M~mJO}{K>OU1Tu+~u$BPksv|WIm}4AaBRbWJYk` z?O7^L>XCCqTX$DB$+$%$Jmtzxf=6}fgj)QdnRsI^eR|Vm_;K9AoDOVL+6)UN5VD4|%)6;|QyA59$=pt>WG!st2M0L$%hG_R* zE8qRB5oe~+&5DDd#*hS2AH|ybuLK4yr)03*Nl2)a#jKWK*8L{{BMz)Yz?e3_g~c1; zx?jA9T^o3#4R&8CuFuC`QfY*W()ms4*kS^s5;s|yod)@Sp@3L4@7VttCST0ok~nZJ zL_e%9?K$yyND4ZP!*FZQO%?0+B=zc}ZM`9k|49m4|49nZAz5Z{TS<53>gljFn*K=& zd;UoZQPe#1Px}noH>5}$9J2nj*nr&XoM^{r%ZgOJB=MDz;utd2G5P382nT{c9r2h`1TS zVJ!(l8j;5gEQiV;UOI%?@7+R8h!Q7`&Un4d3O(dbu0^eQ`G_wWQkBp5Zy(KHrUji8 zU)&e@zLh)ow3;wFxV^0yVTPjyamC9sb9kav&%Q0WfpF;bffAf;x~7EDEUH()H<_#| zg+tWhk`PI5p;1JyFf1VaKA4PtCn@EX;~qb)GaLR07XM}H_@-rY$Cv$KVkGYBJLIze zUn`f(?@5OkN!QQIsqOj5bY(sir`!;i8CACJ+ zTJ6p1tD=WhZvZ!WQ7ry7;k)j@2JD!}R{YyZX_7~&{|}P1H(HzqJfauLkURfWbG$ieoR2z1hbPoU>1WTybiAZu8;+3 z?}EiUE3=NM8?qHG0fMO>Fd$~GD=pKNYDX7NjuXi!u();lzJ!{NF%3%x@v>FoX@RA=jm8%KJ#EEDH1@^<^=kI>k)bQOWu>OUlE69x!KespieAS= zzrueDk-)qq&E<3Zc~o=gf_xT!U%W`uq$&Ckbvov*o|V7>I~iZj&;6a~Of2i4PtK>a zCdxYW>8tqL|k`N|uX_>g0s4rtsc?-~drD;ArCg)}d9KQ`l#N&@+ z%9I3h_3CIZfOneE>HYCQNYljwMUy_loz2~wlS{=81-lnO)sOYL+!f4M3cK8)3H0_t zQ>g9AED$HOyp9>D&6s%Tl4SB!zK^-kG0^92kjIQZ^^;d#HGDbvL1EAH%mT(=4@mL~ z2}Dr}6D~$d&(Qp6YbyY8AP&V;#p70pH7eJ$fVRyx%#hCSO=q{&ab5F;@Rm*;{tOUU zWIxG}?zfH!txHVUd!+lu0hETw(1NmOZ2k-fx;Gb50NHQ|&rB|xfE`|j>>A%kuuEI= z9;{TUhNMFh==_&J;2bvF>0j^byr?{1$)^o~+=z-Hli7n6`_)qQ zpLFZ|d3#?!4;@AD_vadRzO03fcfeo@Z@CYycVQvjCNKQ)rcEcO*GJYE1xJ z2jsW~o}a!KhD>YPVu>vi^64=BatMBY!+3r}GI0b&_-J;>7Xo#QcHleG0>^g>N;j@S z-G8N7NgoqBc{HB-e#vZr6W(@%9w+TNY7Y2AJn8cerdbDX%WfVca}#%3f$z|@=G<6q z@#@aJA@6<;K3o0G?*YGU`PoB}EEBpFMhGpm;|$EztVH+4uyDmLXU;WT<}{&sHD{Kv z&|x@1pCBb*&n(NQo*V1Ohk*8!ZU~;7U4<9C!7n%6(4-AA4#0-SGe10dlO~DbMr@lw zI$;KT;fhrVA(3q)vlLQx%nRK%k_iKH@e`WpECK4h5Ts2v*8=N6YdYq$`(M-4~7N#@jFkQ6q7?I|VfYE?!E{WXIZ` ze}$@0$w|Wx^t{zvQAAi{$vAw@Da?sEvV>TR=oSkii-EXuWV)D?I8INGXWvvYOUU%% zO-Nx8?tpw`6Jhvx{&URBw0TN(e={<0;Nda5I@j5`W%Hz~dvnAxTAap-n+?0YV1(d< z>))Ia&?iq%M+Ft0DAaV4;zV&>iN$#5Rmcd%Lh^dPr8bAp6><~r4no#AkT~TMppG6l zHD$n;8_46xS}F@pyl2HFFr5oGkfPB+}7`T zm>n8OT?a7r$)ScIs@NQ}{1^w$Q%R7(OSyUPEn*6g%Di2a9;dK|&l7d13SNdd3FT(g zzFLfA3JheJ9RlE~Jye1;X=z~e6@~kTr?D{X&#j8u%dDzjyz|1vi?{y3ke< znMM<3Tw`bw`iHdEe7X6Z*GXZxJpIVOGtQtc!;p zBZI&JTctCB9U_G~-%Ug^{&>y#%ebkgoI@q|dWqA&@_pYk%>~ocsDp9Tr{|L&H>(l5 zfijxAD&yJffK*`hH8sZIja>jDA1ue(<`v|TJr zaDl~a-Jx8_%g+8STn}u-pX5n#)YZ#+-3UvsVKQ_9M--c!s0D767x%sdfavv;JecCI)XVl z``H9_V7_i+Q$+16NhQebIBA(013SCQK&^U3&z_H9kLFCHT|SqG>-r092PYdMKj3n%x8{#W^@SW34+H2_GWMLt|niLLZ@hz3t=O}2a_-I`!9fJuwfv;3S4S(IO zY@6)Zo;Dl~wl_xlC@E?M5aC!U3j5)c+ReJ%1vPY5oV|GB#yxBQ)ifjbA4ou4-c6nnyLBEm`EvSJ3f@lYT^7rh3p_!rbd zM|8mKf3>%Hguk4(2c5U`JZ?Oh;=d}>lYf4s(e+G{Dmm>XPjk}nYu5WplM5o`bp)sG z3aQ%G3ojgcIvQRu*m?ywL+Z?`8cHV(wT+7sHhxu$4m74f{vr!dD}_ zTm@S%f^}OF#=ZZ^h%lLvu1L}G@L6iE*)mlpPyudEhM)sD_$1;83AfXgN`+iPojCf0K*#W39d~6my=razh#b#G~Xw znNChh+BtBi$eisXXEu7=m^Zo-MWYL&ox~HiEjrv9oKc50=9JIBxg%KUW$O3q%5WA7! z&vY6KYDoAfP20J=_8fJ+N3*xdY;kCd?yNknm2of4@IsxRqzOoZzw9LNFsOW;XgW9W z8l{-m4&HEHk7Bn8TkMTC7KnPC-WCba zQ?1)y48eFI+}BljE4Eg6^Aks$oYY(t9AaYX5{caDPn=HIP*EuTG{&<~qX`rYS@4J< zDq2xCjfeh0uM2O(4`#k9#qma!Jwh$Zl;%LA^lIT;bwW}c+c#jdrwm2La(sy)3aA0i z13bO9zrAxskh#*bcZL$(OW%;nB>AN;FDe`-!*4?awBle zEo$#Cj|!I2h5=u?`$v0>Nm4SrblYz{VMem8+cj^M>v(=CBVMSjL8~@~CRZ7XT&T}U zsy3#mRGE@qXiP<_HW#y0St2htMJC&fud~{?U^jKkXzZa?Ip9`oHoMr4NRsFJp8Plz z)7N`8KaL||Sjm-+%9dxc6lL7=BX&6j(%Y0Jbu`w*bJ{L#e`ooVKNS%ABBL_|OFGR= zY~Pup+m^P4b5F`5qk4fxliEJ7^;&X>N4PjtV|sfj$6vgtP*{hEZ%9`th*tSNI&)}& z)(vP>fjV=M+Bd2+4q;yrdT&#{5GjZSS^fLvK}>J~Z_f&@8T$1-`z+!%2#F9X^`f4j z(eXKdS{j9Z*27DGhT&!19N^WR#i3X4v7C`fzs#LrPzdfx4F4PE_JH}eUIkv+ylcdb zTxc&Fo3S2!Dx(X#Iy&5q%-H%d%l7T0HBAgu4X!kI%sZ;ksM{HRu1kqxV49hs*+wMyI`?uG6yACu5HmB)KepIMn zhoBx%17tai+Q_ZLK{eU5p;6F?&R)`W%}02YyZiMzvg5w3>*lqc-GZ&^XrcqIdxRfU z+kXMvxUNj>&)ldry3(9Sy}{)4E~MIz=hz}MMa<(cvxINfCT*JRO$bd_`)TTGDzHQq zAa|+^YJX;mIk_!dFXC9~(qD+|EbHgx&j-`n;jDd%D<0K?T3ZL{8qh<%p~a*#<c z1ISrPy=Ml@TV}+g^@#_hFMxIBVClr)$n}!+WWq!Q*`JD(2~8M7W0!dtrzVzZDP}me zxP2uv7`gRl&U|p+NOQ^4`5m^_1;$OG(7K)FIjD(vsC+238;!cN$ZcJA*gjcjv(Ai= z-%HlC?)hU=(x@%@E3XFXTau(yI`nYi#CbjEYivm1AG@)x`Z*|NrU>n^7*5!O?SnEW zhFFA~Cw#^d2lSUvUG#i1(PWDEYx--H95Dv$u63qKLY*!zR~k2(8Sb$%7DJZ65NN9u z>>5**1V!==q6R8MI(TFYO13Dv&GWOj#FJxhXTpW~Qsa9oFkN2xXF~+3}@~ zgsD@5vHuiEF9{zh+wPCGGtaJ9B(7)CtK0tkk%6pDlU}5Rjazex#)-Kru{N(xLQ(j> z11St4K97J-XB-R##wxZa4W>-pn6WkH8pub^DsCb?`^Ho);HzvFvUa5+9}CI`RG6HW zgy~ZGfS8X#j%HaZvW!&Z_eH{<$b|FN=EBqGHBQe>%)~A|%p6(3lVBFTU+&kQ=ll2R zBTJuQD${XD*V7+GL&vQcM#Fm-Jxof8&Ta8&A1S^et%*s&e$u_}8Bk>+IugfT}sx~v1 zUG*29M4~iF-mWrU>+%bY^Q$>_^WreCl7yid> z#T%Jt%lR`Z$J)eRREAm5k}utNyX>ts3#oXIW@)K;6Zr?7=*sOkWq*#p8G5JkUEqaZ zVeMd|`Q>=^eF~KBoaLOJjZhNgY0^4LR+KJgXw2(tWct!p7YH7UNpjy9?2Uh$J&O$; zA}6X=#=98+)TkYc%|p33c&2lt?#OC>h9T|)oSohWpPO3xV%d23s2&PXpnM@}PZjr1pN!tFJ(0xII?H&QnM`c$(lylsiZ2km7trk>N?=Qdy^XvZ7PGwC&9 zX>fHTmdT7!HGvVzy!2RbCE00alfvF2Z^58~(!Bp?%C_~s%=MT>Bw8MqoQtbG0!ufx z2X3Utr=c*3O|)qw6&4-MW2CSLiK8CE4Td8_iNol2`~3d_KS030=eo^iS5mOfo7Lm3mdr6Yh z3G^)sWF=egY0t3dVHkK~D)MmWgFOt!P=KuYxa4bmjlx$2qxxIKT{|nOrHEks!DSM9 z=jAYU(mEULb8k3q#m78&+k7+Y1x;)4r6WSl6lQ5nO4k*}R2awWx!G2|pFP)}hif^r zI2R_^Uy6vRxjBjpC!BbaKW*EtnYaY+R*1q-;EDci^9vIgKm-5(*}J;twsB*j&4wq9b24pu<>tVB3d=puKCQN)J44S*)@}(*xX%9%;#}gUM z9tN}DSB^Tc+x~GnGjs(T-1cY``zs-LR_N-o>m(eKGsHG1na^F@g>9Fu?oJNe9$?ko z(hNR^8er%K5Oh-g5D+l-;RDV+D|*Bo4R`V~oe86MG!2YbVBs$&d{-^TzWH^9RkWaUA_U@8vq)HRpbfXUI3Ph z`+ncX_8DqnOstIPL`i&+JVr9m;IUUsWywQ;;C`OV;PmhYZ&PY|w0>W}FZzUT5gn(| zp001C*4r1!ldE+4fw`I;E!<#ks8NzO)=vZ0SMeLfDEGLDE8p%2dl4jl%rU2tJ<8>& zdWT^{YnSyKgq{92PQ%+bj)i1HvScAG=?G0(vy~g99R_LBW~bAwkT&*#4o1iVBsPPn zP%>%nDOWyowL9mfG;NKTM281do0S>>oxZ8M3(^y`OPQIl2cIzHGU*{ZZi=$Zh&U*> z1Bb>`4-a6V))Z>pK<(<0+fVqhfJ`unAg0yu({%{N_}UMW#p5TH8MIF%#*E|5^}M7t zdCm%}hlIeE3pdC+#fXQVulVWpi%iVg1D;gQ-iD)fWGRciK8nHIk>o12f#7`*#l4@l z$y7j#d5~$L9ZYGbP7aTWYwG3E6#^Us$%>@?rQ10Pyh?UInLZo}cKttx!QAl|SmyBc zja$y1qWF^VYGuKal{n(qz(&14h`6Dtbve3P7YN@DqRa(FbWdmkxybj_2bTGmV?&u2 zZE6WS0R$&mdD!My847qMWDjH#R1TYmLgS8$GY~us1pmJnYWCxX7<3A}a=w)I;47;c znOROgfv`8IR4r&`^VD(`O!i{s*nW`VM+~0NIc>>IL}P$qd$IE^NKs8>bu=+HMU?(% z#hF>l%-|{nG0Rg-!Kc@lFuDyuR*>)X1V&{Ex5$3_I<&V?NCJG&0Oeqw%;5ddX9t$& zF8rnJ`k28Q056%YLBM)MZXvZ-U*M&9A7eJnuCnx3%U%&^Nv~mDcv@Q{D1~b;UgoHbnTB zeViUI#Z7H-({x9Gm+ZmXbha{swgVa)_RAlC{PC_oOcWCS?juN$84D-iB!D?v`ifh6?9B*8;;vDdYLE6!dA+ZN8zh|=k_x)_^n8BA zB6-VfEMD621sK7C@E;N5@>XmK_hJsm+{2oinqKd-Cb<7P4#9;t0^j!# zl3TfvkA=6Yf3pjA4~+^b0&3YYb`_E3WXzolMH2~KB$Q9&Msdpno@?Ls0?4?#MF9y_ zAz*z+3R*{{voJYLT0O;{VVQwXObTA`A`20GcbP1;8aa7csa#(PxfGAA-EAtK)AAU} zBu>PW@0DWz`%#F!`j`V# z*rPrEbl6S>U#>2{22p$^q${jzCBC>bA+AE!eV=;_hO?_|(>tXid`aC34#}5lgV5EK zRk}Yf08K~~)77+m-55^^ue{b2!sn}Jk~UE%qj^w(oW_am*E+~jjoZXnA2x+)l=(!$ z3T4toS5K4K+JNkv97HhdvwdML9eqWrt=vl3+u%er_W~sI>ws-p4nD0-S}D9j9w(ts z`!6d)N{#)-8rWWr9A-l|S`{*}AKP`D+NHHQtJy8Q+;@}>wAnlimYundxk*pKcYK4s zRJHA*P}$_qp<1jo_%+&ojf_upV$Dk97m_d3jo9SRIuVR57n*%mOOsV46t#py{a?Rk z?MT$ft|m;LDPZ#hQYBXubg#KJlj9}#uEdwt$*l}z+b58L>a+Kap*OreuYACMZnH!Ddv%D_QbV`qi z{|=Ux_iE1fhwb#rulY?1%s2kughz2pNls-Xl|wgTAx&L%*wAq3QA*Q6kInZWO+PHp zb#QZXnZ&_2zOvlfr_-caQI>Ap#bX?uPm)+`f}O8W4smW&Ol$fG6=$ia?R=-R_a{fJ zd`R`yky(F08E{<6xJ*^hGKrAjacTJpe#iuKFq{j9`wJcl!B!M}k_$5Avmk&;5&*`lRupz%>J=oB_nLV;HSTTpnXUGj%_Oh8?c^!w#%_(e_Trmu zD{I2KU>iXR@M-d8ZX*JmqC8dWRgmvzF=y{a)(xFL0|dZv*Rw8Sx%=?3h1#^Yk|8TpU1bi46kPAdTywi zh<+odEKAnRK&8=khGDWw9k|Jqz7f1_RenZyE7b&b7sSrBK*-tq5yN3;ANpPBnu_>v z6e{8tsnQ3gAVwYOj&J-NORcQshV4-uQKd-D6CWA3EFc{23w8rNAga<6tv3kr9T&k> z#+oZmf;K0ZZ%mNKyrVGh7@Q6tr)?ZvCA~N9oZGLqH*}Px>)ebrw1ZbVF_SYh8lVv|8D+&~BYreP%X!f?cB6 zuG5d_cNhYQxJMxX2v*4J#XI>Y6mg>py7WByOp*0WRVCTBGTVuAsQIp?leTG~i@mSy z2wdv{2g~crZg+9=W7E`!-~X4mD?#AYPDY+mA;qH@0|7skC>(?sYr^v2w5gF~a!d<_ zN$EsxoRA(`T5!@GB_0lRmo!kAivY`4gSlS1p$KbSv5N-c1xgZ&7!pCH4MHTbC$6tl z2g&F7ntu+HK-7E6$MsrAEO{tyOEwG?tQX|M1D^q98xtb%`=E!QjRJ8(s*wwpFTfW+ zj;Q$-NP~-cLz{AW!F~vQ%wKgmbK%zPB?zBT21AF3?VOMdT@xSMH%#X9YMgxkqXDtCgRL7xJud@aRw)o0jx@z?ZJg8^64F>wP9*K4C#6JkJlbxucXU_BH_?DA312DZQ{vr%Zg|3kQK4FG`tHIkbm3^qJ21KhllK5eSN$^ag_{b_hIZRJ6ep~Q zTP7ht5&KLJFR9dqhzG@Hm)4f6mXFVn-qYkW0(Dg@yF9+X9sdQqc22N(aF;w3E9Etr z5pD}86m^I5Mb3-qA0hsCki?W;01_8jb1r`a^uz8?c-L;=P|8Y{x+)twfoo|&RrfNB z&q&Hqf3daKt^Bz477eds>$*Sl7*_r9geq8v$%of4)bZ@{mqI>IS@7WniwJFq<%3o6 z_%l>wu1gMkbRjVEN|{y;c@UN-1PyxVpq^}pG>2ctU9hB1FCQ+cZ)06XtXeaCWWVTn z1{h9tqbGLuVYE&w`Rj;D!0$!)U#G0pUb9t_PI3tbdnVf3*BcQ&QH=h`E>nS!Ap<2Bq^|?t z_L6G7(90c+91czw&nj{XhXQ(2MB4F5k-A`)^!d@<#&Vrhe%gB71;F|SRmw}=2w0fF^O!)T z(u<#-<5!Bc3>e{M-02Tw{VmS`&H%10;HI%y)a>cFiS~_1r7(*m8&NLd(;NL-a3rK%5T1l^EVkS^ z+VRc@Il_8>!KihE5EuIqRKCC9Y-L5!OAundKJZ)MXIz+&QJ} z4b6%A;~PKccq+kukv(zI>eAodt-qJ`HwhjbSoY9eEabVW%v)gA!gBo!b|sr#YK<=C zRbu{S&32a+Cqg%_K$UYvZ~c9oy(Ei{n>)wi^~V|H65 zoRp>t>;$CV(oXbcIw)iY1}SqhJ3 z3&cC(E?!HTlLE}_*5YnW$mPS=%;_l}e2RVVP5=>a4iLLE+A7xhAkIxYZIzg!Q|-J} z1(L%4IHe!%nDKV$U_Gf`&{rs3UHeW)(#oqEu$?qRDb!`1bobgav+4KMa|zTgg411z z(~0P~9>Zn@4?E}%O=a89QT;LfbZ{#6uxmGQ+UlU|GaRFbejxp{n|i7er=7%Ve=6+= ze62S6>XwTe+CMBW;h(q{yxhQv-GfT2uHH7#cwiQ$rb9EBB%iSD!IW95b}3}f-tRhz zss1{U^lg?>LPm(6uG^aze4BaL)kbae@y0o9;T-NJRjs6}!ych0 zp!HfgiY}bFa)(I!uKk5ot9bL$c^2Dz$e6-$z?BixSw2%Us-NVXlrmQ`E=p#qUOdB*L<|wFu$dSRJjy88pa>f)BwLR&?DJ@k^O(z4XDQ<{VrFTqols?qX-WR?Lb~wX6cyk15eUwEPI+iUjqK)-&iY z$hi-ozgm=zj<7S*=)fh1s83jPDa0+YYA!|K$^;0>abOMf@_eZ%U z1flGjkh?WajU3w0bx-98K?+ez)0hX}pgRPwD~e7I5%;7>vML{#Uua9_u3tuZ7BE?| zD%U$P1E)-^1JzI37r0OZnb=gvi51mS*j+5?1k`Rz&)`bag7xzgH$aU^=umv=Wtujh zsVTS0uuW0$3jA#|dBGz0$A#Drt?KO8^~a%HNpOfa-G&jvI)amNeupW@U3tH6)3vCI ziRHmN=q$@3MbnRWQLTu`4TzNdO#WoHdd61Tsbt>zDhmrU=|i5R<{Gx&QA0*g-S-#` z!7T~?@BVvM*pI{$bD=UX;nVPH52cV1e(i{gh)NZ8w#Jz3s=KiS-Z`T15kDSV2EH2y z@GeTvtM+hvS=0jBzzb|RLW8O9ug2%sY>Ik9wmB!`^ABj(<1QieTX-vs5PN6}<1MQJ zlQ$FA4NHb4Uo=FTPsD%vDyyOm8rdcqkvs&5_r2GW82=gwaS)?XU{~qi(8^M{Kf<)q zOki}8NTxj09k8nDfai#Pma99FQ(k<=p*Jy+XYW_{H=jX|j3Dk}iLc}$Wxy!yY?Aif z18$uacu7uSc}t_<8um)O43`2BC`Hv`DO>&F)$E+nSSf;8htiE^cI$!N?E=KP0}5t2U@AK zsdc*QD{Qoqwoap!-m+F|<*_0_scZUfZUK#z|4g$n*gf&gz|II{ND8xzOQV$IpIstW zvYy4?t%exP-MKjiJ6oYa-&;oC5Pbp-&x3XhbiLD+W02DdHY}$^9Yu)^I%A%AIlwnk zM@2Ve=bAQhls0mNHoE(G7M-jAyz6jbMhm@VE!33{fN_*ojsVV}{Bij=q7PoTq!dfd zd%NnQU3_x+&zXMDw15H+xa-`IeFm(hhoByuZ)s@EM!CqdH$pyS#OE?_hysB6PL_a+}-F0D`~ zWtu`+3!CNS3tC(kdpjLO znM9K*?eIWlCsBEDPky`lE7~E_-SZ=u$kSVnJbhn5a*8fXU;e@@aO(4*`VEYF3Uz1j z81yE2T|ITRN6zL|1d)?JQv`#>ZLWWcrpzmyTtHh>I(lH+XbGbwI`wOjS7bNajzh~* zL^xc~d5(y7+Z~K{*XuO+d&~G6;wd%aW6)Mx(>dMct$|ViM?5V|0ztHM`k*xS~QgJPQqV7sT%TbvK*;9s8+aaFoZ4!*pOEsjV6o zSqE@L>qZSc<0?~r_c3q6o2~(_TyP%>hB&pMjP#-=Dujyk%3CO~j4%p^3VWrJN$ghx zN(0IPZPPV858L9e>z&qi|9TVlZiEVmWXVRP3{sO3u)7_15x;!x=N?Yb4@yN3aUAzn1>EE z<_)x)D&Z!_84HR56sS%~WDy=7xhk=jrbM>5%_TZO z*aR3h>RCK_2eCvMrF2HjNpNSMw@UJkCJ;0DEa5GmsIlIlR%Fz68jFwA^wu@zB@$8Q1-!vvH)oT(&yJf`6!Ieyn5^J*@ z<@sJZ(Yquh*Z+|4pWC`c17>JydLSV^l5O4}8iJ%|Z5cDIX|e41WQ$uJGl z@?Q&KcO35A!tQFy?F0ghR>Z$xkbbK`-QV8Uzj*BM%ecYhcRy}<{i~<<;|3Q4L-S=A zTCerTJlq#NYisvt;`8%QNgN9ggJzd(L3XfQc|7Kh=FfPqrHZxfR7aW0giq?mhtYX8 z?EQ}Belk@LcIni}+WvZf%^t!ef{#3zGBs9~5?IXVFDh3XTx1KNUMfp6_@wtbG6nj^`Kwt*UxTUs>YU%3)Ue`mJ$;V znpzAeKXMUWt(=f15nmF_yRY2ZkU*Sn2upasWivThGP1Imkz%vAS)14lDu$Xy5*cPy zXudK5I9xL=dK0@pJxerD{UX(Imz7Uvq|7MM>z)c-le7=P)li6`0;uR`U}(wK4DIZyryRD! zimZ$dBhO6?_*@FpqU&vukgMoLdWliL0VyS_*PzdKlh5s|RKzx!iBJ z;>%~^J6yh767*lbfG#5(0f#GOE3D=ya1s)ymOA;fJaN+toPnstONIqrSo zrLdlN;WLiO$a3sT~G|aI$GV5-b%U{-twv`2@7))qcwQi zm5+>s(ohuBMq{UJ>p;sglb@+Yj^%D0;gMDEZ|}oD#rEz_`cg>`wl&8KS<=CPney!y z@_}qt4*UrlAd^kD+ci|gM@B4NKN@=umQPS2L4ZR7`ESJ*wzSqbe(im5 zhWXlw1Vvjx$u-lZbYT`Kgi)=CP+L7Beu-74+K~;_oXyEbknO#cc?UwyQ5i|fde$o)c_j|$yi2dQ_r2h6*FHKH6%R~e^s=U4H-4Q;&@TyyE(mMo zZ{&wpdBKG(>&vn3jV>E+>VgM1uv6YtDSsc8^St{yCz4DrCp@(Ek!UT}f=Vwe3pHKk zxkg+W&C(^m2JfUFQSr{NyjF7(Fzn|$R9Q^YP&$$yUC(t9kK!N@a{@7o^f5K*7j}I8DSNZ0tx7tzDvNUs`4X#-r@)qnm_KAgjKKeE|~XBv{Hc_$uY1 zTO6;K3`YX6B-jd-@`?0H1yw|365DPFr4UMti`s7wzpSki0B2V)9djG_U5)VT9z9n4 zWvDQn-Q1H~frUr1k%xFmWFmyDgeT9M87b!rYSJwAA|@|D!k5WbJcc|i#l=@bSy;26 z9?lgVz>rlhLW~AXA2Xd@_2~3CanD%Ag|bei7(?!TO@TSoc`!@z3Vu zmK2TzXq+D53+0#veLWu~{4o7K$jHZP&g~uB_h`5b=>KnAV8XRD$i<%_@r{`fLRPsT z7X}c)e&dw4X{>uWO6DDKzLhpGa+h=E1Y}o_AW1prU=dwIJmWN)u@?bg3s=uIFo-bM zpQ%T(tAR2q((s}dq~P`hs$dz`J9`Q=1=oE}Vs&XjeRKA4g1#i7I+Hs4tyiymoci0i z&A##7gw_DR?2GVJYTZJjQr||e%=Q3nzEDU>t6DeiDY}Wpc2Z692sV_Hl&G@+hss5i z-C>cAqy8370g8Hm>jXs5Nu9#5ir@&s_p-!WfzQgGD4=i1=0v%~o>(_=Wq_1%9{cW) z>)7|B8fJgm7ADdPe-t={XEu8 z>8V>6V)RQw)zn9f4&Xom7L8|~YAW`04m2-H)HyfSFZRU$<)o$hwaqJs-Aac_1|lm0~o5?Z*nLp$ig zeVmBGEkk)hM_p-zC`B2jCS-E>L?ROp2gzgpCN=;Xh!*u?{|)*_BZHj=gXzkK)p%)D zf*`L!0hQjI_f^d3H<;5o*EzshX#V*PT{Q8}ZzKP_0{^(vK)K+f zJXS8zEFdbgu#l@BH+rY*ntZ@5`YO8dH8k={BZk$&B2DnJ8T1j+I<>q)9^;iTJN2k) zxvLN1abG%-eM#NS0w_F1(xiXDp?C#(=jtnaLg)7nUoRvuu&>S~aFDm^1U^+1UXiaR z$diO=;YRd|MjMl;H4weUd?ILhLE?kTlY4L*F)^IYMrN%G;4~!-7Ycpz(0uxEiPZRI z_>biBy|MCyI|*HU63560TCvmeqdCz9X9M>%uEa;DdD({%AD zJ)QAXyC_?_JVpBhCnu7DkZ20E2!hpzM_|agn9!U&Ars9 zA-gw;0LF2^>K&cEsdq{`HAwWHz!8_qg@m>q-8(_bty`+&DK!jCGbKAc>NN?8XQSJnCHHWwrD1i>@x5hu*SjexByt|-Qlrxpyx@z^R*Q_=0^}*Q9 zHhEkV$gc1x;N1-T$82P>aHX&;)VnQ-O0Wk*znOh2WO#^42->>LvA;BLkApyr!*7ug zrW;wCkR~ABhE$R|I>fL3<00>g?PpBVG=ei2+v)0qg7cGzd^e-Z5OK!C8EnYI#N z#7H1#yKTyUcF?MV?F}(hHIPv*jB;U=3$EnCeYj1y{Pru0V@LW01)|2o%aX{mPec7! z-n?8`ObTR2i7`ryQDVHh#DHvM*Pza)E&B@%+-x_rOi+1UMzKzc)b=!rmQl2fqUAM3 zi*=s894D?Zq{UZy!U{v2pUQo&$1Bf(nEt&n(_WrTm7D-qo?K|+*LGDqL!*Eg1;i*I zS__CdOzozR1H(_`SyoYE$a1skQLL_=!DY)dLCx!k4qhB*i{zZ6$QVV&C^DKw#)6BU zmb;!hg^h$*t=?2bSY*r^WyB~WMj6p8Bff>Q@18PZnW)hTwvM4bEUcKM+d?cD)~^x| zE&3Q`!6*wxSzs><=EP4zABW!VD~q|EEYQjU3rK`Ro)2fIrU-ff<<+8;cH_Cn9u0`d z$`;qqIhDvzIq?n8FOua!lZCu7kgeFeNQ}0%bM{tN-pw#IbovF37U4TrjO`EeqC*L* zIjM(Z!HW5^I5^`aRRpjbW4;_YOAa~nnH5sp*foPR0=Sw@0pPc_Y0GMD@IgKRBylN-O_i4RNgm9VOch-9TwV z&Rf|hM<8w-86ktn;BfG-%1oLxKi*V_sYD6rEungAxGYMG39GulK`Ym$?4eA(Wm_@b z4P-~LewHlqX7byQOh%XhicQVO(>SWWpU(P(olktXH; z91-lTZQX|1#bENot4IW;C$6kfiZ9a|otp$jFiq-MJsq07a`=KdBrv$usS!Rwg24?9 z6Hek2$uoFlXX_J3INoG>j_Beee&3Mn6 z=2B(>ezQyw$Xny^i5R79leM6xH=QRJJgIAykZZ$2%9%_mRL41Q(7jHt1S}`_3T2bd zZtg$ap@mEp^HJTcQ78Ss#AvG~w!AAE=M!hAc{D_?BnlzTNmVPzOrwGUPb668?>O=y zWy|sKwBrq^jx{xwRecb9*MG(Yx&(v*Kja-tfALgOuw}%Or?rkN=L{`4+p4o<3Ce8V{`s3`k z3Hpq~@9^jE6Qtf7KK$D+Xa6o9^!OAq)M&Ik^c}^@C|1xYR(@Ww(s&$Slq=JJxRohO4DZI!JPAXv`7^Py5q1~a5SjCv zty%~c@CYa}+JUf5dlkm~^dF;4Q5}skR?Z`M0e#W_BARiTEST#Ixo-xAs35Dk@7$uI{!8v@ePcV zTQP%@_39?9XQF1(lc63(lH4JFPPUj1_EKJvIeSN!RWdI!)6kZS(}thW2{ZJNqsE#b za@uiRZ>0Wr)c)sW1u+eZZ|*~=IHBgUVUyMEj0Uk_E1s4B`C{sUr1WZewlArsyRvU~ z-4UYaI9aILC3Es5bSD*SaKkp+fbjOo$0A8YChY;kN76@&s^TcQIc-4)C9$b?C8Xnq z@HO)rEtL8>b_i=HYw<0NT&zYC=H^ivtKCCwSW zfpxsBX<(JZy!qk5O@#7*+$axFi|N>N9a+svQ=7p}jxxC0OiQ9#*v&`f!-JWK#r5Jg zqR&L<%(4@_q7m|;m5eF;(tNR0>|VOy8v1}_e+WZ_;2vOL2mE4pne=1VZEjNiQ|D`z zaxVIvsX?k-OU& zj^o)HsutRYP~56KV|Sq!?c|r*-zdJpOL?uIMMwpD!3UB)_qPr6>1ro0{)=AGR(5N1 zi(U;4*34&6N>l}0H};qBMfOeA4V)}48q$xap8d4)^4Z7sNEl{GPAEzVSUAnV=eexD zDKp{eldU|kq<_EY+jn1fv%oVN{<-J{(hf*L;Jm8~M5_A>?@OP8XGwlWLDdUM%!d-tTU|g#q)v+h>u92th9q3!hBd%@{%EX?0F7wyZ?blU3MLb`cNX zN(Rbb=n;}E2q1z0o+o}TcWFp|KyFOPtzV782B_%_Eg;K$5uadm8XNVkmJ(E04)?g1_SfGe~Yjr2!WJh7eT zkB8ZH0{Nl2)<3Lm6mpd)u}Y+BU>-KpyRE2K^cvjaIHz*h7riCX1;>q@lsNA|QC7hi8k#P7n01wr+OyARRDSLBIi%3L9c$mWu-<+jn7`=J|w z;V`zEwK)mN3+_H`k!s&@&MaCFZNmPE16wI59;LoEfHmZOv_Azlf^VJ&Xtn$1I?aj!`z;A$Svi$HftC%je2s7*L?Pwtjmm-U!9hHQ z>_O6D1++Z90YIXMuTvCjiK+9fqdECNLK&-l?yGyVQrlPGT__3_{7fRLvqH8+p@Kh= zD1R{o;U`SPOLU_}U7U$I{gj};u@rVqh6TCVCWXLr%edA;o7|Na6}bIN&pyp7T7uf=o%|1rUQ?@kl2K%#@XRWi^({2lYAxbAdkcjNb!y2EE-h=UFf zau$TFwW0|P(RHbAjXp@15Z%BL7Cj$R~pt)vf8`qxsEt3cS%Amvn>1}R2}pT+#?qKWeqOP{VgYnmAMJ~UamE)cJ@ha zhO!C>H@T7Ws9UjUNqwJ$2v%tcO8EKh=l{9rx$orp^Hq3LDJc6E^4lUZ%di9sXLEGM@ySw}PE`gt0ghbBlC7E3aUc^F}+fkylSKV9V1&Kw7`D95FaIBuxN zpob!1V)bacyZ68Eky|8f!Pd%#BHPFMd{h|<1eG5LjqH7dS!vDtPsPI#^~o)bN%(}H ztbLbYHZt89`DyFRa`&%Mm5T`sm3g~Q?9XJgB~g|sl(VNNeaOhy`M%JW#ga>FA?QX=pOiN#%)s=wqCVbAv_uRvHDTwf6kqc zsD5o%s$_UHmPJ@QRCpYqt_&|Z%~D$r(%KZu0cBZ=X_Xhdc(G16WCp4fal+zc=Arvg z3`E|ha#F}f!(%@&xH=6g;0IERlV{43IM^u;kM)p@qZcEt-VouCiT`$BqGnK)z9^vc zXA*NkK?n#^(rf*GS2V?d)?y=42|=czigSE~lQXk>*Ro@Ka;>@X9j5b^#va&Tb^4VBhgxq7S-zS zx$^0mM+Ha-uXXN9f<~I%fhyZf7nW5{trGEI9gtTUTtD;m~ zYF!{SQ!~lj`0$PRX(M{uP&r8jsD%pCO5XO8yY-D5Sf;*l0}s_VZeXfzlD3t^?IC%4 zNZ`(rxUWQZAel=^*y68+q%Lh^i?$Y$yORX(BFQ^Qba%GL={mSe7Om0zxE3bD|0Q4# zKuC(Y45>=X6Xjk(Hy zKMIKJ{B-XE@S&FJc;_40YDJWzK_E4h5_OmgUVf;5FrJNeV%b8^p)3`x!DG)zca=>el@B|+YD=tr5|NdVeEnO)!VSB4A!xL>a)3!`i5-rGokpjP>kqiLwq<450tQaX4KE( zhJ6f|4&6e1sJBAPIdWq8c)C$qYTp31{&@?7pp1)Q<@&1FQkvB9|CMDoM{xh-STyTK zRCY#ZJCwRp#D^zx-$&C{Gi`C+NTG%jg_^D5yuU z|Lh_<)x1-y-OeqnVoC~%EZ{gcxfbg*Uj4`(SS_PJta|UG&eV-#)W-+L40A2=b%Z~J zHx<3l#4o_ap`=ea=NNpi_6&> zq+P&z3h~FUFHfC0nRAW}d(EOmh0XgCASp}2W9mx{K(VAr(;|2@f;>o#a-u-6zmVuQ zrqS~;IOLoA+NB#(jA905u?=!dF{mu;XxSvBB;hw;kck&}e=>OZhmfpr~Abc;-{~#Dh zy9*eLdV48ybKRspIGeza_Ocg7qH7_F6o}MjQ=tF7oFOSwwoE|%8Sjn zal|G!d;++%3b-Q$Z&Z;tec5+DLO-Poa*3c1QPvk$dr>eSZ-p*Dlsd!J{9Mf(v@-d zTSMr`yW7S3y*?@N87&;kJ7=(&N6;#4f{sp+D-JzRmVX{=S-TiLw2QZ(*>5iJuw2cT zUnV~l!+jb$(*TBtiZC&HqoJ6t(4gl_M{of?mlfU7=vRf_JsYf{=by4jsHSi=fdVtv z&eg|0x*dB{2x{CC;G1l^2)s#S;7u9>Z!!Sy+XCLhU5zYbD^=C_As}3A($CIakycR;`1O$%$MyiDg+6ls-W>4P923P=s??G?z!#w+(8U3x~K32-`Y$kjN3FdKp9< z9I`?;CQXL#rEbt_rh!X9v6qA%3Ej7O#7a1`cI`pI2qMPY#c@9U;{YDudkHbGz(pNT zC~?^++V42XRq}yuh9?!sW@B|UD_bh{4jvNZB+}d32tzzm6HT)+tS+OF!Wj?I zT8AXz+bD)OT{w!vDF^QtXT>x%=^nJqEaRi;{k;OV`J zr53q($mRiLoCJ6umB~vfK6sQ@5HI?77W$_%gker5_0V}FZ>InGV89_LyBlaXwUcCr zH^ts%3pxCbqxkr<)(%+n#j@AfqF*1Zw~<;?n&7xVR#~(YA^boR_h0SyQWCptu-8G( zWhcu!p8|=|s4K#r;9`x=wr~|%ro3V3Br=edi@qo#uI!6(9rg?}dz~*Lz;n%L{2Se@ zwlTcm4m`cdmkgSP?m`LP_;63{s=k?XobQ zy345Myb6{P&)d0I1W{S9z0e@o5&1m2ntUEvX!U=86hCDFb^U8PCSvI8ywK3gL6Ety zHF_8MZ?kK8@-^b{7Ty;#Uvg5eM#JJ}x!NRw!&FB&f}yAV?&?^ld@KG|du!A~H@Ryp zsH|%Nhk32XZe4%q_5F7ymqwq2HVln!(5JDWfBRw*sq>fxmZTx zK9Sh8y>pN#LA2)Cwr$(CZQZtQ+qP}nx^3IG?e5z)x8F|eym=F|5j!!l^-o1bMP)^t ztjbe$GQaQVG{ny08{v}*^(e9E9zHDg?cy9mA#i_{AEW7M{`e54rvUi%!vFv7NzL{D z9gHJq;_PPUXeDCeYGGvZKNF4!e=U*`OrI3~A75&*|D$&Qt2ec*{2&1a`0Yoc5BNa4 zx!%$g9rsm94mxuZt7(`HMhR_;m$|>i(p9Hc2d2qHOxW&2Fuyk(c)6B)hB1fOsg7O- zTa5RhgWpj>m~ltnFX)KV1eM(B7j!i8UqDAEU8GHj{|$5mBy$2JB|Qm0|NRR(nxxIQ z*@XB79bNu{j-u5?e?do%44{~t-O!frxyq36pnOtqa3Q`J1q_iv6wf#F_l!tN)=~erH}(Bg3ZGeL`#o+vB~-`Wgye7~@Dh*PUZ}VDWQV!&@`l9wVFR$XCYPvFjRT%*0NaUD9Zz~Yo#;HyM!$YjCH$8*MFn!$K*jLYi)DOUZ%F4%jT z*yPQP_1YD{ycRhLUt0zc_#sG)j$~UUh_2PQ*n$hXh&QA%=bPBO8oW$oySwBZDRY0{NP*0P`4LG{D zgt0L)?z-HM*b-oBDc}gjlnOx82w);d(1>gVP<@Ic2_L(yRq8>^D>U12zwax~%G_(s zSDFMKj9fToR49P=z3uh|WVnR-TnG@+-ov4cH5xQWEB8WF9k!1qJp5%rY{c;iTbqpJ zf@rjCHxTnna~EQ*GCi};pNl>iBK>d&@%0~ zWXHk_9xFDruWuvHtc$UoqN@1S0Nn{LnD8IxwMEIvPGGO;V)dYj!CFNO@V>l!=fH0< z6&;G2JtRJRjpoBB zNMy3T8p=5+^VMNbqLG#E#M$%I45y=K!cmQS+9V(=!pVz7z#zj#nM^G3Mp;iy#SuJY z*#}?xI(GAyE%-S1*)b9t$rx7J3nB%D%0eJ)EZS_<-quFXKA(7?MIGACw%|b2g2&DR z@QoWxMRm9k$|#|9L!fad^)*&X8J~F!{qu$Z>Y}4dIwIv*DPzTVG&5B2COxT89lC7U zIp&VYVvf`4AJVSN{B~xYbL#HRFRUX2JCRQ%2g?>u-a|qEz$JFQBz|rsUU@VM-8(kJ z7j_X2d?g;MRI27&;K{Oo*e$3oXV!|VEBiS69JZGzZKp7)00&r7!csOr|YkcgwUDPXoWMCs2vL9Vp4)m4Vf6U8Ux%Cojz(}ks_Ec7n zpSI@?+Z@|xV`~Q5>!S9Qz>y`;ph7B0e-|FtrpAp90>)BE=i7@iXuqE|j?W8GyyC!a zJF1)uQo*af*H7`XN&&C()~@OzfPamTtPY#$Ts~|gzN1WV5V}sH?rmtpUNqvuoKisP z={#Z+3Rzx!>ByrbW7W@xMawNmZP1{iVhp`zB$;9(>R!6UN3}z)2JWc&_m)wU1t*Hj z-Y=O6SM>NyN0a8c8XTa^X|q<_{jhD@{nu8)L*z14x8rbz`?|8)u#s=}PjSbWk*;Wk z`p@z@OQ$iCIgxP1=~D^Z$`6Rd5BSQ@L%4KeqVvOt&V(!jIG0*1Gp}ToY4*1k#Xp!r zeVk(RJfOi1;3J2(puzobaKeT44Ezo$tDXCvGvyDxQnbhL_lHZ90gFS~@aMQK4}j8% zoDZVcr>b@C&=Jz@36|2j4#B%x>|``RY5EbJm~<|)iIkCs_n2NP6Q#oqeUe^wwB0JL z$d9VF<-XDWMkmy?DTuWz|6$P#L4M*=S1hqq{pDgNcX=w_dgKr{^PD) zk?60gmcPI$ant>tx_Gr49v+ z(ySKqrQ6+YIt<#4a}(3t)|}Qa>sE#CTbk)R2%W}Kq_h(6!J^V-!50gj;T*kx!Hu}& z5gL@KeHda58Df0i5G6?=P0LVJ9Y@87f9axGJvx2@4<(%Ucb+eQTXP(S>J;=y|>#X z%S*Czsu*NP=w4*M*U$aKF!|w_)@wA>R<2LoQ=-_F{y(X076{^SeoGb#?XE>-Q$B^j z`Q@)~NCxzfuD3MWZ!M7ZNw;RW_%%Tg24!)3sSldb>3@3U#}?~!{#b2&gG(`(6>?p6 zrcs3F_J~--U+-T`UmO&+sl&WP4VDP{>6+w*+5cN@dD9j3-D{`JFzRslGYTs_8Z~Zb zkIQ|x;eb0eqG?uue1nkpG~y#RLoCGb^EkLJ&q|d|n}6&7%`VJ=8VdOmJmQL8i1HRg zu6Bk=>RsyA%TBjzx+$K#RWqAJp1wW${sbO;$S`Tg$J316N7X%Aj~uEC-5`q z7RM55Upn|Nh)Xq=$7b#}1Hzg-LRNvhT^USWAqr^%wr{|2vbfg~h&KQk9FP@|=j>!6 z$XmBzdnJ#V5hlLz$}wMn8teApBzin*cWj=2$Rvrom^$R8h!mz{?$|?uFoL+>rURAS zz&OXz2|~L_+tIKSPc1p*w~*NGT|mH2h)w|us6U!f?*|EI7ovf8rCzTavfD?D_x|36 zpBnuFb~qflcb-b!r+lx>13hHrOf^$ZKT{8+Zh{~3hk43BSBJz{iWAy+$ClvKAWX&q z_U<$YQrQCrk%*4uuxLI)LjHW4&*(~ON!1lnF7M8wKTaVLjEc7&QC9O2K@*)msN2Lu z%V+1Udb5DgQUv9Daa}Hu-WP(}+W!dhEH5fW1X6A=Y{C#ud0zDQ24ePzMOQ$s0uTP~ zA%B)I`gD$?ClwaY$R9;HUy9gJ97e%5kSY3r`g4V^i0f}E7*$TZ6JYL)oUd|3dHc*O zLIbY2!yZ0C9d^8H$J=ICNxM@=jgmi()Qr7*9X(vX_It)4p_DAUBp?m?wL`A$mX_@E zm{uUyYD-(6>$?{wi^^aN=q=XePT2aRuD^r8z=Ahuo2bF zRxZ4cHxaBiT|f_`arMQJ@>1;X&VQ5jsjHBl zj_L88njpJpz5Bzy&K%-)hbMt}6dt11SzTC%_XQX=1N_$3n4bv-CX+)))mPJ;3&LA% zFKpUGWk*eyEU6tY0()b6Uj;AtLc@pQ=#Y+tFjTl6Rf6U3-RVvW$%*dQ^7DNV3dj&4 zK87RKnEMQ%AsyVQeX&SE1A1IbxmGhc%Fypzv5S|FPvW*mrT~X_4PDcIg-A0>29BQ2 z#_>V7L_*~hg3BtV)%K?b)Rgpb9{X40d@YV-g>Ct-Kv&i}_!+kha1!@qWN7C-VS=KH zzHtLR68(vrX7^@CZ0U9u|ol*Kj2sLM)1f>uf=53H)9Ka5Vpl)w}QS5Gmqa1Eg z8fNhX2R#zoywKz$itKNAvh{Sh@UaUk7IccKftK`!CiS;TFLwOPyBZKYG<;O5OVseUK`yKMO2|&a;(z?B-dlStP>_$DpR}-ytU(mTIRLgOt zyPphmGi#Th>b^kXVAvqug`kq1DTA)bx8k=hZr*k{w}QP%?XCq7gac8BREGma=oJeL zDd)W*GpEKU-l&M;jF?E~Z(bY{@3oPz8|A1!zJ|W?$0^g9_g)<^$8n0^L!r>ll$7*+ z4^7!%zJ@?~5{enl9Hhir2`{l<}0*jliV%GTF^~7t9YU#R$?|c?~gt$NQz7u1#`l zF)&bkH@)+z3K?=@lE;RUS?P|&W(gsRdK4WCsO1cL%hx0j@xL&mE%@mYe9qY~~gDr;gRrPOHL!XT5#rL)q^ZST(^FB6KLG{Sia zW9qR{*j4Ar{<=nP&I8)Q@D_6P$%kPsvW)xFR8r~H3cdb2H_D7liM=sj)j*JmkZhjj zCh*ePX^B$L0+(rwiJ}}X4?!M?z0QeCshrGsMg2(%lr(^ki6&GY*Y!7izKPH;fT4_w zv>zNp9gTecmZcb^&fqi^MS8OZCGeFrzmUn`CX(esK|k;&pQ*ymzh$|4p9Ib;VtHGb zOQ7?LjO5oyF-h)&&zI4T_2vNG3d~8;3a-VGGpoRn*@iF;#~gF?-(YsW4h_AcjgCel zj-V`5P+ofI5`%QGs1>7h%e7VgbcQ;(Yv_`#d+Bw_dz#+rRviYFLOH ztGC5Y`LJ$HU#o=LSr5wfTBW`uq+See6tV(jF5|&y1Wse%%QZoC)c(~fzDiq@c)Z38 zQ{7+J4F}Bjtd@ezMzzKwss+1-LcTalQCyulU|1TLhAe1qC>WTP*=`4Z$eKAUoA+uV zXS{kwpa2>3vw33#GaQD`J%$ zpy8v0I9>AH7k^F8LIYmyi4D4E!JN8FQ@5_J2Y1O5TnBc|0-`XrPis9=& zqtw1uAMPb{UnHflKGZco-+|_OCiseKxoqUI4D9~Z{x?)4;KN${wW~GpOnO@j8w2zWCojVS2oZE|Ak!ANQW~6(8EsE!$us#!+unqd~X*R~(8E86xpN)&fcx=%f z7}4#Snb6<&&#XHnLro{p&*?Ei_n_VFI>Erj%gL(n_j)wIHSc=@vb_PU*J)_@-Bcs3 zMzu~FhR!{A5}dp+gU`a-iW8HXpnz;}Mhwod9-yOEmNlXZhAy)0AP6+fEQLN@TWK-6 zrH`+HCpJ+vaLHVs!^t?Hs9a^~NlG`3f;ny2FHi6HL^Fktfc<3xc+?@C z3kw>;OSc|Oo+9XoR~eB4n;qdO{|b>uvP9%#b?Y%qt%P<-atFc4qmOYlsTRMWzpF_6 zZ4Yl0d!#3k@MfJr*`SgO(<#!j_34Pud`Qk@A1Ep$dvhYP1J3vRV4ogi)!>jTM`=5=m->RWphwc#z9dvaG(mZSKATuGe(iLXCm~6R6!UJ zIg4EKog`1g2gl=#VAL^ok2AWX6ThPqjj-UzXl~Zdmd$$ZYri=?=yLv(HjyZLGnRD? zhWL$V@Y3!olB-D#%;bIeTVBeu*-0+-?7XwR_2+@GgPN+h9Fq(8{&pZ6U9h-jXxquAe_*}r4-yK=785P$4A-?Kx$cG@3%@gu@>(Ip*(3_ z{2PjGhS*67k`_uDkJT52!VI0PSpZTtXzez%PRRcaHQ|B!39JFUNZg#wNSM+4LCP+3 zEe?g2kmENCM$ke&FiR>tAGfu4^IVhq{?U-An2hF*N%dG#JsAC0KNEM zYt=oA$?)+e{CSnU=)?i1G z-?_^Ngj(yf8re21L3V@Thj47<$_RHYmF(lSFx~5tIPH&38DPhdCC1-1qW~h^_SqA* zIT7hvIoC3ov(Nv|8X_ibPh5!0wx)_o#7Fz$>w|`*;;#nJ382aSt4FY+0UL=AFU!Zc zY-BQok=%={KsoVVc z`5<7Ky@_I3MXVU4yi&neOs4x@bb%*#58Rtc<*La1cMpjwvql<%3?%d$Q0H0%R`NGHFA-K6gK2Y3@4OV^!g-!8DYPOw{2wfdyA-K}y^zbt$`o~9bi4Djv=xlmEcEacwP+?`dnT$R)j9BM_(tIlb3t7H1}5N36HEH+DV^R&^MJIUTd?=56$Bp2G_aiufGk2}K8k=61W)_m9_F(zZY!0-@P_Ykhpt4gs zhWde7dT|u|PgPX&^ZP0dQb7_NzSRTAFa~6u#7oe0E83B_`A#$KXf5t>l&@>>Jn!0= zeAQ-}PiSb%G?erh7WzkQa{KV_RlME^1|C_454pS+g3ZY=P4T*Y^I&k@D=V54hYEIA zEDprlBB|mnWz?l|+4%RFhvv`y5JmM^Wi2AuR)#9z4PUK-nM6O~24S{zCs{E2ZI>vd zCgB7&=kgUmoJJ-T8x%$I;it7wyvh;0&_NPULUY1e%V8E~R`dF>9KR-Kb!v>kWEakE zrO#S-8zdPS;H5oAES6i6b-u$0ZK29>>Y?c%($I4q{-#Z-!})h9jZ{eerF8tF;`IYy z^?$tyu=kkMa|>Z>N@I{UYE&>s1|_L0fjBfzjamss4?Zs^Bb^D`w(#vyz;nYMZ4HUq zeO@#}0p;K)?L(9v41=3!NEH{r1s&fiUb)qkMY?3X+Zx<^#ti~ zQfe6aGfP%+EAoOQye-c3J>CAo(r&2w3wDL;=~#tx-Z3rjrx*BrpCHX8uN3nRK}hN~ zp=FMk`&*r3 z8KD_#vf_tMQ_$dfSuhhsi8zYB0fRD>k|8pScd*gBsz=mSVPvTWuG z4phUlyxoAU*~t9BB5M>pN`$gt2W(KX+%s?mdX~?Mp#S@I-*lgNtI*_UX>RF@;Eg{b zYo*0;WQDNbGZ~f=Y?pE)C0iz~&COs2lrbX7G(wrA`)_yheFU zEzg3#z3pf3?H4`Bs9HqTgXXK)!Pw9A&uLogI`SY3*lwLcy3A^k)AWt-1yUKoH@6+2 z%`HoMtw7PlM5%|RVlgjBN)C!uvO_jJZ)Srl=KRc3shA|pIbGGUwFC?=HxQ2&7 z+C)aTuX@fTw)PqwY@4FeF-6nvU*dUZm=kFuhn~|7MEYxN zKuBlsXkhW@>zsK`O)pd;P9-36(qTTI2FGZPN}@e2t;Q6~YH#%~&s~Vz&1-1zJ;93@ z+(CTl@mz$qx?A%Z-oGsOu}e9jkL)LObef-6mvl$npH3;WOOgh4%vqauFl#cD!#H^p z&EeGL8ABQe!Qx;&=@MNFcK*IdZcEh|nx zU45(}5uSLeTWbmPca2P-S5nh^yT66@^(|2ozWC0SrN{2jyIKq&2adGgP^VBo3I>+$ zd7Sb5^z4d0o*ESv*0TaU<26P_W8Fa(99jj&C;h|NP2n|Bv99+5FAof8c{HoC_wi`Dksi?~hcg}cJPR2V1S121agVczg!Cl! z1vP)ZP>%NYiYDnf2P(}CHXTQ)NXkKA6O*vN6ponb;ZONvg*{s74TDV#e77&g>OM6B zfcUM1*0EC>SgVPFvV||o+@z4JJN(tgR@Od@KT9t#+Zfl$P!E-r#VzhIWU z1yG}j!TfiDr2Ax7PaqhYR{8Ov)L7L;if#F@(YP~*El*u)QbJevMxz}m2Img6QCWWr zovxFN#FM^1f1xI8flD^VbVKwM3HHr86U}sh?`=IqF zjilc!#7M=#B0$K0SJw8J8npdN>k&XUuE(lZ4L%JuimD-z;YzjV@>RSJaQ-9VQu|Of zbc*c_nif&x0Mq2sjWtmh9Oakj!jZPuuoy)=NBk+et!QcLiWWpMO29TOM57id&A`hYy;%E|MXkVNdFNmRB0m>NB$Y>=L8%rE?Ok@K!dG`Af zHbKlkgB)Dq<|+%z^IUT)N3v#Po_fzaL+#aw=wb^h^r9pmm@+>t}; zkrvb};=(=#;FUQHm%>%m5xPweQd-A3AzCVkvOW)O{y(pe|j6b)0<@^dNIQH#VLfFLh8!O11_` z=|8nnc&Pv!gEyaUFwVV%z$INz^$siI>2f34TBrZv`(1{fX+qZ;i4jvOix+ROlpw+# z%F<~rD^c6Q8M949pZq>%D9>)AxF(FqW)T4o`IQM(zrK-w&7QC{B=?7q0C^yA&4Lb4 znzWw$S+y_;-HVf2v_UJe%|v5Xc4FfGxbx#64sB>Udm>jeNRfdd_yVM0j)@kP2E%n6 z`##NWI1I`|h$+dXx-+=sOkq%|g?kCC`)uch5#5}4aEy~48x`00gL2b;QT%{4mL-z`?Vd77OIcw>I{BCsHW#dF<@z8URx<*85lHd z?*ZKSY1ia@`yG%8-)5hDH=tM)l%SrY$V`N^FW3a9`JSOSP>pTcy#~jd1B6tUPZrUI z1?SH5*htX4<#?f}$SnD4FOl{5O8>8ZgMG);5gR@{p)j{b9Wt^Q@?%p#Bgq-2+#EH6 za;dyVsA5K*6Auloq=)zOVSyAkr98YQP5mbtKnuwMrrZ#9U#ZS6B_!k5hFlUtm7NAn zbB<+m4rq3hB{#T$MOTL$t2(VqP9(M#a6OCEcCJ5FLHlf^%M%~xAy;ag)8AN>3Ka?&g{AQ_cpRayPawt+uM&uf%Tkg!iOaI$TLC+%0}>|e6Ct!S=RGJ1m#db6l^x>$#InayTx?pW)S%9^5qU2>8NBF%D! zX~>#!gOoAuIBQ!dqddZc%#ycd%vmW+ngi-jBFz!?UZ+~I2o4jp zuM@Iv|D}K-U@3&#sH~*aVIo7*XN6w2nx>YJiCRu;)t079V7*iusfbIhk1;kGJU2kX zZ>%)KC85k3BG#5OQT;V&K(%x|UNk7A{blpKc$wNT?-;wUq(+~CA#B9LSB;=&IGRuP`$H&!{jOO%qTIzP&wPIQ;+v zVSYzyegrZqR7*^nd;ZNp%%Q9pn{&v~z>9PYNGULR9U_ob={k=mX_-U6U$-Lz8&vSywLFZlRz-?IXp4n=D^D3777kOqWHW=S-xBz@RQw{+mnrmAqf}?O4ZlA(EXYH1>3#M(Cfv#pTqQ^rbH6aF?E850@m5t} zq?dGdwGg7gpel_*5~ax`isZ{0s7Hw_Tj*R)dfEZSeB_*vV-p*(p*l?5Jd9n&h?;=n zuO`3h>o)Z-ES4?jC2I4Jfe3`#HXz&JiW6`f+?wq#AQw&P4IaWsLenUuI{`Ygvf zE91WhAYSYFV{l#3=M?<#rplt0*fp)ql>th0`gIri$alV8QzU%w3Z3Tr!#q|PPyxxT z``ED8CFRPK3`x={GR@~#9FxVOPimV*xxt(&1iG+_#o9kImq37}pz2aET`_!q)O8d}X4b>p|Ol^>2X99C;73!F2;w zs$(G*8%8&TEfh|Jm2r$eO^cKiS-&doV5LO62zHkPLYFkG3m(UJ)sj?k5MWwp4nCGMaG|5e0 z+D>pdiR;kqDQVhFIH>$CigQ$RJUNgzhg+I^y{nHY+gSc+7(oyH5#w;-}ycio^#c8x?sadyo)U+qM9m4Rw4;JFeyb$bX#6i$s90}3I{vPwr z5QK7{VM(AR&8(dRy?;aipm=k9P$kn|YFJAk6S{`Ge$MiId&HSl0WUt zJwFb0bq~fi0jdUer!N*SdM6prN6?xBW&N=39e$fzzepO+tQQ2c6rWtOU<*k0vCYjY zAW9(&j`fFfcqxa$rlL2LoArHJKIP&hem)TXba|ZdW=RWNS-73^8=@w#GA{^`@G)0R znCkx8aj%0=I#rDNw|W$0otZchrv#_caWfY2z}!4cg{-*M)nD>+RtUf5LI7sts(0bg zv6|0jkh@1hyRZS0!5 zB7TPwKfUA;Rt*yRN-0W|*;S&wNmnPbdc`uuxz6uu^SaJ|e_i%X+sf3TY?XZQW&pj5 z)B^uu!#I|yQ#N@Akg=H1CwUReVRSi4 z_t^Cdog(g-0Z~{Nk=`>)|D)ho-<~6oNBy|R_k$lXdfnT9_ z)$wy5`7D?Sl?9w6M^1x#GY*~S1@TFicRy{by4uaW7cXN34wwtjXW>8GzmMeqe5GF8 z8-h{4unQJR)d!vqe?s%}Rt-=7VpH%!{Ah!AN_9tB&VaOwrX6>%W9pjl6gmoS_!;e( zSX*8T=yUtmoPDe<5?g4#ij2HwKc%)~0IqsxgJ72=!+%~6MH3sXPl^>4UWLvBbIU2! zh$%k4V~Q=cAUPdu9n+E?QxF5ObY!{cN(q)$NE-gu5AM~!?v8I)XrlV3Q8g%@l{A;1+=3XM&`K zwvWtMB7lbTSQ2j%?Sv|JcCBB+h_e(gq`}%WVc65$?pih8(;fK`ACVPdNJ2S)`B~`& z_+ydae$CL&({g=lJy!-Gb;9%~^v_HUWCMf+G_5{r6DYFE{d*q3Np&4%W4zK7k_Z39 zl%ajCP>c{%(Hu>~6U7>hD*9Kc_~&8ShZPR-ob?mmT3!70ZVF^B1or{Z}PjW(i@HCH_%=wbK zZ~Fa2=Nk?OxKO`OfSlSQNLMQcU_mK`HYN)M=Vv(N6Hp3+EL-RN*CYVDw~;;XV?OQghH z-JtF$-|+L>{fp>nf*=Sp%#J2z5z#IK%Yb#{d zKrTJodU)M!v=GNZ1gdJ5Q6Z=k#_>C!;O*fx_0M@+un!GRG@6^3Q z%K9w-bSh>RIkDlCOLD>J+MFcBh=3{^_8XAO49lHiDC-neE<>}7tUoUr1M5m^WeMK3 z{7p}HShccJ$y2yvX7qG3+E9IP#SaG1WdoRT zJ;w_d0xAsYjN^)57@h;o&jDK}@#PI~fLhcfqtzx;P*q;(qWKi9R>0}^y+NJt2kGx0 zw+e^f*W*cRuWu!WN&3&u2n)n_@5}HHEdpx~SvC8U?{mp0xnoM{nFPNhq*DEC0Zmjc z5)PUX8lxLpCda~2B)H0=Jn7gM#UJI=^Y=t0li)wILk2f&sAxeh7KwF?*p3oHssAuH z9%Ku5Vr7F2;oZe^9e6>Sekj*7-mfLNzU^j%nSI{71{ppdm7nynP!e1DdF(~szW|cQ z*XL)u?n?|f7xxBOBpyVakw6Wa*7a2%f)s^5`Sl>$iN_a@P1CdMWvh?Q1OLdJ53rm$ z#;jI5Dm-G4%d?0W1M?pLegmL#gU1eHC!(EJ(Q%xH8xm0aQTufq;TYRnWF%QPIo7tb zE>?J@)bJ~o0=ljWWy9{}hHzlbXTy>r4`J`nNIcQnhPfIrl3z^OKNBcz zvc|6K@<|@+EwUc-;>L1Hbi?J?IP1vEnE~C#QT(+V+s3rvs-tGhEA1x(Y$^SlMd5Oc zYMxPto8}+sBg{B)u&0D%E#3GziMGqovZJ$0mhF&MqSZqyCVxCD3UvE^wmPz3ab&_s zXU463X{X2oN>FmS-^Qm+Gb^3hTZL!c2?FY~o$cdcxE#BKX<%=Jmbcqu%F+4tdEHh9 zEpFzUqF0@5S`wv@w3~Jib#!c;*bX=9kR{pgXZrp3@=v)-RX{vJHcKrVtnR#_oF7w3(1I4+C=&dTLS+C;}Y z2dahQ(DuS7i*6RE$skO5$j<%rtq9q;)odIC2D-PHVtnl>FzwWUuKoV~%!;P{iWwm&?vY_g_4F5M*oKNl`Yc*HmT@!Q%#m3G(Ahu%WK zT-ky9cKhtyT_>NJSK}uJ{rO*EbW%X^0aYh-LQ`DcAHoYhu>)PforX~LHbul&=Kz@A z2TWiE!)2Q3x2*sXfZIiIC3I(rNx5v-Zh$mz6*=!%DUM5}oB7>YRc0I__ok;!nAuD=o z`d^4gYsgM3XE19S0=IrKxbIt*FHe(ClVeYA!AE`zu5Kp%U%61CI0wf6O1JPWI{TUJ zIM&J#4HTV|&K;wkE>W(>P zBg?x3O(D3UvksvVNsdP*<37m4$9LKw3!kB)3E*aNFPLPS$xfm7--{L{z7H^@12X>5 z-bRzpEe4^=AP+8j07ot%JfUOYNG6ZmSW^+ zm9!wLwQ!<~UtV9HTqB&$^Nk!oAEDiaCDbNp{5$yU zR+x^`8hy>s>aq3huMyvam76uBbGFf}YXTUlE?fgMMTfm)Q%84*YBVNGkw@d##NJ5a zIHInzK$9-Rud@^=>o0YjWNSN!`CGRlLC+d1R5(LknEXgCAIJKEHT>=>emw>Bsu0J&Qa4rbNtB?q7Dh|kKBcq@O8wg$0FEeClB{^8 zR<`HxA0$=I$eO{FCJw(&G15} z@0WB*oERtL-dui&Qr2VKt?4KKH7kc&Yhd6CzBT)IStHMBW>*1mT!z9Q*}4546PMfG zx7%-j5oF;Zb{thuC3KB%66xC!bIr~7jhxF-?mJOqFLBzph7@_AI#MXUA&oitR~AOI z4Kuv)+A6WY45x#a=yIq%%?9NGpnjC={0A-qVu;?V(TKOUVP>*R8ADw1?^go7=BF!% zV?Lwd&4!^l>1)Zt@WJ))Q3a$7`?rq>WC*Q``WsATiX2eC97_+48-W?<5xO7-5Ud2u zscd*ErNa+xIGad%W4T2zf+_g`hW;(H9f@D@(q$SacrMyab?v$+{XgG6YoS zPTteH=Wzd;xT_*dew_%%T&nA~oeP=N6`YEX+Vz+fJ2}+LC;jA#$B1qcLC5l2Q-lc- z%vRE@RSB}yb|DfRHIErO@mq-i%dY8HD+CFNe;?(yuZctTZLA=|9XK>r(%|oTt9^j7 z#!){;p$f?u)i5JqF+r}gBU0fzA$AO;`>seetuE_Z2zzhwfioI7bM@DG$DGm2gaVhD z&AfY`@nm{qu!bM;;$i!u(+AqjUFA(%;UklU`40jIr8KTWU4mg8e*c8Q<{kW*s-qF1 z`c{j*H$BZ@svFUmjS9$6IkRC}Ao=V{ElZRRkb0|G`3rg4Km?H&Z2fmk@pp7QK$Rdl zz8lCh-2Z}q@FJQ4pO;U?V#+@C0ovBH6Ag)eO?XNXlbeY-1cM zP+W>)-LYZV+lHHpivo6``I~Z1ylo=M<6eaB^HNtATLb&4taxm(F^O!6R)t2cyx~*7BnQK8Jq31DPY(svF*6Xk^%Yk1?Fgt|&_fK)Zt`q5 z#kB&@uy!6%M84F=EdtOj2==^ZH$~mcLOJYZymFt2d|oD0`A*GiqsTow!UTQEm;IEd zT@z0wp}k@gXPJu}u;-26j(4ktWtlGMPVya0<|GR5NCj>BvjfXXLV&Ex$cPdjewNzV zifuXs1@$5uo`92bUj`OSHhU}^rh z0SHb(p%?GDQo+Xs6|f54CY2@iR2F0V8M+|yl93R@MVuT`8ZZmnq@T;`<=VK3sKTu^ z19s*exkyf=o9wIk{w9F;=58{93Ceg-cN}+xP7Dw^jj9yNv5~c*Ih_+^8oml zg^XGF{N8$rkdyIv%y?Vl(~hWcXJzM5dGP}Hcas+{a*!~G&=4A~7mtKX4{ma>b$7Jv zPs-^(4{ADi9nHY_zcD2&*YM1=t_d{PEJH6;kofkwcmao9$1jXR!y6kLCI>byk`e8% zzow5rU-IX23Fmt%Kg{dHb1Sl{qqWY#cpT?H9`H7A@(=Wu)JE~qg$E)=jV#RV40(0WP@+LwU}g=4{a1Ces@ z1mB25GwxrZB=FDti?G8l!RMw8xaqQ3f2q00hY`v&oK+dy_EcOep+c>**tLAT8A1W2 zF#BenBzwpliCmFixXF{IE3!I&kk$3o7wgmlZIt^ez-2cn(X4iwbaPwwEI{ZF1L~?S z)e26*aS3?q5x3^NIPv9-DAOrAD?#Oj)M+LjkLi2!LLr(xX=@g&$HK(7w*ZSUxXS(8 z??ng9d@|AR>HKf-=Sal>Y!aH*b4`#7O}sRbp{ZhQ>_`=f$$v)*e|*d&Bz-4R^&*lu(nt=vBxbysad^MI zp0Ee=R`OO6h6f%u%BZl-=l`v*;8&}B4aUO9?euW+@$i}Y_4@#=G*aX3IN&z8EddScM4=*g=TR->z*TQT#-no z8!^iS0d9wtZ$n9CsSMHDZ3==JU)|vMW1u*~>LBr$zr^`=eL1YvN$dx8)u`>5QT?;3|hmhU!Y>6QBOy&4ic4( z!I&wgn<=O^U|!!>B&t@C0Q$Tcc$>E%Dp){J%XJOe*s8~2qdnWRwauwEOv0x;OYMXt zZfhV@pY+MZ9sU+Kk4K;pnUDxu{h5zb*Ik~_s~EDQjFcU6jzkjfA*S`g>*C-t%U`2+ zDnfAMV<+KV&}j1Clgn_o5?@8!EJkC=M(f&6&S5=CV!nC#&LGB)ODbfj^F$#|P34ei%?HTqDu#=0|j7$-YI)`54sM{}khRTh!pU^1GH;PYxjAUfy zD-g=az6Vo>Z3P6vT4P{P(&3*ftU$KKeAtPLP=*%gq$jX2-560~{kBj5x)hr-io3xF zS3a4@_WhNFGMCoM>@yO<#{%t+^NVkyH!crN|I8 zm=tB}vl1~%$zEoY=rfXQ%|LE}-f^5+9aAX-Z6Ix^|BJPE3=$;@_B`A6ZQHhO+_r7o zwr$(CZQHhO-}d%vZWB~mv_wE0K!rO(ShR{cj_{S_l9G@YY&?--nV357>&CiwCzH`th9Ma9 zmW8aSUBx&z-nWbbCP*v}R;20yuV)oBd;a>%=f}r+rooQLXj`Lw0?C z(!r#xRzKl3u>SLy43&XF622gk-e~3CSZl7sZpD+HVZxMVPYY|d2}47AActI)IqWwg zLCRTnxIbPEKkI3861En4vUus*C)`T%Kxw99!VUuO5Ov3Pt=uDy~3c ziwhJ*S39v~{CXoXJmeIKZ2U>q>i6F=y4UE`Kfg~j9F!N2*N6WrPe)_!1s z_%MV&!qoh!az|*L+fX?Vi&$DQGgaKOsEUSG1}7AFNmExZ+#RrM*JMEm@7_A{81JhD z2(mqY^}lF$!3G2A{8dpP+L8GjEt-%$z@kxK?{k&hp+Xtp-6Qvw6|)6Y9kWI|05r$d zpU>3=b1M!5mz4-=?ZWk6f43pE%&}P2Z`#u>q^Zu|*(tW&sX6^wv@iUM2hg7a^um3f zr|)tO`Y#IumFczS_8r)9CJ^uDURPiJdcdDbfzK*;kjX#3cx#~9%eue#;Ks2A#sr@O z@sFI)-pzrIxTQCFRd4<6;iG2p(9w2joV$oe(uWf@mOexLK}(SjR5jd-%%2!Xo-nr( ziFZZrMdalvjEl8~svuY+v#{j&{Jj?qeh;>IiGjnS+~{t4xYSx--*7mi@36(0ushNu z2sp>VpgL6hx@6l56f#YCEtf7m-sBE9HtZ zJ2}Kh`7urcIFH}75R|VAb~l~&>jLm*zu|Ph zb6?FLu6H?j=#PBn&^>wSUu65H(mN)eu>rYP3huD#&CDpVLfUq5OQ?9(I6aG6y4!8D z#<2j`enD4W4G*gF7*!vQbn1*)17#!B(={J^^1F;T~1aLxC01NyV zT}Z|(k&J8gr#ppygvl*YB8`ee;&yC_C!6{lhhpKVXI1dq%8KErLHn3LuX#Z-U(fNg zup}cBV!chQFE!E+Q``Y3#hQ?+FRIWWI4rTB;eeOO?e3ygUd>FNu7>3^3gK}V(IEJ; zt~?e_duMTIS6q`_>1#EKGDTq|IYjMqGvm`_9(h~!#~zT7+XAlze*Rte2l&6_9?}0I z_qhKbWQIFC{jvo98!UjH*6}~z{wL+}AC?>CO$IuCEx!HUBL5#P8#_4II?y_~IZ4Y* zLj~~vN{=h9Dd4936Z1l$q?LR*yYQNlM4I)eDoJ_STrhe1)LYvgTT3Z8c?8LND@`A> zHDVK>O{4Y{gJEGc_sOFDh_&*DX4lU<-0{jF${HFL%#74)pHH~*do);oa{K?PvRVK4ouj1hXer`iY~%F50+0T~ zW-;*N0P=rV*n>rIvsr*-|B>#nr)D)s-St~=|bqqHC)R&U9HHW5t9L!Sj?nf_V1Epd~G5Q4^z+XioAYnY?O|0J1X)29Us> z;^bGmeFegR3n}O|Ajqj}c!%BS8trh|0A6>f&|7Hk_LxB`4q5!d78(mF#=8|W<(QU? zB;3gFag2M_7om_GdEmV5qtZ{!xm82I+dLD>v!l%l28JwI&|tJnvzVJ%RogSm8f>E-ZP5V*ER!se%Il;QxQ^^Z%08%c6Z z;m!`c)b;907#+m8w;?e_C*ELWp254m_ZG!!Z{6=uS{W!o9S`^r5&Kva$rS`h2GH5i zADIP8JnYz90Z+8ZC(?sj{~A&z=T%DS1N<5I8%FvkMVPlA7LB)qKFV-xkr*P0oE5!I zrgmuxxFD?3g#xo4kCePPgqogtFS`?i+auPyRYkivR{lMpL^M}iS9Hm1h&2FUH7Oqi zg@70pUw;~uyii6@D#~J8x8x|Yz*azJLAu7;Xzyj)2c?IIdg^alrHG0$8c=Z!ZOC8} zHj|b)FvD7GS2b>R6OA(B96${i0wN@pFxZd+WwtRz?-n-wbOK7mx(B%+k*{3rY&ib7 z0(@Nf_Zs{O>=cY%ek0zS`Y5&B13T3R=P?X?@z!NOg3|Sad!?^j?oe&pYR~vP1(xJt!q?xloe|pTjA%cpTF(VfJNGJEWQ~X6u#(nKr zOPlOpAod1kBrGqw39oHt7Jx9{+?ihqtFByhxGto`4Y({hGkPua>Hy$&lp3qkuinMg z{6-UxrBSFge`)4gUmKnjI8E;S1ki6Uu*=unKY;%givEKQ^4n|w&x`E$>3;_vW1;__ z!5->AKP35IjQsuIH)3FJ>!|PK#>}34k;WX~fOpLTH47!ZEY^?v&kn$gYc`r6E z_#ea>rT-uQ@_&hW|AR0?`k#cEO;8X5?3J&+$o`;chdl)eG|EY*Mbv1_@6JuoLJ_X+ zsj0`7$Clh`DkVB@X-96s)2eb|!OL~>!Qs3>1z4(5S`>#F=pN1X76#H5zMC3=(E`*CGvFANSNU2YrWl$h}%z# z0^CJ`#4sIB;XLP6J<;)G`P1vpx14u=T1@o8b2+*_Jbf}%Jaz&-(x=VljFnmHjvki4 z4dk?EQjOiA>71$>HpE(Sk#AYt7RJ6kAu;nh)x$>0ls$uF|JFJ9Ce zNeF@S6#zg?BO-vp|Bp@cU!n0oh%%e(DL%UuU+@)Ek_wyK2VV;x4KZ}v72yWfMr81X z<+O1i);5v_nMDb1B`3XffN>yy1CZPjmvB!7j{g#eJ>uML+276ne8!5u-%kGo;r{KD z9e@1e_4s%+txKCg43(t~#Md8+FH>-u+cVKC-Yd?x?Bn(*#5y!3Z zyen1M_DQt1Csy1my)$c*ns`tnZhZ!?_fZE7|L^?=czCsSx26AO-y;)boaz01b=dh{ zlXt`veORDPgiqDf4%CnhDktIUv~v_cM|j=(5Bz&S>d2ospJ(KLbelhZHCaJE&K>=% zGJPw-_SgI8O9l8}->2dsOyACMtz1vryJxOvyL^*BG_=$Hf@3oRbt1dnZ~l(=$_RYb z{f_qDoRjAkr4l*ey!p|*+9=czLbp4uS;JiKU_a>ow3~M zC2~m~Yu-ToT|2djX8!5n2<@=+3ZLV58tsyVZGry9MHJ_g-c73gw+eqvuf;nGxwU1G zGfIe0sDvGrD|E-?kfm@0Ad;#Dd|z4{p;v+p+sHWo1>l7jGOk_cU$Ev5rmbzZj1f{& z<yxZl-GIs9w-m65=k$?SuGHziY<4y3pcV#b-3xO zY(X~A3Ma*v7hgwgs8bRcZ0Xh=E)smg+l7;?7ye^X7drFg(St0Y#)lSEsulI#?}Nuh zgZlFI;QfPQnFS#mvb4jvPZdSm6QBp1r5A05A)lYO2zn;|w%Y;qwLG(gLTp1aj0`x> zjTnZ#0S?F%qwfITOZFAlq_sNqm(ZA`{hXzvc!JPPqjb0t-xq@3RFm&2)R61y>aove zLT(p+1lsnG)v!D>4t{BFMpA}M3h}x1ePS^aVBEsCF9sN`RI(D#R?(vaG3TZzDw#*V z^z2{#-*it4*g7v#07t*`&?jX8+!p;T5Sy(D-e$jy3p*ij9ba$S+%bj>hp^kw6GA9$ z^ilmKsL27{Q8iAu=Z*E{tv`o{?eZ)L@A{mfne-kukmO1CWDJM>0CzaEl9Y>^jywf& zY8?ly<6Xuu!hs4Mn6M}V%QMVU{4kU9dCRiE*GbSad|iA#-B7HVE^5A?UM!ijzMt#> z2_qN;9M$^sjuf^VejRDE;C+kSWZY<({&AlqLpQy6+)W7(CH_YKfJT|o=5+`b+bvp%0nKKaU^SC;&ssX@Tr zFl`|}xcpxf3+Vx~{*`Rs=S*Mp8+l9Wn$YSer?uRF^G5bIf$M~LbzSV{E~n$6Z>cb6 zEyv-I@LjD*F9z%M!kU5#vgn8^@}3U|PVpsN^l(0bO*1t$&eg~a@8o%{0oGzq$sW#c zLP;bxj)|P7R9{5z+-e9Vt@*Zi`@r{j5AP8$Xb6Ic`S%t2yx3$bmG_%zkdK%0kD>j` zbAhJJfw6`3xji)w?T7ECrEJWwKJLA^G`$ciw&kLjfSf1%jmfj*)0m-FEzz6(I^pa& zz@>Wptw`JI#58Da9=YG-f~)bkcn6L&(Z6;SirRFVT_E3)?f2mEOJh%6Rq)Y4WQWQS z>2b8MHpm3sC;H3r?k1hnhNj8{?aL-Hid-0~81i@|h51#B9|65J0;}=RP!WX-jeu$O z6F@dYTf$N0MwO$mP~{dZokqa~z2antL&1{X1%BLNTZr*nBI~AU1Kv;J(eT#&@)2w% z%Izu>*Az{N^+9kqz_`@tFgu(;Ie{UJp55Sdg8$|G4FGBKvv;?5t+&u`e-2URLab6m zP4hv}wav1!l79}VprGbKiR`Gr(`j?|zjRl^K8-0v*my6WtI=D6x2wWj-v_HBj~M|v zRH81+Ux|gp>$TY!JB`gfO}xA{^Zm>1w?r=sN+{{<`)MPm#@YCf)9-9U2_2Y5w=^W= zdqsH^1HkMO#xG|j?;`Y*@Dr@Ch5}{tPEpHwc;w6iT^m{wM3Kj2K!hhJa4kqxmiFja zrhNK(aL7BzP{}tL8*KnNQRh4%13Ot~*HJdi$)ZH+wQnO zqRSd+^)*r*8lqh8RoR3uJ28e4plRYfznXsmevi934A-euC{tT(Y${^%MXHWIV9Ytq z5{&$3ekswh4&%|^Ej)*d9cvP*i|kL+qdw5PH~QyoJ{~pRzDG9v>Ox_6Z%?{BcX&^5 z3_{N6qpYRy%V3lh`xtcXyEPD}RwrrDF(S@1g5Dta^XWHY;*9&a6FkJV)G#eV|pB{}P;k z3rWz6IDXcOz*#rU{zu=gh|Q)TO+ZG?-T}ZWZlA?MF;l>p?B7jCoCtC;}a4S|2o@uHeeK}cRc)|*NaVE>> zH^G*Zmc`jkpZXwt>tp!Zz=BMmTJRL$&J2jtP?dJbBb`CrMX7&tzz}{NrI^1mV!$#x zMb(7d3H(IYG51A!1+r$$iMd^694Ca$1bth0HQQxT8*InUlD^%a#-FRigA%xl4_I8g ztL>I^H{QuQEGL`3mm5S;tU8-;b5#9QiVQFd9w3yZZ#W=q5GJs&d-R9$xa^gB43lS* zXcLn)SEo~YD03eGr>rDgLip{Bld`_QN8V3 zb22jt`mOQ0{vZ*rLM%=om0&zDt@2Mo%P7j^iALD7L{t!$p|cMhJpsIH)rtNYHytJ{ zny}gZRtbmhCeB*#`(Aj1Wmt1@6hO{ty<(sn+&FWJa7tfwV%y`J);#q97hYC?SS{Pa z1~{`;wDHOUVc)N}Q~b6OIcEXa(~*~sW<5dkx0eWRk>pQ-&3Q`4)`1 za7{evpSt_+kj)#D2ZC~f+tkt+y%3zZD-ObBdU-&w(gU@z!L{=^oB=Vt^+%r*`eA~( ztP1okK?&I*waTV4ImUbUBwn>O5pINUV=YF6EG29IJaB$21mBUxF%nP*tL6i47bH9D zE06&fDu+vOH1mjGgkcGTt2c|%1N0Z-amq752~bh#%i^Z$NS2%Mb7kGXLuAEPxWRY^ zxS|@1r0ztFFa+f5m|HzoeOwMeFEY>BTh2e0gA3{>LHR_8K=N3N`;;h{n0qGxAWxQ= z1fdC_OBG6BwF*RYYUar#eC`X%Y~IZ$Ld4G*U_vOl18NlCNsgz(2;XSA;toAJH~Xyq zZ0OI^6o|LU2TW=s_gg<;RJoqjZ*F@`cT)d+**@=*ddchdu%vGH_E}3TVXC@ofB5Wy zoe$CtPAgU*?R?sqC1nuK;j2_e929^VqpIiRX}JcfC3S*H`(!b9Gl&tI!}Tzc#>t4pNH$AQqQxu$tS)y;yuS&%~9VHL;>5xR^NT+sq; zqPLm7`9BXYE^^|7O0D-KE`eSMTcuF8V4R>QNx{8IIJ?FQEr8PAdT57$nIrR|Qul(v z$4*tILGHHp($ela4+fg2lD~ktBz7Bx5cxZRZUc0KO>QqLqB|qDheW~12qnlX8n1#Z zS=v9n=kpexuRw6~fZ5EF)Z5?>y`lip6v@QvnNsF{pUdEx&uN=|2+9TO$ z%yx{|T4$JiUG}!ddMqEXsLpEEL26kAX$6#)>QQMJ6uNoXgks=sSXi{jD6(=ZM8aa- za&jia>7nU9@c6S!Z=#2sWDbXO7?;W>WE#x7i*X$oc|K=9MFrj+@~}->Ci1!N^n1XM8l6BiHqLA5SvqR-_}R3HNV z!e(UDB~r~Dh+Nwjv5j01L9;v_*4y!H!2g>!T{aFgjROAl38VrWN&^*CpTq=VsC|`C z7YI~}n7@8Q_i9$2p@ODrT{T6ES^ z@i;4K58DDG)YoB7q)MFrBL{qPu|{v4D=a=#m11IC)c$FT7%A*>&meE(m@)>GkTA*Q zuqRbh2Qz241aqmQXb8+Fnd*(7*W#4}+3%@ha*7z}-&P=Oj)W2wgTe$8eG*YY8ezSr zCdd`sL<)YM)^XK{Ej-$Lq4ytCbgzo>W074%2d@vy&z!4=^7MdxC}Oq)20=N_s*Z{G?T2NJT#G zyvCq>%myoBNlZ-gX^v14cKsV6+2uJqsVv0>vZ`X}HmOQ5m4yKjQ2S0u&B zXHcAVZc+KPar|8q`m`nmSpo(tC3q%DSKX*|e_oiX6hS9DH`=D^3GmR5--FG@y2HaNjt*_sEvgychGXi}3DmQL|f&KNfb| z%&FoLfVkeQ{8;T);xDnC884kg>J7`uUOjUOo_)J7)9~g>Ltnf+bf6P&J2_h zK)#OLU~=pvx0oUvj9sO1DQ$h19G?Y((=ztw21gJ z?+65xRI#`PJ->tlZ@~GJKT-L5CQW6H_2p9jNQVEI@(EWbl(iKjVvwElfC*!+T%PfZ z2*?eos5vU_FM8YVOTk=g;N3CW@=#?Dmac1F(0Q5XC7uHJEhIiVibl}US%;iM<@ZSNjg;*^FuF#l zex~jxNTPu1dZbhZ+d?AgkrtZW2L>6=Jt2`bZf9=l?9id{IJ2%H2sfI~1&;H}#K;oU z5D?eFeyZ-YVB9I4>B8`d<~jE6nKrM$3>)r8OeSm5!9f{U+f<~FIGQ8!cUXmgE6B-+ zVB1x(EBQs}cYA;}UyQDo#0-Q2fcnEIa-6N7&k2J;BwaJW7)0a#*%3!{H)Z6t(A5|crH zVFcNWhw0cFAZlCmc$|?b6nT@ix_QNL-Kesl43c`TstgFa9BD7`yb8S*A3&%~Kby4L z_-ul+So?`|o0X|*FLlK6nftW<1X=C_JL<}Hm%wE@_I|;lu(BmzBZ5DzDu5!&$NxK* z^N6G~Hn%9dt$^2{RnoY+xyiZD9inO#S8i&rm8qv;`}fg2#oZ2sd7bZ-{A%hOj)uda zYuv|dY|u8_9D$16P}_Y}_hUyI>I_CYdMcb!w8DA%h|^(7EaFxl9k{~O@vki_nuQ>0 z-k>|ObN@;AaQc$>z8Ws^{r>yrBnh?8v+j}C9|V`6r9W&|!D+)Hf9nz}M!T^hh`H5Q zi#RzR;oz2}{USwO=1nz$i1Ixm^Ct&si5D0$gU)304FB)FG*Nh{mqA0dQyNCQia!h=8>}$S!Bont)Ne7ThU)SMx%3`e4MFE~FZsya(ABb7!oj?_ifbw^Dw2?X z*D`>r2)7>WQ3=YdYNeN>8ZM-y*NSQ_5~6H$AD>xhRu>$a#_j5E=~i2mOj80IwHKjgv92cGXuOQt?h&xY95b_bd8SD6&i3zxPPN!F;&nrHZQGZBeV|7+ zIDxGkSQ3A+B<#%QIpm!R#P*uz$1H!{j$bYQSe&0ey_|-781j6V?QC(! ztQ<0Kk)LZV%Q!0EX)RmTKxI@i9%%gpvFNAsT2ei5Q8XHIt!b0Ky*xVD(|fwAbO@^* zlqMa&GMAE=+t-`}q+8?gc`MxtJ(xSzHnG2< zB=N@DJWFsq^G=g#|L{qTS#+~VA*@NfLFRgt;1FeDDsj4@cXMZa#VF@^jI>bK@`+9Rn_heJFIQN4^wvc? zB(j+lY-7L*py@Bn?~2pv=jQssAeX=Yeh=sz_a|i`+waOsL%o*6^%tk@usdq43ON_& zU~#G9p9n8D_(8`OYUp%UWa!4nk!Oc&ZKhk@v=F|~6s`8w)+btlqiqoRtfz;UjG>U~ zIzl(A-RIgnjvLuY2{}95(3ZRM6XA~HZc`%*Z6s}QVI_}(O=qHjoLp3`0YD^8{Z>U2Ne%{Zxf4f z_6=+J5ln=gc?*xsAU}Ea!j#}12J2=MtS&R0uZ_KnVfX#uamQe(oMTR8D6mL$4({Ev zGmD~4X4NfW>vd>U*-vRIDb>=>+x=|M`?SrsFO|! zmKmDy51`7ef3Ax`jsb8i?u;zNd(M*zs@OWP-LIm+%h9B5dK)wRjYGgcbW$Q|wUh_N zJ9Qrq*@{m0>#iyu>LEbA##N&n$jwF5eG}lBOPbRuuwIh| zNUL^m1(aY)quY6>%CG-WMA38w>cC{`;1Wy;%8j}uiqXiE<#c!KQl|o~-@U2MkC-}j z#oIDK@?iy-l+V1Ew0aV$bF@vYbN#V0VU1voKQhFRS>Ke6O^Q>aH@AQ|6Vzpq~wt8UQX9cj(p~_8STn<94CUYHhR8JUWC zOeXB<6}gxTIcBCdm>vP>M&%P4OQr8XiEj$gc=OU*>5oh!->N*e_)*R9lmASyrN`(s zQJTl>bslPdWFhr=U4$f-w!wljlGfg^VLt%u7Cd6_K9hZ1r&e~leoTC2It$a(%wqId zVAa7^;hfk`^B|AU;pCQ&(MMr(iW%pKjkQKfNDYEa5j3HIVMBfVb!b#v!d5jD+bjNV z3}ina-}sr`X}lh>HhQBPFaWoNCq>tZG}G|J|5zSyEW#Z2AiX!fiSbjhG#=*a`{G&E}FQUo)&8YY>Q z#@+wMAH~i_2d!rFWQfbiBNGc7lTQ#$ zSWkE9fm-=#n+V*IHQa2EKU}ta30I0iqmjel&t||72xm-F*yjPPJ*^)rQ9?^x5C5;% z+#$_gB)Xyik8wLx3TH5}5V&*U@OP*-@6V@Ma6G3|cm;wv0C2V{nak5UoGsfg2_%>HBy z)`ndR&ho`0CI`_ikoyq3DwOdV9mVbRyOQHyZDb@LEYy`Du+7xvsNi#`d`?p$`z!4p z!xIrL)oL$~pO>ib-4}Szm8PB^j}7)pqZ?wO?PzGW4y`Aba&sL02&@j2ou`(C=%oYu z5*G6h*3umfO{C7>nrG*<#KaYFn`HE`7E!zoFw<5!kAb8p>#CL0FI&ADwKqMS?#~%z zmjC>x4W72Yk+&?ZL^ z6OEMT^!p<-vJWx8yc%xb+uzeovmgG&lqJiQVlLR84b(x5 zXH=f*>RfJ4naya#E|Y~Wg^p4r!6@d2GWJ?M^;74q zO+R;vxn+3C1)*?Nw7QwSoh3KKdO z)jsQ^`fL=t#+(8__5k$6ZJdB55%^o*h=9biduKBTY9w^Da3Tjib(2kO#pahzH)`r{ zG!%YZN6?Q+ik(0>YVVUA=(GcKp~%b{@nbIp4F-Y4I8tOjJ=;2^v^z%k99hzk!Y2pGS<#N-=C11M+2s8Z6kxgbYyd(OT%#7Mp+WaNA z)h!=ZlF%KC!AX5~JWJoGA^s0Otq0)=u8Vy@;d@H~u1F>NYvfZgl{yffW;fvzPljjy zjvgO0KlSxt1otc=q|drJ?Zmu6UP=azKd?E_Pw;My+ST`+UX9ijWp@yJrHHEVdaydQ z;qyFO*g;ZI=$l`d@KD{tt9am~R_!QAObIFx;eL-i(D-hVF}VuuiKu(qGOSYhi4@{6 ztbw<|YeLg6iq6xi?`9F(_)b%(W{U)jJuc}LNXLV=rYp9T>Aoei4@3yD)X*UqgZ2fn zvyn0RB4YH_nAtG$wls+UhTI|exz4y&&w42`- zKmGiHTa%}mXa=jubWJ5Y%|)d_E6nbYUjPv}m=p7ej#Z`V;{;Vi7!49i$%}}i1)(G* zfZV}(FzzUDj955a1&__&U;apz=Z>T+YtWcHHBroeFmCR^N=AvuN52!k9r721^Wi2v z*c;6@e5Kb5DI8$Wch#dWlwXU2ih{qkXu&y?bDa=k{;GS|6Tn_y{&lv|sH^ z)bYWk+F`}&vW}_#y8X3qOnmZkllOA+vC6Vzg*o08c;oxstd{lJr1tsa`}55AW60=G z+BwO0EB0WnPC8^(@S8$=0A(91nfJ5z*o;ssg3di)8ISYYtcP}B(Y;}C`YyyYEb7ek zL_?D>w9lEw8_+cp6t*}A?n7IQWG6xB>d<}W$8S+;0`XfBbdD`*2bBu37caSmJlQH! z;#^;0s&BycV#W~xH8?-C8^O_@hCbi0+3v0pwGhISA~%L9jZ3_Z?Us&`pc?Z9Joa1G z-D}j;E7oXmpTWt-y_M1zFL@%bm()?61uwPL5Kx*)>T`zN148q}!rL*m)>q5sW$^}m z(EnRc1108h@{*^CdxX>~*R)r{F~jdf{i(N|rPn9ljeMHUBPc`nj1MgE%;BThSCZB> z1W9>o{QhYgf1vyO;^v0ae~XePe}bzanTe z=Xu?teR{H*36v~0AOPH~`zEPaRRR9*(yYb2LS;&TY10LsY>lwqSO1>=EzUnbo^~fMBoTrJP=eLJjRpET;HenA=H1zr+F37M;Z^ zDq?O}vHX_Z`XqZ+gzV8i_>!?1piL`04($uWvxlFpZ<7s+yXT5eXEFK9>(u8MUg-mY z(tY7PzsL%L;Yj!*>h`KPcuGA{)IKLG&22J^&8I*|#V?(g-7y2^Kdfbn2cg(&wnr@5 zV?asuYk_Mgh%ssPZ@tUpl{K@ z*hE?kt{JZkJRCrF#cq?`lDJdvKeT7|4Jef$MmmF?rB~TQI9^FeULl_~16Q{zPotmJ zgqJT!Z@lL^8!D5$VD3A2)?MpWD?&%Fj;fzzWWAbBIn^#B3(AR#-IUs(ZP3tR=8thR zOr-T`*bU)tznU-=*7T7!^Os?3;(z5_hpF6gES)R*{Lgw&luUUzH?@2Q9NAN#s5Y&^ zCZszBH0RseElhsi`6?`9x2QRFoad!v7h{N)yP-*9oUX7551jSd@YNfN#!fpv|F?24 z??B79rw}9^B`olHbhe}xRqs=0T#f8}txKBO`jLoJ+944|5CCjbNN zh;-F!2#qc055|lOp~x|gIZ=0qt_msN;b^Vy8{LzB_$6cS^r~&@G3M@dQ_S|QSEj;~ zOZ#x{y$5aZ7>kG_kihoU(aSs4$TCaMaPe{^WmjWkx$KxHSqfTy+H#M`Sc%EE&B(}> zIviYEawN2U7$eP(({uE=90!A2@lxO>n*I6W$JRR0L9%>0kHiq2k$ZB3>tT@%A)q+_ zRlvzW0g_|@P#C8Al2a;==o6RDsPPbM+X(B%`(8M?x5tHn2CbvZbA0zsE0qCgu{w|j z5EY&k4N_yn{Z8^VEY@i4Ayv|!qO0tI#;HtcW-Z8(fjc&D526zY%W@x9^D??mUuG6M&f4Hnr7Xrvr5|ho$hC{Qj@1oabH~`@aUb(}nqgzF?)g zwxo_PzVI@&J2~kf61BVrzS&xJ!aYZd(F(IbGi)p)yeqPK`;1YH@5ELKKS)U~R*^56 zCfXlaqRWGb7xXi?Zw8gF+LNazsp3mkEHa9e*vYjtU|f`nV8P@vVk$ivh^ks0{Fk)Mb-RH6yEco;&W zJqEOq`(9o$_b$AE4NIZ#O5wl%>j5ixw-;R)_#m~jMXI!8c7 zj9Jm$?e|NxSjMBHpS9$EzX}JR7mpTgyDO~(datrWr;L};j|vvSv`3Jk6=Nw?0Am>E6gvt zE?f%KU7&zT|Fx5}D{(oZVd; zU(M~CmyWH3N}d6=t=PhF;-!bwb}0iB-5!cbc`WBH3r=XW8k*~}ZMSx5wi^eXq8eX+l95Yzk&i{~K{#tBc>B^a0hDM4BwC{x;1~(k^${zJc_=pu{~^61VG=pIszfj;mq5>W@^tB=w}hK% zCv!{!GY?=BaqUQh4J7sjccUW3#_PzJV$1}vLXYEe??aNVKXE*FB81lvA`KpNkb{XDUA z93KgEssCEU0d#f`K4SrKxXRE_6jS)sMe@r~S@bSAemVseC$Y(``wHBvCx;OZVQA<8 z??W zkf;-j9M(us&Q?(KKoX$i4a)VMzM%XjsBjUQWrWnIwzj(Qh*n)2R&s}(H8Op?wH|^I zNVkVwZne^jpmSl&lL=7uHgR;OAnfMLp(dZG&4=+uwv$ZDcevzsXm!NJ3E|O-a z186e#zfVxEx0ROoV$Y!{5|Md8ZAANmY)qejxv&U&?t$nn;C@F{NPl~af&8xiNz301 z*Z!QA%=Fo{vu?+f@S0kDZ3`qPactn`C51FPXKCSKpJ}3ucr5Z)sh~U{arc5jih?bf z`fL3`Hhs^4Rf1{V&~Ah{-J31hq6IH11r;Kh_H+<3R-&}`rJ|H3kCXs4mgTs?0iR_Y zK&lObVH+E;qfeTaB!jKwg$RNm86?>1c4CJhn#F?KzbPIRIE&>l{_!ilDkYL>cOM7a zmx6-s*}N}#zIf@-+C>}2#Z7Co$Qddda0sBDaU*1tM9yWZ(}Vaz#gCFJIq~W&8$mzX z6yOl2Neg-l7CBU+tId1hXPRnchvovVCR`uX2|`0n-^xX)-HhBqn#_t1p>|(0P|4E- zuPw!Q&fO&C<2bzfsu(B~EKAc3XI$(Y0x@07%BtBFZsf?{@$F(Ku>|SsElslTPh%Kp zpiq5t@UPi%U)kmD--FGpAZ-KXOjIwvkTnb$wtISdHcYTqg2mk8V&oSqgqDwq1wNBm zJoyg7Ay4DBchy=j(A?D=s5x+x(-m?N3z3{5q+b+^s$*Z>OWn70Lt)^Iw%f#h9etn;i+~ z-tb71?I}7-eqHU3h&7!ecr4j|dOK^pZ!2_e%t1Xdkfxh`15<*iXJ0dD6o+(8{XF%Q z^?qw$&+WG~nmT7DI&)#sIQ>Lby?F)$tuo8(Pp5@lHLcr?{4Vxs^%aw=FXMT^|N4i!rq>Pt;gzv{FcpL$Cdtb-LHoHgV=Gf!RUDG%BX6stO)v^nsjt+CMtYVAv@|?L zU;r+LdCua9E2=T4%~pv@5NShCTr3C~*(5|V`nQwNUQn2i3{$4;yWYM*q85v4CklDB z56>^8z1>@L=MaZ^IY|^VU5k&I&nBITqK~&r$_+DJ`n#P2mkwfIrNbBSUTxWt7AsSk zFt}cc{>F)q=n1L1y)`SFAIH*6#$TAbE7lkVnbH``BGN`m`8J1??ZvXGkd3`) zm2uWyzP=liv#f|VmD2EGd zo~n-d@iME3FVJX4%+f^kk5{`Z>jR&!swew1V|RO>MT}^M-vX@oElx=F?E&sW?zBV! z>#(G)MlIz*@ixXDhKC`xh4pOvVzV?7F>apAesAB#t-F2Q%5`)lDgNmA_EonwWBx<6 zauaLNObx}xpduf^)%;_uF*Rubnk+QhY!f4h3I2|ovZO4JiYz6awtDCq3|f9~5Xw1F zVv{$a`XVP>^Z>z$fSRaU_%L2Pp=KZ~tv&~nH3FtRHe`8x^^@GBvaC5n``UX!RTX2^ zdBWd{`r7cARJg{}MD@&i(S{xVsP5TheybhMyd_o@;h%A{aT0k|<72 zQ0mlVY1|>>h}^4d)?M1^jtFgf^@~cEBY&e&QL$)%@W#1SXQpLoPXyZ>P1+achK;#t*-K!>Nx+b>30^_< ztx66=Z52?Ul{DkBd`&)W_b7u}Ace6v9FcyyG@e6`3MN4{?!s*Tl3C~zo@M)|7fLzS zC-M*t=#rUT&}-MQFGm;}2fkyr&BtX-@@pb1xJCu8kXQwl8jOD4RO@Gp<_({YbszO@ z+tj3qfdOO_giKmT` zoq3`o4r=1$#)^?9ipa6Xd*!p?$NP8B!zVl5wQN|!&(&0I|***t~Ofjvp< zr=bH>zU5%Vj_WX-Dp2{3i|l3)jDL48C!1Riwt5|n@G|FgXP8TuPsC|B8-~IFDU;&& z)TXS_9o)>9NZdinRt81Y^#2lw&DY&tM$1Qp?$d}%1x{Q|u~8mhR+ltH)4=OcpO&T$ z)^Wv86fDqS6|k*}1~O^Le=T}8dTXwB`jiu%?oWHPkH?yYj!8C0Nn=GVS3Z>`L)U?(H>&Z~e zFTI;nS0>7bln9|pYBV+TG^0R@=bkf)2-35GY0#0;D{Tx#V-xU_ZymigvnFGfs67)H zCs?O?j~UbI%$lCJv)cN@o|Iv8yX5^il+Bh}FtbFX>h0KV_94#sWUf*tPjQ+sE3)## zqX#8#9PBBL@W)@gV2J@jjFld*mCeNzP;R&$pC)>%twk=vuWG-j;!z$Cq7!0XX>A~v z5{)R}vW8ifrmmZc6l!3=LD*`}B=01-Rb3$bAH=;=oF(6~EnKcHS9OG;O9vD1ps6JbV7$`HnNFyC3 zy!=kvb>I6VpO@f+#dYyvts(sW6RDjodD+4lkT1tlBF&B~miWWX_|cnzqs^<_z?_U= z^t#3KT^PU*APN`s*IalH_gNDp1U6>cEr%k2&Kvw9U8M?50E}R|B0-C(wr$}fDz#RX z#N|cWMkS5pu)g$f!`b~Vb-NSg=wBG7Dw66uWyhshS-YI$f-I4=p7p>muJNy8uL6;+ zqop9z>os$mW;UUjhcuzklB}mBk3U0*FE1=;E|Z(JsUhC=jx;^mnh$U+M|Zq^c&(JC z0J?^OPN150(3UT|j$2!479TI02?jHu0Yv70SxuoTC8*Q zWO&)8S){sq`yWHZ&tG(m=!bFSF;any8~1YAue}^wnKKAxC?|6FNz}E-&zdbTX(O*i zt||sKuiK5|yC^yFH|jfiC~}m3K*vt?madMv9bauSYj}lu`ewQ; zd6J^K@|#^8H0I(wZ?LC(!RPm*uCF7Jv@DF0!7|YI4Y(w zhyqn|tASDX&58WPsP5(Cs#LH#LOF<7K;Z}omALr$h0IE#(L4V}mV82{xj3t>hvTqc zt!{E$lce)1@L~YIdq!3__BJ5C#a%M z+^C5YCBj4ogwLk!O#10smei;HO2~ZfT*;y5hS92nRj-_=eY{z)*r7@DWmPvwM>0%PgHPbS2 z742kuc%IVBN5NT$=E|uauBn;6tijq6d}~S~-X}l9#B?De=q|fY9-rX|5{y&&K$nMc z_~{OjapUn-mXM9*>7ma<$f59GA5ig7k&nt)YlF4k&qm~<^*$ujys94B>;%NOtY^fKO%zdgV8w z$^6U;Zou$b2pB~laR#8%j@FSf?de2dx@cd@g$jl#Y_t*7iDQM)nJ3}?bG?clWKmeD6`Pj%Sn;WM2{n)}$e)25AI+XlxgO#}@$ z00@g~u*O$rSkQLdJ5lu1m+185NWX;bY8=sti&wUiLmr)%PaZ_Y zdkQgBV(@J}f;Tr!YetqU#!IE|$R`Ri&reG8XJaLHr;g7}E#(2IU68ouegOXE5j&0KtCiXqR4@a3ghy7bx~@$dGus&1Ub zZef(%5$HIWRwxH;)#8*$=V3^;Hy#57D0*Rk{k^nNcdl9n|PJtjBAwo_f8J%@o?t-H`iDY^I z8(?GF1y8w(;{BnLB~8kym{lzt9)@F-BLF0>=Pi_drREK$l7+@Kl_dZKQ^T7p%2l4p$t#RTbp2+7pI@&uiAP&MA&z@e0XrItP50Gyqjcp-ZWa#Lpl7+ylyZVQB1J8Rv$c_Aqm9e4R z`HgoM=eyBagjD>WB3BnUJ+c4;LC{+XT}E;u!gS&C5DMiOe5qe<{AI(RK7I zLCm0-T534B1{VLSx0-`r{?7!M$=*JB6SEUeEn#K_!=iLs%M&UiS{^(z|u@_1EE`O)N zw!YD2f1QQ41#tL924xtm+N}vlI-zR6v7K{6v4Q>or_6d%( zmDe3glBiy)!Yr0d^7Li@cmQXocr_y_qq>a?w8m3`!}-GP685GarR%08fHypkiO zilRmX*aN%uf<>Ix#8ix5BDP(e2&(~kc6**fh$@U$N^P7er7J924yG#J zp$`#|Rr`m_ZQaZ5qVvs@H8(|p=L20~1C)nb2FHX3^6dWVA?SeTF3s&(r+SQ(r)iHy zYF$TTIzn0VS_r}(X{dc&pD%i*tfIq2_E$Ie*QvonHXg2P*7wy%YGqTYH3WwpY&y4R zmLZ#+Rj}m^b%PIN*{_GFA{428oTJLc!Q?!&{Y8gP4Sr!vM8V>4ZHt&_w7D@(0_sRS+3(11vg z%7N81gd57jpkYn|gLkf_HrdaSs3#p65xn@tfmTPtgKHc1?Ys}E{d}MfR(#`o?gCB} zK+Ihoe#59TImJOLXEK#d{h6MgjI|A49;4V@Zx7t-<|fzgZF&!i{r9|B<%o_E+apL)#0Bx+e;IvRT^sS!1l^K zvWWHT;Tg=`BQx=34DQ&D-Hy!r?BgG&3xXXw=Obnk5kp$RyxvO3YwcO19;C&O`;BSt zT{FRQ8q^asj(?L_KvgUO%of-}an9cJrB#y1$3#@k8S6rIEM_2G@&ouGVHmHZq8S+l zq6scL6V^h8=vJ5sx-7U^-@5gE%HsF$L%I7N3khc!a0RYw`@i*&~_H#Dr z?&m&@QQPf$dU>jc^scP}{a)j|bZkQrD#@yiV&LNuIO_2zy?myKw4c@NbT=+Zz%FkV zApNKEoWjmn`V=}xF$u8M4b&j&fvgKrbO<8YpaAyZd?gTIY_JNSXUO|d(KrEWDspgy zj5hWj3TTz#M(mg#AW-xeVVI(FKA{~Gx5+O+gH`=Wv+iu8me%ZBUtvQ9?xfCKx3cU7Z`mff^>K z$`t`ZSyu8WW4~x!RuQSb*zRq=Ufbf4(sH4qj?-H43VhmPY5&gn2jq582M0c7ulnm% z{p0;IU9|pqv6TLpz25d%D(XDq>TrLlzD%yVKf$o&f0%Q>%$h$Y_Fv{N6HEC|a3hv; z?xOu7T1)ak^@>NziUr5vK;^k_fv@1VjCD2JnHGyLv+{JKtHq+%_s6{bY7&c!`Xl&)eQWc< zPy2P|gK&+-?k^|HVp>tf>OkA{sS9mY#p*Z{Ny%vgo#kB%?0=8_Dr4QEf=ybz(fmv3 zy^)rBW2&iy>>}4{+!wL%*93iK&1tbvz4^-8YhH1Ec91f=;IPWZ;$e={WtH)x{I`hohQu7HUt)BcoJ6(I7^dv4+$kl$eezWMipi0{zQ%(#OAm5Nm#ucx!gnmB-?QF=lQo9olwjcf{_0$MNYd+z9Zv=!GX;eik-dH)KtHNk_+; zIVSEjw%we;U&cD=JD_!_D$&w*N8v4=Ght1fn9cnv=jIvxNt$|VP~P)5sVm#1B__k7 zll>$OO2F|Ax~I>B$$}+{%coIAhHn7P6qF-XXfqWUgcZ%UNKoo{a;!|kg6!P3P|HLs zccEyl8A*5yz2|Z7;JA%gyIz~6RF_(WKBpvmFCrkhEn+D7#CEOj!8#ShsA=$(GxS&oR&YPnfl_VwdmaYF2MTGjP@dm9~}7W8+A+G)1}TY*Bjg=G7>u{#K$mPYx)>| z?pPh6$pLb2aL&<8kK=C>%3*2+orE?4?Gykbs?vCJNns1zo>S+Zd4{3&(P$>z!h8!= zOS98d?qE1;di!`cY3W+Nv0%>h^fZOSJmIZzDc>{M5VUzu4wa~$wYxgM>t6Bv1zlR z!D!KF3T}TdTwe6Wr)b8=KB3U&q^@fp^PF-K!6~|r%+~xc>%Ca#r8=&Bc5hMYAdH;t zT+J`%qmkT4>L@zjzFR+c4Pl7b8>Ov`aTXA1OETC=F8DB%x=F2?oBC1RxKS^C_4@uA z3@B%+E>^Icw}JlbHJ6<>(jDe1z)@+wU-JWviBqt+m&7q&C5hk~B4qQ_s3FJC`SiOm z#mBRZcl0u#5X1LLE#dx2=7s^xcz1p*QmK;6@HL`nTJj{G-)DUMMv-awi>X}>pAP(6 zDb5c~H$A&BsNV!`hbtm^<$iRtcPa@h#T|`CuF^ayU=M`cY=aceM=JL#l+afr1#zb9 zFsZ7q%-4nNE-C6wOjUZF&Gir=`MN6WFRJWUEAM};I(cMf+r}E}24gobJx9s~*GBLS zW)|neChjLUoxTULeDb;V3C*S8n)*0s`EZ*03>f%aAkRL-{aCeie4V{-+yrl=HCt-x zwWvbCe`us3ncNZQ_ucvWGf6V@utIjM|*BH&(>XFVbEu}Eg~}&N|iz!(R`*| zGunOnbga4recjO=)lqu(QJ+MbO&-dF%1I~dKpg7@l2g*l zqfvZ!GA6@`>^&|D-pKuTCoqT7b>H<2)IBC<@PHbjPx|NkZT5wh?fBF*F$wFs9)W4f z{Lz88qrn<`lTavx?CHKKXB0h~b8YkjwRgtzr_#5+y8yLSL9Q2${r zU^Up@@s4^5sfbN=02oN+i)g$bmMe;K%zjhSZ=AcgWc}Rh)^X-PFj#e8v*&DCMR0lc z&5KOpF27K`%zTvSoj!V$J6){VPf@upaU-u{#obT^A{8DJBMA(QJT_1=voaificvE9 zag%GTpdaxtR`OGIXZg0yj+FRc*PSGUD9xlX(4B{sfWOxjc_dZw!@6fVZYo^u(J9}6 zrIJD$ta%k^Zb#jjs;(d(|3IY{AVvL?_P1)Yl4xQM*0Lb_sV zoPLO^>T1n(drsU|72TF_;mg9sD1pyQ)wy!{!eN0&PB5l7{P5Gq=L6I}$`15~!c=ssfunteDIUr;JvED%+H z7@kD6XHdH&WbdQniJNDJrcs|<#Dw60C?GPS4iSp4;d~2=L=SHsOBMB^4+xOuthBy@xZWVgn4cDa&@&#yD<(RSN^-}i(EQ>q z7}?Dl2f=cU9G4(1sbDTRJNoJ#(R#6B3Nwp2W+mfyEzDQ1|KR z*)eyhe!#CV2@r>hg>~@D$KTQ8Z(GLcOGaQd7EF7kCx*!zlNTq$Mcw!?`@-BTkXl%j z6*u{IhCvvk>$q}Iie`{~M~m;YovhyPH|$sZBEDaWMJ3tEi#DdK;9P+xYhY^0R8EJm zmaeZohz%VjXtkp;+bgg`o39|9RwSR3$E=x6oH%mqOe)g|XK$}GvU6`+e)UxI%s?3( z#+g;-_H@s1iue(HLNtoz*Kso$yQ;l@ghXQ>OopC;L>gy9cRUqSu;Acpl}T~+YRM?} zczm%r`{b9r;un7Z8_WCD0h;7v>E>apAF8E`<#y2cp}`miSTOH5+Ex*~0~SdQPSs;c zz!~*W^AC%yRTpQYSojhvpAT3iel&Zb4O7{%)1-h{7h*5{fGABz;T6)$5y5URPT*S3 zsZ?F_`U4%V`JO&pR9Z?2#pN!)7ITCl>L;Ef?v=sgyj?{08ZhM@Ia009pbt;{ z^pF&bnyfkaX4H_Hj{`HuXNT8zo8_N+^F8RP@YRfZN0aZz%CJE6>5h@H4=B zvoLjhOH86lSNXdHylX>tyAKK97w!<8NRcvrB3@A@c>va*7D@o?*aPinCHGCsNyI&< zDJZ2q?eHssuU`z~N@{wb7XNU7E(~7Z+21*LN!Zn4Po=)zT?NCQq)pH_Z&OCx{q*uQ=_!gf2h}z?8r`-cJ4aJDj^2*8j@If+waLU?s0c#D?k^{ z4&}5HDf!!xR`Q$37W&WVPRCD2*Bv$o*Szu((C7-PG%)~x7Dk`7xcXq*87AOv6?U6v zLP(<-$oW^?)w4JVxH(fwUI+JEfef-;8NLz`8BkKQwW?_q@4eszj|L^~Hd!wIK0A$Z zni8&pVnrOl9d`MuqQ!ltTREAe*!p2T-&-BKX??T2@A~kB5Lf`MI!Hq*m__ptC78I{ zDx1+W(q$Re+Zdtf!;l1riGlJN%tX`U0c1B9dH7c%1!#Or1=O5iW{{`UqP|$zpDNdK zp@<9;hopXp*u_ykyGSxtko+!g)>`}73fZ_{Z?R2p)1}3<)PB616X4;ew?pL8oJZg` zLGW2kg1fnW0#<4i2nD)M1(cL}y0>MIj8H0+lz99^puTGJ%1N(1oH7E2+*IdM(`;wq zIrFFy-xBE1Uy%d1cK?3US>Sz@4ny*SD_IvFTCY>+*C0)9<9JHyS#+@c7PE#iwQ(Zy zbT^ww^VrsefGAPTwqFm5=xf>OG^QutdO6I21~T&?hP+h;DsXSHjCh@jA?@|%m{#_9 zFWMWYxvB6m-crf8DH^#zirt&tDr|}fQRV4;)=3c+y5k`pO$fvYVXhOy>?mT5{~n%4 zpHtv&KB-{F6H8Bnd|6Xp;~JnY{I!n?-d;I9A0?D;o77S&UNeO6lyc|5scW%PxL0^V zX*{U^5D}Y&`{BaX+U&GcZJN5UoPDF30;scEW2S)QZtbb)v!KIE2u*-Vg)IKD-wGKi z!tSCa-#~QgcI%Fb4%Y+cmsUQlAeAe3?G{A2d5+@M^$wQ z_xsn?)zjzo`+Eb`(m;>Ttd2 zyUmDW%_@lMO%WA8QDTrLk(MA?xaju}^+;-FXQ?)O4$onBDUDq~pH31kW)&~xr8KE# zL^en#|5aY0UIK2=i9yi4{VqNup@^QVM`U=eC~d&8*N&hHg5~Tia%YTh`Lw;OYB)Js zxxlorUaO108TWMPQ(3A!#Rc`W%${H_Ti9~3Aen;?A4p+cSan-J$5*Q6Sw(70g)4nB zX@BsHZ$$DQY?FX&Fk78pel8nOWH33Fl@i$uE|GUnFUa-Q;M~zWddcC#4w+tPdzj2| z#I=9^+_XM;-2506|3LUz6VM(y6Y`+D$Obky>d;cNGFqu8$&Y;Ps_uSMIb7IyYn+y; zoc^`B`d;?(UXgCVu#f;E*U2K|N?_2;{seDqiuQn+`Xaryufc0wSt;z=C~Rbig9yEy zL2ti5(Asp38&9j(OdRcz$ zeHjo3$+}M%TxOL8Z#iUmi*nwT79CF(B8R8V%<(Y=8pV+NieT#-_?G23#1n1Iw%Z{ z_hk31PU6BKie;7G&@McW;$M0V4mL5(x9Ce&1^Zhki#zC35uMQDnUQo9WWKQ7Y4}pF z&-JfUcn8=cRsB#XCvt=zm}(9M&QI)p z*Wlx}t+5HVYGE+q)j~kQrrByXbXKUGgi}hp5zY90k5gi&JwC$mL7ehMZFQMsrB= zOOcB!l# z!YJ#s{*SbG&_AUKd`bI%QQf;P7A4Q!|7d%K`nI_A9Pp*>|3wGRye+Ff1^~Y*d0Lmg z4G;c@Sodqr{(JCm;@m?F^??@*tkb^}bR|x-spSdy|FdH2TbKtF_=@V=@Oj`(t@p2q z{PQX89$=i&(Asn~FM&ySlh{ioTA?C?T67qlDg=qK`UESb@J0=1UZ1JF%`u6|Irb{1 zLamBd;VkI2FEQAM}2x5}RpS{;76)V_W{1X^PLY znD?oMabxT5w;{5BnDUTmD(g`({$XoAJZW#a@sK*Y71@|dQO}_xOjgc6_nNX!(DvW>I+5whaNSk;zKrQcqyf6JtS=){+kd$c>42`R>ZKt^v12Ol z*8c&(EnD;u>KyQiKXw9T1^CLJIGv^rd<#mPUDF7z3q>V@#-+vwyBD(7l449(N&DVh zu+lAC>=5exYeeD%%FEXX>U5gBuMz6(nnzzFTI@QeaJ*>jj@`0(05p$gp7}iiI;Qe( z{Wqd$Tz;%MxxIYov_9`n?iO3bAnuT?KNT8ctG_QN;vKI(+6N1wM+Vy(Hmf`__13PZ z4G|;Ma7M?@5<_N@v_+W)>51GyE2DEK%95K*yoIS1wj7CUxxUI9G+#@GJ}uAL2&!b* zl_-VGwZ!6ZcZA2~$c1{4|HdE9(2>uEtdx2>RCvSh)hBy*admZnczb^Cx7_<&>({|p zTT4?9G>UE)BYAF>kjP5q{5R#gBzSy%leE8(+I{xjGnR^oRaCLd}Ww94-L$Z+P^E>ey<(p92+qmHa-%F*Zf#qaJ z==aaV$&1=f4bIn7hSyim+@GIpsp7qcDBG)Hm9>}j%?@dqy=lUhj+s=NoUT9gL)^Gh z-_5z1It_SWZ|xltT%C|VRMX;%??hMM?;f&WjZiAd53YKICY` z1S>NkoqvtUOrI3$a59a^NS_w+_r8!8^(im0^Mu0WPcpN<3i&YHo+y64G^(tIwZDAq z_gm%#R91IJ`Ly&y&c1wzjBrVV?T|ow`yzdCT(gc&@xngN;^G%k5(yV$xWwgD*E!Cm zR=4T|2W6A~{xr!eKIdStOTO=dTq2j)Tu6^=YyN0!TVkMr^=up`RVA(;dIr_R>_OH9 z`RFKf?u2g|tnW11o2rT88?}|xc6?bpZ4g6sf|}qROaW>7R2v=Vi$FN;5> zpxq}p#OPAL@BgmC&?(>ZIfuqTq@Qy#7Tq*OX*rTKTP&ZsPgs+AREE026vI!exLVsI z8k_6Vm#k;(+Hb0}6f`noWvA%DzL4~b341;2S0YE=i~h^{*W=4`j)vek?}IEcymlUk z<-V(q7vr8OTSbOeM^+jop_Qnc)DMYam@C<{G@%3`01yFcHj{=C~f3L6%|t(;Z6{6>I02l^c_(TNXez zV}p8`ediQbqu*UHvs8@}Wf3HWwt$_WIWOQMkBxwEygQX?QV42L8VMJ7vHBGQyoTZ( z*m(7D>EWOG;FmEW@MjZK?``h)b!?k&P6vpM96nsDw~U6^r)DYvM|2Fe)^Q2+7)u}a zO)65X_QZi^@Ui@iBwfY(@<^mX=7Sa+>hKbd&@9S+ERUX%*R@xjVoMR;b!IPfIJzHd zGz_6zJ_@6VO&RDwuya=bEEbgjhKp}8dE$UE8=<k_ zU}xiyMIuVCC>2XNc5S64SQB6Ou)8Q&_f2Z+faY*%QVUYIdGtc$cu9b!b5Ld%-(S){ zW<=6U%%7EuQBRPNmHq;b6zQ1c}Q9?O7!9pI3tH%Nh2Srf_u;{Jvw{#J{mZSr++uuCw8(~u|~ z>si|ZePXo_hqEa$_s)e^=5I{z$IdQ%qj(6%&XMT}FBPW!PS1rKYfhVggQo|ds!I3|@!?xk^fCdr&!vP7w;Fk?asz@pQH5=y# z)nKg**_q4rtf@+xhrcq9+IYTJ7iG*iau7PfAs4*Mk-&+$h`+434ba zh8sm}rzPp54@AE6I|X@RvqB2i8fI@y4cp4NjLhhWJf6IC@uzLUlX|y^ux6PCN9UTB zia3~Lak6OC@R@~adMU}(KTPulk&V_kPpmal#aAf>6BGA0C(twJmV8vzLF$Xu&EVJ_ z{47lnIA)T+&cM+IfAnJYU%U=%|mBSvW=e7{)l8iz8*ff z`c7T@)EJVF&}1i>iLG?VNFHUO*l;XSWj{8_H@YtYi2_x_SE6WC{Eg} z$Z$OE6X}clqE}fW_R2Ks@;b`jCPE><)fZb3t7|PPOXS@u3KWr_YfqLL#D(@o@D)`x zI9(!m=s-NkeX;}&%SSoXxe8o(L>7e7#J`g?#3ee6b!jwA!Yva-i^3yiWiJii;`9h< zeWzjPT&l6dGnY3iS-2~lf7!8r!)9LoUU=wgsd(DTv*V}ayi(iNiH>9;rx!4yl+c26 zAc2euLZWqSyBcyMqjOl1^rMOdodTu4n1B_Dp62N$WTZy?ttgNU)Ja5L0M%_NrRsV} z=W`g+ZhD6gI`l0H?iSNTso!15EE#;m?B)eu&vWP}(snH1$;w6KE11^>q_A!-}3TDcz{r0>CODs zZtetev&(98b9?d^qsDTW&-b@O&76fh&FKNU+4=WpGZ$N)OmUV+oSr)0*Tvf7n~!nI z4g#Km!g-h*V@yhfJ%Ol8SUzr$XZWupIKB>8z6!>|Z#Q^Dfw(w6ZvQ!mBpDL^SHvvr z&9S|&TRwp#$g>mi9|BA0e-qG5fcm&$oe6(2{fm;uDyM*vtJ#$tDEYvqziVA`Q#w>iI#9MA+qEBhAJjZK%15-}U!365VJMU9R&F#mdO{~54Z+Tf;aDod~&P#*g zZ`K8At30P7Y$~+ITBGxcts#UqVcHp8#Xgmb6^>|>9nLOCP{|Vb4JjQHh|rqL%(iXQ z*pG7EMMP;dCplw#Z}ZcK(AbzUoUq*Z8T5)gS1~rC;bbd&Y$!P6hg|E|Z2tMQ*ZVWy zf^=#l#p(Rj5gFbUx~bQQ5M(Wf%d`2BV@0TJziwACIb@mE(jC*opX5<`9H+MV_0rQ&9PxA{;Q5NEs7NTS=iWBRWG-a{Hz zdthOIz^(e)g!8~Fli=I#f?7K~@kso1NFh!`S1{e#?s$IONz% z7M8|Xy)q{>GZJaZ6>4=J(x3~WdhXpRGv9{SD-=&@ zNLGr+1JC9H%O?lHA@KoP9Yn)H>YU1Cq|!WEoM zGNWhph>33#6=yMtKdI>vH44$5FTg-o*5jFsC?yYr3xU?X6z52RdNl zr{Oz!6Qq{Eam8wsl#Tllq}l#7ugMevCs>8Z;Hj*7M3HkptYvcyH5Iocu`B&38K7^&{WxU0Ycb8FYZnutKymKMIEg3<;-Y^SW41y9!!JA za{-t`dE^UMbyhTFM1Y}fXX%RbKByey*fLGTb~C^UL=!+#Pt33V%F4E8*IXg?qyxYP zXLmapjID3Sv5^}fo>Kl&L%cP zvJ@%SMftF0GBf!>jLe==<-`{*LrG-p5I7lTV)8pp+^mp6-_g+UG_TThpNm6L$M+Jr zvq5Bfz>Qu{e(gtNt_rn(|IuOQ)@f|23X?ikCQdes$@a~rxmn)Sq2i7Mg=P};0unjL z{3=T55HG$#&oHk8fipYs)(>p|@#mJ??9%PA8yE&><~vlzq!bs9c+O#N_pSFK@FaK! z9A{?WjT<}8Z@@{zPoF~uxk=%~qvxY5x2@-{zafX&oS74?_dU1EomV8aXzZR6tNk<-b1;xjb)eZdIiAsCFVjMW|M8&HxE}$FG}4iny|K z$l@?>QMoc;VOHWxV^t>-kQre{LYT%IwS_lO^2KC`?b2A&d5hY#iWJ*QDw9&kf{_)J z#rnCMszONj#z)n4#TJrD`AgyH$NNhH3eF$uM=iS66cOU$8kNXjDd6C`L~%LEvgcIe zbe6%upWlf@qtqSbJ$1K;L8nW=Qg}zScVSxWX1!s>7&I~W2QWt03M##28?$_O3QSGc zD)KWy(WG(CSM~en>f%l;>6V2uJWgQExIE({mNls^^4*{9Y1Yqu&LgLK#ya3%nk+V7 zH!ETeo~>=?<#0bf1|4JdQUwZY9zEZ#E{-JBTFo4mewM@Iq*7h&DF5<--|1P?zh^kk zu_HfY|EcUOgaLJm&=Q+}u1`02vl1t{-ErwpB&DIC{%gyN!A3^k>c$%h7Kn)rQgt21 zB3)_@Y{RTU@uFNM5Ul6pdt7;eY-HGda))YMK33U}#4G(k!E`1RiVfRd(++Ze^6x)O zu|%_++kspu^feBb3&7^Od-Zc<3Gj1IQxQoGAkpT>wymIY9F=4!byP~03 zng802fSA>z#{ifB5prG9NB|R7fPr?Pm_S{CTSK6jXZQ44U34u#5rF^LFkTF5UD@h@ zfk0LOtTuqc;9JlrR$~=jy8qaL09FA|tO|-<)c~vjn9W|ge{F{^8}P3!0La=4iYb3w z_9hF!=7rfD1zdg|g;&_RgleM88=*Jkz2Y(%-T#&LZ!!1Q55I1hzx}27-$I(B z1ilLVDnJ3}R0;>!hEM?Z--5CJhhTv}1^r*a_WwgL?Eet_pKRdJYt14|7W+>5Z%}0!~Ch`>&9(8Q)4*Aac9m7N$W{o4~57? zDuJOv8wrYKT3YhT4AeKD2nW64Qjz53+fz8esGmOwMWT@P1rNkVqJLIR1H8Q0?{?uE z^5bNt4>hm9i8f{)y?glAuIu32Jwenw2aD~q<-BQ*NrK$(lkBXre(rk-vl!5ap~#Zsz?~9ZSoHpe>L4P5S71nxB}RKXI6C z5^_H*2|y4bIN7YWKPioz#yG|&5OHc5Lw7JC7e@W(2g@h3Hzusuu|~3buAOFQ%C#Zo zusi<2z$TwsbBI0puF^+(lg$SmPB^<)!BJsy%Y`-NCj9G7V~|2KN>lb0w(216{v4iW z1r5Iefp9{4_^~XdoXn7%=*avpM8!?iWkM<^)D^_q%_?>DtSJhz;3jBWbHc|AoJBUy z*s@U;7my?&z}Xy~BeQSW1pWLW=7SmuV9Tu1Q3-weD{+xq*O~$R!L2vSeaZXrfwD%j zH23PX$!9F25Vey6-v{Ljf*QZIhZbQq;>0WuwhDH5ytoe&`e(+Rtb3y6@Y^x1cv^tVQ<#TRpV1J3uWVb zBo?f5($`j{>psp8yT@}7Z7rX(bp^|RE3*(H{mir(Ks!c|@FPnypX}1D>4OufF819~ z_do>&^-XbJGhB>9L@gU=lX9FLY(3EdrJFVOHiUTYd*-WFdrA9Y2KStFiLt|or6Le< z!*!A{U~`M?vThjS{lhSiV3lIhz3VX+KER~`iVhywpO^pMYDQ_W$L+_Rf!-c(Z;h4! zpZu^BB!>QmpVO30+f&{p-2bM;1h6$6@Ll;(!8z}tLWF(1fLqKS z#o?0Hm{Q%SaY?^Bg!okCdf}kbE|(I$t&lznUex0yKRP$J(_-uRUAk3pA83Q^q`vg zagg}7*I?o|;mRh+!U&GD$@|tbr8m#Tb6dtNs)*TD8C7O@?=UB;{Owj$NUJ$`Sm{Ez zAwBLGdHC8+EUpd%gg^s>+bYy)=bS_d2b}KmOWJT2fdVIVv4!q#70XXp+Vq)~WK#18 zZDM&0<#%XmY=6Rr@`1XH;j@xJaJU|yy7xz0#?~mlEjPOL7WigP*H_qd{zgBxm!FPy z<*63;*(uaKOZ+(VDnD_UPY*Nhflw_HYj;(1RD91NY!}CYChmut(#`|iHY|6;lZ{nG zI_5wTf}VC_mvXua#QHk55}w-xp0%*c@_3yBcOHcT4!1QLmr#7_8X2L&0FgKl4ah=nMM-&E# z*uwOimvjrI3EkcJH~u_yGBT^6r>U~eVo0LAISOI|G}E`^BRpvA=(AW#=38ZWUh*y~ z{jk6)x5_J~lhk5KRvtUKy}oC|yD73eb~L2)=g1!c^%1$*8x_Y7AC?Vx8ogo*IXuIWmNpz~WaCYXTtr$a~78#kE}bc_p}2j79~`1N41oEVWn(!@P+%m@j)r)zJnmVAuu3mQFoUX zLEg_~gWq0zOVeS3N{tC_JG?4jK+;MRPmSPud-@zsI| zS-dKAGuC}D59<9H@1|X*oFrp%qOXd5`n?d%4|{Ur7l;3Y)aA7%FdeIa#Ddbn8b+JW znk1OSKJAG1-7rj_zkL3{^>JWQ$78CV2rbz+IrrDLqk?CH`X0JWC8)4ci>Oy>TT=nd z!ujQI+2@5zXZ#R9P9apr*+{9S?^S|>KD=sivhe9Dt9y^HbJ^33IalrLzt)8zv3|Z5* zhPvYz!e!%I$@wQb&eQ4_>eDS~lZ~$fWB(|5sY`$QJrtd~z21{3I)` zKYe6*gQM*1F;@S&@Rgi|_l4RgLG{imNx}k?q=SyZ0fd|A?a@T( zM9G{xu6zaK`%Q_);{@0oBWtATRKIBsmSzUgjV^x1N$Htw+R9?SEWm(av0x2h2ZnHz z1kV~__EzQD)oI4^I@r43x$M9c9gfq{)~O;A3cex$7)8@l({~SW7wxahN1e?y8@4dq zt~KE7!wYIvsHP9p*{8{zs%B}SS8Z*uM#psI47mjNe1`V(d#A8)c#JHbw7B3Iz>PJ` zo6K&m3X!H1KD2=M(Um`+$q*_X)Vh$i>h@0NquH%HMO^G9=-X?T&(~UE{<_>Q-D}#g z>MHO?;)(wWcC@m&SOF!tgV-CrE!TRRSDuR-iAE+s6rYJNiQ)pF!lF7CfvRW4J9C#~ z$pddklrX8!_p0n07AV41e(K_$F&aVeZwRcoUxNdjMZ=TA=%DnSIpze>ul`#`O3aUn ztjCCii7q&PY2)K)0$96JWiMseS_#M6-dp((W(JG+$8E#xd&R)tZkX3^p(EH=DK1$~_bqDGD=ss4N`2K?QY{~r zw^o(8Z%BjiY?)XX7nn^=*>?-gYno}Uii5Lt(vTYrpawi?GKg--pl5j4+SsM?ZK%vQ zr{n{cY|`A2tJ!TV{FTMG%{PUhB~JsrEDfpnB(qhoK)N`K;@)bAQ>pa5$2fcx-SzT- z_o7tYa>VwK2EowHXu(ibbH7bzkUB?n(u}!VAM76Sv#gHZGeA zfp03$Vo}*5p-2A}q`LZh@^@_-zwA*gjAG}YCl$^EoFsp3xX`N2JL5`Ct&>`~V`HRp z8oQ$nG?T`|R4KkxfvuIxY3;{?BOvyra0n(Bbm>>?5~RJuhIZ0kt8Q5xM$HeQc)#UF zeh>B-mB={(J^ebaozBwd?>YRDf|hP1R&z$b<#mvCuMKzNd|2(I`sEw_x=oI#39wL) zyivZrW%*hsah5$e3Kt-5WYJup($CA zZd85f#}l@w?c=L17P=GRIUwYf7zK)ZXqbBG@O17(z}t;}>l@3&#BEpwHtT0K56u&h z906W!6DeQ{t}zUlOKsTjEp~6c%%nMJB~87t9(7!xN0wqxD@$i*2-iSm}H2B}L; zs*KJ|3!Fl$n#oiku(DMLz>6Xp|%qNWOtP7M%xPv%n~uC zlc*;bn!4<@w((O!Et)LSu%gmtf~x-EDP=xpys`#^8@SR#BtH&2VdT4Pd_VMBLw`f+ zIm!rTxxq>zfKCxDbfQ#kcrEjdu!T;w=Ov;&p^sEuVZNur7|RAeAhVR_Sv(M~3=X(+ z&#vLmYt}%Pe*3oBN+H`z;ZF6>XQyzllK;D-q}UH;ws3@)>4{wIOTC8ET3He`(P~EO z*i4NcmM~LwTM_W$-@!7d$&i>-_@u%o6+Wr(1F3LtQsL*O!mr8xZnvfQp`Yt~J^vz) zt&AL%$aZTK&)Q6tADp&Hn@`$&(&m#kKQnFaPulzpwfW6sZ%sbCxm`S~x*kBlq?3OP zo!s8-zmD&3?{!mR$CNHNQW$h&Wo6AC%ySkw)KNOhO!|D%=i}>hH0krRgRQN4Mb|5s ztuAf)%$-Du+ZB*6KxP$3UdSe(7W5^D7a2P)&H2$}Q5apkGim(E3zyTIwDzR6`)KW8 z(%R>ywSRxy_4C1hzx}-E>Hj{n_SWldU?zb`lH$7@V1ly zrD4&ssL+-+D7cS|O@zo%ZK5;i@Avv<(@Qr^O)Sn%1@KPWAC~0$0nfkU z^_s5CZ}M+w4E^C|KD&N@rTV``hn4?W?A~mb$vwUO z>%m0c<;EYPO*UniCU#MYQoWy*lDgy=r@3hBRZ}_jx_&*+TPHKl8{rsLdJI zZp&&iio4(|ha<=%!wp}Os23H~joprWuz>^*z2=;2F5kn}g~uv?w7+cJ_i0}Rr{)RwMunJl3Jww%c5d{F;TpsJo_b^sdtg!6!ODF9 zi?tUfpf7oss$6pkkKLj`J>B|v?b#YhQ^TC|bPK;c@|%+18a3Y1c^qGE8}CU5TtB`y z*d0DBjU4qFI%3=E?f2@`8fnmKo}51<1l?o>VWA1C>7uK*tCZcBh8I-IUPS8U9nG-Z zI#1vQ8Svr^v4S3@JY$#N0^P7iIZqM`Y$rwx_5A*sOxA&r`?m4ZQ@1~m2zmh zYzxcv8Pq^saC^1O26~(FY}T`j|Jg6eA2W7LXN<91vRSVw* zI=}r=yvdJQ&rCmnYi!x386;>3L{Cp6=qGA_7#s8wT z*3_uzY~2rbx8VpHNWEU-$hyanszp^ZSazxrIL$giJSL=1<9!-IEwj^T-nZO*m#R`+ zCxblF9;%j{?RRxBCK~b%+8-Q&!l+_G|wsY*E!vr50~pqg5N#TL7GQe zoLpK8>E~07j;n~6L)5D@pa@-vWAkH|1{lv}Dh-%Q1C(h@r2$iEz(PB-msuJx$i|qu z{+yk6d%fIJvirQrj0;1PVpbfJh#xmErS|ON+WBWUl(P53=W}vSp})pdN%Jy}bXoQF z-^<;OZs(izZo65ToNiNdJPyI|$LZb}+s zRXVi`QIaRHFy#fMpd<}>D_6c`g z{VrUF#>I$R*1WQhj$H%$j%nLBoBcY;e$`l$`sMLa{=&8_tMONN1h4S+W=*yN+?oBf z%_Lx9w|lyMK6Ajd8O~^;o>BX-{I~J-+I4ccn$-2kL83NJ;!6yP z&37}U^}{Ha}0Ld>LF z5J!R8$eGOLN+4gsxCw<@qMCq535qUkk~VW2<{{ZS1}I?dWqdnr<3@hhvCL6F|y zs4rxMm_zKlaa;|-oJV_xC+dq+Xi$@@44VAB*?#`I-R$qbKJIq|9H8L>X)KQpPVF7u z>0F@Bd3BtYBhKi5>2~v!nV89d<2tSL&6d8|Y`*QX(_?D0$aF@L;7AE@D8i#-)Wp)G z&=qnT_lZ*X?dw&=_tYb`UCddO3!Z0-s9MFDl2+u)3l`bYDRkI5>4@K$nfh@A(A)J_ zu_Lw{!gj?W9VgS1?Wb;#tB%uz*Y=-?isS4fPKNXpG8MN~s`Bzbk=($ne8eq-ab<7~ zt52c07GeQzo@GBLEY~C5r7#`=X-na9;Nfq4LE_(@#Q(X8|1y#`->lQ+{pai3cl0|w zAQ(zwBeJmyEFzSG_=i#N%D5`r#cb=MT!({dm^eU5s7#n$+}f8jO&<>pwRMnG zJ?GO6m4NxHcA9f#6GlOys;jE2S&;+@gBzhBB2^4a8#m1P@M4t5DfBD(z^1esBA!dc z&{(R2i(PvFX{tn>*`t!^9D+pW$V!eZZz$Cb5U8x4?cEeW;Z3( z&ja3h$#?AWoS7qE@TxT3r_v>Ry!^#d$pc#tgn0t zd3IHFfvU9))3D-OTYgJI0B~e`EwTcb$^1n&06-qwhGA+&UB&l$ct(NX*7g5vF13f5 zq^FcJvRQ;tj&P2u8?0Z?&lh8IOwDG_u6F0<ewu+U&Cmr3Z`R*$cANJZF*hGC>-hWM=F4|K z&n{r%L%cVZ7ui57p`j@>khVAlI?0uC8I_G73k-Bv%G^>=5;gG|IYnN+&1QHp!f5J0 z@?%H!vhDDRK5TY0Ka#)x9dDP(?f%=>0YtYRcK)AKN}UANI)X9ik}o;xCdKPS{QtLqWr|{qjarSJ>K@>)f6Cq* z$C|j^eB054H~rl1A9oA^wA-zyar8S;9fe}Ks~0DPX-p)l4^aRYO2AVkbX+Fa3_=K! zcNN28_GR38|{z$qF; zV&s@}aZ&Mp8?NvR1@g10NzRM0Po~}_XXh+^qRD=p;PsAgnY;btB@}g{tX2F`6E4QcZp=6cZp1B@1^O#u^$|IY^iaMy_Qy;cj3t6{MlcH$*{~gys|} zI8!Y=QMxuDHz`-YN}IZ}W~*s(n(8~hovUi{7|u@YRlVf#NG$;qH8)Za1t1iJ$lK6f z(!JKqNJ9_2nLq|!sx9`y$UUBN*ZxTAd4l-3~W0`QjF7Lm-P17Y=vKoSc!LV-Gbpem` z<#8tSF-h)rnYSPRJ=T=qxrb-EP2wJD@^8P>_1Loqa_z~pAII8%`w-J4p~)ATF7Lk5 zl_7{v=!?*I{r|A{_*R!`JNA{fu$ z+15T=WD>e`J6mcxSHo?&k>jx108i%0;4YC_g^!2I`h0n`S&dt0V3x))7y*-7-b3V}6M;M(!Mg>r?F z=KrjlvI#!BQe!cDjo$ zy4Q|p`U1BvrO{1A?ltXprR3h@lY5J;zuDg3Hj#Q_5*3;gF6ka5338O4764hEA=_B? zJh466Lh99TQwNG@RG(+CWB&YrnDLAY3@{>0!n8<@yD0U8*foNL_=FIwVKq&K2%Y;e zIlC|y48X87+K<$A*C1dUEPs;u zwf24Xo^C~D>`K&jT4WSkp$z*~H^DAg>ZD8=`_~=dAogvV1}pX+)5L);Y}(W`#iplj zQ=PAOq$ z4OJ{0crL4h1|Cbu^PN3_Es|e`wi>?325EyQjN`-K7O$2J{z){@Cia`xugRl1JGsQ7 zCL(Bq40&=;kH6{_@@p5ppdUkJcF^2t+Tn7^t`9H}71*(vIz8-+P}933xH;leZFigA zTwcy!qJI|E(>}YL(>)UQaT*6CpFZfGsKNJ-OT63#&uh(JE3w;b;GCfo>AU?naCj}i zai1x#lA11J5+Gn%FzI)_Wh@UR;9Z=0*L&HDQFm#|SlovK0+m9?|}3kh+fn{CE_JTqO5h- zNp;c`xw>|Z9!RO1&N6}$3{m$jP^XX2NIpPkS9-i5#wC`-;U!tQYCGMX!s@cm zW6$p6+xb_E)CVMd))QbjmcPw$iZ_8_-=q^c`Z)s0)3;-QQkY{crX&Dxst92(3I<+$ z;#rO>_AX^U$aVu@$!~4HBuXo&mx=Ul z>gcPqnZ!k|Zjc{u++DZ=+|m%$O6sw-n@glK5T4OU@(Be}KiEWwNDHm>oO~KGRx6Z^ zp<}RAgNNd6x%6(0jC6$@w0xC%Fg2abf-i1Xu6Y$R_IKLZ&Kq0G&S6BG%~$GGzv`g6 zOfVJF)W*=+TZQe0b|UOMVh3QQX%yVW3A^X)%KkDc9k==BGuGL(U3cFu2DTZTNY!MW z5z}%5X!=7s(ROmtw02!Qu(iWMuplwBi$z4I!dju+hM1N`gr3Z>h{-vtC2CrHoi*F)Y7c1@;3VidhF%zf1q#tXYz%^oA2+A4)4A%jt;+ke{+=V3~wyk({lNH zvMmIf|2#fnW9z9=BrrGEYT`P^HuC;wrCZ-`6?he56&STC0F-T<6Cs}Qx7)p z0*3eLFz#()^ltC(8XLTgbHd5QhD<78L!eA9`8|JRH;k6{dha#r=~tism-PlY*Ohkv#t zU#`YP(-7HU+>e(T4ed_Q9bQdO-crO(5x44LJ~`sPyuCjCvbud6HKS*i7%t~{JcnLV zQRKXR-GDqBt#mwFTwbig&3ei0yq)DR2J_3yS)47P=~b7`yOb#Yo+XbM+61WeWpZk* zOr|k3w|%$1>DJU1*F)IOP*l6vrdRA=@POAfv@ zh;>vm6wn#fB_JE^@k*2IzFA^Qq`NT0On-?>+(*t1OwnQctOs7h^(W5Q#?T(`-MR}^ zW=A_Tb4x(ejV{2=^cTi}Kp9#mpo|y$X9mdL*_|7dMnnI6fL_0FI_E9JC?EXsEC(vi zTkYiU5vJ1U#b^Ns1rh+v!j=xHx7Iybs^62bnp(4~F?2P1x8BY-@Gf~{YYJ>~VTR%v z8O%GFSoK$UVA#8xuJtsvcdmH0y1nbn6lZ5|=Zj8*t3-><4$ojhW&YLd?M*rq1X1N| zzFCJT(sT29mJTrRHxZfz>}iIH{`CRfjF_5N`VahAHuYoX~fo%uoU_9<5 z+^)XDdAQku(E~!2I+>N50o&>Eqer%}MGK)AZyw!v-QJ8G7!2@gw8Q zoZgMo=ws-7^r$$^;)}1h1~R{Cc{<~OzzHsC9eCOG-vfYpcOdm@sxJn8@BGiu7VCKX zm%oAO4CmMnVVmHegl7e5crCKa;C*%21T|xm$Z^XO0i7jd1@9Cs91X0;i8_1sepzA9 zrypKDSxr$NLw}KX>yxl!CktSOQ8@v0Xx@FcirY6r$uC`-i#*f@PB%eo_%rh81N_0* z>HAw5!SG$M!S%|}IPQEkXx1Swt?D1s4~EOf?0MLwc>CYU8)1!B|Kzk= z97Gv&`d|64qHUdYe}?}+7?QQQA&(ZiP@#%QYkT0lEx^SyZCFh4ZpM%%S#UH zvJEZuGQ{yi3v9OV0Dm#_!M)5lah|(T-3ULTDhs)%PXsv%FdxB)C^|xP;Ll|;%kiut zLNEjMvCo6>f3Wq9JWxGDDpm-DT9zP*u<(fRR~I8f$&e|?kX;Hxl?>qk%4T*89#@&& zt>W8l#oBN|;uZpNPjKuUntpUlYYYXiD(kE^>?u)3-#^JaAQ2=B!$f2SKN zJ&cy_8N;Y_NKt1)x#GZd28>C`zk%)1w`M>N+`A}by6kYj6e|%_Hr=oNWW8E_eViy}ua%oaK~N@iA0`zga~Q>>|@V;Ad^(h7toQyS#$Cz-ANI*xEb4 zM{U*K-)`2|7tp`E7xrS~D6_ebSxjsn-d~WO{XI(o1mA3a+62aG45D@NQCrA)Je%hR z-*FdKNc3zZ+Sf!*2N(Zi=3`?h{#Na1dgWeuuHh-%Z1KSPhLzX(^@kptjFze3Ua6r# zjo+!0=iY3@;D&kilFPAZ(_5Ce__(OQ8OghfXg$Z(G>~sB2|&_~B@F`QMi! zO4_rQ(hOPRY6>}*IEUGYJs4;r%TgrF%BX&-Iq+02*??@Az#tTMq8VLq+h}W z)AWy*&!fK9%52Epm$E{(X)`lwu>3+cXUS`NtMYTm4o9x5@^aGY2?vGYE}cuj=)Bpx zyWq*Qu^#~hVieF}yZUDOO%-YaY)=D4U>Sb}qa$~M+RoF8(=`*TW2nSeVzpPXdZz2B z*D|^rO(iRgStoWjXF(IB3E-58loVkm2@aF@E*Xgto8(A=qrFMv`TNCX+kMr7zm)JM z$+(XjG{X$Kh!^Ybakbuv<1#)7lJh&@50Mc1d*cQpNGPxGBp8^XDF!x4yWnc|IXS`k zX8m=A<~1~QWfEVVk>8yq+({b?cfv$20+m&kx;X+k#NV~zad|JBenN+^in_rd!*>e3 z5s(@fjsqEWSa2*9!n0ksP%dp9R25h{kktmMk{N12#XM?t?DTPQ^zadmf!QC&))mK| zobz_G4o_gi<{g_Bc6!!av-MLw|$6Se0@ZeFAUfQQ(b8K?j1R6{t#79EsW z1EIyP9J+@X?xP*tw>>f;vFypLUm{>>SyN&#YHaT07)){j(t)|J{P55F+qc*L=jPEN zjU6$PO@qv|zbx9C8HVJ%Q*1@SqI}Lb_g$eNP_AH4`>L|Ka;M7&ikeH*P&!x2wurQy zfDOiFtvr*@`U$o*#37(t!mJ}6 z6KBpA%tZ)3Sre$oIRbchZo{GNoIBs=uIcQW>=~CnFAEyQeM_FlXX=&Dq=g>9@sVWK z39eE-wSIb#mE2I>VLetm4BZsRslpO^+TNXtVh!GoWl-m$Bwsxe{u7D5ubd78V^&`8>tK1D1IUP%GLheJ;bJyx0&b7Y!_r zlvUU?vzF*z`9c8;c#Vfuv{2}<^ZOyS^kMpkxXcR+i}NoZI;zK<9ruqdYY1%722Aa$ zM1`&eBYc~6)+n}P**HQgq*+xp=|Vy|0<{4ItWUljE2K^M#~KGsWYBB)6_4V7c@ll~ zZ$cO)A7-B~P&${=xl(AA&ZTrNrE@8r>)~{+F*IUPI#=aK>0HUa%pP?vQ|Vkv=Srbf zI+xP9l+LAeu7}gP#?UlM>0Fhcr>%3PfyIk(d;4m$_M_0h+b-^JZ`Ygc&Jo7h#p&go z%}&c05z#>on&k=^lY}DnwRZ)M9(~RVCkda27&T6Sl2#l`!@7(~RQ-}0i6aLw9F%G+6#jYga#VP&Pyi${Hv;*wV8pjo zJ?$VSP~`>)v+}!`@3pRs4quck3p8lZBY{%E9D+EQSJ8lATI+D%pwu`qX8osrnO6PIe|2-~+r{-)}-V_oJv`Yr=OQFW@Za zQn)2aKyVgJbdg@VsOeg+JW=8T+JKc>cy^rw4@ykmgx-wWp)X}hQQ}7yfaJqtYQi-RBaZzvT25FCh zC}Q8b>v1#<-DAkSRNuwu!U~xc>wdlth|Hjg#`oA1pk{i{7`lAETW_xYt1fC!08A`E zhEjVjV6?iw?f@EMwL<~*X7%|?2apg$*slh5;eSI~_~I7w6~~_{FqW(&VGy%lzuj)& z-Ce3Fq!~*-sMW8i@5xhxs@$P`PtFUtodO7+Nm$0h?msdZ>ehDy7AnukyQL)07dAI- z*a3%DGi@6ge_qxsuC%Ca9RfMmn+?^_3LBmvfGqaV%U$2pb1wz?^4g2l6tz~^ z0Ablj#2x6C0N#AOjnbjTxR#-94hhj$w-gK#bSC4bDF&O_-UNWT9I-sr8jfrxLGd^0=znf_wW zDSf|Q2MhmB$4<94;S`xTCwyJ~JAxQ1j&%gdV5|C#r!%IKVhY)*wqXck=q)?igyTo( z_sy=r`ReA+#+C=|=7`O_Hlq~e1JHA;swk&{-x1btBY$@z2Q6JQ1*&RUE3aXP4aK4j zRUJ*g}u192Kd@&Yp7=kR1Pzc_l_GF`H<<-JH8HkSV9+8wX|EA!2vIkrgn6X{(+ zOr&iUD>#m(GdMB=G$cy5g2LUE531t@(9ZR-Z$DkrcAWgZPGqJ2OBY8b!*aC{5VFcC zQlrxNt&>GpNsAAM$Sj6>Y7pKYy=*D`Be-%JSFs_9J`aGV7>Fb6!ozM&z`K^oY6hEn zS;d~F=Q;}ZzZSt=i@#<{CtgY2}qyt~(xEvQ*QD$$9V2uHd)x^|eatpB8QB$J&Ov$57g=9P|B?wsOrY*SvDg zE7!aXF;Cq!-$h;;N?ty!bN=aO_UG4Cg%DH-L4^=h2tkDqCLTiQqMxWbedc4*Aff-No~_>^kgzzpJQ-~up$@nwL*Dthwjpm-RX9!BZt8Bp#Dmpv z06mSe$`>c+^L@J;PCkD|9UfO-;S5DXX7lx5a5KB`Z~V{jI=PfH43#468p0k!Ro#Jmam8`Fl^;NR|#FO>A=qD;!|FH%T9&fUKeos{pLAeE(Q03`QleDK1L{LEl6+}=$1QkRWkGup*UXnj5h_HXru7U_Eh@gT9 zDu|$h2u~x3&`Lj1qxGmC6-3yhVxocw%FQTXOJgW5R6&FxsNPgTgeg+D*@n8+tfFa> zwhAJsAc6`as33w2F)E1AT3!N8$xHG_1rhcy+Eoxi1rbybK?M<15aDSA5nAadsOLZgC%HPxP zLTDpgTB+3l;H$Uq7qbj-%nYDjej~tYO{$!kLTa9sFA52L$~VeSB1igyLi5V}G;yZ= zrLV!>N$8cUWoWU>H6yP?QRr5-8OV@^wM#p0gbHWeZ0scZ>feMg!h-6q8SC1mw)5Yc z)fQ&k-EQvTknAl3DIv=)OvH?n+hjZV`~f6nT6r~wVt%ju@X!0(Zh+U5R<;$yaco0# za+?BxIDOc1_scdvt|GW@Z~>_;V#>u_!e2_+;6rd!{9Vj~u<@-C42l7s_Ig*nF_?*1 zQI(StXX}-0C^mU-DMfY;r>(no@^;&_dC!+pRN$RYKX5+bT(E0HFW4+dtYZX8 zT=DqZv21sIOeXI&mlR`9-cIcMmKNtw|3)>bjuM>1w$g9w+u;i9?D+vOl2%Tpg8DY|k_gF)RC1R;2W> z#eTbwMJ&wYZZv15+Jv|e97h%WwzLwadhWc!ouyz0gVhY8eXDJU0n_SleV+lR_8fc@ z5=&s*1{TiyBld_@W54>!FcLK1hSTd|mnHx@mDHYNgw>tkm*7$0CNRwnlH ztkO`4hZB{0z-f!lDwXTAew$Tj>=cJO4LV+$1A3&-XL~UQ7EM@3m?&q0J(7|;3y zeUXVpkEtKOa9A6X5nn;UX@h97$&x8##7?hq6p%&NMa3O{UU|{JWHU+qYWjpEraU za0=l=#Cle9PRXs(!pHrvS@7bGf(}xt{-NIKte1Ne`L=9$2JDeUuTPVUx&T{zre8Pr z*bszPL9z9;;JSyv5ZZ4QsO|#P&3v=nao;QcX?JnHydD;*Vnk{Sh`oR)Z5sv3aq23y z+C7_9TX7MWMNP;*coKgqM5JQKE}y?56m1#rU=M8a`HDT)D=bcR2*$ao0pOobxxhtlF2i*QOx3AshG-y3KX64=VQhCsd}jf`F#F`XT`Ckmv^_f zi?8qb?P|RpZ1~|>t8vUwrLJ+76IDmSnPm<3Z`y6?4^`@|N9o-eRh+k@7J4RvdejoJ zN_ER$ZOJ2Pxgu#0Wx1sk$J8t(D)uv}FAB=TFlf`WkbfQ&?wRsB+~{CQ?a)VShn|kF ze{}lyCA*!!z2)11>b7Y2AS~soHPv3)Smm(FUkho-*|WD7udkk;yga=)YqgF2dU-!k z%<7P!)Im}sq)kVq0vGcEh3Q!73@Woxx!&_;)s#?6)tR_`gqDpUuJ`k$iWW3dfO!5s z1Gyr-onR4Mq2h1qCxyC~z0O<`96J1j5-PgPk{a2>^Qjp@+xQ9MSK(A7{DL3>#47Iq zM3=^bnTf#fO5s1v9C~yL|6;Y-7S$la-(IZ;DgKM!FRxm*6D$&U;H23&;QH%cTl8l2 z4NtI>R0bXep>7skf^Ge#VkX^x2LLp0jWKtYYyKD z0~wf6qr}!txyM!#z?2mA}<((U}77+AVWA3#spM5(mqP= zF6334S-a7W6Y+{XBt{xfCn!;5HBprxlYzQKyWAMUA_$K;50r98soL67@0X;9b0n%+ z6R~ew{(&&pOc3!57a}d-iF07CN|ptgW0(jW?kq&ibUj#ZT4|Q3r^+OSjAX6tt@?G9 zuy8FE^ZaIo)2v5yK!&QKs zpVqeSM#ZaCZ4y(krX@dv)l^&1hH9YtccBVss+G8;QWRNvxZqwC`nXwXdwTJqO8`Az zud-^2o=r$2)(}akgFtPo=L2%dthp>j2+dqR=3RmuF(t@^x7U!3B!$IDSaMoJQIK`V z3|EdUEG9S1Ui}pkkOUMH7cg)j?=&}c1@zNBtdDJjknoLCu zRFyo$4A!r2=(6;W#yH&M7$ye_fD6BFwP@Mu>`!gAIy+N2-DgX-=5)g|cd+}7^i;r~ z(=YB|+wIC!puS#yEckq<=G;LZp+CP#NOSq|Zkw$>59~zKosKdd2~DHTpY zwrvYZ=-@aNo)n5AYOkRys;ttyVR^dsI;X1jkmeo5$w4T-o>RYTv#9Calv~=xJ>0Nw zh8^42rhW^)8CNCl(x2tP4bglq;Nfzxpyg(otX<28uASO&i<1O*wbC;JJnpWWEy#S)#43w^%yaL`|hU%#C#qY_gAH%%8r=6<3 zT8bSfoGmw7x>&sD{}^T`nlTRCIFb39i020wqu&yJ*!O9SMlISAthE-_#>vQTVcuDU z#VdOzXNT%h{McbJ-KABkVnB(3suFOUxvDH;leQR!U{7))B^ic1|B$z%VFn16eGFf!mY}warzb+_SUuchA+1U9%ppwQ0ak4V3%EuTiG* zS5amTF;NsCG!#-$LfhG1JDly5f_rFeXMDXNM;uJXh|&Qpw*_Y%>=<`fjmng6sB%3+ z)gQ#&))&|{p+ILH`-Fm8=_}{4!aZqM-#V4#G=zw%)^)g!wwZ(ms*nkk$(oe_)dgts zDG-CGXvH86ch|wt=P!u`>Yq$v;gE{b+XTm5n+r~o(Y^BJ+E(hK#rQVU@6FHxruVh2 z@@!`Cc(H#YOVq$H^N4!|7Lk;LR8JRIEnRWokbL`tu9x%WH3(mQmPty!Xs7F*HO?5R zOMs`6s(tY%33!9eidXza#&Ar|HE8_^mtxstDJ}vkM!Ge z%uPmaj!0>xJ#qCO`UbQ$e2XfFP0SsJuAown+fDlD&Y*=ajKJ_d+yTE8)6lP+wLL6< z)jaRM{6o}2bD8hIv^p|FGX-tQ7~{KxTWCxr;G*Ye_i_@CMeVeZY?z06FiilWjFO;0 zwshSvHoi!Lj`$)JrHTlbyJ9XoTL%c4;arxIe))ZA{1i}+38=r%c-o#ieA1iWabzAI zL1f-l*P}nt2=@-oT+@wWTdY1Gm;g{+DR=k4bH=}H`7-0#%bRq*W4SASb33qSCE&%D znW&OSk&s-3^FZ%qIf`D>s_ncQmgh1L4Y~$8f@bx$e5#!w{d->e6kL?F6fQNoFT1^U zMNj?x$`P~`L-(6XUCGO*NN!@T#7*d-n43?faLnPr~P8dK+*g%mHRz9(nTR3Jevyb*K|= z9pwkqRksT1j$7JyTN)zULMhZismPU5=s{Dez45=xDztLqiOzU9-qHL-CoyiEY?1^+ zMz5#^z@SeurftbTmvDZVGFJ=St$v|L)o0u6T5A9HY&J+|kAf=hwCKet31U=rt}=H#DEi$=6RG`gLq!{!Mt`Fc(lzun!Wd_A-hpp4b2s?-zNN`izEL}5<$ zoCxUegYO5aQg3=_-L8vk;E)&88wq-1OX|jy)KNQ28E6FP$T|!I7jqNg@;u)Zn9*22 zEMOOfi7BmqZfpSPN%_8X_Aq~MAQrVR5;KwI#&M{e>vCE+jv98Zz_ci32n6IP7b_Bb z9;z*0B1|#HdDOO$GsCERe%}fXYvLHOg7Ks)vL_pQPQSe4%j?28`qt^@=ksNKhu39> zFSqNqY0=#lxcc`cUw@i2KFSQ==irpH&E?n4mfw6>&i`@8FV?GDzTWm8O#b@I?V4{k z!r9ni^S}QyoBi7_v)TXs`5*uO!#;)ru25L zTFrB`8+LuvbXnQ!_1F69(+Li&pWRT>CqnAex6KTcj^5a$srj~KV9K~Vt<*fcv>H{7 z(|T|Sk5GL@D}@0nW>g7?+xeN*3iXc+)hBVb?+FewE<;XU?KU$}o)u5U@i>!HD^|# zx^d%3nSV&sa2)O(er)|;R;%sK;ky=|+z|Il?J1~{p2!yy$Pz@PAA%KA$X~e_G7x$A zz;4rU!210^)$8T5pFGN+ASe{0ISCG0j(2PE0((v&7J*qV%ZI7g?loesu=R21x6CW( zm}Ln)Hrr6hG-(tVcI=6jCZ%YHA}Na0Q)Z);Ttb2r%qR$=;{T}OeRAM03Qvs6QC`@8 zh()dL{>Cw!LUPpphKxNOKx>!KsXdPU%$h&&Sy|bq(>2|Ee06tod%nu}P#Z)8Flb)KhE3ZJ^S!e|Yp2|owdONtaIs{U)@%C$YWnsjHox;S=?FAKWTYuds6}AA2 z!PW%9H(Oe48#WH};g;?t+s;4nlee5MwjWPqLTq-YpJ#}h6Pmh9(poU?o`J^JR`{auNN8ogX{cDJ5yzm8E1@qI?l|FQcTFUiok#kB|J@!Lu`7Au$L zJsh!26~9YQ3X!Q4$$Nf%x1j4bC%muEu0tlKg1FKmqrtU{_kp$G{D%McYB@OIfrsu& zCo<&<`az@F-TcUQFLvAsgYtZ&>I`wrhafd8wO!>)Jq$hfif*}B-eHRD7^ZB0*s^m! z7%fL1u1r=5)C zz^`buHwa!uEC*qHij;Dp!KC;`lU znJk#IP+5dcy5sseCABb4@Xcp z-`5KoHb5#nQ>Z5O0o_3NEk0Gs_4SNt9-GcBtgFu&WuuJ1rzS+(QM7f(7xEoT!S;~F zUa6;e064TTU0JEqCdBuT*H`<%n0Y|*sVRp%GgVq1PKeWm6YKtDWnJzyaujkwJ@u>S zo9x<30?F7MJO#Wt&#z?L=J#a?`h8Q9FK{DYU?E@GIg^3wa?4g)2U+JAnpIRhHT6Pi z5#W1bb!QnE%V)hQNfWw}#xRhQr{umd*ga;z)KOs4C@^?(v)%(-!z1%q9sq+1V(?N_ zsY%dmQekv-mwqzcrGgZ)SBM`#heU2bM;0N-Fi?>|CuGp^0cL{5Ca=(3aX?9qSiKES zjnsq#*1t_lEY~%*g*mz=m=bK{1~k&wI0oz2Fo3Z7F!k(ekSB^8;QcJIheONi&T&4Ef4=rB^(l$m6GDI~I}3amObWbn<sR41J=mh`%FFYax)+(XdbIkT}`>SB!;$L;(?qRDH~!68XdpdAP44Qx*vhY6-=p z2yS@9)D`0Ewy8&a#EV+A}68J3h@JXGS zs)(0|p$oDP7F`|N*YNn#p>7Uwp!TR$qX$!wubdfoIpu_)Olygs{L521+Byq{EQZwH z{h>cgV;E_pB6B~hOSrtu05_p`;2HFrt3MHnclNoccq@r6&iWYO;*U`ny% z`Pi%r?qM41?v{hr=)j7~71 z&VPYKga$_P33W}ZW)=fQGd-N9uN4)V3d+=^eh35u9BG@)MsFr98!Pv?uz)VY6g z>V&x*_Np!GJA1XgE-!Hjmw%{gW07?O3yJZECFIYm_NmsF5DVC3wE7YJ=>uF6H+GTh z0_jt{^elbQ+oAcrs0P=?%U;d&l6T8W)$%j^=-#FVkH>a|-g2Wz8e99yL9#GK6uz@3 z9@cAJ?7;+YoAg+yI#V|dWPZO&-&yv}Tr83Pmr=6N{!nfkKi%F^F1zkzc<5bJ-ORn} z*x{GK7!>5@xRUd&@GKV4r)E;vx?e&{UZQVKx>0g(JX~@0CWY&8(YpKoGu+t0l5`2X zNQ1a2Vxjb^U=eH<>N^1kw~I`lU#M2>a$k5vs;0hqsoTgX4vKo?*DekP_BJjY=*`fG zF|yOh0p>YHL-LW6dy-;f2TDN0P>O84y%IQ5^te%PXiH0Z-#2~<#Zq72q12gfeBdUs z^qu1F&p_t!6oE2}fIvlFH~(i9l$SJ)C<3t$N^Ka`9NO%O0p8*0-bypq^8TMzAYs5K z@uH_X*;g|i)0{|-jtY{|4M4k8 zf^70?ZqAoU7#(n|5ZN?7&_cH;VFS9RfF5sx3W7O29n-Eoq}d_aU?`D<=wmbdIh*C1 z5tm=jwbWFLWu;L&E)BdPVdn0=5A`epI3oS9M1ZS%R0jjM4Q(Rg!TvOPG)+a&su|0U zgNCneaJZYsd+9zN@j>44tYneY@(Zo+dY|x?NBSS0I7l{ma^bKJ6G!?~&`sr1oEm-q zmgr;XJmByc8gRBo?gGj(wK6fWp)wEa(tfCES!BpDXgHcXnibuG?M$4qHHmR|vE=IH zenEUeO|mgAuWC`n5s^UtE}&zkDp(9xNApBFsZ57E=#rrgtm`#XZ0LiuQ=_&n*|`x; z{+q}@O3n$@-@7B(mXB*#0e8PstDyw!qv}49zGaTe-a(Fz95@ZVe=gcl6l%=^`JdJ_;f$`7Vre=w!URP3vH7%4q_;sM2xt`Kk#Icx$B7 zt&xxaILtK5%>{SLd;8`6X>G%GigN?CpiXx6Axtq^p^fikHjV;;*95@}6|OZP>Sn^E z;q%P1jc#}U!lS{>H=PSNCeLUk$#rdk0q_#;gQcm&2p;#7I$qVa^l;z$qmCkI7bsD-&8SM;5q|aho@7g zk6x#uo7aF?e^3Ggb+Oh$Yee)`R>7Qy&hED*zXDV&faaRe;OQZ91O5^(!)YH>nH@oQ ztO6EP>Aa+s!Fh1sEnmFWdjG>lS#E#T1KgxbwY@TOW)HT8Y%Pl~!%+hWwiOrD&RPyg z(^Y=4Mnwh__n@@_OXs-)K3rFmVOma;0JULCuC1bNj@zqo-Ho6*s%JyT3%KPVdpJQ( z&F<7a6Ue2#+IMj^+iasbldef1x0#JH{GuwVr-_ZyGbjP8)$Oa-?d!);k;s@KxB>e& z*AFlrI7792=4&80y{6MnN_t4)ntJT&cZ^t~W>I0i=3Zw}Z#2w7#?5b95Q7ZfuK5do z(YI3>8)&*2?0ym&4R0br1Fnvvintr#>((FTLhWTV^6OlOF29VKnQXn}z$7VCV!UYr z{FhoSuoP$lh?S*s;Cd1SzghW2!nGy{=Dhtr{ZaIU1lq_%smEUVxrM(Im- zKPA@l0AQ|-0$=$cxMSf%0Mhj!ctew|)#&-szr*v4^mFWoXqhKsElY4^o>N<8JW&%h zr2}16Oiv>5P9@&8B&E= zMfA*58X=Gt8fy3B6aF6nQ47w}+l=?|{tPutuN$d2WK%H&TBCz^mCOScG^HZ%ddi>>&W zf4yK~k{(lwCZJbYis0YgK=F?^Sei1xRVDxoXUPs%ogfHoX~+*(o*>vmolW9$Y#KLj z##&UM2?L||wr22Lff%kk_RDa)0ue^%4BN;K09Co$jFJI(_3sr-m`jjBH6I^L?~9NF zRT!`J-|X( zu2^G@xzAEqu3h3ZsYL{{_v0i%zloUArQ#xPr-7JKhwd_l2%t3sx{K%>Kwbms!t zp@!?ElWg+&^n3);1A+zh%AQj+bepIWHtF*U{=_L^gc8r&%0_C={sTVGwsx-H@i&x?%a!Lnl9?5PCWw~-2 zEn6CPVH@Ccr0OWY4HZj2D@_#C_NgwyGf#vU`}ouAJz_QQ+pzF?si_EPGi#CYUanPt^SvoRI!8P@<3?|>tMwJ|C4b?rBG5ZMabZWfdf%-JyRnNCX6{w$fn;Mxy3+b8fgl zB!Y1e6;{>TXxRm+j%~Ok-=>{3(OQs}H3E5O6{RzDZ&P(Ba9RNeqXWGF5o@b0_pYI8 z4rHk^FrGE9TxQZoF12R6HC#G14)1*7;nRY2DHpKd zc+;j2@1i$#a0Llla#Ct!ZK0pF7jXYGRCfnmP%NCs;CX=(=a&WmljS?#nr#!ikZ%(o zr5nK5J@sHAZLcB3W?b!YS_6kj(HK`lb)TO9nAhHqD>X$ zo&hCKmaf^kl1!O;=x}j&ax|!x6&W>i&LM6NHlM4?fVV3jr+WH^6bebHq7d${&!D_E z3pH*JyDxhcGfy{fNs(b!^W>}9P^WDRu40_ckRYe&!=8jBgj1&VD>2AOm%&@B?Z>I5 z#5lh_Q=Kmk92R~)2qY)T^&X&f>XueN?vIm@?k zZq!9UkMg>Z6NPZ$!7C2AQ_CpaMff}$pLJ(vDmRIIcET+S zj(!WKzjgL?lM^Q)GwXDdD>YuNUVoIGsH1MGCnY0Vym=D3;NA#cOs{$ErWM@WP98Id zS+QGnBq$;FGMv)4Y@H^?R3c2|AS`H?nZgy_e3;f7I?dVm*87NAbAqc$uiy=dP#mqI zDxQENTQ_4=DDv{Yc9|-A&0Jo20><2}CG`ui3+9F2%*YRn34gh_3k|P4$rN^x87mBteqSjW4@$z z7GIvGZ1C+6t9={xgX+wL%O;kzpZkj*R5b{}ONuRNPV{g((;*rv#uKqk#j&R}!B_2k zD`d-#s9EhfZlqnD!4=r2WO07in6}Nubtf;+^KQ%lj9QASktBVE*pXT36E z^82o;-K&?~FQnkIzMzewo*GN@OK=9a0*XxogL9w`)}9$l_tPK-&mfAeT|4;dHx>>T zvV5Iu6$r?xKmFYOmvh_839)WHnlK1DL}9Lhe>u>Q-S{`5;O`C2mY7g8*-a$fT60yF1Rffhg%To zrt1Gh&^h>@5~R)kleIGnd{mpcNe;4h)`W{(Y(fx4ipdB+7tx6FvAhG5r;*Q@JehpZ#Ev#iaso znzK2Wz5DN7;jzz0{m-u4_QxpvXII8hME{>W{!D&<~)!dkOK5 z^)E$$n!lG|bQEkKC&YTRfEEMPY@opKx9gUsr@Tw#(6KCAP4A4-o@fVO^`%YTMctC8 z541~?mvjvKn_D?gdR(kr;`B-^b0}Lzsz&;VgSWMIO;K$lLt9hVdyLoM%$w~5I#*S@ z2)%aB^}dpyXo5{Qda7p~(-t1+L9P?~h2(P=$<~kXq;rp)bE_uKFQHa|b2eMK-5Qtv znW{>ZwGhwnt)W$(GS?ZhPLWDGvbo}Aoxv7#~5rA){$U5ay`X%VB z%eRmucLBbTbX(HtZ^2O987uq13MhDJ@GM<;GBH@_!0(2Ite&ktg;s&&QUTRa;q9Sr zGi|v1=rwabZTyKrUOC?thgN>MAw-i!Z3_JHS7bsM4FJae3$_CAD5|f5&a!;UCc4;YlLxz~kMD5W&dB9>MiC>rld=z0J#;C4&&l~SnT9jkq}528R_ z3vXC{l=Ty5MuXUzzx^{-w`xW43j4qz;q3Opn(%(iN|F8Fo+BrAC zro=9&tYSdX%0N-72en+UpW*og$@j~@C#tMGL2wKhTOWp2Ry8U_{r2~VQE{vlPa4hhJITWuB)2?`o*?& zzYihrSSF2d$d&9B`Y|N{UYZ~mF~JvB(5c6TtvtJP)3qq`<9Yop?EHh zONME^W#(6;oG}rySjXx2xg5DC+`NwB#8u$9QSC9@{zYO$e5Y!37{bkJk9qh)kUa@( z4LIOa#^;qJefNGvM%MY2j4dldyJfnh1!qW|^ybIsiMNuqfzOqk1agbIazI(f89 zkkYACM+sp0Y+S=lhw!es0oCIIcf4r!P*6gUKgl1>F-ss(;wo_<)i|K1&QNNh(Kx{W z3n?@X`2Io$jRQ$Q`E3E<5LG!qeN|#*gc4N%!9Oe%s+<%Lefg%l5#fWnkqMan z$J{dqZ(c6E%jnNU7wfS0?K@{6=SpV8{Ux51Y%p~YQ>|yTvJlJTmIvx83JlYYRAXdh zm2Oj%PE1O*_APew2F0bD@$=6bNhj4E7Jh#ekT^W&bCfV`@%cg?eEltSX~pe&*%;}x zhxx0Kq~QBWy=+ehVGm213B;KczL7bPs`)mkBfJ#MrOc63535WM%Seh$U;gu@$7;Ox zNj!Y~{t1^X%*~~#+zp!Sj@U@94a$dE?`~pYlVCCU>Ap>aMIw&K0t#_#2qvev1LX>7 zG^4}pzF4g|zTSSmxO>xsH;l3q4_a}}^0k(j#jYIOa37($&!YTCs7Ip^54)h1|2;yK zjlC9oW#$BB^r5N;*TP(w1X|bforp0?`zNYpV7oJ5+%P8HcdDG){;w%{O~l=Ud+EjJh?-ZE z7O{~hd4PW1_Fb3noO|RQ06zpG4`aVXL z(ULv6La?}L8B?|NF=r3#QA>{SW&%s&|7CFtcXG=y>Ok2t#+*L}D4BV>oIdzVNK^Rm{+IOM6-Kl(iM0Pa>0jwdreaBdrMK}2wetLxet|=V1}ORY?-G)~ zC8!_2+5V%(KSDzPEkxwM3CaE23V@Jr{}%H5`1W5ylIWxJXk7vAaXI-Pn134hFT{PD z+kaI3j{-n50JQ%#;_>)z?`3t8j(9$EC;kaA8j>I#>ejsA4qBuVtep|g8<=&@#jsIp z;eY*mHNhOZ6Ry#M6?mPV8Re1GW&s@?1ZQP&*FEUr3Q)xt>n5hI)UQ6sR3UHjiw zqi0XGYxBq{$-La3FTzl0__XNy+YE7*o%)@BSD&57H-Amb^-e?+_Gs^SRaFh2c7B2{ z*lNq}Ot7)4M?iRYOxv&g4Q-j+@G@sns6yEoWZ9#7!zscoi`~Q`r>?(@A5y!&fVjHTUe;IiY0iM?AP+Mj^90{ty_rE=c+W4PEXjNqK`*LudFKJK zLF|8GgG!M23<4Jy8_aSK*%n`TEVn6{CXNsE{3;RR*V0*Z3dybfA=x9zzltB^EN5^* zraiJZVpu|eYVZwQ`zMJ0vAVq@l-^m7%g`k!*uSjL8u5?yHR`e-1lmZlSz(nBi@Aw4 z>Hs2I4ZSQ?_~xQx2ynDn)X6(xBC1$rGOi}ru$>T_o_qo|C0pyN>4Ji+FAU_H&Sr{1 zF`6A-wY%wpz$=~c7~&IqbLT%hfvqI<^(`$0(aQ^}^%`nO&w%E|U6fH1hx8NkSAiNZ zSXV>>E_WV3qwOsFCLojPf(FV1{b}ta_5Ema2+x4l-!Oi7e`WrSdZL>(HD6Y4xNsL? zLxi=$Jk%>^ON%b`9Y66Ccda^n3*Jl}K5p>wfOE4X4p_S70&%b;CQ<#t3f##WvqO_p z2(*FSr5EyVTuWiQh=_@7(ExM;aNm| zg$J?lE6wan9}(!(o4^9Fi#JrboVSCr8$?BhAEv^rp@kwy)>C6E34}_F?6J@;LR0>O zsvBhS6(3DZkUCoyTrpW=vn*ETetL?$WX3{9wn3JzEV%Dd|7j<>+EV-urZvGY$I=}K zwkg4n+euQW%s`M@!MLe$TLTNT(jZj}suJ!uAkL{hT>%HD&5fgL2Y{-YntHwfsD_iK zU#Z8d1Jq!;Q7tWW33w~v;@m?Bt1iC5(7wBHS&8xE8+G;?pb4Yr4n!C&y{(#mg35g> z(WUgMbJM_;vNg5_Vk7VW{@MK>k>lb^*BWeuwvdew{@zM$G!QUV2$AZK1dwADh)Z^D z%_+N$o>%*Cw6gUwO8F)pI_eV{)oPyL>O~*!<8+p)~ z;Qc?^Nub-rSSm)%~{kU}l+ZOX0~s=GDAnD#$~`AA-tv=R1D&7vChy=A0V zv>n8Lx1aFp)n%+e@uv)t2?I#4oC8CQ08s;&v|@*IKT&-=9}* zjZXIYp$umf)v-WkJTh|#CR&^QK>n;AvZ$JOQZrsnxFR*70C;n9ST-~yF9)ND_*%q! z+}G}jo%fZdXN9Myo7Fs&iU_wdGKYMs};_~R??0-L6mQj45*>>S($ zrC0L^>GYbpxi)o#os)wYU9dxz6p9qJ_e&MNk{x}Qs+KbO!W8KpIK6B(X96e91O`rx zhF=n1Yln0a(v-b7rlt&6i2tnSr6$_OB^DnVYh&6O1py~`^FF>Sa4vY|_iE1T-&qGs zXNTah%7206wgxhYd*53Rw?lGrqM6sq&bV^h`*6n#ODAnah>nM)Uf=vWkKr2boFKG3 zJsq4eEwhbibN+lCo#)LgE<^XOGF(X_@sEoyYa_Jm>?G>!eP1h9Z$&R<_U|Gh@#TC5 zs|?|-mIY|NeANK3lY++iY4kGk!A|DVNrDPSPeFPzptMWV;n3O%i((|uZeT&x*tG7@ zctR40!MW&onChKNYq6du(|GoD{Y`eKz=oWVmBCV{*Uh}f(+H2=QspuwzD&DdPMr&z z`Fjj!*6VA(J=zA|h{cRDM_V4Ber+DfZpJZ4d!v9h=w$BP%H{a|fM8*}#vgZS|K9g? z4wF(DHR5`BGKz)Mgr_(y_mJjBdB-}0TpwE`UiZ||`wH1TBSjF$R4TI$hWh9X!Xvh* z)JzuAuA0zvVw!?euZN6|xs>WMl#-q^rrQ3j$h^(;^BrY@BiNl?vdF_QrhM{)HA1rK zhR7~zIq$CxK9c(;rdox~eX{S5_RADc9PmG(r!sv8l~#m^d+n>=yx!lrb08znD~NFw zWCL0`qLg2H9#gu7n#(A1bRc|w_EL$1L6I20aePyZGLLU^L`x7-N+i!Zt0CK=VZ}b3 zJ1@~Qj&uU`e_==tVJ9VGT+r&JLdcIsM*kBg0a>=XBB&K)?i-O+j=oN*qd(d=R)KRjoEU(Gs;e+{|Eu(~cD%qb2@&T0JIG~J{cmcc2 zkc{D*JLnHPak}p>NO`K(LZHi@2Nb^N#&{aDQhte_F=9a2i~0003Ei(~iQ6_j@2W06 zJzXE|OWT_7uoReFLprtZMh@qWjdH)Y9MtJvgSJEkbNGt{c}oU&GEVB)B5$MJ$j_1K zK#Nh^r@-_GSQjVh3RN~V!;$&hGsWMOInBJ&4gn4+xzBZe>>{fX7;OBG@X)43v?y*Q zkhbeyVn#&zCidCihrn$!My(2ko= z1uu2&0+zNanVSfjs{HBDVXHlz$L?IrvAZt5281^!zr0W|533leG34c~TBiSL4rxQe?L|U}rOKz2e_j96U)JUW|FYQjwE z>c@GrAp1)yxUJ7}!gS9#I(SEI0%&%4Y|;HLM9I9`4;#gz{hrJz)RdG`#a*9qBR8TT z;~rvz|I)aNnK%?&MwHDtzCM1L+c6QtcHG z8M6i7HtxiOfaa=9q9QtO~sJ-}5`KeW|y_%w3(R@__6 zA?pl7Cc2ILbd3i7ixhve1oAL4IVR1WjK`e~s*E{WbE;#FBBIlohx8IXj{&Q!jWTO{ zu$`q2Vl8^H@2S5qx6OFoZy)Wj3(amot8=w0fGtl0QVP}!M~MTc(qRQFU2z7OQ=q1+ zlOPFz73VYJ_<{cJTLXheju}i!=Oqs`Ei-NrDe&s7lp42f;-xJ1ZaD;ZLNWQs7?w7% z7YdXJ_smU#5F1JS3OpM(l&YL!@@`em0wJy*eG~7!7&)x_U?hHcyanZ$nUH^BqL(A( z(V;M}qU-gkMcrcT6trL2fz~@EP4}(q;I;1Xqx}a0aY(j5f>O0MwHwAZ<<=N@2fKv# zc9L~9O_)JjyOfPKdNBCnrLJ2@5sZXbl|d{`CEFQM=_rI&dOiJJ*uZ_vPlE+hsw@LO z3Sue(N9`1xJa%>-x9zd@MDcOr4|AyA~s2BuQNT^kIj$JDKa!kZ2&TkWAig~ zin1htwCB1qKR5herKpl3JVjaVLH)J)xqp8z%yg0By-4<0{r=ztz*;NHHc9htu;J(Y z{rtb79_}HNi<~Dm;Zw@$2wvptD&|;TQt|_izeUa`_H-kPsk|4>4mkdK?&B#FTnfd> zg+Y-h117aey~PSpzC-5IEz!=G41b`#LWXR8SN=FBEFbd+nyM$#tizff6lcg6!sadZ zpFchLVCmQ8kTg_X`gwfbPM{}W!%D(RP!lS_AV|YzLlSMTZBC2w3Z$TZR>)kS%`S!_ z*nMHN(ZN>fHy#G{l$vj1|QFrzc(-sPieL# z&Fn7Kp%Z%7YcD6=Ww9$VX~@9&aAb6g>c7?+`S8nKxnoBy^lZr|kc872L7Y@d1Ek}l z6q@A9_-#^=+|P7@=Jz;>c<-~UQfLOH%E|qQoUuYG0ftSg;GOi!!`lnaj#X%o_wo)@ zxvCNhFkfTMaBu6p0Js>lWSwxNxh)f^WbQBX^5Dt7gIAPj8K@n_!q1Ehs&%I7+MOQf zs*Bh@Gmw|z0lIyaw_+<8Vb<842g;D;^Bx7KGZQJpqap~N zZqOhZgZi$5dwy9R2;ZpUXl-yXnO~Ba1Pi+F&aNc-7aE9K>TytHTN||umBm|0QKE5j z9z9`==HwF&O1M?|L4b!bYg%{)+G~;yvG@(o4ALsvgy~*ps_8Dr{-2Ne-`bI zqEk!t5JD!OAVoRHIFg}34*%vI%aJP^OKtCbuhh7N##6i+GkRZgKB1*S)^nyp=qrQV zM;+qmZYcs1RpVU7R2DA=CWn~l?&t4-KF53#qjPeTXj$Mm%8vX;Nl%5{yzgQV4gKfUh(a5Ss}hGxMJstl@b$Bg0@r zlVC%uU_*;wL!&`>SXYVsJDRHb!dIf8Dfo8fjBNVzk;y*~!w$du zJpaUfqd58bDw0xLuuHLPJ0WZvimiS}A%O1NIS9sv#NUO=e5ZoDtz5KE`RSA+GXS}g zU(!6P_~m<2Fb9*~CKfb>FGv&Pg?r%owEky{-S=GKcWonSb+mak)r4A;hVy_jMfypB zI&yDe$;$2^2fXPD?Wdis<6%)I=5v7pweAG|3Q3()r;aVKl`QFxf{WS|cljD+=+oyh z`k|5Bq~Pz*-2-E5)Pj!ryCQbBR{emO!E?Mv6Vtip0vG_Zb z3Cuz{MHT|ZEPm_cfuIA<6$yUtjm4?apr${6$SQ_3Ls8!Ok^?TMm0G?FtjkbtIV0QA zftM{_@UNV?u_J?p z9mD^c3D5sN6Gvw!09Se!CS68dM*4r{{^5)Y-~shd^XlYHdRqax7r?LZ|4+`w4i2^s z^iFP0(lQe;{sKsy4CmbAp!GS2=6OQ#i#c+3VU>k(bSuBhCFNzaAmka7u53GPEu|3T zktA!ZG`-E1Nlif3j9L;627ao!kLB-#FPGFdxV~TGkCX*cSJJU!rzTx^zax~~V8HvK zp3UY3&#yoS0_VG7x8`E~WX6kvOzVgt#?dO^%0A;)zHx%WUwBG$cPXy5NuRMKyd24# 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νi>{GS{we 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%0ApYxFa}2BZh(Au2mbZ6_fm*= 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%0Axloc1Y!5LWrxMIs;;NhpW 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%0A1n2_;$tEROo$HGC@>LVKZx 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 xbPqLz4qe4YG#w(`Rz{Px5X7;~7Cn_Trkz3P?+) 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%0AQnFJ{j+&iruWXyoJfZw?bNBe_ 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

    KvlaS2QQ6{Z%h}!9Tr;oTB}b9k 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�aEXK4*9YJpX3PEWbVW>YU9 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 literal 0 HcmV?d00001 From 236e088a4fcaefdc67da076e4ad390305c6276bc Mon Sep 17 00:00:00 2001 From: Rajeev Kallur Date: Fri, 17 Feb 2023 15:39:22 +0530 Subject: [PATCH 002/159] Add files via upload --- examples/Jupyter_notebooks.zip | Bin 0 -> 110214 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/Jupyter_notebooks.zip diff --git a/examples/Jupyter_notebooks.zip b/examples/Jupyter_notebooks.zip new file mode 100644 index 0000000000000000000000000000000000000000..996cc660fb56441801ce32657e00641acb55df10 GIT binary patch literal 110214 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 literal 0 HcmV?d00001 From 5df43f551b4f931054765d32a107903449784a80 Mon Sep 17 00:00:00 2001 From: Rajeevalochana Kallur Date: Fri, 3 Mar 2023 14:38:03 +0530 Subject: [PATCH 003/159] jupyter notebooks --- .../.ipynb_checkpoints/index-checkpoint.ipynb | 53 +++ .../account_remove-checkpoint.ipynb | 246 +++++++++++++ .../bios_revert_default-checkpoint.ipynb | 259 ++++++++++++++ .../change_bios_settings-checkpoint.ipynb | 327 ++++++++++++++++++ .../computer_details-checkpoint.ipynb | 237 +++++++++++++ .../configure_snmp-checkpoint.ipynb | 244 +++++++++++++ .../generate_csr-checkpoint.ipynb | 279 +++++++++++++++ .../get_bios_settings-checkpoint.ipynb | 255 ++++++++++++++ .../get_powermetrics_average-checkpoint.ipynb | 226 ++++++++++++ .../examples/account_remove.ipynb | 246 +++++++++++++ .../examples/bios_revert_default.ipynb | 259 ++++++++++++++ .../examples/change_bios_settings.ipynb | 327 ++++++++++++++++++ .../examples/clear_ahs_data.ipynb | 258 ++++++++++++++ .../examples/clear_ilo_iel_iml_log.ipynb | 230 ++++++++++++ .../examples/computer_details.ipynb | 237 +++++++++++++ .../examples/configure_snmp.ipynb | 244 +++++++++++++ .../examples/configure_snmp_trap_source.ipynb | 220 ++++++++++++ .../examples/eject_virtual_media_iso.ipynb | 246 +++++++++++++ .../examples/enable_secure_boot.ipynb | 249 +++++++++++++ .../examples/enabling_ntp_server.ipynb | 246 +++++++++++++ .../examples/find_ilo_mac_address.ipynb | 227 ++++++++++++ .../examples/generate_csr.ipynb | 279 +++++++++++++++ .../examples/get_ahs_data.ipynb | 264 ++++++++++++++ .../examples/get_bios_settings.ipynb | 255 ++++++++++++++ .../examples/get_powermetrics_average.ipynb | 226 ++++++++++++ .../examples/modify_user_account.ipynb | 317 +++++++++++++++++ .../examples/reboot_server (1).ipynb | 234 +++++++++++++ .../examples/reset_ilo.ipynb | 252 ++++++++++++++ .../examples/set_bios_password.ipynb | 236 +++++++++++++ .../examples/test_ESKM_connection.ipynb | 239 +++++++++++++ examples/Jupyter_notebooks/index.ipynb | 53 +++ 31 files changed, 7470 insertions(+) create mode 100644 examples/Jupyter_notebooks/.ipynb_checkpoints/index-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/account_remove-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/computer_details-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/configure_snmp-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/generate_csr-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_bios_settings-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_powermetrics_average-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/examples/account_remove.ipynb create mode 100644 examples/Jupyter_notebooks/examples/bios_revert_default.ipynb create mode 100644 examples/Jupyter_notebooks/examples/change_bios_settings.ipynb create mode 100644 examples/Jupyter_notebooks/examples/clear_ahs_data.ipynb create mode 100644 examples/Jupyter_notebooks/examples/clear_ilo_iel_iml_log.ipynb create mode 100644 examples/Jupyter_notebooks/examples/computer_details.ipynb create mode 100644 examples/Jupyter_notebooks/examples/configure_snmp.ipynb create mode 100644 examples/Jupyter_notebooks/examples/configure_snmp_trap_source.ipynb create mode 100644 examples/Jupyter_notebooks/examples/eject_virtual_media_iso.ipynb create mode 100644 examples/Jupyter_notebooks/examples/enable_secure_boot.ipynb create mode 100644 examples/Jupyter_notebooks/examples/enabling_ntp_server.ipynb create mode 100644 examples/Jupyter_notebooks/examples/find_ilo_mac_address.ipynb create mode 100644 examples/Jupyter_notebooks/examples/generate_csr.ipynb create mode 100644 examples/Jupyter_notebooks/examples/get_ahs_data.ipynb create mode 100644 examples/Jupyter_notebooks/examples/get_bios_settings.ipynb create mode 100644 examples/Jupyter_notebooks/examples/get_powermetrics_average.ipynb create mode 100644 examples/Jupyter_notebooks/examples/modify_user_account.ipynb create mode 100644 examples/Jupyter_notebooks/examples/reboot_server (1).ipynb create mode 100644 examples/Jupyter_notebooks/examples/reset_ilo.ipynb create mode 100644 examples/Jupyter_notebooks/examples/set_bios_password.ipynb create mode 100644 examples/Jupyter_notebooks/examples/test_ESKM_connection.ipynb create mode 100644 examples/Jupyter_notebooks/index.ipynb diff --git a/examples/Jupyter_notebooks/.ipynb_checkpoints/index-checkpoint.ipynb b/examples/Jupyter_notebooks/.ipynb_checkpoints/index-checkpoint.ipynb new file mode 100644 index 0000000..58031df --- /dev/null +++ b/examples/Jupyter_notebooks/.ipynb_checkpoints/index-checkpoint.ipynb @@ -0,0 +1,53 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "453f77bb-9a66-492a-bf03-a737b524a484", + "metadata": {}, + "source": [ + "|OPERATION|DESCRIPTION| METHOD | LOCATION |\n", + "|-------------|--------------------------------------|-------------------------|------------------------|\n", + "|bios settings|update bios settings for iLO server| PATCH |[change_bios_setting](examples/change_bios_settings.ipynb)|\n", + "|bios default| update bios to default setting | PATCH |[revert_bios_default](examples/bios_revert_default.ipynb)|\n", + "|powermetrics average|get powewr measurement average of servers| GET |[get_powermetrics_average](examples/get_powermetrics_average.ipynb)|\n", + "|change boot order|update the existing boot order or add new order| PUT |[change_boot_order](examples/change_bios_settings.ipynb)|\n", + "|change temporary boot order|update or reset an temporary boot order| PUT |[change_temporary_boot_order](examples/change_bios_settings.ipynb)|\n", + "|clear ahs data | clear active health state data of iLO server| DELETE |[clear_ahs_data](examples/clear_ahs_data.ipynb)|\n", + "|computer details|get all the available computer/hosts details in iLO| GET |[computer_details](examples/computer_details.ipynb)|\n", + "|expand data|expand the response data obtained from any of the http methods| GET |[expand_data](examples/change_bios_settings.ipynb)\n", + "|generate_csr|obtain a certificate signing request for iLO server | GET |[generate_csr](examples/generate_csr.ipynb)|\n", + "|get ahs info|obtain active health status data of the iLO servers| GET |[get_ahs_data](examples/get_ahs_data.ipynb)|\n", + "|base message registry|get base message registry info of iLO servers| GET |[get_base_registry](examples/change_bios_settings.ipynb)|\n", + "|iLO ip address|obtain the ip address of iLO servers| GET |[get_ilo_ip](examples/get_ilo_ip.ipynb)|\n", + "|License key|get iLO license key for iLO| GET |[get_license_key](examples/get_license_key.ipynb)|\n" + ] + }, + { + "cell_type": "markdown", + "id": "974fdedd-2bb1-4a4c-adb5-a6052e134085", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/account_remove-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/account_remove-checkpoint.ipynb new file mode 100644 index 0000000..6b07a69 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/account_remove-checkpoint.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remove iLO User Account" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to a particular user account on HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have
    python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + "
    In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + " for proper execution of our code.
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of removing a user account from the HPE iLO systems\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    2.
    \n", + "
    \n", + " Below is the remove_ilo_user_account function, after sucessful execution of this function we will be able to delete the information of any user account that is present on the HPE iLO system.\n", + " \n", + "
    \n", + "Let me give you a walk through of it!\n", + "
    \n", + " \n", + "For removal of any general account from the system we will first have to search for the accounts that we wan't to delete based on any attribute or property that uniquely identifies the account. Upon finding that account we can just make http delete request and we are done!\n", + " \n", + "1. In the remove_ilo_user_account function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In case the resource directory was disabled we are navigating to the actual location where the all the member account information is stored by using DELETErequest.\n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources to obtain the account_collection_uri.\n", + "
    \n", + "4.
      \n", + "
    • Now we are having the location at which all the member accounts are present.
    • Simply we just find out what user account matches the account that has to be deleted based on username of the accounts.
    • If we do not find the required account after completion of iteration we print out a message that required acccount was not found on the server side.
    • \n", + "
    • After this we simply make a DELETE request to delete that particular account and save the response obtained in resp variable.
    If the http status code returned was 200, then we simply print a message that delete operation was success.
    \n", + " Else if the status code returned was anything else we print out the status code with an error message to get idea about what went wrong.\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def remove_ilo_user_account(_redfishobj, username_to_delete):\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " break\n", + "\n", + " #find the account to delete\n", + " account_uri_to_delete = None\n", + " account_uris = _redfishobj.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " account = _redfishobj.get(account_uri['@odata.id'])\n", + " if account.dict['UserName'] == username_to_delete:\n", + " account_uri_to_delete = account_uri['@odata.id']\n", + " break\n", + "\n", + " if not account_uri_to_delete:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + "\n", + " resp = _redfishobj.delete(account_uri_to_delete)\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    3.
    \n", + "
    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • The ACCOUNT_TO_DELETE contains the username of the account that we need to delete. We are passing the same as an argument while making a call to remove_ilo_user_account function.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to remove_ilo_user_account function .
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + " \n", + " \n", + " # The username of the account to remove\n", + " ACCOUNT_TO_DELETE = \"joker\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " remove_ilo_user_account(REDFISHOBJ, ACCOUNT_TO_DELETE)\n", + "\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb new file mode 100644 index 0000000..aa96161 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb @@ -0,0 +1,259 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Reverting the BIOS to default values" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to reset your bios to default settings!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "658962be-a0df-4696-ab9e-73f844703ff9", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  1. sys \n", + "
  2. \n", + "
  3. json
  4. \n", + "
  5. redfish
  6. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "53341fc4-f674-4781-bcb1-04bb06d3d1fb", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    This is our reset bios to default function overview, in the end this will set the bios settings to default.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the bios_revert_default function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in bios_response.\n", + " Then we set the resret_action_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios settings of the user through redfish object and then then set the path to post the action we will perform\n", + "
    \n", + "\n", + "5. Then we set the bios settings to default using the action type as Bios.ResetBios and say set it to default\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a5f7d7b2-6ab5-473d-ba19-113d603f9e2d", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def bios_revert_default(_redfishobj):\n", + "\n", + " bios_reset_action_uri = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_response.obj['Actions']['#Bios.ResetBios']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_data.obj['Actions']['#Bios.ResetBios']['target']\n", + " break\n", + "\n", + " body = {'Action': 'Bios.ResetBios', 'ResetType':'default'}\n", + " resp = _redfishobj.post(bios_reset_action_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " bios_revert_default(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d0ded655-d8e4-452d-b181-783a6b1788f5", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb new file mode 100644 index 0000000..98e679b --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb @@ -0,0 +1,327 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "266e8885", + "metadata": { + "tags": [] + }, + "source": [ + "# Change BIOS settings" + ] + }, + { + "cell_type": "markdown", + "id": "358b08b4", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to Change BIOS settings!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "578dfc4d", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  7. sys \n", + "
  8. \n", + "
  9. json
  10. \n", + "
  11. redfish
  12. \n", + "
  13. get_resource_directory
  14. \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c82681e9", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/1390777471.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'get_resource_directory'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "84274de2", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our change bios settings function overview, in the end this will be able to change the bios settings.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in systems_response.\n", + " Then we set the systems_members_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", + "
    \n", + "\n", + "5. Then if bios password is present, then we will update the bios password. Finally we will send patch request from redfish object using bios_setting_uri. \n", + "\n", + " Ultimately if the operation was successfull without any errors then we will get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc680e58", + "metadata": {}, + "outputs": [], + "source": [ + "def change_bios_setting(_redfishobj, bios_property, property_value, bios_password):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if bios_uri:\n", + " #BIOS settings URI is needed\n", + " \n", + " bios_settings_uri = bios_data.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " body = {'Attributes': {bios_property: property_value}}\n", + " \n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " resp = _redfishobj.patch(bios_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " #uncomment if you would like to see the full list of attributes\n", + " #print(\"\\n\\nShowing BIOS attributes after changes:\\n\\n\")\n", + " #bios_data = _redfishobj.get(bios_uri)\n", + " #print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "567eb3f8", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Please enter iLO url, username, password, bios.attribute, attribute_value,bios password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "7c01d222", + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Enter System URL: 15.146.51.201\n", + "Enter Name: Administrator\n", + "Enter password: 12iso*help\n", + "Enter bios password: \n", + "Enter bios property you wish to change: \n", + "Enter Value of the property to change: \n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Initializing no proxy.\n", + "Redirecting 15.146.51.201/redfish/v1/ -> https://15.146.51.201/redfish/v1/\n", + "Response Time to /redfish/v1/: 0.5402989387512207 seconds.\n", + "Performing session authentication.\n", + "Redirecting 15.146.51.201/redfish/v1/SessionService/Sessions/ -> https://15.146.51.201/redfish/v1/SessionService/Sessions/\n", + "Response Time to /redfish/v1/SessionService/Sessions/: 0.11417365074157715 seconds.\n", + "{'@odata.context': '/redfish/v1/$metadata#Session.Session', '@odata.etag': 'W/\"793BFE96\"', '@odata.id': '/redfish/v1/SessionService/Sessions/administrator0000000062d1d61d46e97804/', '@odata.type': '#Session.v1_0_0.Session', 'Id': 'administrator0000000062d1d61d46e97804', 'Description': 'Manager User Session', 'Name': 'User Session', 'Oem': {'Hpe': {'@odata.context': '/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession', '@odata.type': '#HpeiLOSession.v2_1_0.HpeiLOSession', 'AccessTime': '2022-07-15T21:03:25Z', 'LoginTime': '2022-07-15T21:03:25Z', 'MySession': False, 'UserExpires': '2022-07-15T21:33:25Z', 'UserIP': '16.242.171.23', 'UserTag': 'REST', 'UserType': 'Local'}}, 'UserName': 'Administrator'}\n", + "Login returned code 201: {\"@odata.context\":\"/redfish/v1/$metadata#Session.Session\",\"@odata.etag\":\"W/\\\"793BFE96\\\"\",\"@odata.id\":\"/redfish/v1/SessionService/Sessions/administrator0000000062d1d61d46e97804/\",\"@odata.type\":\"#Session.v1_0_0.Session\",\"Id\":\"administrator0000000062d1d61d46e97804\",\"Description\":\"Manager User Session\",\"Name\":\"User Session\",\"Oem\":{\"Hpe\":{\"@odata.context\":\"/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession\",\"@odata.type\":\"#HpeiLOSession.v2_1_0.HpeiLOSession\",\"AccessTime\":\"2022-07-15T21:03:25Z\",\"LoginTime\":\"2022-07-15T21:03:25Z\",\"MySession\":false,\"UserExpires\":\"2022-07-15T21:33:25Z\",\"UserIP\":\"16.242.171.23\",\"UserTag\":\"REST\",\"UserType\":\"Local\"}},\"UserName\":\"Administrator\"}\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'get_resource_directory' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/3485138033.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 25\u001b[1;33m \u001b[0mchange_bios_setting\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mATTRIBUTE\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mATTRIBUTE_VAL\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mBIOS_PASSWORD\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 26\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/2914597885.py\u001b[0m in \u001b[0;36mchange_bios_setting\u001b[1;34m(_redfishobj, bios_property, property_value, bios_password)\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mbios_uri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mbios_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mresource_instances\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_redfishobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mDISABLE_RESOURCE_DIR\u001b[0m \u001b[1;32mor\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mresource_instances\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m#if we do not have a resource directory or want to force it's non use to find the relevant URI\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mNameError\u001b[0m: name 'get_resource_directory' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " BIOS_PASSWORD = input(\"Enter bios password: \")\n", + " #provide the attribute name and the associated attribute value. Note: some, values may\n", + " #be containers (arrays or dictionaries) so keep this in mind.\n", + " ATTRIBUTE = input(\"Enter bios property you wish to change: \")\n", + " ATTRIBUTE_VAL = input(\"Enter Value of the property to change: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_bios_setting(REDFISHOBJ, ATTRIBUTE, ATTRIBUTE_VAL, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "9d0181a9", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "9e9f0846", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/computer_details-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/computer_details-checkpoint.ipynb new file mode 100644 index 0000000..4b81113 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/computer_details-checkpoint.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a38bafdc", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering the computer system details" + ] + }, + { + "cell_type": "markdown", + "id": "cfe2e2b6", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to get_computer_details!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b3fec1a9", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  15. sys \n", + "
  16. \n", + "
  17. json
  18. \n", + "
  19. redfish
  20. \n", + "
  21. get_resource_directory
  22. \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab7125e9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "8d23d990", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    \n", + " This is our function to get the computer details requested.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the computer_details function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about computer is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the computer data of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if computerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.\n", + " \n", + "
    \n", + " \n", + "5. Finally print the Computer Details through systems_members_response.\n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1b4d0494", + "metadata": {}, + "outputs": [], + "source": [ + "def computer_details(_redfishobj):\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " print(\"\\n\\nPrinting computer system details:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0de7de8", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter ilo url, username,password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call computer_details with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f538059", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " computer_details(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "bd337e8f", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f7fd2c36", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/configure_snmp-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/configure_snmp-checkpoint.ipynb new file mode 100644 index 0000000..0be3ae9 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/configure_snmp-checkpoint.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of configuring SNMP for HPE iLO systems.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  23. sys \n", + "
  24. \n", + "
  25. json
  26. \n", + "
  27. redfish
  28. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccd0447f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import " + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

    2.

    This is our configure_snmp function overview, in the end this will give us with snmp configure related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings..\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alerts):\n", + "\n", + " snmp_service_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to configure_snmp function to obtain snmp related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "faa032c5", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " ALERTS_ENABLED = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_ENABLED, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/generate_csr-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/generate_csr-checkpoint.ipynb new file mode 100644 index 0000000..5ed55a6 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/generate_csr-checkpoint.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "042acf39", + "metadata": { + "tags": [] + }, + "source": [ + "# Generating a certificate signing request for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "7b34599c", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to generate_csr!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e7338dfb", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  29. sys \n", + "
  30. \n", + "
  31. json
  32. \n", + "
  33. redfish
  34. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c9837f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "034daf66", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our generate csr function overview, in the end we will be able to make a certificate signing request.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the generate_csr function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about Http certificates is stored inside the managers json object.\n", + " And now through managers_response variable, we are making a http GET operation to and trying to obtain the certificates of signing of iLO system.\n", + "
    \n", + "\n", + "3. In the system managers members response object with different odata_id we get a security service uri .\n", + " Then again an http GET request is made and response is stored in security_service_response.\n", + " Then we will make a http_cert_response by using csr_uri through security_service_response and then using http_cert_response we will get generate_csr_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeHttpsCert attribute is present in @odata.type attribute then we'll set csr_uri and get generate csr uri of the target.\n", + "
    \n", + "\n", + "5. If generate_csr_uri exists, then we will define the body and send a post request through redfish object. After generating the csr, we can obtain the csr_response using get method for csr_uri. csr_response contains CertificateSigningRequest. \n", + "\n", + "
    \n", + "6. If you get the result, then it is successful. if you don't get the result, then there is an error.\n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "644bd708", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_csr(_redfishobj, csr_file, csr_properties):\n", + "\n", + " csr_uri = None\n", + " generate_csr_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " csr_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", + " https_cert_response = _redfishobj.get(csr_uri)\n", + " generate_csr_uri = https_cert_response.obj['Actions']['#HpeHttpsCert.GenerateCSR']\\\n", + " ['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeHttpsCert.' in instance['@odata.type']:\n", + " csr_uri = instance['@odata.id']\n", + " generate_csr_uri = _redfishobj.get(csr_uri).obj['Actions']\\\n", + " ['#HpeHttpsCert.GenerateCSR']['target']\n", + " break\n", + "\n", + " if generate_csr_uri:\n", + " body = dict()\n", + " body[\"Action\"] = \"HpeHttpsCert.GenerateCSR\"\n", + " body[\"City\"] = csr_properties[\"City\"]\n", + " body[\"CommonName\"] = csr_properties[\"CommonName\"]\n", + " body[\"Country\"] = csr_properties[\"Country\"]\n", + " body[\"OrgName\"] = csr_properties[\"OrgName\"]\n", + " body[\"OrgUnit\"] = csr_properties[\"OrgUnit\"]\n", + " body[\"State\"] = csr_properties[\"State\"]\n", + " resp = _redfishobj.post(generate_csr_uri, body)\n", + " if resp.status in [200, 201]:\n", + " sys.stdout.write(\"Generating CSR, this may take a few minutes\\n\")\n", + " sys.stdout.write(\"Sleeping for 5 minutes...\\n\")\n", + " time.sleep(600)\n", + " csr_resp = _redfishobj.get(csr_uri).dict['CertificateSigningRequest']\n", + " with open(csr_file, 'wb') as csroutput:\n", + " csroutput.write(csr_resp)\n", + " sys.stdout.write(\"CSR Data saved to file: '%s'\\n\" % csr_file)\n", + " else:\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", + " #info error message to see what went wrong\n", + " if resp.status not in [200, 201]:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2da11ba0", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter your ilo url,Username,Password here.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call generate_csr with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46b3e899", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #CSR Dictionary, each value should be updated to reflect the desired CSR\n", + " CSR_DICT = {\"City\" : input(\"Enter city:\"), \"CommonName\": input(\"Enter name:\"), \"Country\": input(\"Enter country :\"), \\\n", + " \"OrgName\": input(\"Enter organization :\"), \"OrgUnit\": input(\"Enter unit :\"), \"State\": input(\"Enter state:\")}\n", + "\n", + " #After CSR is generated, a file will be created and the CSR will be downloaded\n", + " CSR_FILE = \"csr.txt\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " generate_csr(REDFISHOBJ, CSR_FILE, CSR_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "06934cbc", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "12c33902", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_bios_settings-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_bios_settings-checkpoint.ipynb new file mode 100644 index 0000000..66d8a23 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_bios_settings-checkpoint.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GETTING BIOS SETTINGS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to getting bios(basic input/output system) settings about HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " In the beginning, we are having some import statements that are actually providing us with the required modules and libraries\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of retrieving bios settings from iLO servers.\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the get_bios_settings function, after everything is done this function will give details about bios settings of system.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the get_bios_setting function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In case the resource directory was disabled we are using systems making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
      \n", + "
    • The information about bios settings is present inside a particular json object of iLO rest api.
    • We just need to navigate to that directory so as to obtain info about bios settings.
    • For that purpose simply we are making series of get requests.
    • \n", + " We make a final get operation by at the location bios_uri and save the response inside bios_data.\n", + "
    \n", + "
    \n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately, if bios_data variable is not null we print out information about bios settings. \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def get_bios_setting(_redfishobj):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing bios attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to get_bios_settings function to obtain information about bios settings of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 15.146.51.201\n", + "Enter Username: Administrator\n", + "Enter password: 12iso*help\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Initializing no proxy.\n", + "Redirecting 15.146.51.201/redfish/v1/ -> https://15.146.51.201/redfish/v1/\n", + "Response Time to /redfish/v1/: 0.4612421989440918 seconds.\n", + "Performing session authentication.\n", + "Redirecting 15.146.51.201/redfish/v1/SessionService/Sessions/ -> https://15.146.51.201/redfish/v1/SessionService/Sessions/\n", + "Response Time to /redfish/v1/SessionService/Sessions/: 0.23828959465026855 seconds.\n", + "{'@odata.context': '/redfish/v1/$metadata#Session.Session', '@odata.etag': 'W/\"B18A5BAF\"', '@odata.id': '/redfish/v1/SessionService/Sessions/administrator0000000062d211f0f2b02038/', '@odata.type': '#Session.v1_0_0.Session', 'Id': 'administrator0000000062d211f0f2b02038', 'Description': 'Manager User Session', 'Name': 'User Session', 'Oem': {'Hpe': {'@odata.context': '/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession', '@odata.type': '#HpeiLOSession.v2_1_0.HpeiLOSession', 'AccessTime': '2022-07-16T01:18:40Z', 'LoginTime': '2022-07-16T01:18:40Z', 'MySession': False, 'UserExpires': '2022-07-16T01:48:40Z', 'UserIP': '16.242.171.23', 'UserTag': 'REST', 'UserType': 'Local'}}, 'UserName': 'Administrator'}\n", + "Login returned code 201: {\"@odata.context\":\"/redfish/v1/$metadata#Session.Session\",\"@odata.etag\":\"W/\\\"B18A5BAF\\\"\",\"@odata.id\":\"/redfish/v1/SessionService/Sessions/administrator0000000062d211f0f2b02038/\",\"@odata.type\":\"#Session.v1_0_0.Session\",\"Id\":\"administrator0000000062d211f0f2b02038\",\"Description\":\"Manager User Session\",\"Name\":\"User Session\",\"Oem\":{\"Hpe\":{\"@odata.context\":\"/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession\",\"@odata.type\":\"#HpeiLOSession.v2_1_0.HpeiLOSession\",\"AccessTime\":\"2022-07-16T01:18:40Z\",\"LoginTime\":\"2022-07-16T01:18:40Z\",\"MySession\":false,\"UserExpires\":\"2022-07-16T01:48:40Z\",\"UserIP\":\"16.242.171.23\",\"UserTag\":\"REST\",\"UserType\":\"Local\"}},\"UserName\":\"Administrator\"}\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'RedfishClient' object has no attribute 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_32988/1002653862.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 19\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 20\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 21\u001b[1;33m \u001b[0mget_bios_setting\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 22\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_32988/1804850166.py\u001b[0m in \u001b[0;36mget_bios_setting\u001b[1;34m(_redfishobj)\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mbios_uri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mbios_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mresource_instances\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_redfishobj\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_resource_directory\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_redfishobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mDISABLE_RESOURCE_DIR\u001b[0m \u001b[1;32mor\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mresource_instances\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m#if we do not have a resource directory or want to force it's non use to find the\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'RedfishClient' object has no attribute 'get_resource_directory'" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_bios_setting(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_powermetrics_average-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_powermetrics_average-checkpoint.ipynb new file mode 100644 index 0000000..81c02f5 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/get_powermetrics_average-checkpoint.ipynb @@ -0,0 +1,226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GETTING POWERMETRICS AVERAGE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to get powermetrics average about HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_15656/4041776832.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 11\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'get_resource_directory'" + ] + } + ], + "source": [ + "\n", + "\"\"\"\n", + "An example of gathering the power metrics average on HPE iLO systems\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    This is our powermetrics function overview, in the end this will give us with power related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. In the get_powermetrics_average function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about power metrics is stored inside the chassis json object.\n", + " Through chassis_response variable we are making a http GET operation to and trying to obtain the power metrics about iLO system.\n", + "
    \n", + "\n", + "3. In the chassis response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in chassis_members_response.\n", + " The power metrics information is ultimately present in the chassis_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if power attribute is present in @odata.type attribute then we'll store information about power metrics in power_metrics_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if power_metrics_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def get_powermetrics_average(_redfishobj):\n", + "\n", + " power_metrics_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " chassis_uri = _redfishobj.root.obj['Chassis']['@odata.id']\n", + " chassis_response = _redfishobj.get(chassis_uri)\n", + " chassis_members_uri = next(iter(chassis_response.obj['Members']))['@odata.id']\n", + " chassis_members_response = _redfishobj.get(chassis_members_uri)\n", + " power_metrics_uri = chassis_members_response.obj.Oem.Hpe['Power']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#Power.' in instance['@odata.type']:\n", + " power_metrics_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if power_metrics_uri:\n", + " power_metrics_data = _redfishobj.get(power_metrics_uri).obj.Oem.Hpe\n", + " print(\"\\n\\nPower Data:\\n\\n\")\n", + " print(json.dumps(power_metrics_data, indent=4, sort_keys=True))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to get_powermetrics_average function to obtain power related info of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_powermetrics_average(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/account_remove.ipynb b/examples/Jupyter_notebooks/examples/account_remove.ipynb new file mode 100644 index 0000000..6b07a69 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/account_remove.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remove iLO User Account" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to a particular user account on HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + "
    In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + " for proper execution of our code.
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of removing a user account from the HPE iLO systems\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    2.
    \n", + "
    \n", + " Below is the remove_ilo_user_account function, after sucessful execution of this function we will be able to delete the information of any user account that is present on the HPE iLO system.\n", + " \n", + "
    \n", + "Let me give you a walk through of it!\n", + "
    \n", + " \n", + "For removal of any general account from the system we will first have to search for the accounts that we wan't to delete based on any attribute or property that uniquely identifies the account. Upon finding that account we can just make http delete request and we are done!\n", + " \n", + "1. In the remove_ilo_user_account function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In case the resource directory was disabled we are navigating to the actual location where the all the member account information is stored by using DELETErequest.\n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources to obtain the account_collection_uri.\n", + "
    \n", + "4.
      \n", + "
    • Now we are having the location at which all the member accounts are present.
    • Simply we just find out what user account matches the account that has to be deleted based on username of the accounts.
    • If we do not find the required account after completion of iteration we print out a message that required acccount was not found on the server side.
    • \n", + "
    • After this we simply make a DELETE request to delete that particular account and save the response obtained in resp variable.
    If the http status code returned was 200, then we simply print a message that delete operation was success.
    \n", + " Else if the status code returned was anything else we print out the status code with an error message to get idea about what went wrong.\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def remove_ilo_user_account(_redfishobj, username_to_delete):\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " break\n", + "\n", + " #find the account to delete\n", + " account_uri_to_delete = None\n", + " account_uris = _redfishobj.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " account = _redfishobj.get(account_uri['@odata.id'])\n", + " if account.dict['UserName'] == username_to_delete:\n", + " account_uri_to_delete = account_uri['@odata.id']\n", + " break\n", + "\n", + " if not account_uri_to_delete:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + "\n", + " resp = _redfishobj.delete(account_uri_to_delete)\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    3.
    \n", + "
    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • The ACCOUNT_TO_DELETE contains the username of the account that we need to delete. We are passing the same as an argument while making a call to remove_ilo_user_account function.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to remove_ilo_user_account function .
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + " \n", + " \n", + " # The username of the account to remove\n", + " ACCOUNT_TO_DELETE = \"joker\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " remove_ilo_user_account(REDFISHOBJ, ACCOUNT_TO_DELETE)\n", + "\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb b/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb new file mode 100644 index 0000000..aa96161 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb @@ -0,0 +1,259 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Reverting the BIOS to default values" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to reset your bios to default settings!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "658962be-a0df-4696-ab9e-73f844703ff9", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  35. sys \n", + "
  36. \n", + "
  37. json
  38. \n", + "
  39. redfish
  40. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "53341fc4-f674-4781-bcb1-04bb06d3d1fb", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    This is our reset bios to default function overview, in the end this will set the bios settings to default.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the bios_revert_default function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in bios_response.\n", + " Then we set the resret_action_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios settings of the user through redfish object and then then set the path to post the action we will perform\n", + "
    \n", + "\n", + "5. Then we set the bios settings to default using the action type as Bios.ResetBios and say set it to default\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a5f7d7b2-6ab5-473d-ba19-113d603f9e2d", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def bios_revert_default(_redfishobj):\n", + "\n", + " bios_reset_action_uri = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_response.obj['Actions']['#Bios.ResetBios']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_data.obj['Actions']['#Bios.ResetBios']['target']\n", + " break\n", + "\n", + " body = {'Action': 'Bios.ResetBios', 'ResetType':'default'}\n", + " resp = _redfishobj.post(bios_reset_action_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " bios_revert_default(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d0ded655-d8e4-452d-b181-783a6b1788f5", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb b/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb new file mode 100644 index 0000000..98e679b --- /dev/null +++ b/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb @@ -0,0 +1,327 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "266e8885", + "metadata": { + "tags": [] + }, + "source": [ + "# Change BIOS settings" + ] + }, + { + "cell_type": "markdown", + "id": "358b08b4", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to Change BIOS settings!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "578dfc4d", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  41. sys \n", + "
  42. \n", + "
  43. json
  44. \n", + "
  45. redfish
  46. \n", + "
  47. get_resource_directory
  48. \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c82681e9", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/1390777471.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'get_resource_directory'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "84274de2", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our change bios settings function overview, in the end this will be able to change the bios settings.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in systems_response.\n", + " Then we set the systems_members_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", + "
    \n", + "\n", + "5. Then if bios password is present, then we will update the bios password. Finally we will send patch request from redfish object using bios_setting_uri. \n", + "\n", + " Ultimately if the operation was successfull without any errors then we will get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc680e58", + "metadata": {}, + "outputs": [], + "source": [ + "def change_bios_setting(_redfishobj, bios_property, property_value, bios_password):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if bios_uri:\n", + " #BIOS settings URI is needed\n", + " \n", + " bios_settings_uri = bios_data.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " body = {'Attributes': {bios_property: property_value}}\n", + " \n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " resp = _redfishobj.patch(bios_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " #uncomment if you would like to see the full list of attributes\n", + " #print(\"\\n\\nShowing BIOS attributes after changes:\\n\\n\")\n", + " #bios_data = _redfishobj.get(bios_uri)\n", + " #print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "567eb3f8", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Please enter iLO url, username, password, bios.attribute, attribute_value,bios password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "7c01d222", + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Enter System URL: 15.146.51.201\n", + "Enter Name: Administrator\n", + "Enter password: 12iso*help\n", + "Enter bios password: \n", + "Enter bios property you wish to change: \n", + "Enter Value of the property to change: \n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Initializing no proxy.\n", + "Redirecting 15.146.51.201/redfish/v1/ -> https://15.146.51.201/redfish/v1/\n", + "Response Time to /redfish/v1/: 0.5402989387512207 seconds.\n", + "Performing session authentication.\n", + "Redirecting 15.146.51.201/redfish/v1/SessionService/Sessions/ -> https://15.146.51.201/redfish/v1/SessionService/Sessions/\n", + "Response Time to /redfish/v1/SessionService/Sessions/: 0.11417365074157715 seconds.\n", + "{'@odata.context': '/redfish/v1/$metadata#Session.Session', '@odata.etag': 'W/\"793BFE96\"', '@odata.id': '/redfish/v1/SessionService/Sessions/administrator0000000062d1d61d46e97804/', '@odata.type': '#Session.v1_0_0.Session', 'Id': 'administrator0000000062d1d61d46e97804', 'Description': 'Manager User Session', 'Name': 'User Session', 'Oem': {'Hpe': {'@odata.context': '/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession', '@odata.type': '#HpeiLOSession.v2_1_0.HpeiLOSession', 'AccessTime': '2022-07-15T21:03:25Z', 'LoginTime': '2022-07-15T21:03:25Z', 'MySession': False, 'UserExpires': '2022-07-15T21:33:25Z', 'UserIP': '16.242.171.23', 'UserTag': 'REST', 'UserType': 'Local'}}, 'UserName': 'Administrator'}\n", + "Login returned code 201: {\"@odata.context\":\"/redfish/v1/$metadata#Session.Session\",\"@odata.etag\":\"W/\\\"793BFE96\\\"\",\"@odata.id\":\"/redfish/v1/SessionService/Sessions/administrator0000000062d1d61d46e97804/\",\"@odata.type\":\"#Session.v1_0_0.Session\",\"Id\":\"administrator0000000062d1d61d46e97804\",\"Description\":\"Manager User Session\",\"Name\":\"User Session\",\"Oem\":{\"Hpe\":{\"@odata.context\":\"/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession\",\"@odata.type\":\"#HpeiLOSession.v2_1_0.HpeiLOSession\",\"AccessTime\":\"2022-07-15T21:03:25Z\",\"LoginTime\":\"2022-07-15T21:03:25Z\",\"MySession\":false,\"UserExpires\":\"2022-07-15T21:33:25Z\",\"UserIP\":\"16.242.171.23\",\"UserTag\":\"REST\",\"UserType\":\"Local\"}},\"UserName\":\"Administrator\"}\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'get_resource_directory' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/3485138033.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 25\u001b[1;33m \u001b[0mchange_bios_setting\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mATTRIBUTE\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mATTRIBUTE_VAL\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mBIOS_PASSWORD\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 26\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/2914597885.py\u001b[0m in \u001b[0;36mchange_bios_setting\u001b[1;34m(_redfishobj, bios_property, property_value, bios_password)\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mbios_uri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mbios_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mresource_instances\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_redfishobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mDISABLE_RESOURCE_DIR\u001b[0m \u001b[1;32mor\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mresource_instances\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m#if we do not have a resource directory or want to force it's non use to find the relevant URI\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mNameError\u001b[0m: name 'get_resource_directory' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " BIOS_PASSWORD = input(\"Enter bios password: \")\n", + " #provide the attribute name and the associated attribute value. Note: some, values may\n", + " #be containers (arrays or dictionaries) so keep this in mind.\n", + " ATTRIBUTE = input(\"Enter bios property you wish to change: \")\n", + " ATTRIBUTE_VAL = input(\"Enter Value of the property to change: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_bios_setting(REDFISHOBJ, ATTRIBUTE, ATTRIBUTE_VAL, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "9d0181a9", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "9e9f0846", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/clear_ahs_data.ipynb b/examples/Jupyter_notebooks/examples/clear_ahs_data.ipynb new file mode 100644 index 0000000..3d1f409 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/clear_ahs_data.ipynb @@ -0,0 +1,258 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d7d850", + "metadata": { + "tags": [] + }, + "source": [ + "# Clearing AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "88f096f8", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to Clearing AHS data!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d1525f25", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  49. sys \n", + "
  50. \n", + "
  51. json
  52. \n", + "
  53. redfish
  54. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "8ce9142d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b9615aea", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our clear_ahs_data to function overview, in the end this will clear ahs data.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", + " Then we set the active_health_system_clear_log_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data we will perform\n", + "
    \n", + "\n", + "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "16042277", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ahs_data(_redfishobj):\n", + "\n", + " active_health_system_clear_log_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " else:\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " break\n", + "\n", + " if active_health_system_clear_log_uri:\n", + " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", + " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "6e7543eb", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270f99bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ahs_data(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "1557bfee", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e685a623", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/clear_ilo_iel_iml_log.ipynb b/examples/Jupyter_notebooks/examples/clear_ilo_iel_iml_log.ipynb new file mode 100644 index 0000000..0bf7897 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/clear_ilo_iel_iml_log.ipynb @@ -0,0 +1,230 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# CLEAR iLO LOGS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to for clearing out the ilo event log and management log at server side!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    1

    \n", + "In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    2

    \n", + "This cell gives overview about of the function used to clear event logs such as IML and IEL logs. \n", + "The IML provides a record of historical events that have occurred on the server and the IEL is the iLO event log provides record of significant events detected by iLO.\n", + " \n", + "1. When the resource directory is disabled then we simply navigate through the API for obtaining the relevant uri.\n", + " The series of HTTP get requests aims to extracts log_services_response so as to get the path of the directory for which IEL and IML logs need to be cleared.\n", + "
    \n", + "2. Else if the resource directory enabled then rather we can simply extract the uri by #LogService.attribute inside the instance['odatatype'] dictionary and again make a HTTP get request to obtain the required uri.\n", + "
    \n", + "3. After obtaining the uri we just need to make changes on the same location using a post request so as to clear IEL and IML logs successfully. For this body dictionary contains the attribute to be changed and IEL/IML are searched in the path of clear_log_services_uri and the respective changes are made by redfishobj.post(path,body).\n", + "
    \n", + " \n", + "4. Later we also check for the response returned by the server side. If the response is anything outside of status code with 200 then error message gets rendered on the webpage else the success message is printed out with the response dictionary returned by the server.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ilo_event_log(_redfishobj, clear_IML_IEL):\n", + "\n", + " clear_log_services_uri = []\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " log_services_uri = systems_members_response.obj['LogServices']['@odata.id']\n", + " log_services_response = _redfishobj.get(log_services_uri)\n", + " log_services_uris = log_services_response.obj['Members']\n", + " for log_services_uri in log_services_uris:\n", + " log_services_response = _redfishobj.get(log_services_uri['@odata.id'])\n", + " clear_log_services_uri.append(log_services_response.obj['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#LogService.' in instance['@odata.type']:\n", + " log_service_uri = instance['@odata.id']\n", + " clear_log_services_uri.append(_redfishobj.get(log_service_uri).dict['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + "\n", + " if clear_log_services_uri:\n", + " body = {\"Action\": \"LogService.ClearLog\"}\n", + " for path in clear_log_services_uri:\n", + " if (\"IEL\" in clear_IML_IEL and \"IEL\" in path) or (\"IML\" in clear_IML_IEL and \\\n", + " \"IML\" in path):\n", + " if \"IEL\" in path:\n", + " sys.stdout.write(\"Clearing IEL log.\\n\")\n", + " else:\n", + " sys.stdout.write(\"Clearing IML log.\\n\")\n", + " resp = _redfishobj.post(path, body)\n", + " else:\n", + " continue\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", + " #info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    3

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • Else if no error is encountered a function call is made i.e. clear_ilo_event_log(REDFISHOBJ, CLEAR_IEL_IML)\n", + " that is responsible for handling clearing all the IEL and IML logs at the server side.
    • .\n", + "
    • Lastly, Redfishobj.logout logs us out of the system and ends the session.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " CLEAR_IML_IEL = \"IML\" # provide either the string IML or IEL\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ilo_event_log(REDFISHOBJ, CLEAR_IML_IEL)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/computer_details.ipynb b/examples/Jupyter_notebooks/examples/computer_details.ipynb new file mode 100644 index 0000000..4b81113 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/computer_details.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a38bafdc", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering the computer system details" + ] + }, + { + "cell_type": "markdown", + "id": "cfe2e2b6", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to get_computer_details!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b3fec1a9", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  55. sys \n", + "
  56. \n", + "
  57. json
  58. \n", + "
  59. redfish
  60. \n", + "
  61. get_resource_directory
  62. \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab7125e9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "8d23d990", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    \n", + " This is our function to get the computer details requested.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the computer_details function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about computer is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the computer data of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if computerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.\n", + " \n", + "
    \n", + " \n", + "5. Finally print the Computer Details through systems_members_response.\n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1b4d0494", + "metadata": {}, + "outputs": [], + "source": [ + "def computer_details(_redfishobj):\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " print(\"\\n\\nPrinting computer system details:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0de7de8", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter ilo url, username,password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call computer_details with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f538059", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " computer_details(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "bd337e8f", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f7fd2c36", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/configure_snmp.ipynb b/examples/Jupyter_notebooks/examples/configure_snmp.ipynb new file mode 100644 index 0000000..0be3ae9 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/configure_snmp.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of configuring SNMP for HPE iLO systems.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  63. sys \n", + "
  64. \n", + "
  65. json
  66. \n", + "
  67. redfish
  68. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccd0447f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import " + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

    2.

    This is our configure_snmp function overview, in the end this will give us with snmp configure related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings..\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alerts):\n", + "\n", + " snmp_service_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to configure_snmp function to obtain snmp related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "faa032c5", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " ALERTS_ENABLED = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_ENABLED, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/configure_snmp_trap_source.ipynb b/examples/Jupyter_notebooks/examples/configure_snmp_trap_source.ipynb new file mode 100644 index 0000000..3418e6b --- /dev/null +++ b/examples/Jupyter_notebooks/examples/configure_snmp_trap_source.ipynb @@ -0,0 +1,220 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "594a0e06", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of configuring SNMP trap source for HPE iLO systems.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "25be0e98", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  69. sys \n", + "
  70. \n", + "
  71. json
  72. \n", + "
  73. redfish
  74. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f16a98ad", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError" + ] + }, + { + "cell_type": "markdown", + "id": "8c2b4d45", + "metadata": {}, + "source": [ + "

    2.

    This is our configure_snmp function overview, in the end this will give us with snmp service related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the snmp service information.\n", + "\n", + " \n", + "\n", + " \n", + "1. In the ILO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
    \n", + "\n", + "2. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if power snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b53e8e73", + "metadata": {}, + "outputs": [], + "source": [ + " def configure_snmp(_redfishobj):\n", + "\n", + " snmp_service_uri = None\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " # print(managers_members_response.obj['Oem']['Hpe']['Links'])\n", + " # exit(0)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['SNMPService']['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " # resp = _redfishobj.get(snmp_service_uri)\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " # exit(0)\n", + " # TrapSourceHostname : Manager or System\n", + " body = {\"TrapSourceHostname\": \"System\"}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b852d783", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to configure_snmp function to obtain snmp related info of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "610979dd", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " if len(sys.argv) <= 3:\n", + " sys.stderr.write(\"ERROR: We need 3 arguments. \\nUsage: change-snmp.py \"\n", + " \"ILOIPADDR ILOUSER ILOPASSWORD \\n\")\n", + " sys.exit()\n", + "\n", + " SYSTEM_URL = \"https://\" + sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " try:\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT,\n", + " password=LOGIN_PASSWORD)\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "80f7da07", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "00b5c8a5", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/eject_virtual_media_iso.ipynb b/examples/Jupyter_notebooks/examples/eject_virtual_media_iso.ipynb new file mode 100644 index 0000000..fbd4918 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/eject_virtual_media_iso.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "45dd47a5", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of mounting virtual media for HPE iLO systems
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "23eeb2bf", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  75. sys \n", + "
  76. \n", + "
  77. json
  78. \n", + "
  79. redfish
  80. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92ec68a2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "10a8e977", + "metadata": {}, + "source": [ + "

    2.

    This is our mount_virtual_media_iso function overview, in the end this will give us with virtual media related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the virtual media information.\n", + "\n", + "1. In the mount_virtual_media_iso function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about virtual media is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The virtual media information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if virtual media is present in @odata.type attribute then we will store information about virtual media in virtual_media_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if virtual_media_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f034ef9c", + "metadata": {}, + "outputs": [], + "source": [ + "def mount_virtual_media_iso(_redfishobj, media_type,):\n", + "\n", + " virtual_media_uri = None\n", + " virtual_media_response = []\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", + " virtual_media_uri = instance['@odata.id']\n", + "\n", + " if virtual_media_uri:\n", + " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", + " for virtual_media_slot in virtual_media_response.obj['Members']:\n", + " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", + " if media_type in data.dict['MediaTypes']:\n", + " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.EjectMedia']['target']\n", + " post_body = {\"Action\": \"HpeiLOVirtualMedia.EjectVirtualMedia\"}\n", + " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "268b5a18", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab494baf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #specify the type of content the media represents\n", + " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + "\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " mount_virtual_media_iso(REDFISHOBJ, MEDIA_TYPE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "90621a8a", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a839daaa", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/enable_secure_boot.ipynb b/examples/Jupyter_notebooks/examples/enable_secure_boot.ipynb new file mode 100644 index 0000000..9760b1d --- /dev/null +++ b/examples/Jupyter_notebooks/examples/enable_secure_boot.ipynb @@ -0,0 +1,249 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b44c9aad", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of enabling secure boot
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "74ee46a2", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  81. sys \n", + "
  82. \n", + "
  83. json
  84. \n", + "
  85. redfish
  86. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3b9ca27", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "d0e073c6", + "metadata": {}, + "source": [ + "

    2.

    This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", + "\n", + "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", + " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", + "
    \n", + "\n", + "3. In the systems response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in systems_members_response.\n", + " The secure boot information is ultimately present in the systems_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d60549e", + "metadata": {}, + "outputs": [], + "source": [ + "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", + "\n", + " secure_boot_uri = None\n", + " secure_boot_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#SecureBoot.' in instance['@odata.type']:\n", + " secure_boot_uri = instance['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + "\n", + " if secure_boot_data:\n", + " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if secure_boot_uri:\n", + " body = {'SecureBootEnable': secure_boot_enable}\n", + " resp = _redfishobj.patch(secure_boot_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b227f8f6", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to enable_secure_boot function to obtain secure boot related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8028b4ff", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Properties:\n", + " #secure boot enable property\n", + " SECURE_BOOT_ENABLE = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "28cb201c", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cf8a164b", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/enabling_ntp_server.ipynb b/examples/Jupyter_notebooks/examples/enabling_ntp_server.ipynb new file mode 100644 index 0000000..12cd454 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/enabling_ntp_server.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ENABLING NTP SERVER " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to enable ntp servers .
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "
    \n", + "

    1

    \n", + "In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    2

    \n", + "Below function describes the process how to enable NTP servers for HPE ilo systems. NTP or Network Time Protocol is an internet protocol used to synchronize with computer clokc time sources in a network. \n", + "Current cell is the explains the processes performed inside the below function.\n", + "
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. Initially, to obtain NTP server related information for HPE ilo systems a series of HTTP GET requests are being made so as to navigate to that path inside the iLO rest api where required information is stored.\n", + "After completion of these get requests we will be having the relevant uri in manager_ethernet_interfaces_members.\n", + "
    \n", + "2. Else if resource directory is enabled we can just use the resource directory to and then again navigate through the api to find relevant uri.\n", + "
    \n", + " \n", + "3. Whatever changes need to be made to enable the NTP server are being enclosed inside the dictionary named as body. Next up for all the instances of ethernet in ethernet_data we simply make a HTTP PATCH request by passing the ethernet instance and body dictionary with the PATCH request. \n", + " \n", + "\n", + "4. Following the patch request, the response returned by server is being saved inside resp variable and later if the server returns proper response it means there is no error else error is returned with error information. A reference for json.dumps\n", + "function as it is used multiple times - click here.\n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def enable_ntp(_redfishobj, ntp_servers, DISABLE_RESOURCE_DIR):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " print(json.dumps(ethernet_data, indent=4, sort_keys=True))\n", + "\n", + " body = {\"Oem\": {\"Hpe\": {\"DHCPv4\": {\"UseNTPServers\": ntp_servers}, \\\n", + " \"DHCPv6\": {\"UseNTPServers\": ntp_servers}}}}\n", + " for ethernet in ethernet_data:\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " _data = _redfishobj.get(ethernet).dict\n", + " sys.stdout.write(\"\\nShowing \\'%s\\' interface after changes:\\n\" % ethernet)\n", + " print(json.dumps(_data, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    3

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + " \n", + "
    • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to enable_ntp function by passing parameters such as redfishclient object and enable flag to perform required operation.
    • \n", + "
    • After getting required information Redfish.logout() closes the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/find_ilo_mac_address.ipynb b/examples/Jupyter_notebooks/examples/find_ilo_mac_address.ipynb new file mode 100644 index 0000000..0fcb8d3 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/find_ilo_mac_address.ipynb @@ -0,0 +1,227 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Finding iLo Mac address" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to find_ilo_mac_address!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  87. sys \n", + "
  88. \n", + "
  89. json
  90. \n", + "
  91. redfish
  92. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    This is our find_ilo_mac_address function overview, in the end this will give us about finding ilo mac address related information.

    \n", + "

    Let me give you a walk through of it!

    \n", + "
      \n", + "
    1. For the identification of a device, its mac address is very much required. If you have the Systems Management Homepage installed, you can find out by clicking \"Management Processor\" and then check the Physical Address field.
    2. \n", + "
    3. If we don't have a resource directory, information about the ethernet data is stored inside the managers json object. Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.
    4. \n", + "
    5. Ethernet interface gives the response for that member about the ilo mac address
    6. \n", + "
    7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the ethernet interface is present in @odata.type attribute then we will store information about ethernet interface in ethernet_data dictionary and break out of iteration.
    8. \n", + "
    9. Finally, we get iLo Network Manager Interface and iLO Mac Address as output.
    10. \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def find_ilo_mac_address(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " for iface in ethernet_data:\n", + " sys.stdout.write(\"iLO Network Manager Interface: \\'%s\\'\\n\" % ethernet_data[iface]['Id'])\n", + " sys.stdout.write(\"\\tiLO Mac Address: \\'%s\\'\\n\" % ethernet_data[iface].get('MACAddress'))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    The Main function:
    PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • If server is down or Unreachable we get \"server not reachable\" message!
    • \n", + "
    • and Once everything is done you are automatically logged out with .logout() 😁.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " find_ilo_mac_address(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/generate_csr.ipynb b/examples/Jupyter_notebooks/examples/generate_csr.ipynb new file mode 100644 index 0000000..5ed55a6 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/generate_csr.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "042acf39", + "metadata": { + "tags": [] + }, + "source": [ + "# Generating a certificate signing request for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "7b34599c", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to generate_csr!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e7338dfb", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  93. sys \n", + "
  94. \n", + "
  95. json
  96. \n", + "
  97. redfish
  98. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c9837f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "034daf66", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our generate csr function overview, in the end we will be able to make a certificate signing request.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the generate_csr function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about Http certificates is stored inside the managers json object.\n", + " And now through managers_response variable, we are making a http GET operation to and trying to obtain the certificates of signing of iLO system.\n", + "
    \n", + "\n", + "3. In the system managers members response object with different odata_id we get a security service uri .\n", + " Then again an http GET request is made and response is stored in security_service_response.\n", + " Then we will make a http_cert_response by using csr_uri through security_service_response and then using http_cert_response we will get generate_csr_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeHttpsCert attribute is present in @odata.type attribute then we'll set csr_uri and get generate csr uri of the target.\n", + "
    \n", + "\n", + "5. If generate_csr_uri exists, then we will define the body and send a post request through redfish object. After generating the csr, we can obtain the csr_response using get method for csr_uri. csr_response contains CertificateSigningRequest. \n", + "\n", + "
    \n", + "6. If you get the result, then it is successful. if you don't get the result, then there is an error.\n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "644bd708", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_csr(_redfishobj, csr_file, csr_properties):\n", + "\n", + " csr_uri = None\n", + " generate_csr_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " csr_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", + " https_cert_response = _redfishobj.get(csr_uri)\n", + " generate_csr_uri = https_cert_response.obj['Actions']['#HpeHttpsCert.GenerateCSR']\\\n", + " ['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeHttpsCert.' in instance['@odata.type']:\n", + " csr_uri = instance['@odata.id']\n", + " generate_csr_uri = _redfishobj.get(csr_uri).obj['Actions']\\\n", + " ['#HpeHttpsCert.GenerateCSR']['target']\n", + " break\n", + "\n", + " if generate_csr_uri:\n", + " body = dict()\n", + " body[\"Action\"] = \"HpeHttpsCert.GenerateCSR\"\n", + " body[\"City\"] = csr_properties[\"City\"]\n", + " body[\"CommonName\"] = csr_properties[\"CommonName\"]\n", + " body[\"Country\"] = csr_properties[\"Country\"]\n", + " body[\"OrgName\"] = csr_properties[\"OrgName\"]\n", + " body[\"OrgUnit\"] = csr_properties[\"OrgUnit\"]\n", + " body[\"State\"] = csr_properties[\"State\"]\n", + " resp = _redfishobj.post(generate_csr_uri, body)\n", + " if resp.status in [200, 201]:\n", + " sys.stdout.write(\"Generating CSR, this may take a few minutes\\n\")\n", + " sys.stdout.write(\"Sleeping for 5 minutes...\\n\")\n", + " time.sleep(600)\n", + " csr_resp = _redfishobj.get(csr_uri).dict['CertificateSigningRequest']\n", + " with open(csr_file, 'wb') as csroutput:\n", + " csroutput.write(csr_resp)\n", + " sys.stdout.write(\"CSR Data saved to file: '%s'\\n\" % csr_file)\n", + " else:\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", + " #info error message to see what went wrong\n", + " if resp.status not in [200, 201]:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2da11ba0", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter your ilo url,Username,Password here.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call generate_csr with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46b3e899", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #CSR Dictionary, each value should be updated to reflect the desired CSR\n", + " CSR_DICT = {\"City\" : input(\"Enter city:\"), \"CommonName\": input(\"Enter name:\"), \"Country\": input(\"Enter country :\"), \\\n", + " \"OrgName\": input(\"Enter organization :\"), \"OrgUnit\": input(\"Enter unit :\"), \"State\": input(\"Enter state:\")}\n", + "\n", + " #After CSR is generated, a file will be created and the CSR will be downloaded\n", + " CSR_FILE = \"csr.txt\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " generate_csr(REDFISHOBJ, CSR_FILE, CSR_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "06934cbc", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "12c33902", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/get_ahs_data.ipynb b/examples/Jupyter_notebooks/examples/get_ahs_data.ipynb new file mode 100644 index 0000000..2115568 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/get_ahs_data.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a597eefb", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "6b03740b", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to get_ahs_data!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "45944a06", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  99. sys \n", + "
  100. \n", + "
  101. json
  102. \n", + "
  103. redfish
  104. \n", + "
  105. get_resource_directory
  106. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "29082d3a", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    This is our ahs gathering data function overview, in the end we will get the Active Health System data.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the get_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about the Active Health System is stored inside the managers json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the ahs data of iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object with different odata_id we get the managers members uri .\n", + " Then again an http GET request is made and response is stored in managers_response_response.\n", + " Then we set the active_health_system_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeiLOActiveHealthSystem attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_log_resp through redfish object.\n", + "
    \n", + "\n", + "5. If this is successful, then we will open a logfile and write active_health_system_log_resp.ori which is the get_ahs_data to that logfile.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ahs_data(_redfishobj, logfile=\"data.ahs\"):\n", + "\n", + " active_health_system_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + "\n", + " if active_health_system_uri:\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_log_uri = active_health_system_response.obj.Links['AHSLocation']\\\n", + " ['extref']\n", + " active_health_system_log_resp = _redfishobj.get(active_health_system_log_uri)\n", + " if active_health_system_log_resp.status == 400:\n", + " try:\n", + " print(json.dumps(active_health_system_log_resp.obj['error']\\\n", + " ['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif active_health_system_log_resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % active_health_system_log_resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " with open(logfile, 'wb') as ahsoutput:\n", + " ahsoutput.write(active_health_system_log_resp.ori)\n", + " ahsoutput.close()\n", + " sys.stdout.write(\"AHS Data saved successfully as: \\'%s\\'\" % logfile)\n" + ] + }, + { + "cell_type": "markdown", + "id": "155fb958", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter ilo url,username,password, and the path of log file
    \n", + " \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call get_ahs_data with our redfish object and logfile.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # logfile path and filename\n", + " LOGFILE = input(\"Enter log file path and file name: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_ahs_data(REDFISHOBJ, LOGFILE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " LOGFILE = data.ahs
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "10a528a3", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/get_bios_settings.ipynb b/examples/Jupyter_notebooks/examples/get_bios_settings.ipynb new file mode 100644 index 0000000..66d8a23 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/get_bios_settings.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GETTING BIOS SETTINGS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to getting bios(basic input/output system) settings about HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " In the beginning, we are having some import statements that are actually providing us with the required modules and libraries\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of retrieving bios settings from iLO servers.\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the get_bios_settings function, after everything is done this function will give details about bios settings of system.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the get_bios_setting function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In case the resource directory was disabled we are using systems making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
      \n", + "
    • The information about bios settings is present inside a particular json object of iLO rest api.
    • We just need to navigate to that directory so as to obtain info about bios settings.
    • For that purpose simply we are making series of get requests.
    • \n", + " We make a final get operation by at the location bios_uri and save the response inside bios_data.\n", + "
    \n", + "
    \n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately, if bios_data variable is not null we print out information about bios settings. \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def get_bios_setting(_redfishobj):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing bios attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to get_bios_settings function to obtain information about bios settings of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 15.146.51.201\n", + "Enter Username: Administrator\n", + "Enter password: 12iso*help\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Initializing no proxy.\n", + "Redirecting 15.146.51.201/redfish/v1/ -> https://15.146.51.201/redfish/v1/\n", + "Response Time to /redfish/v1/: 0.4612421989440918 seconds.\n", + "Performing session authentication.\n", + "Redirecting 15.146.51.201/redfish/v1/SessionService/Sessions/ -> https://15.146.51.201/redfish/v1/SessionService/Sessions/\n", + "Response Time to /redfish/v1/SessionService/Sessions/: 0.23828959465026855 seconds.\n", + "{'@odata.context': '/redfish/v1/$metadata#Session.Session', '@odata.etag': 'W/\"B18A5BAF\"', '@odata.id': '/redfish/v1/SessionService/Sessions/administrator0000000062d211f0f2b02038/', '@odata.type': '#Session.v1_0_0.Session', 'Id': 'administrator0000000062d211f0f2b02038', 'Description': 'Manager User Session', 'Name': 'User Session', 'Oem': {'Hpe': {'@odata.context': '/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession', '@odata.type': '#HpeiLOSession.v2_1_0.HpeiLOSession', 'AccessTime': '2022-07-16T01:18:40Z', 'LoginTime': '2022-07-16T01:18:40Z', 'MySession': False, 'UserExpires': '2022-07-16T01:48:40Z', 'UserIP': '16.242.171.23', 'UserTag': 'REST', 'UserType': 'Local'}}, 'UserName': 'Administrator'}\n", + "Login returned code 201: {\"@odata.context\":\"/redfish/v1/$metadata#Session.Session\",\"@odata.etag\":\"W/\\\"B18A5BAF\\\"\",\"@odata.id\":\"/redfish/v1/SessionService/Sessions/administrator0000000062d211f0f2b02038/\",\"@odata.type\":\"#Session.v1_0_0.Session\",\"Id\":\"administrator0000000062d211f0f2b02038\",\"Description\":\"Manager User Session\",\"Name\":\"User Session\",\"Oem\":{\"Hpe\":{\"@odata.context\":\"/redfish/v1/$metadata#HpeiLOSession.HpeiLOSession\",\"@odata.type\":\"#HpeiLOSession.v2_1_0.HpeiLOSession\",\"AccessTime\":\"2022-07-16T01:18:40Z\",\"LoginTime\":\"2022-07-16T01:18:40Z\",\"MySession\":false,\"UserExpires\":\"2022-07-16T01:48:40Z\",\"UserIP\":\"16.242.171.23\",\"UserTag\":\"REST\",\"UserType\":\"Local\"}},\"UserName\":\"Administrator\"}\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'RedfishClient' object has no attribute 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_32988/1002653862.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 19\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 20\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 21\u001b[1;33m \u001b[0mget_bios_setting\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 22\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_32988/1804850166.py\u001b[0m in \u001b[0;36mget_bios_setting\u001b[1;34m(_redfishobj)\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mbios_uri\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mbios_data\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mresource_instances\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_redfishobj\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_resource_directory\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_redfishobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mDISABLE_RESOURCE_DIR\u001b[0m \u001b[1;32mor\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mresource_instances\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m#if we do not have a resource directory or want to force it's non use to find the\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'RedfishClient' object has no attribute 'get_resource_directory'" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_bios_setting(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/get_powermetrics_average.ipynb b/examples/Jupyter_notebooks/examples/get_powermetrics_average.ipynb new file mode 100644 index 0000000..81c02f5 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/get_powermetrics_average.ipynb @@ -0,0 +1,226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GETTING POWERMETRICS AVERAGE" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to get powermetrics average about HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_15656/4041776832.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 11\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'get_resource_directory'" + ] + } + ], + "source": [ + "\n", + "\"\"\"\n", + "An example of gathering the power metrics average on HPE iLO systems\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    This is our powermetrics function overview, in the end this will give us with power related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. In the get_powermetrics_average function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about power metrics is stored inside the chassis json object.\n", + " Through chassis_response variable we are making a http GET operation to and trying to obtain the power metrics about iLO system.\n", + "
    \n", + "\n", + "3. In the chassis response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in chassis_members_response.\n", + " The power metrics information is ultimately present in the chassis_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if power attribute is present in @odata.type attribute then we'll store information about power metrics in power_metrics_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if power_metrics_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def get_powermetrics_average(_redfishobj):\n", + "\n", + " power_metrics_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " chassis_uri = _redfishobj.root.obj['Chassis']['@odata.id']\n", + " chassis_response = _redfishobj.get(chassis_uri)\n", + " chassis_members_uri = next(iter(chassis_response.obj['Members']))['@odata.id']\n", + " chassis_members_response = _redfishobj.get(chassis_members_uri)\n", + " power_metrics_uri = chassis_members_response.obj.Oem.Hpe['Power']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#Power.' in instance['@odata.type']:\n", + " power_metrics_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if power_metrics_uri:\n", + " power_metrics_data = _redfishobj.get(power_metrics_uri).obj.Oem.Hpe\n", + " print(\"\\n\\nPower Data:\\n\\n\")\n", + " print(json.dumps(power_metrics_data, indent=4, sort_keys=True))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to get_powermetrics_average function to obtain power related info of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_powermetrics_average(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/modify_user_account.ipynb b/examples/Jupyter_notebooks/examples/modify_user_account.ipynb new file mode 100644 index 0000000..9742aca --- /dev/null +++ b/examples/Jupyter_notebooks/examples/modify_user_account.ipynb @@ -0,0 +1,317 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Modify the user account" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to modify_user_account!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  107. sys \n", + "
  108. \n", + "
  109. json
  110. \n", + "
  111. redfish
  112. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    This is our modify_ilo_user_account function overview, in the end this will give us about modifying the ilo user account related information.

    \n", + "

    Let me give you a walk through of it!

    \n", + "
      \n", + "
    1. Users are having a facility to modify their ilo accounts. They can change their username, password and role using the below function.
    2. \n", + "
    3. If we don't have a resource directory, information about the account is stored inside the account_service json object. Through account_service_response variable we are making a http GET operation to and trying to obtain the account details of an user in iLO system.
    4. \n", + "
    5. account_collection_uri gives the response for that member about the user information
    6. \n", + "
    7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the account_collection_uri is present in @odata.type attribute then we will store information in a dictionary called body which recieves the values like new_username, new_password and is updated.
    8. \n", + "
    9. If a non-existing user tries to change the account, then it throws error.
    10. \n", + "
    11. Finally, the username and password is updated.
    12. \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def modify_ilo_user_account(_redfishobj, username_to_modify, new_loginname, new_username, \\\n", + " new_password, role_id, privilege_dict):\n", + "\n", + " account_collection_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " #modify role id\n", + " if role_id:\n", + " body = {\"RoleId\": role_id}\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " if privilege_dict:\n", + " #HPE server, so modify privileges\n", + " body = {\"Oem\": {\"Hpe\": {\"Privileges\": {}}}}\n", + " for priv in privilege_dict:\n", + " body[\"Oem\"][\"Hpe\"][\"Privileges\"][priv] = privilege_dict[priv]\n", + " if new_loginname:\n", + " #modify login name\n", + " body[\"Oem\"][\"Hpe\"][\"LoginName\"] = new_loginname\n", + "\n", + " if new_username:\n", + " body[\"UserName\"] = new_username\n", + " if new_password:\n", + " body[\"Password\"] = new_password\n", + "\n", + " #find the account to modify\n", + " account_uri_to_modify = None\n", + " account_uris = REDFISHOBJ.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " account = REDFISHOBJ.get(account_uri['@odata.id'])\n", + " if account.dict['UserName'] == username_to_modify:\n", + " account_uri_to_modify = account_uri['@odata.id']\n", + " break\n", + "\n", + " if not account_uri_to_modify:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + "\n", + " #modify the account\n", + " resp = REDFISHOBJ.patch(account_uri_to_modify, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    The Main function:
    PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • If server is down or Unreachable we get \"server not reachable\" message!
    • \n", + "
    • and Once everything is done you are automatically logged out with .logout() 😁.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " #username of the account to modify\n", + " USERNAME_TO_MODIFY = input(\"Enter the username to be modified: \")\n", + " # USERNAME_TO_MODIFY = \"bruce_wayne\"\n", + "\n", + " #account login name to change the account to\n", + " NEW_LOGINNAME = input(\"Enter the new login name: \")\n", + " # NEW_LOGINNAME = \"joker\"\n", + "\n", + " #account user name to change the account to\n", + " NEW_USERNAME = input(\"Enter the new username: \")\n", + " # NEW_USERNAME = \"joker\"\n", + "\n", + " #account password to change the account to\n", + " NEW_PASSWORD = getpass.getpass(\"Enter the new password: \")\n", + " # NEW_PASSWORD = \"joker123\"\n", + "\n", + " #role to change account to\n", + " ROLE_ID = input(\"Enter the Role ID: (Administrator, ReadOnly or Operator are available)\")\n", + " # ROLE_ID = \"ReadOnly\"\n", + "\n", + " #update HPE account privileges\n", + " PRIVILEGE_DICT = {\"iLOConfigPriv\": False, \"VirtualMediaPriv\": False, \"RemoteConsolePriv\": True,\\\n", + " \"UserConfigPriv\": False, \"VirtualPowerAndResetPriv\": False, \\\n", + " \"SystemRecoveryConfigPriv\": False, \"LoginPriv\": True, \\\n", + " \"HostStorageConfigPriv\": False, \"HostNICConfigPriv\": False, \\\n", + " \"HostBIOSConfigPriv\": False}\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " modify_ilo_user_account(REDFISHOBJ, USERNAME_TO_MODIFY, NEW_LOGINNAME, NEW_USERNAME, \\\n", + " NEW_PASSWORD, ROLE_ID, PRIVILEGE_DICT)\n", + "\n", + " REDFISHOBJ.logout()\n", + "\n", + "\n", + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " find_ilo_mac_address(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/reboot_server (1).ipynb b/examples/Jupyter_notebooks/examples/reboot_server (1).ipynb new file mode 100644 index 0000000..2d90a23 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/reboot_server (1).ipynb @@ -0,0 +1,234 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# REBOOTING A SERVER" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to perform rebooting of a server.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "
    \n", + "

    1

    \n", + "In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    2

    \n", + "In below cell is the reboot_server function.\n", + "Current cell is the overview of it, utimately at the end this will reboot the server and provide the response for the same.\n", + "
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. In the reboot server function we are first using system_members_response variable to obtain information about the path at which server related information is stored by using couple of get requests.\n", + "
    \n", + "2. If the resource directory was accessible then we simply search for '#ComputerSystem' key (as this is the place comprising of server related information inside the instance['odata.type'] dictionary and finally making a get request to that location.\n", + "
    \n", + " \n", + "3. If we obtain systems_response successfully then a ressettype list is created specifying the parameters that how we want to restart.\n", + " \n", + "\n", + "4. Later both the parameters are passed into a new dictionary named body and post request is created to make changes on the server side.\n", + " A successful HTTP post request will set the values at server end so that a server gets rebooted.\n", + " \n", + "\n", + "5. Lastly, we also save response status inside resp variable and check what is the status code returned to confirm whether the post request was success or not. If success then response by server is printed and if not then error message is printed.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def reboot_server(_redfishobj):\n", + "\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj.get_resource_directory)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_uri = instance['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + "\n", + " if systems_response:\n", + " system_reboot_uri = systems_response.obj['Actions']['#ComputerSystem.Reset']['target']\n", + " body = dict()\n", + " resettype = ['ForceRestart','GracefulRestart']\n", + " body['Action'] = 'ComputerSystem.Reset'\n", + " for reset in resettype:\n", + " if reset.lower() == \"forcerestart\":\n", + " body['ResetType'] = \"ForceRestart\"\n", + " resp = _redfishobj.post(system_reboot_uri, body)\n", + " elif reset.lower() == \"gracefulrestart\":\n", + " body['ResetType'] = \"GracefulRestart\"\n", + " resp = _redfishobj.post(system_reboot_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    3

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + " \n", + "
    • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to reboot_server function to perform rebooting of server.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " reboot_server(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/examples/reset_ilo.ipynb b/examples/Jupyter_notebooks/examples/reset_ilo.ipynb new file mode 100644 index 0000000..999bc97 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/reset_ilo.ipynb @@ -0,0 +1,252 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d4d890e", + "metadata": { + "tags": [] + }, + "source": [ + "# Resetting iLO manager" + ] + }, + { + "cell_type": "markdown", + "id": "62aaa233", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to reset the ilo manager!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "fbfec992", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  113. sys \n", + "
  114. \n", + "
  115. json
  116. \n", + "
  117. redfish
  118. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "9b53ecf2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b8c9efd9", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    Below is the overview of reset_ilo function. In this function we are resetting values for an iLO manager.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "\n", + "
    \n", + "\n", + "2. If the resource directory is enabled or we want to force it's non-use then navigate to the directory where managers members data is present. We make two http get requests to obtain the directory where we actually need to perform the reset operation.\n", + " manager_member_response saves the result of final http get request made in this case.\n", + "
    \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #\"Manager\" attribute is present inside the record instances[@odata.type]. we save the uri inside of manager_member_response. \n", + "
    \n", + "4.
      \n", + "
    • Lastly, we navigate in the manager_member_response by following this path 'Actions'->'#Manager.Reset'->'target'to obtained the url at which reset opreation has to be made and save the same inside reset_ilo_uri.
    • On the next line we create a dictionary having the value of 'Action' as 'Manager.Reset' and make a POST request to server and pass the same dictionary so as to make changes at the reset_ilo_url location.
    • \n", + "
    \n", + " \n", + " If the response of this POST request was 400 it means there was some error from server-side while doing the same operation.
    \n", + " Else there can also be an error which we aren't aware of, in that case we print out the response status code alongwith erro message .
    \n", + " Ultimately, if everything went properly we print out the response object along with success message.\n", + " \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "93003c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def reset_ilo(_redfishobj, DISABLE_RESOURCE_DIR):\n", + "\n", + " managers_members_response = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Manager.' in instance['@odata.type']:\n", + " managers_members_uri = instance['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + "\n", + " if managers_members_response:\n", + " reset_ilo_uri = managers_members_response.obj['Actions']['#Manager.Reset']['target']\n", + " body = {'Action': 'Manager.Reset'}\n", + " resp = _redfishobj.post(reset_ilo_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5a583e0e", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient object is being created mainly to log into the system with valid credentials.\n", + " \n", + "
    \n", + "\n", + "3. We try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "4. Then we call reset_ilofunction with our redfish object and the function does the resetting of manager.
    \n", + " \n", + "\n", + "5. Lastly, REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85745d7d", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " reset_ilo(REDFISHOBJ, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "69132144", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "ea6fce6f", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/set_bios_password.ipynb b/examples/Jupyter_notebooks/examples/set_bios_password.ipynb new file mode 100644 index 0000000..dae0399 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/set_bios_password.ipynb @@ -0,0 +1,236 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d357d38b", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting Bios Password" + ] + }, + { + "cell_type": "markdown", + "id": "fce7e904", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to change bios password for HPE iLO system!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + " Also do run each succesive cell of code \n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a89aa82f", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + "
    In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + " for proper execution of our code.
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e96dc046", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "828be423", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the set_bios_password function, through which we can change the password of bios system.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the set_bios_setting function we are taking three parameters i.e. Redfish object, new_password and exisiting password as bios_password. Also resource_instances variable is being obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. If the resource directory was disabled we are making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
      \n", + "
    • The information about bios settings is present inside a particular json object of iLO rest api.
    • We just need to navigate to that directory so as to obtain info about bios settings and later make changes to the existing password.
    • For that purpose simply we are making series of get requests.
    • \n", + "
    • After navigating through iLO rest api we actually save the http address of location where bios settings are present inside bios_uri
    • \n", + "
    \n", + "
    \n", + " \n", + "\n", + "3. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
    \n", + "4. If bios_uri is not null after making above operations, we can perform the required actions to change the bios password.
      \n", + "
    • Following up we make get request and obtain the URL of the location where we are actually going to make the changes.
    • Ultimately, we make a post request by passing the bios_change_pass_uri and body dictionary that contains the changes made to the password.
    • \n", + "
    • The job of post request here is to update the password at the provided location and send a response whether the job was done properly or not.
    • \n", + " \n", + " If the reponse status code was anything other than 200 or 201 then we can print out the response status code and error message.
      \n", + " Else we print out success message with the response obtained after making post request.\n", + "
      \n", + " \n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ee515d74", + "metadata": {}, + "outputs": [], + "source": [ + "def set_bios_password(_redfishobj, new_password, bios_password):\n", + "\n", + " bios_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if bios_uri:\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_change_pass_uri = bios_data.obj['Actions']['#Bios.ChangePassword']['target']\n", + " body = dict()\n", + " body[\"PasswordName\"] = \"Administrator\"\n", + " body[\"OldPassword\"] = bios_password\n", + " body[\"NewPassword\"] = new_password\n", + " resp = _redfishobj.post(bios_change_pass_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "1b93c0d7", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • We are passing the required information to change the password of iLO user account i.e. base_url, username, password
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • Once everything is done you are automatically logged out.
    • \n", + "
    • Need more help . Please check here\n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38b9fd3a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #new BIOS password\n", + " NEW_BIOS_PASSWORD = \"password\"\n", + " #old BIOS password\n", + " OLD_BIOS_PASSWORD = \"password\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_bios_password(REDFISHOBJ, NEW_BIOS_PASSWORD, OLD_BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "34f69788", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/examples/test_ESKM_connection.ipynb b/examples/Jupyter_notebooks/examples/test_ESKM_connection.ipynb new file mode 100644 index 0000000..0ff9077 --- /dev/null +++ b/examples/Jupyter_notebooks/examples/test_ESKM_connection.ipynb @@ -0,0 +1,239 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Testing ESKM Connection" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to test_ESKM_connection!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  119. sys \n", + "
  120. \n", + "
  121. json
  122. \n", + "
  123. redfish
  124. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    This is our test_ESKM_connection function overview, in the end this will give us about the ESKM connection related information.

    \n", + "

    Let me give you a walk through of it!

    \n", + "
      \n", + "
    1. Enterprise Secure Key Manager(ESKM) is used by HPE to protect customer and user data. To check the connection of eskm, test_ESKM_connection function is used.
    2. \n", + "
    3. If we don't have a resource directory, information about the security service is stored inside the managers json object. Through managers_response variable we are making a http GET operation to and trying to obtain the security_service_uri in the iLO system.
    4. \n", + "
    5. eskm_uri stores the value of the security_service_uri
    6. \n", + "
    7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the ESKM instance is present in @odata.type attribute then we will store information in eskm_uri and break out of iteration.
    8. \n", + "
    9. Finally, we check fot the eskm_uri and a http response is created indicating the successfull retrival of information.
    10. \n", + "
    11. More details can be found out using this Link\n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def test_ESKM_connection(_redfishobj):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + "\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " eskm_test_conn_uri = _redfishobj.get(eskm_uri).obj['Actions']\\\n", + " ['#HpeESKM.TestESKMConnections']['target']\n", + " body[\"Action\"] = \"HpeESKM.TestESKMConnections\"\n", + " resp = _redfishobj.post(eskm_test_conn_uri, body)\n", + " #If iLO responds with something outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    The Main function:
    PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • If server is down or Unreachable we get \"server not reachable\" message!
    • \n", + "
    • and Once everything is done you are automatically logged out with .logout() 😁.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " test_ESKM_connection(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/index.ipynb b/examples/Jupyter_notebooks/index.ipynb new file mode 100644 index 0000000..58031df --- /dev/null +++ b/examples/Jupyter_notebooks/index.ipynb @@ -0,0 +1,53 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "453f77bb-9a66-492a-bf03-a737b524a484", + "metadata": {}, + "source": [ + "|OPERATION|DESCRIPTION| METHOD | LOCATION |\n", + "|-------------|--------------------------------------|-------------------------|------------------------|\n", + "|bios settings|update bios settings for iLO server| PATCH |[change_bios_setting](examples/change_bios_settings.ipynb)|\n", + "|bios default| update bios to default setting | PATCH |[revert_bios_default](examples/bios_revert_default.ipynb)|\n", + "|powermetrics average|get powewr measurement average of servers| GET |[get_powermetrics_average](examples/get_powermetrics_average.ipynb)|\n", + "|change boot order|update the existing boot order or add new order| PUT |[change_boot_order](examples/change_bios_settings.ipynb)|\n", + "|change temporary boot order|update or reset an temporary boot order| PUT |[change_temporary_boot_order](examples/change_bios_settings.ipynb)|\n", + "|clear ahs data | clear active health state data of iLO server| DELETE |[clear_ahs_data](examples/clear_ahs_data.ipynb)|\n", + "|computer details|get all the available computer/hosts details in iLO| GET |[computer_details](examples/computer_details.ipynb)|\n", + "|expand data|expand the response data obtained from any of the http methods| GET |[expand_data](examples/change_bios_settings.ipynb)\n", + "|generate_csr|obtain a certificate signing request for iLO server | GET |[generate_csr](examples/generate_csr.ipynb)|\n", + "|get ahs info|obtain active health status data of the iLO servers| GET |[get_ahs_data](examples/get_ahs_data.ipynb)|\n", + "|base message registry|get base message registry info of iLO servers| GET |[get_base_registry](examples/change_bios_settings.ipynb)|\n", + "|iLO ip address|obtain the ip address of iLO servers| GET |[get_ilo_ip](examples/get_ilo_ip.ipynb)|\n", + "|License key|get iLO license key for iLO| GET |[get_license_key](examples/get_license_key.ipynb)|\n" + ] + }, + { + "cell_type": "markdown", + "id": "974fdedd-2bb1-4a4c-adb5-a6052e134085", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 650e7b5f97f65f5fc71859f09410fe2b9c169401 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Apr 2023 19:19:55 +0530 Subject: [PATCH 004/159] addec hpe cty folder --- examples/Jupyter_notebooks/HPECTY/index.ipynb | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/index.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/index.ipynb b/examples/Jupyter_notebooks/HPECTY/index.ipynb new file mode 100644 index 0000000..4c277c2 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/index.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "18ad6013", + "metadata": {}, + "source": [ + "\"HPE" + ] + }, + { + "cell_type": "markdown", + "id": "fa8b0fad", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    BIOS SettingsUpdate BIOS Settings for iLO serverPATCHchange_bios_setting
    BIOS DefaultUpdate BIOS to default settingPATCHrevert_bios_default
    Powermetrics AverageGet powewr measurement average of serversGETget_powermetrics_average
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62458584", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 3097216f52305ff58976f42f41969f25d5654348 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2023 21:03:30 +0530 Subject: [PATCH 005/159] bhuvan - added 2 scripts --- .../sphinx_rtd_theme/static/css/theme.css | 6490 ++++++++++++++++- .../sphinx_rtd_theme/static/css/theme.css.map | 2 +- .../.ipynb_checkpoints/index-checkpoint.ipynb | 111 + .../BIOS_ChangeSettings-checkpoint.ipynb | 285 + .../BIOS_RevertToDefault-checkpoint.ipynb | 331 + .../bios_revert_default-checkpoint.ipynb | 259 + .../Bhuvan/BIOS/BIOS_ChangeSettings.ipynb | 285 + .../Bhuvan/BIOS/BIOS_RevertToDefault.ipynb | 331 + .../Add_user_account-checkpoint.ipynb | 260 + .../HPECTY/{ => Bhuvan}/index.ipynb | 59 +- .../change_bios_settings-checkpoint.ipynb | 2 +- .../examples/bios_revert_default.ipynb | 4 +- .../examples/change_bios_settings.ipynb | 2 +- 13 files changed, 8400 insertions(+), 21 deletions(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb rename examples/Jupyter_notebooks/HPECTY/{ => Bhuvan}/index.ipynb (52%) diff --git a/docs/themes/sphinx_rtd_theme/static/css/theme.css b/docs/themes/sphinx_rtd_theme/static/css/theme.css index a2d7c0f..bfe901f 100644 --- a/docs/themes/sphinx_rtd_theme/static/css/theme.css +++ b/docs/themes/sphinx_rtd_theme/static/css/theme.css @@ -1,5 +1,6489 @@ -*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,.rst-content .toctree-wrapper p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block +} + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1 +} + +audio:not([controls]) { + display: none +} + +[hidden] { + display: none +} + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100% +} + +body { + margin: 0 +} + +a:hover, +a:active { + outline: 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, +strong { + font-weight: bold +} + +blockquote { + margin: 0 +} + +dfn { + font-style: italic +} + +ins { + background: #ff9; + color: #000; + text-decoration: none +} + +mark { + background: #ff0; + color: #000; + font-style: italic; + font-weight: bold +} + +pre, +code, +.rst-content tt, +.rst-content code, +kbd, +samp { + font-family: monospace, serif; + _font-family: "courier new", monospace; + font-size: 1em +} + +pre { + white-space: pre +} + +q { + quotes: none +} + +q:before, +q:after { + content: ""; + content: none +} + +small { + font-size: 85% +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -0.5em +} + +sub { + bottom: -0.25em +} + +ul, +ol, +dl { + margin: 0; + padding: 0; + list-style: none; + list-style-image: none +} + +li { + list-style: none +} + +dd { + margin: 0 +} + +img { + border: 0; + -ms-interpolation-mode: bicubic; + vertical-align: middle; + max-width: 100% +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 0 +} + +form { + margin: 0 +} + +fieldset { + border: 0; + margin: 0; + padding: 0 +} + +label { + cursor: pointer +} + +legend { + border: 0; + *margin-left: -7px; + padding: 0; + white-space: normal +} + +button, +input, +select, +textarea { + font-size: 100%; + margin: 0; + vertical-align: baseline; + *vertical-align: middle +} + +button, +input { + line-height: normal +} + +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; + *overflow: visible +} + +button[disabled], +input[disabled] { + cursor: default +} + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; + *width: 13px; + *height: 13px +} + +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0 +} + +textarea { + overflow: auto; + vertical-align: top; + resize: vertical +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +td { + vertical-align: top +} + +.chromeframe { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0 +} + +.ir { + display: block; + border: 0; + text-indent: -999em; + overflow: hidden; + background-color: transparent; + background-repeat: no-repeat; + text-align: left; + direction: ltr; + *line-height: 0 +} + +.ir br { + display: none +} + +.hidden { + display: none !important; + visibility: hidden +} + +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px +} + +.visuallyhidden.focusable:active, +.visuallyhidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto +} + +.invisible { + visibility: hidden +} + +.relative { + position: relative +} + +big, +small { + font-size: 100% +} + +@media print { + + html, + body, + section { + background: none !important + } + + * { + box-shadow: none !important; + text-shadow: none !important; + filter: none !important; + -ms-filter: none !important + } + + a, + a:visited { + text-decoration: underline + } + + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: "" + } + + pre, + blockquote { + page-break-inside: avoid + } + + thead { + display: table-header-group + } + + tr, + img { + page-break-inside: avoid + } + + img { + max-width: 100% !important + } + + @page { + margin: 0.5cm + } + + p, + h2, + .rst-content .toctree-wrapper p.caption, + h3 { + orphans: 3; + widows: 3 + } + + h2, + .rst-content .toctree-wrapper p.caption, + h3 { + page-break-after: avoid + } +} + +.fa:before, +.wy-menu-vertical li span.toctree-expand:before, +.wy-menu-vertical li.on a span.toctree-expand:before, +.wy-menu-vertical li.current>a span.toctree-expand:before, +.rst-content .admonition-title:before, +.rst-content h1 .headerlink:before, +.rst-content h2 .headerlink:before, +.rst-content h3 .headerlink:before, +.rst-content h4 .headerlink:before, +.rst-content h5 .headerlink:before, +.rst-content h6 .headerlink:before, +.rst-content dl dt .headerlink:before, +.rst-content p.caption .headerlink:before, +.rst-content tt.download span:first-child:before, +.rst-content code.download span:first-child:before, +.icon:before, +.wy-dropdown .caret:before, +.wy-inline-validate.wy-inline-validate-success .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-info .wy-input-context:before, +.wy-alert, +.rst-content .note, +.rst-content .attention, +.rst-content .caution, +.rst-content .danger, +.rst-content .error, +.rst-content .hint, +.rst-content .important, +.rst-content .tip, +.rst-content .warning, +.rst-content .seealso, +.rst-content .admonition-todo, +.btn, +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="datetime"], +input[type="datetime-local"], +input[type="week"], +input[type="number"], +input[type="search"], +input[type="tel"], +input[type="color"], +select, +textarea, +.wy-menu-vertical li.on a, +.wy-menu-vertical li.current>a, +.wy-side-nav-search>a, +.wy-side-nav-search .wy-dropdown>a, +.wy-nav-top a { + -webkit-font-smoothing: antialiased +} + +.clearfix { + *zoom: 1 +} + +.clearfix:before, +.clearfix:after { + display: table; + content: "" +} + +.clearfix:after { + clear: both +} + +/*! * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs li code,.wy-breadcrumbs li .rst-content tt,.rst-content .wy-breadcrumbs li tt{padding:5px;border:none;background:none}.wy-breadcrumbs li code.literal,.wy-breadcrumbs li .rst-content tt.literal,.rst-content .wy-breadcrumbs li tt.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:0.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:0.809em;margin-bottom:0.809em;z-index:200;background-color:#2980B9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-side-nav-search>div.version{margin-top:-0.4045em;margin-bottom:0.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:#999}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content .toctree-wrapper p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content .toctree-wrapper p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.docutils.citation tt,.rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code{color:#555}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),local("Inconsolata-Regular"),url(../fonts/Inconsolata-Regular.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} -/*# sourceMappingURL=theme.css.map */ + */ +@font-face { + font-family: 'FontAwesome'; + src: url("../fonts/fontawesome-webfont.eot?v=4.2.0"); + src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"), url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg"); + font-weight: normal; + font-style: normal +} + +.fa, +.wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand, +.rst-content .admonition-title, +.rst-content h1 .headerlink, +.rst-content h2 .headerlink, +.rst-content h3 .headerlink, +.rst-content h4 .headerlink, +.rst-content h5 .headerlink, +.rst-content h6 .headerlink, +.rst-content dl dt .headerlink, +.rst-content p.caption .headerlink, +.rst-content tt.download span:first-child, +.rst-content code.download span:first-child, +.icon { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -15% +} + +.fa-2x { + font-size: 2em +} + +.fa-3x { + font-size: 3em +} + +.fa-4x { + font-size: 4em +} + +.fa-5x { + font-size: 5em +} + +.fa-fw { + width: 1.28571em; + text-align: center +} + +.fa-ul { + padding-left: 0; + margin-left: 2.14286em; + list-style-type: none +} + +.fa-ul>li { + position: relative +} + +.fa-li { + position: absolute; + left: -2.14286em; + width: 2.14286em; + top: 0.14286em; + text-align: center +} + +.fa-li.fa-lg { + left: -1.85714em +} + +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eee; + border-radius: .1em +} + +.pull-right { + float: right +} + +.pull-left { + float: left +} + +.fa.pull-left, +.wy-menu-vertical li span.pull-left.toctree-expand, +.wy-menu-vertical li.on a span.pull-left.toctree-expand, +.wy-menu-vertical li.current>a span.pull-left.toctree-expand, +.rst-content .pull-left.admonition-title, +.rst-content h1 .pull-left.headerlink, +.rst-content h2 .pull-left.headerlink, +.rst-content h3 .pull-left.headerlink, +.rst-content h4 .pull-left.headerlink, +.rst-content h5 .pull-left.headerlink, +.rst-content h6 .pull-left.headerlink, +.rst-content dl dt .pull-left.headerlink, +.rst-content p.caption .pull-left.headerlink, +.rst-content tt.download span.pull-left:first-child, +.rst-content code.download span.pull-left:first-child, +.pull-left.icon { + margin-right: .3em +} + +.fa.pull-right, +.wy-menu-vertical li span.pull-right.toctree-expand, +.wy-menu-vertical li.on a span.pull-right.toctree-expand, +.wy-menu-vertical li.current>a span.pull-right.toctree-expand, +.rst-content .pull-right.admonition-title, +.rst-content h1 .pull-right.headerlink, +.rst-content h2 .pull-right.headerlink, +.rst-content h3 .pull-right.headerlink, +.rst-content h4 .pull-right.headerlink, +.rst-content h5 .pull-right.headerlink, +.rst-content h6 .pull-right.headerlink, +.rst-content dl dt .pull-right.headerlink, +.rst-content p.caption .pull-right.headerlink, +.rst-content tt.download span.pull-right:first-child, +.rst-content code.download span.pull-right:first-child, +.pull-right.icon { + margin-left: .3em +} + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear +} + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg) + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg) + } +} + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg) + } + + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg) + } +} + +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg) +} + +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg) +} + +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg) +} + +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1) +} + +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1) +} + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none +} + +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle +} + +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center +} + +.fa-stack-1x { + line-height: inherit +} + +.fa-stack-2x { + font-size: 2em +} + +.fa-inverse { + color: #fff +} + +.fa-glass:before { + content: "" +} + +.fa-music:before { + content: "" +} + +.fa-search:before, +.icon-search:before { + content: "" +} + +.fa-envelope-o:before { + content: "" +} + +.fa-heart:before { + content: "" +} + +.fa-star:before { + content: "" +} + +.fa-star-o:before { + content: "" +} + +.fa-user:before { + content: "" +} + +.fa-film:before { + content: "" +} + +.fa-th-large:before { + content: "" +} + +.fa-th:before { + content: "" +} + +.fa-th-list:before { + content: "" +} + +.fa-check:before { + content: "" +} + +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "" +} + +.fa-search-plus:before { + content: "" +} + +.fa-search-minus:before { + content: "" +} + +.fa-power-off:before { + content: "" +} + +.fa-signal:before { + content: "" +} + +.fa-gear:before, +.fa-cog:before { + content: "" +} + +.fa-trash-o:before { + content: "" +} + +.fa-home:before, +.icon-home:before { + content: "" +} + +.fa-file-o:before { + content: "" +} + +.fa-clock-o:before { + content: "" +} + +.fa-road:before { + content: "" +} + +.fa-download:before, +.rst-content tt.download span:first-child:before, +.rst-content code.download span:first-child:before { + content: "" +} + +.fa-arrow-circle-o-down:before { + content: "" +} + +.fa-arrow-circle-o-up:before { + content: "" +} + +.fa-inbox:before { + content: "" +} + +.fa-play-circle-o:before { + content: "" +} + +.fa-rotate-right:before, +.fa-repeat:before { + content: "" +} + +.fa-refresh:before { + content: "" +} + +.fa-list-alt:before { + content: "" +} + +.fa-lock:before { + content: "" +} + +.fa-flag:before { + content: "" +} + +.fa-headphones:before { + content: "" +} + +.fa-volume-off:before { + content: "" +} + +.fa-volume-down:before { + content: "" +} + +.fa-volume-up:before { + content: "" +} + +.fa-qrcode:before { + content: "" +} + +.fa-barcode:before { + content: "" +} + +.fa-tag:before { + content: "" +} + +.fa-tags:before { + content: "" +} + +.fa-book:before, +.icon-book:before { + content: "" +} + +.fa-bookmark:before { + content: "" +} + +.fa-print:before { + content: "" +} + +.fa-camera:before { + content: "" +} + +.fa-font:before { + content: "" +} + +.fa-bold:before { + content: "" +} + +.fa-italic:before { + content: "" +} + +.fa-text-height:before { + content: "" +} + +.fa-text-width:before { + content: "" +} + +.fa-align-left:before { + content: "" +} + +.fa-align-center:before { + content: "" +} + +.fa-align-right:before { + content: "" +} + +.fa-align-justify:before { + content: "" +} + +.fa-list:before { + content: "" +} + +.fa-dedent:before, +.fa-outdent:before { + content: "" +} + +.fa-indent:before { + content: "" +} + +.fa-video-camera:before { + content: "" +} + +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "" +} + +.fa-pencil:before { + content: "" +} + +.fa-map-marker:before { + content: "" +} + +.fa-adjust:before { + content: "" +} + +.fa-tint:before { + content: "" +} + +.fa-edit:before, +.fa-pencil-square-o:before { + content: "" +} + +.fa-share-square-o:before { + content: "" +} + +.fa-check-square-o:before { + content: "" +} + +.fa-arrows:before { + content: "" +} + +.fa-step-backward:before { + content: "" +} + +.fa-fast-backward:before { + content: "" +} + +.fa-backward:before { + content: "" +} + +.fa-play:before { + content: "" +} + +.fa-pause:before { + content: "" +} + +.fa-stop:before { + content: "" +} + +.fa-forward:before { + content: "" +} + +.fa-fast-forward:before { + content: "" +} + +.fa-step-forward:before { + content: "" +} + +.fa-eject:before { + content: "" +} + +.fa-chevron-left:before { + content: "" +} + +.fa-chevron-right:before { + content: "" +} + +.fa-plus-circle:before { + content: "" +} + +.fa-minus-circle:before { + content: "" +} + +.fa-times-circle:before, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before { + content: "" +} + +.fa-check-circle:before, +.wy-inline-validate.wy-inline-validate-success .wy-input-context:before { + content: "" +} + +.fa-question-circle:before { + content: "" +} + +.fa-info-circle:before { + content: "" +} + +.fa-crosshairs:before { + content: "" +} + +.fa-times-circle-o:before { + content: "" +} + +.fa-check-circle-o:before { + content: "" +} + +.fa-ban:before { + content: "" +} + +.fa-arrow-left:before { + content: "" +} + +.fa-arrow-right:before { + content: "" +} + +.fa-arrow-up:before { + content: "" +} + +.fa-arrow-down:before { + content: "" +} + +.fa-mail-forward:before, +.fa-share:before { + content: "" +} + +.fa-expand:before { + content: "" +} + +.fa-compress:before { + content: "" +} + +.fa-plus:before { + content: "" +} + +.fa-minus:before { + content: "" +} + +.fa-asterisk:before { + content: "" +} + +.fa-exclamation-circle:before, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-info .wy-input-context:before, +.rst-content .admonition-title:before { + content: "" +} + +.fa-gift:before { + content: "" +} + +.fa-leaf:before { + content: "" +} + +.fa-fire:before, +.icon-fire:before { + content: "" +} + +.fa-eye:before { + content: "" +} + +.fa-eye-slash:before { + content: "" +} + +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "" +} + +.fa-plane:before { + content: "" +} + +.fa-calendar:before { + content: "" +} + +.fa-random:before { + content: "" +} + +.fa-comment:before { + content: "" +} + +.fa-magnet:before { + content: "" +} + +.fa-chevron-up:before { + content: "" +} + +.fa-chevron-down:before { + content: "" +} + +.fa-retweet:before { + content: "" +} + +.fa-shopping-cart:before { + content: "" +} + +.fa-folder:before { + content: "" +} + +.fa-folder-open:before { + content: "" +} + +.fa-arrows-v:before { + content: "" +} + +.fa-arrows-h:before { + content: "" +} + +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "" +} + +.fa-twitter-square:before { + content: "" +} + +.fa-facebook-square:before { + content: "" +} + +.fa-camera-retro:before { + content: "" +} + +.fa-key:before { + content: "" +} + +.fa-gears:before, +.fa-cogs:before { + content: "" +} + +.fa-comments:before { + content: "" +} + +.fa-thumbs-o-up:before { + content: "" +} + +.fa-thumbs-o-down:before { + content: "" +} + +.fa-star-half:before { + content: "" +} + +.fa-heart-o:before { + content: "" +} + +.fa-sign-out:before { + content: "" +} + +.fa-linkedin-square:before { + content: "" +} + +.fa-thumb-tack:before { + content: "" +} + +.fa-external-link:before { + content: "" +} + +.fa-sign-in:before { + content: "" +} + +.fa-trophy:before { + content: "" +} + +.fa-github-square:before { + content: "" +} + +.fa-upload:before { + content: "" +} + +.fa-lemon-o:before { + content: "" +} + +.fa-phone:before { + content: "" +} + +.fa-square-o:before { + content: "" +} + +.fa-bookmark-o:before { + content: "" +} + +.fa-phone-square:before { + content: "" +} + +.fa-twitter:before { + content: "" +} + +.fa-facebook:before { + content: "" +} + +.fa-github:before, +.icon-github:before { + content: "" +} + +.fa-unlock:before { + content: "" +} + +.fa-credit-card:before { + content: "" +} + +.fa-rss:before { + content: "" +} + +.fa-hdd-o:before { + content: "" +} + +.fa-bullhorn:before { + content: "" +} + +.fa-bell:before { + content: "" +} + +.fa-certificate:before { + content: "" +} + +.fa-hand-o-right:before { + content: "" +} + +.fa-hand-o-left:before { + content: "" +} + +.fa-hand-o-up:before { + content: "" +} + +.fa-hand-o-down:before { + content: "" +} + +.fa-arrow-circle-left:before, +.icon-circle-arrow-left:before { + content: "" +} + +.fa-arrow-circle-right:before, +.icon-circle-arrow-right:before { + content: "" +} + +.fa-arrow-circle-up:before { + content: "" +} + +.fa-arrow-circle-down:before { + content: "" +} + +.fa-globe:before { + content: "" +} + +.fa-wrench:before { + content: "" +} + +.fa-tasks:before { + content: "" +} + +.fa-filter:before { + content: "" +} + +.fa-briefcase:before { + content: "" +} + +.fa-arrows-alt:before { + content: "" +} + +.fa-group:before, +.fa-users:before { + content: "" +} + +.fa-chain:before, +.fa-link:before, +.icon-link:before { + content: "" +} + +.fa-cloud:before { + content: "" +} + +.fa-flask:before { + content: "" +} + +.fa-cut:before, +.fa-scissors:before { + content: "" +} + +.fa-copy:before, +.fa-files-o:before { + content: "" +} + +.fa-paperclip:before { + content: "" +} + +.fa-save:before, +.fa-floppy-o:before { + content: "" +} + +.fa-square:before { + content: "" +} + +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "" +} + +.fa-list-ul:before { + content: "" +} + +.fa-list-ol:before { + content: "" +} + +.fa-strikethrough:before { + content: "" +} + +.fa-underline:before { + content: "" +} + +.fa-table:before { + content: "" +} + +.fa-magic:before { + content: "" +} + +.fa-truck:before { + content: "" +} + +.fa-pinterest:before { + content: "" +} + +.fa-pinterest-square:before { + content: "" +} + +.fa-google-plus-square:before { + content: "" +} + +.fa-google-plus:before { + content: "" +} + +.fa-money:before { + content: "" +} + +.fa-caret-down:before, +.wy-dropdown .caret:before, +.icon-caret-down:before { + content: "" +} + +.fa-caret-up:before { + content: "" +} + +.fa-caret-left:before { + content: "" +} + +.fa-caret-right:before { + content: "" +} + +.fa-columns:before { + content: "" +} + +.fa-unsorted:before, +.fa-sort:before { + content: "" +} + +.fa-sort-down:before, +.fa-sort-desc:before { + content: "" +} + +.fa-sort-up:before, +.fa-sort-asc:before { + content: "" +} + +.fa-envelope:before { + content: "" +} + +.fa-linkedin:before { + content: "" +} + +.fa-rotate-left:before, +.fa-undo:before { + content: "" +} + +.fa-legal:before, +.fa-gavel:before { + content: "" +} + +.fa-dashboard:before, +.fa-tachometer:before { + content: "" +} + +.fa-comment-o:before { + content: "" +} + +.fa-comments-o:before { + content: "" +} + +.fa-flash:before, +.fa-bolt:before { + content: "" +} + +.fa-sitemap:before { + content: "" +} + +.fa-umbrella:before { + content: "" +} + +.fa-paste:before, +.fa-clipboard:before { + content: "" +} + +.fa-lightbulb-o:before { + content: "" +} + +.fa-exchange:before { + content: "" +} + +.fa-cloud-download:before { + content: "" +} + +.fa-cloud-upload:before { + content: "" +} + +.fa-user-md:before { + content: "" +} + +.fa-stethoscope:before { + content: "" +} + +.fa-suitcase:before { + content: "" +} + +.fa-bell-o:before { + content: "" +} + +.fa-coffee:before { + content: "" +} + +.fa-cutlery:before { + content: "" +} + +.fa-file-text-o:before { + content: "" +} + +.fa-building-o:before { + content: "" +} + +.fa-hospital-o:before { + content: "" +} + +.fa-ambulance:before { + content: "" +} + +.fa-medkit:before { + content: "" +} + +.fa-fighter-jet:before { + content: "" +} + +.fa-beer:before { + content: "" +} + +.fa-h-square:before { + content: "" +} + +.fa-plus-square:before { + content: "" +} + +.fa-angle-double-left:before { + content: "" +} + +.fa-angle-double-right:before { + content: "" +} + +.fa-angle-double-up:before { + content: "" +} + +.fa-angle-double-down:before { + content: "" +} + +.fa-angle-left:before { + content: "" +} + +.fa-angle-right:before { + content: "" +} + +.fa-angle-up:before { + content: "" +} + +.fa-angle-down:before { + content: "" +} + +.fa-desktop:before { + content: "" +} + +.fa-laptop:before { + content: "" +} + +.fa-tablet:before { + content: "" +} + +.fa-mobile-phone:before, +.fa-mobile:before { + content: "" +} + +.fa-circle-o:before { + content: "" +} + +.fa-quote-left:before { + content: "" +} + +.fa-quote-right:before { + content: "" +} + +.fa-spinner:before { + content: "" +} + +.fa-circle:before { + content: "" +} + +.fa-mail-reply:before, +.fa-reply:before { + content: "" +} + +.fa-github-alt:before { + content: "" +} + +.fa-folder-o:before { + content: "" +} + +.fa-folder-open-o:before { + content: "" +} + +.fa-smile-o:before { + content: "" +} + +.fa-frown-o:before { + content: "" +} + +.fa-meh-o:before { + content: "" +} + +.fa-gamepad:before { + content: "" +} + +.fa-keyboard-o:before { + content: "" +} + +.fa-flag-o:before { + content: "" +} + +.fa-flag-checkered:before { + content: "" +} + +.fa-terminal:before { + content: "" +} + +.fa-code:before { + content: "" +} + +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "" +} + +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "" +} + +.fa-location-arrow:before { + content: "" +} + +.fa-crop:before { + content: "" +} + +.fa-code-fork:before { + content: "" +} + +.fa-unlink:before, +.fa-chain-broken:before { + content: "" +} + +.fa-question:before { + content: "" +} + +.fa-info:before { + content: "" +} + +.fa-exclamation:before { + content: "" +} + +.fa-superscript:before { + content: "" +} + +.fa-subscript:before { + content: "" +} + +.fa-eraser:before { + content: "" +} + +.fa-puzzle-piece:before { + content: "" +} + +.fa-microphone:before { + content: "" +} + +.fa-microphone-slash:before { + content: "" +} + +.fa-shield:before { + content: "" +} + +.fa-calendar-o:before { + content: "" +} + +.fa-fire-extinguisher:before { + content: "" +} + +.fa-rocket:before { + content: "" +} + +.fa-maxcdn:before { + content: "" +} + +.fa-chevron-circle-left:before { + content: "" +} + +.fa-chevron-circle-right:before { + content: "" +} + +.fa-chevron-circle-up:before { + content: "" +} + +.fa-chevron-circle-down:before { + content: "" +} + +.fa-html5:before { + content: "" +} + +.fa-css3:before { + content: "" +} + +.fa-anchor:before { + content: "" +} + +.fa-unlock-alt:before { + content: "" +} + +.fa-bullseye:before { + content: "" +} + +.fa-ellipsis-h:before { + content: "" +} + +.fa-ellipsis-v:before { + content: "" +} + +.fa-rss-square:before { + content: "" +} + +.fa-play-circle:before { + content: "" +} + +.fa-ticket:before { + content: "" +} + +.fa-minus-square:before { + content: "" +} + +.fa-minus-square-o:before, +.wy-menu-vertical li.on a span.toctree-expand:before, +.wy-menu-vertical li.current>a span.toctree-expand:before { + content: "" +} + +.fa-level-up:before { + content: "" +} + +.fa-level-down:before { + content: "" +} + +.fa-check-square:before { + content: "" +} + +.fa-pencil-square:before { + content: "" +} + +.fa-external-link-square:before { + content: "" +} + +.fa-share-square:before { + content: "" +} + +.fa-compass:before { + content: "" +} + +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "" +} + +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "" +} + +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "" +} + +.fa-euro:before, +.fa-eur:before { + content: "" +} + +.fa-gbp:before { + content: "" +} + +.fa-dollar:before, +.fa-usd:before { + content: "" +} + +.fa-rupee:before, +.fa-inr:before { + content: "" +} + +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "" +} + +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "" +} + +.fa-won:before, +.fa-krw:before { + content: "" +} + +.fa-bitcoin:before, +.fa-btc:before { + content: "" +} + +.fa-file:before { + content: "" +} + +.fa-file-text:before { + content: "" +} + +.fa-sort-alpha-asc:before { + content: "" +} + +.fa-sort-alpha-desc:before { + content: "" +} + +.fa-sort-amount-asc:before { + content: "" +} + +.fa-sort-amount-desc:before { + content: "" +} + +.fa-sort-numeric-asc:before { + content: "" +} + +.fa-sort-numeric-desc:before { + content: "" +} + +.fa-thumbs-up:before { + content: "" +} + +.fa-thumbs-down:before { + content: "" +} + +.fa-youtube-square:before { + content: "" +} + +.fa-youtube:before { + content: "" +} + +.fa-xing:before { + content: "" +} + +.fa-xing-square:before { + content: "" +} + +.fa-youtube-play:before { + content: "" +} + +.fa-dropbox:before { + content: "" +} + +.fa-stack-overflow:before { + content: "" +} + +.fa-instagram:before { + content: "" +} + +.fa-flickr:before { + content: "" +} + +.fa-adn:before { + content: "" +} + +.fa-bitbucket:before, +.icon-bitbucket:before { + content: "" +} + +.fa-bitbucket-square:before { + content: "" +} + +.fa-tumblr:before { + content: "" +} + +.fa-tumblr-square:before { + content: "" +} + +.fa-long-arrow-down:before { + content: "" +} + +.fa-long-arrow-up:before { + content: "" +} + +.fa-long-arrow-left:before { + content: "" +} + +.fa-long-arrow-right:before { + content: "" +} + +.fa-apple:before { + content: "" +} + +.fa-windows:before { + content: "" +} + +.fa-android:before { + content: "" +} + +.fa-linux:before { + content: "" +} + +.fa-dribbble:before { + content: "" +} + +.fa-skype:before { + content: "" +} + +.fa-foursquare:before { + content: "" +} + +.fa-trello:before { + content: "" +} + +.fa-female:before { + content: "" +} + +.fa-male:before { + content: "" +} + +.fa-gittip:before { + content: "" +} + +.fa-sun-o:before { + content: "" +} + +.fa-moon-o:before { + content: "" +} + +.fa-archive:before { + content: "" +} + +.fa-bug:before { + content: "" +} + +.fa-vk:before { + content: "" +} + +.fa-weibo:before { + content: "" +} + +.fa-renren:before { + content: "" +} + +.fa-pagelines:before { + content: "" +} + +.fa-stack-exchange:before { + content: "" +} + +.fa-arrow-circle-o-right:before { + content: "" +} + +.fa-arrow-circle-o-left:before { + content: "" +} + +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "" +} + +.fa-dot-circle-o:before { + content: "" +} + +.fa-wheelchair:before { + content: "" +} + +.fa-vimeo-square:before { + content: "" +} + +.fa-turkish-lira:before, +.fa-try:before { + content: "" +} + +.fa-plus-square-o:before, +.wy-menu-vertical li span.toctree-expand:before { + content: "" +} + +.fa-space-shuttle:before { + content: "" +} + +.fa-slack:before { + content: "" +} + +.fa-envelope-square:before { + content: "" +} + +.fa-wordpress:before { + content: "" +} + +.fa-openid:before { + content: "" +} + +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "" +} + +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "" +} + +.fa-yahoo:before { + content: "" +} + +.fa-google:before { + content: "" +} + +.fa-reddit:before { + content: "" +} + +.fa-reddit-square:before { + content: "" +} + +.fa-stumbleupon-circle:before { + content: "" +} + +.fa-stumbleupon:before { + content: "" +} + +.fa-delicious:before { + content: "" +} + +.fa-digg:before { + content: "" +} + +.fa-pied-piper:before { + content: "" +} + +.fa-pied-piper-alt:before { + content: "" +} + +.fa-drupal:before { + content: "" +} + +.fa-joomla:before { + content: "" +} + +.fa-language:before { + content: "" +} + +.fa-fax:before { + content: "" +} + +.fa-building:before { + content: "" +} + +.fa-child:before { + content: "" +} + +.fa-paw:before { + content: "" +} + +.fa-spoon:before { + content: "" +} + +.fa-cube:before { + content: "" +} + +.fa-cubes:before { + content: "" +} + +.fa-behance:before { + content: "" +} + +.fa-behance-square:before { + content: "" +} + +.fa-steam:before { + content: "" +} + +.fa-steam-square:before { + content: "" +} + +.fa-recycle:before { + content: "" +} + +.fa-automobile:before, +.fa-car:before { + content: "" +} + +.fa-cab:before, +.fa-taxi:before { + content: "" +} + +.fa-tree:before { + content: "" +} + +.fa-spotify:before { + content: "" +} + +.fa-deviantart:before { + content: "" +} + +.fa-soundcloud:before { + content: "" +} + +.fa-database:before { + content: "" +} + +.fa-file-pdf-o:before { + content: "" +} + +.fa-file-word-o:before { + content: "" +} + +.fa-file-excel-o:before { + content: "" +} + +.fa-file-powerpoint-o:before { + content: "" +} + +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "" +} + +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "" +} + +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "" +} + +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "" +} + +.fa-file-code-o:before { + content: "" +} + +.fa-vine:before { + content: "" +} + +.fa-codepen:before { + content: "" +} + +.fa-jsfiddle:before { + content: "" +} + +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "" +} + +.fa-circle-o-notch:before { + content: "" +} + +.fa-ra:before, +.fa-rebel:before { + content: "" +} + +.fa-ge:before, +.fa-empire:before { + content: "" +} + +.fa-git-square:before { + content: "" +} + +.fa-git:before { + content: "" +} + +.fa-hacker-news:before { + content: "" +} + +.fa-tencent-weibo:before { + content: "" +} + +.fa-qq:before { + content: "" +} + +.fa-wechat:before, +.fa-weixin:before { + content: "" +} + +.fa-send:before, +.fa-paper-plane:before { + content: "" +} + +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "" +} + +.fa-history:before { + content: "" +} + +.fa-circle-thin:before { + content: "" +} + +.fa-header:before { + content: "" +} + +.fa-paragraph:before { + content: "" +} + +.fa-sliders:before { + content: "" +} + +.fa-share-alt:before { + content: "" +} + +.fa-share-alt-square:before { + content: "" +} + +.fa-bomb:before { + content: "" +} + +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "" +} + +.fa-tty:before { + content: "" +} + +.fa-binoculars:before { + content: "" +} + +.fa-plug:before { + content: "" +} + +.fa-slideshare:before { + content: "" +} + +.fa-twitch:before { + content: "" +} + +.fa-yelp:before { + content: "" +} + +.fa-newspaper-o:before { + content: "" +} + +.fa-wifi:before { + content: "" +} + +.fa-calculator:before { + content: "" +} + +.fa-paypal:before { + content: "" +} + +.fa-google-wallet:before { + content: "" +} + +.fa-cc-visa:before { + content: "" +} + +.fa-cc-mastercard:before { + content: "" +} + +.fa-cc-discover:before { + content: "" +} + +.fa-cc-amex:before { + content: "" +} + +.fa-cc-paypal:before { + content: "" +} + +.fa-cc-stripe:before { + content: "" +} + +.fa-bell-slash:before { + content: "" +} + +.fa-bell-slash-o:before { + content: "" +} + +.fa-trash:before { + content: "" +} + +.fa-copyright:before { + content: "" +} + +.fa-at:before { + content: "" +} + +.fa-eyedropper:before { + content: "" +} + +.fa-paint-brush:before { + content: "" +} + +.fa-birthday-cake:before { + content: "" +} + +.fa-area-chart:before { + content: "" +} + +.fa-pie-chart:before { + content: "" +} + +.fa-line-chart:before { + content: "" +} + +.fa-lastfm:before { + content: "" +} + +.fa-lastfm-square:before { + content: "" +} + +.fa-toggle-off:before { + content: "" +} + +.fa-toggle-on:before { + content: "" +} + +.fa-bicycle:before { + content: "" +} + +.fa-bus:before { + content: "" +} + +.fa-ioxhost:before { + content: "" +} + +.fa-angellist:before { + content: "" +} + +.fa-cc:before { + content: "" +} + +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "" +} + +.fa-meanpath:before { + content: "" +} + +.fa, +.wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand, +.rst-content .admonition-title, +.rst-content h1 .headerlink, +.rst-content h2 .headerlink, +.rst-content h3 .headerlink, +.rst-content h4 .headerlink, +.rst-content h5 .headerlink, +.rst-content h6 .headerlink, +.rst-content dl dt .headerlink, +.rst-content p.caption .headerlink, +.rst-content tt.download span:first-child, +.rst-content code.download span:first-child, +.icon, +.wy-dropdown .caret, +.wy-inline-validate.wy-inline-validate-success .wy-input-context, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context, +.wy-inline-validate.wy-inline-validate-info .wy-input-context { + font-family: inherit +} + +.fa:before, +.wy-menu-vertical li span.toctree-expand:before, +.wy-menu-vertical li.on a span.toctree-expand:before, +.wy-menu-vertical li.current>a span.toctree-expand:before, +.rst-content .admonition-title:before, +.rst-content h1 .headerlink:before, +.rst-content h2 .headerlink:before, +.rst-content h3 .headerlink:before, +.rst-content h4 .headerlink:before, +.rst-content h5 .headerlink:before, +.rst-content h6 .headerlink:before, +.rst-content dl dt .headerlink:before, +.rst-content p.caption .headerlink:before, +.rst-content tt.download span:first-child:before, +.rst-content code.download span:first-child:before, +.icon:before, +.wy-dropdown .caret:before, +.wy-inline-validate.wy-inline-validate-success .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-info .wy-input-context:before { + font-family: "FontAwesome"; + display: inline-block; + font-style: normal; + font-weight: normal; + line-height: 1; + text-decoration: inherit +} + +a .fa, +a .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li a span.toctree-expand, +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand, +a .rst-content .admonition-title, +.rst-content a .admonition-title, +a .rst-content h1 .headerlink, +.rst-content h1 a .headerlink, +a .rst-content h2 .headerlink, +.rst-content h2 a .headerlink, +a .rst-content h3 .headerlink, +.rst-content h3 a .headerlink, +a .rst-content h4 .headerlink, +.rst-content h4 a .headerlink, +a .rst-content h5 .headerlink, +.rst-content h5 a .headerlink, +a .rst-content h6 .headerlink, +.rst-content h6 a .headerlink, +a .rst-content dl dt .headerlink, +.rst-content dl dt a .headerlink, +a .rst-content p.caption .headerlink, +.rst-content p.caption a .headerlink, +a .rst-content tt.download span:first-child, +.rst-content tt.download a span:first-child, +a .rst-content code.download span:first-child, +.rst-content code.download a span:first-child, +a .icon { + display: inline-block; + text-decoration: inherit +} + +.btn .fa, +.btn .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li .btn span.toctree-expand, +.btn .wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.on a .btn span.toctree-expand, +.btn .wy-menu-vertical li.current>a span.toctree-expand, +.wy-menu-vertical li.current>a .btn span.toctree-expand, +.btn .rst-content .admonition-title, +.rst-content .btn .admonition-title, +.btn .rst-content h1 .headerlink, +.rst-content h1 .btn .headerlink, +.btn .rst-content h2 .headerlink, +.rst-content h2 .btn .headerlink, +.btn .rst-content h3 .headerlink, +.rst-content h3 .btn .headerlink, +.btn .rst-content h4 .headerlink, +.rst-content h4 .btn .headerlink, +.btn .rst-content h5 .headerlink, +.rst-content h5 .btn .headerlink, +.btn .rst-content h6 .headerlink, +.rst-content h6 .btn .headerlink, +.btn .rst-content dl dt .headerlink, +.rst-content dl dt .btn .headerlink, +.btn .rst-content p.caption .headerlink, +.rst-content p.caption .btn .headerlink, +.btn .rst-content tt.download span:first-child, +.rst-content tt.download .btn span:first-child, +.btn .rst-content code.download span:first-child, +.rst-content code.download .btn span:first-child, +.btn .icon, +.nav .fa, +.nav .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li .nav span.toctree-expand, +.nav .wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.on a .nav span.toctree-expand, +.nav .wy-menu-vertical li.current>a span.toctree-expand, +.wy-menu-vertical li.current>a .nav span.toctree-expand, +.nav .rst-content .admonition-title, +.rst-content .nav .admonition-title, +.nav .rst-content h1 .headerlink, +.rst-content h1 .nav .headerlink, +.nav .rst-content h2 .headerlink, +.rst-content h2 .nav .headerlink, +.nav .rst-content h3 .headerlink, +.rst-content h3 .nav .headerlink, +.nav .rst-content h4 .headerlink, +.rst-content h4 .nav .headerlink, +.nav .rst-content h5 .headerlink, +.rst-content h5 .nav .headerlink, +.nav .rst-content h6 .headerlink, +.rst-content h6 .nav .headerlink, +.nav .rst-content dl dt .headerlink, +.rst-content dl dt .nav .headerlink, +.nav .rst-content p.caption .headerlink, +.rst-content p.caption .nav .headerlink, +.nav .rst-content tt.download span:first-child, +.rst-content tt.download .nav span:first-child, +.nav .rst-content code.download span:first-child, +.rst-content code.download .nav span:first-child, +.nav .icon { + display: inline +} + +.btn .fa.fa-large, +.btn .wy-menu-vertical li span.fa-large.toctree-expand, +.wy-menu-vertical li .btn span.fa-large.toctree-expand, +.btn .rst-content .fa-large.admonition-title, +.rst-content .btn .fa-large.admonition-title, +.btn .rst-content h1 .fa-large.headerlink, +.rst-content h1 .btn .fa-large.headerlink, +.btn .rst-content h2 .fa-large.headerlink, +.rst-content h2 .btn .fa-large.headerlink, +.btn .rst-content h3 .fa-large.headerlink, +.rst-content h3 .btn .fa-large.headerlink, +.btn .rst-content h4 .fa-large.headerlink, +.rst-content h4 .btn .fa-large.headerlink, +.btn .rst-content h5 .fa-large.headerlink, +.rst-content h5 .btn .fa-large.headerlink, +.btn .rst-content h6 .fa-large.headerlink, +.rst-content h6 .btn .fa-large.headerlink, +.btn .rst-content dl dt .fa-large.headerlink, +.rst-content dl dt .btn .fa-large.headerlink, +.btn .rst-content p.caption .fa-large.headerlink, +.rst-content p.caption .btn .fa-large.headerlink, +.btn .rst-content tt.download span.fa-large:first-child, +.rst-content tt.download .btn span.fa-large:first-child, +.btn .rst-content code.download span.fa-large:first-child, +.rst-content code.download .btn span.fa-large:first-child, +.btn .fa-large.icon, +.nav .fa.fa-large, +.nav .wy-menu-vertical li span.fa-large.toctree-expand, +.wy-menu-vertical li .nav span.fa-large.toctree-expand, +.nav .rst-content .fa-large.admonition-title, +.rst-content .nav .fa-large.admonition-title, +.nav .rst-content h1 .fa-large.headerlink, +.rst-content h1 .nav .fa-large.headerlink, +.nav .rst-content h2 .fa-large.headerlink, +.rst-content h2 .nav .fa-large.headerlink, +.nav .rst-content h3 .fa-large.headerlink, +.rst-content h3 .nav .fa-large.headerlink, +.nav .rst-content h4 .fa-large.headerlink, +.rst-content h4 .nav .fa-large.headerlink, +.nav .rst-content h5 .fa-large.headerlink, +.rst-content h5 .nav .fa-large.headerlink, +.nav .rst-content h6 .fa-large.headerlink, +.rst-content h6 .nav .fa-large.headerlink, +.nav .rst-content dl dt .fa-large.headerlink, +.rst-content dl dt .nav .fa-large.headerlink, +.nav .rst-content p.caption .fa-large.headerlink, +.rst-content p.caption .nav .fa-large.headerlink, +.nav .rst-content tt.download span.fa-large:first-child, +.rst-content tt.download .nav span.fa-large:first-child, +.nav .rst-content code.download span.fa-large:first-child, +.rst-content code.download .nav span.fa-large:first-child, +.nav .fa-large.icon { + line-height: 0.9em +} + +.btn .fa.fa-spin, +.btn .wy-menu-vertical li span.fa-spin.toctree-expand, +.wy-menu-vertical li .btn span.fa-spin.toctree-expand, +.btn .rst-content .fa-spin.admonition-title, +.rst-content .btn .fa-spin.admonition-title, +.btn .rst-content h1 .fa-spin.headerlink, +.rst-content h1 .btn .fa-spin.headerlink, +.btn .rst-content h2 .fa-spin.headerlink, +.rst-content h2 .btn .fa-spin.headerlink, +.btn .rst-content h3 .fa-spin.headerlink, +.rst-content h3 .btn .fa-spin.headerlink, +.btn .rst-content h4 .fa-spin.headerlink, +.rst-content h4 .btn .fa-spin.headerlink, +.btn .rst-content h5 .fa-spin.headerlink, +.rst-content h5 .btn .fa-spin.headerlink, +.btn .rst-content h6 .fa-spin.headerlink, +.rst-content h6 .btn .fa-spin.headerlink, +.btn .rst-content dl dt .fa-spin.headerlink, +.rst-content dl dt .btn .fa-spin.headerlink, +.btn .rst-content p.caption .fa-spin.headerlink, +.rst-content p.caption .btn .fa-spin.headerlink, +.btn .rst-content tt.download span.fa-spin:first-child, +.rst-content tt.download .btn span.fa-spin:first-child, +.btn .rst-content code.download span.fa-spin:first-child, +.rst-content code.download .btn span.fa-spin:first-child, +.btn .fa-spin.icon, +.nav .fa.fa-spin, +.nav .wy-menu-vertical li span.fa-spin.toctree-expand, +.wy-menu-vertical li .nav span.fa-spin.toctree-expand, +.nav .rst-content .fa-spin.admonition-title, +.rst-content .nav .fa-spin.admonition-title, +.nav .rst-content h1 .fa-spin.headerlink, +.rst-content h1 .nav .fa-spin.headerlink, +.nav .rst-content h2 .fa-spin.headerlink, +.rst-content h2 .nav .fa-spin.headerlink, +.nav .rst-content h3 .fa-spin.headerlink, +.rst-content h3 .nav .fa-spin.headerlink, +.nav .rst-content h4 .fa-spin.headerlink, +.rst-content h4 .nav .fa-spin.headerlink, +.nav .rst-content h5 .fa-spin.headerlink, +.rst-content h5 .nav .fa-spin.headerlink, +.nav .rst-content h6 .fa-spin.headerlink, +.rst-content h6 .nav .fa-spin.headerlink, +.nav .rst-content dl dt .fa-spin.headerlink, +.rst-content dl dt .nav .fa-spin.headerlink, +.nav .rst-content p.caption .fa-spin.headerlink, +.rst-content p.caption .nav .fa-spin.headerlink, +.nav .rst-content tt.download span.fa-spin:first-child, +.rst-content tt.download .nav span.fa-spin:first-child, +.nav .rst-content code.download span.fa-spin:first-child, +.rst-content code.download .nav span.fa-spin:first-child, +.nav .fa-spin.icon { + display: inline-block +} + +.btn.fa:before, +.wy-menu-vertical li span.btn.toctree-expand:before, +.rst-content .btn.admonition-title:before, +.rst-content h1 .btn.headerlink:before, +.rst-content h2 .btn.headerlink:before, +.rst-content h3 .btn.headerlink:before, +.rst-content h4 .btn.headerlink:before, +.rst-content h5 .btn.headerlink:before, +.rst-content h6 .btn.headerlink:before, +.rst-content dl dt .btn.headerlink:before, +.rst-content p.caption .btn.headerlink:before, +.rst-content tt.download span.btn:first-child:before, +.rst-content code.download span.btn:first-child:before, +.btn.icon:before { + opacity: 0.5; + -webkit-transition: opacity 0.05s ease-in; + -moz-transition: opacity 0.05s ease-in; + transition: opacity 0.05s ease-in +} + +.btn.fa:hover:before, +.wy-menu-vertical li span.btn.toctree-expand:hover:before, +.rst-content .btn.admonition-title:hover:before, +.rst-content h1 .btn.headerlink:hover:before, +.rst-content h2 .btn.headerlink:hover:before, +.rst-content h3 .btn.headerlink:hover:before, +.rst-content h4 .btn.headerlink:hover:before, +.rst-content h5 .btn.headerlink:hover:before, +.rst-content h6 .btn.headerlink:hover:before, +.rst-content dl dt .btn.headerlink:hover:before, +.rst-content p.caption .btn.headerlink:hover:before, +.rst-content tt.download span.btn:first-child:hover:before, +.rst-content code.download span.btn:first-child:hover:before, +.btn.icon:hover:before { + opacity: 1 +} + +.btn-mini .fa:before, +.btn-mini .wy-menu-vertical li span.toctree-expand:before, +.wy-menu-vertical li .btn-mini span.toctree-expand:before, +.btn-mini .rst-content .admonition-title:before, +.rst-content .btn-mini .admonition-title:before, +.btn-mini .rst-content h1 .headerlink:before, +.rst-content h1 .btn-mini .headerlink:before, +.btn-mini .rst-content h2 .headerlink:before, +.rst-content h2 .btn-mini .headerlink:before, +.btn-mini .rst-content h3 .headerlink:before, +.rst-content h3 .btn-mini .headerlink:before, +.btn-mini .rst-content h4 .headerlink:before, +.rst-content h4 .btn-mini .headerlink:before, +.btn-mini .rst-content h5 .headerlink:before, +.rst-content h5 .btn-mini .headerlink:before, +.btn-mini .rst-content h6 .headerlink:before, +.rst-content h6 .btn-mini .headerlink:before, +.btn-mini .rst-content dl dt .headerlink:before, +.rst-content dl dt .btn-mini .headerlink:before, +.btn-mini .rst-content p.caption .headerlink:before, +.rst-content p.caption .btn-mini .headerlink:before, +.btn-mini .rst-content tt.download span:first-child:before, +.rst-content tt.download .btn-mini span:first-child:before, +.btn-mini .rst-content code.download span:first-child:before, +.rst-content code.download .btn-mini span:first-child:before, +.btn-mini .icon:before { + font-size: 14px; + vertical-align: -15% +} + +.wy-alert, +.rst-content .note, +.rst-content .attention, +.rst-content .caution, +.rst-content .danger, +.rst-content .error, +.rst-content .hint, +.rst-content .important, +.rst-content .tip, +.rst-content .warning, +.rst-content .seealso, +.rst-content .admonition-todo { + padding: 12px; + line-height: 24px; + margin-bottom: 24px; + background: #e7f2fa +} + +.wy-alert-title, +.rst-content .admonition-title { + color: #fff; + font-weight: bold; + display: block; + color: #fff; + background: #6ab0de; + margin: -12px; + padding: 6px 12px; + margin-bottom: 12px +} + +.wy-alert.wy-alert-danger, +.rst-content .wy-alert-danger.note, +.rst-content .wy-alert-danger.attention, +.rst-content .wy-alert-danger.caution, +.rst-content .danger, +.rst-content .error, +.rst-content .wy-alert-danger.hint, +.rst-content .wy-alert-danger.important, +.rst-content .wy-alert-danger.tip, +.rst-content .wy-alert-danger.warning, +.rst-content .wy-alert-danger.seealso, +.rst-content .wy-alert-danger.admonition-todo { + background: #fdf3f2 +} + +.wy-alert.wy-alert-danger .wy-alert-title, +.rst-content .wy-alert-danger.note .wy-alert-title, +.rst-content .wy-alert-danger.attention .wy-alert-title, +.rst-content .wy-alert-danger.caution .wy-alert-title, +.rst-content .danger .wy-alert-title, +.rst-content .error .wy-alert-title, +.rst-content .wy-alert-danger.hint .wy-alert-title, +.rst-content .wy-alert-danger.important .wy-alert-title, +.rst-content .wy-alert-danger.tip .wy-alert-title, +.rst-content .wy-alert-danger.warning .wy-alert-title, +.rst-content .wy-alert-danger.seealso .wy-alert-title, +.rst-content .wy-alert-danger.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-danger .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-danger .admonition-title, +.rst-content .wy-alert-danger.note .admonition-title, +.rst-content .wy-alert-danger.attention .admonition-title, +.rst-content .wy-alert-danger.caution .admonition-title, +.rst-content .danger .admonition-title, +.rst-content .error .admonition-title, +.rst-content .wy-alert-danger.hint .admonition-title, +.rst-content .wy-alert-danger.important .admonition-title, +.rst-content .wy-alert-danger.tip .admonition-title, +.rst-content .wy-alert-danger.warning .admonition-title, +.rst-content .wy-alert-danger.seealso .admonition-title, +.rst-content .wy-alert-danger.admonition-todo .admonition-title { + background: #f29f97 +} + +.wy-alert.wy-alert-warning, +.rst-content .wy-alert-warning.note, +.rst-content .attention, +.rst-content .caution, +.rst-content .wy-alert-warning.danger, +.rst-content .wy-alert-warning.error, +.rst-content .wy-alert-warning.hint, +.rst-content .wy-alert-warning.important, +.rst-content .wy-alert-warning.tip, +.rst-content .warning, +.rst-content .wy-alert-warning.seealso, +.rst-content .admonition-todo { + background: #ffedcc +} + +.wy-alert.wy-alert-warning .wy-alert-title, +.rst-content .wy-alert-warning.note .wy-alert-title, +.rst-content .attention .wy-alert-title, +.rst-content .caution .wy-alert-title, +.rst-content .wy-alert-warning.danger .wy-alert-title, +.rst-content .wy-alert-warning.error .wy-alert-title, +.rst-content .wy-alert-warning.hint .wy-alert-title, +.rst-content .wy-alert-warning.important .wy-alert-title, +.rst-content .wy-alert-warning.tip .wy-alert-title, +.rst-content .warning .wy-alert-title, +.rst-content .wy-alert-warning.seealso .wy-alert-title, +.rst-content .admonition-todo .wy-alert-title, +.wy-alert.wy-alert-warning .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-warning .admonition-title, +.rst-content .wy-alert-warning.note .admonition-title, +.rst-content .attention .admonition-title, +.rst-content .caution .admonition-title, +.rst-content .wy-alert-warning.danger .admonition-title, +.rst-content .wy-alert-warning.error .admonition-title, +.rst-content .wy-alert-warning.hint .admonition-title, +.rst-content .wy-alert-warning.important .admonition-title, +.rst-content .wy-alert-warning.tip .admonition-title, +.rst-content .warning .admonition-title, +.rst-content .wy-alert-warning.seealso .admonition-title, +.rst-content .admonition-todo .admonition-title { + background: #f0b37e +} + +.wy-alert.wy-alert-info, +.rst-content .note, +.rst-content .wy-alert-info.attention, +.rst-content .wy-alert-info.caution, +.rst-content .wy-alert-info.danger, +.rst-content .wy-alert-info.error, +.rst-content .wy-alert-info.hint, +.rst-content .wy-alert-info.important, +.rst-content .wy-alert-info.tip, +.rst-content .wy-alert-info.warning, +.rst-content .seealso, +.rst-content .wy-alert-info.admonition-todo { + background: #e7f2fa +} + +.wy-alert.wy-alert-info .wy-alert-title, +.rst-content .note .wy-alert-title, +.rst-content .wy-alert-info.attention .wy-alert-title, +.rst-content .wy-alert-info.caution .wy-alert-title, +.rst-content .wy-alert-info.danger .wy-alert-title, +.rst-content .wy-alert-info.error .wy-alert-title, +.rst-content .wy-alert-info.hint .wy-alert-title, +.rst-content .wy-alert-info.important .wy-alert-title, +.rst-content .wy-alert-info.tip .wy-alert-title, +.rst-content .wy-alert-info.warning .wy-alert-title, +.rst-content .seealso .wy-alert-title, +.rst-content .wy-alert-info.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-info .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-info .admonition-title, +.rst-content .note .admonition-title, +.rst-content .wy-alert-info.attention .admonition-title, +.rst-content .wy-alert-info.caution .admonition-title, +.rst-content .wy-alert-info.danger .admonition-title, +.rst-content .wy-alert-info.error .admonition-title, +.rst-content .wy-alert-info.hint .admonition-title, +.rst-content .wy-alert-info.important .admonition-title, +.rst-content .wy-alert-info.tip .admonition-title, +.rst-content .wy-alert-info.warning .admonition-title, +.rst-content .seealso .admonition-title, +.rst-content .wy-alert-info.admonition-todo .admonition-title { + background: #6ab0de +} + +.wy-alert.wy-alert-success, +.rst-content .wy-alert-success.note, +.rst-content .wy-alert-success.attention, +.rst-content .wy-alert-success.caution, +.rst-content .wy-alert-success.danger, +.rst-content .wy-alert-success.error, +.rst-content .hint, +.rst-content .important, +.rst-content .tip, +.rst-content .wy-alert-success.warning, +.rst-content .wy-alert-success.seealso, +.rst-content .wy-alert-success.admonition-todo { + background: #dbfaf4 +} + +.wy-alert.wy-alert-success .wy-alert-title, +.rst-content .wy-alert-success.note .wy-alert-title, +.rst-content .wy-alert-success.attention .wy-alert-title, +.rst-content .wy-alert-success.caution .wy-alert-title, +.rst-content .wy-alert-success.danger .wy-alert-title, +.rst-content .wy-alert-success.error .wy-alert-title, +.rst-content .hint .wy-alert-title, +.rst-content .important .wy-alert-title, +.rst-content .tip .wy-alert-title, +.rst-content .wy-alert-success.warning .wy-alert-title, +.rst-content .wy-alert-success.seealso .wy-alert-title, +.rst-content .wy-alert-success.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-success .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-success .admonition-title, +.rst-content .wy-alert-success.note .admonition-title, +.rst-content .wy-alert-success.attention .admonition-title, +.rst-content .wy-alert-success.caution .admonition-title, +.rst-content .wy-alert-success.danger .admonition-title, +.rst-content .wy-alert-success.error .admonition-title, +.rst-content .hint .admonition-title, +.rst-content .important .admonition-title, +.rst-content .tip .admonition-title, +.rst-content .wy-alert-success.warning .admonition-title, +.rst-content .wy-alert-success.seealso .admonition-title, +.rst-content .wy-alert-success.admonition-todo .admonition-title { + background: #1abc9c +} + +.wy-alert.wy-alert-neutral, +.rst-content .wy-alert-neutral.note, +.rst-content .wy-alert-neutral.attention, +.rst-content .wy-alert-neutral.caution, +.rst-content .wy-alert-neutral.danger, +.rst-content .wy-alert-neutral.error, +.rst-content .wy-alert-neutral.hint, +.rst-content .wy-alert-neutral.important, +.rst-content .wy-alert-neutral.tip, +.rst-content .wy-alert-neutral.warning, +.rst-content .wy-alert-neutral.seealso, +.rst-content .wy-alert-neutral.admonition-todo { + background: #f3f6f6 +} + +.wy-alert.wy-alert-neutral .wy-alert-title, +.rst-content .wy-alert-neutral.note .wy-alert-title, +.rst-content .wy-alert-neutral.attention .wy-alert-title, +.rst-content .wy-alert-neutral.caution .wy-alert-title, +.rst-content .wy-alert-neutral.danger .wy-alert-title, +.rst-content .wy-alert-neutral.error .wy-alert-title, +.rst-content .wy-alert-neutral.hint .wy-alert-title, +.rst-content .wy-alert-neutral.important .wy-alert-title, +.rst-content .wy-alert-neutral.tip .wy-alert-title, +.rst-content .wy-alert-neutral.warning .wy-alert-title, +.rst-content .wy-alert-neutral.seealso .wy-alert-title, +.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-neutral .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-neutral .admonition-title, +.rst-content .wy-alert-neutral.note .admonition-title, +.rst-content .wy-alert-neutral.attention .admonition-title, +.rst-content .wy-alert-neutral.caution .admonition-title, +.rst-content .wy-alert-neutral.danger .admonition-title, +.rst-content .wy-alert-neutral.error .admonition-title, +.rst-content .wy-alert-neutral.hint .admonition-title, +.rst-content .wy-alert-neutral.important .admonition-title, +.rst-content .wy-alert-neutral.tip .admonition-title, +.rst-content .wy-alert-neutral.warning .admonition-title, +.rst-content .wy-alert-neutral.seealso .admonition-title, +.rst-content .wy-alert-neutral.admonition-todo .admonition-title { + color: #404040; + background: #e1e4e5 +} + +.wy-alert.wy-alert-neutral a, +.rst-content .wy-alert-neutral.note a, +.rst-content .wy-alert-neutral.attention a, +.rst-content .wy-alert-neutral.caution a, +.rst-content .wy-alert-neutral.danger a, +.rst-content .wy-alert-neutral.error a, +.rst-content .wy-alert-neutral.hint a, +.rst-content .wy-alert-neutral.important a, +.rst-content .wy-alert-neutral.tip a, +.rst-content .wy-alert-neutral.warning a, +.rst-content .wy-alert-neutral.seealso a, +.rst-content .wy-alert-neutral.admonition-todo a { + color: #2980B9 +} + +.wy-alert p:last-child, +.rst-content .note p:last-child, +.rst-content .attention p:last-child, +.rst-content .caution p:last-child, +.rst-content .danger p:last-child, +.rst-content .error p:last-child, +.rst-content .hint p:last-child, +.rst-content .important p:last-child, +.rst-content .tip p:last-child, +.rst-content .warning p:last-child, +.rst-content .seealso p:last-child, +.rst-content .admonition-todo p:last-child { + margin-bottom: 0 +} + +.wy-tray-container { + position: fixed; + bottom: 0px; + left: 0; + z-index: 600 +} + +.wy-tray-container li { + display: block; + width: 300px; + background: transparent; + color: #fff; + text-align: center; + box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.1); + padding: 0 24px; + min-width: 20%; + opacity: 0; + height: 0; + line-height: 56px; + overflow: hidden; + -webkit-transition: all 0.3s ease-in; + -moz-transition: all 0.3s ease-in; + transition: all 0.3s ease-in +} + +.wy-tray-container li.wy-tray-item-success { + background: #27AE60 +} + +.wy-tray-container li.wy-tray-item-info { + background: #2980B9 +} + +.wy-tray-container li.wy-tray-item-warning { + background: #E67E22 +} + +.wy-tray-container li.wy-tray-item-danger { + background: #E74C3C +} + +.wy-tray-container li.on { + opacity: 1; + height: 56px +} + +@media screen and (max-width: 768px) { + .wy-tray-container { + bottom: auto; + top: 0; + width: 100% + } + + .wy-tray-container li { + width: 100% + } +} + +button { + font-size: 100%; + margin: 0; + vertical-align: baseline; + *vertical-align: middle; + cursor: pointer; + line-height: normal; + -webkit-appearance: button; + *overflow: visible +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0 +} + +button[disabled] { + cursor: default +} + +.btn { + display: inline-block; + border-radius: 2px; + line-height: normal; + white-space: nowrap; + text-align: center; + cursor: pointer; + font-size: 100%; + padding: 6px 12px 8px 12px; + color: #fff; + border: 1px solid rgba(0, 0, 0, 0.1); + background-color: #27AE60; + text-decoration: none; + font-weight: normal; + font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif; + box-shadow: 0px 1px 2px -1px rgba(255, 255, 255, 0.5) inset, 0px -2px 0px 0px rgba(0, 0, 0, 0.1) inset; + outline-none: false; + vertical-align: middle; + *display: inline; + zoom: 1; + -webkit-user-drag: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-transition: all 0.1s linear; + -moz-transition: all 0.1s linear; + transition: all 0.1s linear +} + +.btn-hover { + background: #2e8ece; + color: #fff +} + +.btn:hover { + background: #2cc36b; + color: #fff +} + +.btn:focus { + background: #2cc36b; + outline: 0 +} + +.btn:active { + box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.05) inset, 0px 2px 0px 0px rgba(0, 0, 0, 0.1) inset; + padding: 8px 12px 6px 12px +} + +.btn:visited { + color: #fff +} + +.btn:disabled { + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + filter: alpha(opacity=40); + opacity: 0.4; + cursor: not-allowed; + box-shadow: none +} + +.btn-disabled { + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + filter: alpha(opacity=40); + opacity: 0.4; + cursor: not-allowed; + box-shadow: none +} + +.btn-disabled:hover, +.btn-disabled:focus, +.btn-disabled:active { + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + filter: alpha(opacity=40); + opacity: 0.4; + cursor: not-allowed; + box-shadow: none +} + +.btn::-moz-focus-inner { + padding: 0; + border: 0 +} + +.btn-small { + font-size: 80% +} + +.btn-info { + background-color: #2980B9 !important +} + +.btn-info:hover { + background-color: #2e8ece !important +} + +.btn-neutral { + background-color: #f3f6f6 !important; + color: #404040 !important +} + +.btn-neutral:hover { + background-color: #e5ebeb !important; + color: #404040 +} + +.btn-neutral:visited { + color: #404040 !important +} + +.btn-success { + background-color: #27AE60 !important +} + +.btn-success:hover { + background-color: #295 !important +} + +.btn-danger { + background-color: #E74C3C !important +} + +.btn-danger:hover { + background-color: #ea6153 !important +} + +.btn-warning { + background-color: #E67E22 !important +} + +.btn-warning:hover { + background-color: #e98b39 !important +} + +.btn-invert { + background-color: #222 +} + +.btn-invert:hover { + background-color: #2f2f2f !important +} + +.btn-link { + background-color: transparent !important; + color: #2980B9; + box-shadow: none; + border-color: transparent !important +} + +.btn-link:hover { + background-color: transparent !important; + color: #409ad5 !important; + box-shadow: none +} + +.btn-link:active { + background-color: transparent !important; + color: #409ad5 !important; + box-shadow: none +} + +.btn-link:visited { + color: #9B59B6 +} + +.wy-btn-group .btn, +.wy-control .btn { + vertical-align: middle +} + +.wy-btn-group { + margin-bottom: 24px; + *zoom: 1 +} + +.wy-btn-group:before, +.wy-btn-group:after { + display: table; + content: "" +} + +.wy-btn-group:after { + clear: both +} + +.wy-dropdown { + position: relative; + display: inline-block +} + +.wy-dropdown-active .wy-dropdown-menu { + display: block +} + +.wy-dropdown-menu { + position: absolute; + left: 0; + display: none; + float: left; + top: 100%; + min-width: 100%; + background: #fcfcfc; + z-index: 100; + border: solid 1px #cfd7dd; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1); + padding: 12px +} + +.wy-dropdown-menu>dd>a { + display: block; + clear: both; + color: #404040; + white-space: nowrap; + font-size: 90%; + padding: 0 12px; + cursor: pointer +} + +.wy-dropdown-menu>dd>a:hover { + background: #2980B9; + color: #fff +} + +.wy-dropdown-menu>dd.divider { + border-top: solid 1px #cfd7dd; + margin: 6px 0 +} + +.wy-dropdown-menu>dd.search { + padding-bottom: 12px +} + +.wy-dropdown-menu>dd.search input[type="search"] { + width: 100% +} + +.wy-dropdown-menu>dd.call-to-action { + background: #e3e3e3; + text-transform: uppercase; + font-weight: 500; + font-size: 80% +} + +.wy-dropdown-menu>dd.call-to-action:hover { + background: #e3e3e3 +} + +.wy-dropdown-menu>dd.call-to-action .btn { + color: #fff +} + +.wy-dropdown.wy-dropdown-up .wy-dropdown-menu { + bottom: 100%; + top: auto; + left: auto; + right: 0 +} + +.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu { + background: #fcfcfc; + margin-top: 2px +} + +.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a { + padding: 6px 12px +} + +.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover { + background: #2980B9; + color: #fff +} + +.wy-dropdown.wy-dropdown-left .wy-dropdown-menu { + right: 0; + left: auto; + text-align: right +} + +.wy-dropdown-arrow:before { + content: " "; + border-bottom: 5px solid #f5f5f5; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + position: absolute; + display: block; + top: -4px; + left: 50%; + margin-left: -3px +} + +.wy-dropdown-arrow.wy-dropdown-arrow-left:before { + left: 11px +} + +.wy-form-stacked select { + display: block +} + +.wy-form-aligned input, +.wy-form-aligned textarea, +.wy-form-aligned select, +.wy-form-aligned .wy-help-inline, +.wy-form-aligned label { + display: inline-block; + *display: inline; + *zoom: 1; + vertical-align: middle +} + +.wy-form-aligned .wy-control-group>label { + display: inline-block; + vertical-align: middle; + width: 10em; + margin: 6px 12px 0 0; + float: left +} + +.wy-form-aligned .wy-control { + float: left +} + +.wy-form-aligned .wy-control label { + display: block +} + +.wy-form-aligned .wy-control select { + margin-top: 6px +} + +fieldset { + border: 0; + margin: 0; + padding: 0 +} + +legend { + display: block; + width: 100%; + border: 0; + padding: 0; + white-space: normal; + margin-bottom: 24px; + font-size: 150%; + *margin-left: -7px +} + +label { + display: block; + margin: 0 0 0.3125em 0; + color: #333; + font-size: 90% +} + +input, +select, +textarea { + font-size: 100%; + margin: 0; + vertical-align: baseline; + *vertical-align: middle +} + +.wy-control-group { + margin-bottom: 24px; + *zoom: 1; + max-width: 68em; + margin-left: auto; + margin-right: auto; + *zoom: 1 +} + +.wy-control-group:before, +.wy-control-group:after { + display: table; + content: "" +} + +.wy-control-group:after { + clear: both +} + +.wy-control-group:before, +.wy-control-group:after { + display: table; + content: "" +} + +.wy-control-group:after { + clear: both +} + +.wy-control-group.wy-control-group-required>label:after { + content: " *"; + color: #E74C3C +} + +.wy-control-group .wy-form-full, +.wy-control-group .wy-form-halves, +.wy-control-group .wy-form-thirds { + padding-bottom: 12px +} + +.wy-control-group .wy-form-full select, +.wy-control-group .wy-form-halves select, +.wy-control-group .wy-form-thirds select { + width: 100% +} + +.wy-control-group .wy-form-full input[type="text"], +.wy-control-group .wy-form-full input[type="password"], +.wy-control-group .wy-form-full input[type="email"], +.wy-control-group .wy-form-full input[type="url"], +.wy-control-group .wy-form-full input[type="date"], +.wy-control-group .wy-form-full input[type="month"], +.wy-control-group .wy-form-full input[type="time"], +.wy-control-group .wy-form-full input[type="datetime"], +.wy-control-group .wy-form-full input[type="datetime-local"], +.wy-control-group .wy-form-full input[type="week"], +.wy-control-group .wy-form-full input[type="number"], +.wy-control-group .wy-form-full input[type="search"], +.wy-control-group .wy-form-full input[type="tel"], +.wy-control-group .wy-form-full input[type="color"], +.wy-control-group .wy-form-halves input[type="text"], +.wy-control-group .wy-form-halves input[type="password"], +.wy-control-group .wy-form-halves input[type="email"], +.wy-control-group .wy-form-halves input[type="url"], +.wy-control-group .wy-form-halves input[type="date"], +.wy-control-group .wy-form-halves input[type="month"], +.wy-control-group .wy-form-halves input[type="time"], +.wy-control-group .wy-form-halves input[type="datetime"], +.wy-control-group .wy-form-halves input[type="datetime-local"], +.wy-control-group .wy-form-halves input[type="week"], +.wy-control-group .wy-form-halves input[type="number"], +.wy-control-group .wy-form-halves input[type="search"], +.wy-control-group .wy-form-halves input[type="tel"], +.wy-control-group .wy-form-halves input[type="color"], +.wy-control-group .wy-form-thirds input[type="text"], +.wy-control-group .wy-form-thirds input[type="password"], +.wy-control-group .wy-form-thirds input[type="email"], +.wy-control-group .wy-form-thirds input[type="url"], +.wy-control-group .wy-form-thirds input[type="date"], +.wy-control-group .wy-form-thirds input[type="month"], +.wy-control-group .wy-form-thirds input[type="time"], +.wy-control-group .wy-form-thirds input[type="datetime"], +.wy-control-group .wy-form-thirds input[type="datetime-local"], +.wy-control-group .wy-form-thirds input[type="week"], +.wy-control-group .wy-form-thirds input[type="number"], +.wy-control-group .wy-form-thirds input[type="search"], +.wy-control-group .wy-form-thirds input[type="tel"], +.wy-control-group .wy-form-thirds input[type="color"] { + width: 100% +} + +.wy-control-group .wy-form-full { + float: left; + display: block; + margin-right: 2.35765%; + width: 100%; + margin-right: 0 +} + +.wy-control-group .wy-form-full:last-child { + margin-right: 0 +} + +.wy-control-group .wy-form-halves { + float: left; + display: block; + margin-right: 2.35765%; + width: 48.82117% +} + +.wy-control-group .wy-form-halves:last-child { + margin-right: 0 +} + +.wy-control-group .wy-form-halves:nth-of-type(2n) { + margin-right: 0 +} + +.wy-control-group .wy-form-halves:nth-of-type(2n+1) { + clear: left +} + +.wy-control-group .wy-form-thirds { + float: left; + display: block; + margin-right: 2.35765%; + width: 31.76157% +} + +.wy-control-group .wy-form-thirds:last-child { + margin-right: 0 +} + +.wy-control-group .wy-form-thirds:nth-of-type(3n) { + margin-right: 0 +} + +.wy-control-group .wy-form-thirds:nth-of-type(3n+1) { + clear: left +} + +.wy-control-group.wy-control-group-no-input .wy-control { + margin: 6px 0 0 0; + font-size: 90% +} + +.wy-control-no-input { + display: inline-block; + margin: 6px 0 0 0; + font-size: 90% +} + +.wy-control-group.fluid-input input[type="text"], +.wy-control-group.fluid-input input[type="password"], +.wy-control-group.fluid-input input[type="email"], +.wy-control-group.fluid-input input[type="url"], +.wy-control-group.fluid-input input[type="date"], +.wy-control-group.fluid-input input[type="month"], +.wy-control-group.fluid-input input[type="time"], +.wy-control-group.fluid-input input[type="datetime"], +.wy-control-group.fluid-input input[type="datetime-local"], +.wy-control-group.fluid-input input[type="week"], +.wy-control-group.fluid-input input[type="number"], +.wy-control-group.fluid-input input[type="search"], +.wy-control-group.fluid-input input[type="tel"], +.wy-control-group.fluid-input input[type="color"] { + width: 100% +} + +.wy-form-message-inline { + display: inline-block; + padding-left: 0.3em; + color: #666; + vertical-align: middle; + font-size: 90% +} + +.wy-form-message { + display: block; + color: #999; + font-size: 70%; + margin-top: 0.3125em; + font-style: italic +} + +.wy-form-message p { + font-size: inherit; + font-style: italic; + margin-bottom: 6px +} + +.wy-form-message p:last-child { + margin-bottom: 0 +} + +input { + line-height: normal +} + +input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; + font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif; + *overflow: visible +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="datetime"], +input[type="datetime-local"], +input[type="week"], +input[type="number"], +input[type="search"], +input[type="tel"], +input[type="color"] { + -webkit-appearance: none; + padding: 6px; + display: inline-block; + border: 1px solid #ccc; + font-size: 80%; + font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif; + box-shadow: inset 0 1px 3px #ddd; + border-radius: 0; + -webkit-transition: border 0.3s linear; + -moz-transition: border 0.3s linear; + transition: border 0.3s linear +} + +input[type="datetime-local"] { + padding: 0.34375em 0.625em +} + +input[disabled] { + cursor: default +} + +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; + margin-right: 0.3125em; + *height: 13px; + *width: 13px +} + +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none +} + +input[type="text"]:focus, +input[type="password"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus { + outline: 0; + outline: thin dotted \9; + border-color: #333 +} + +input.no-focus:focus { + border-color: #ccc !important +} + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 1px auto #129FEA +} + +input[type="text"][disabled], +input[type="password"][disabled], +input[type="email"][disabled], +input[type="url"][disabled], +input[type="date"][disabled], +input[type="month"][disabled], +input[type="time"][disabled], +input[type="datetime"][disabled], +input[type="datetime-local"][disabled], +input[type="week"][disabled], +input[type="number"][disabled], +input[type="search"][disabled], +input[type="tel"][disabled], +input[type="color"][disabled] { + cursor: not-allowed; + background-color: #fafafa +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #E74C3C; + border: 1px solid #E74C3C +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #E74C3C +} + +input[type="file"]:focus:invalid:focus, +input[type="radio"]:focus:invalid:focus, +input[type="checkbox"]:focus:invalid:focus { + outline-color: #E74C3C +} + +input.wy-input-large { + padding: 12px; + font-size: 100% +} + +textarea { + overflow: auto; + vertical-align: top; + width: 100%; + font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif +} + +select, +textarea { + padding: 0.5em 0.625em; + display: inline-block; + border: 1px solid #ccc; + font-size: 80%; + box-shadow: inset 0 1px 3px #ddd; + -webkit-transition: border 0.3s linear; + -moz-transition: border 0.3s linear; + transition: border 0.3s linear +} + +select { + border: 1px solid #ccc; + background-color: #fff +} + +select[multiple] { + height: auto +} + +select:focus, +textarea:focus { + outline: 0 +} + +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #fafafa +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled] { + cursor: not-allowed +} + +.wy-checkbox, +.wy-radio { + margin: 6px 0; + color: #404040; + display: block +} + +.wy-checkbox input, +.wy-radio input { + vertical-align: baseline +} + +.wy-form-message-inline { + display: inline-block; + *display: inline; + *zoom: 1; + vertical-align: middle +} + +.wy-input-prefix, +.wy-input-suffix { + white-space: nowrap; + padding: 6px +} + +.wy-input-prefix .wy-input-context, +.wy-input-suffix .wy-input-context { + line-height: 27px; + padding: 0 8px; + display: inline-block; + font-size: 80%; + background-color: #f3f6f6; + border: solid 1px #ccc; + color: #999 +} + +.wy-input-suffix .wy-input-context { + border-left: 0 +} + +.wy-input-prefix .wy-input-context { + border-right: 0 +} + +.wy-switch { + width: 36px; + height: 12px; + margin: 12px 0; + position: relative; + border-radius: 4px; + background: #ccc; + cursor: pointer; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out +} + +.wy-switch:before { + position: absolute; + content: ""; + display: block; + width: 18px; + height: 18px; + border-radius: 4px; + background: #999; + left: -3px; + top: -3px; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out +} + +.wy-switch:after { + content: "false"; + position: absolute; + left: 48px; + display: block; + font-size: 12px; + color: #ccc +} + +.wy-switch.active { + background: #1e8449 +} + +.wy-switch.active:before { + left: 24px; + background: #27AE60 +} + +.wy-switch.active:after { + content: "true" +} + +.wy-switch.disabled, +.wy-switch.active.disabled { + cursor: not-allowed +} + +.wy-control-group.wy-control-group-error .wy-form-message, +.wy-control-group.wy-control-group-error>label { + color: #E74C3C +} + +.wy-control-group.wy-control-group-error input[type="text"], +.wy-control-group.wy-control-group-error input[type="password"], +.wy-control-group.wy-control-group-error input[type="email"], +.wy-control-group.wy-control-group-error input[type="url"], +.wy-control-group.wy-control-group-error input[type="date"], +.wy-control-group.wy-control-group-error input[type="month"], +.wy-control-group.wy-control-group-error input[type="time"], +.wy-control-group.wy-control-group-error input[type="datetime"], +.wy-control-group.wy-control-group-error input[type="datetime-local"], +.wy-control-group.wy-control-group-error input[type="week"], +.wy-control-group.wy-control-group-error input[type="number"], +.wy-control-group.wy-control-group-error input[type="search"], +.wy-control-group.wy-control-group-error input[type="tel"], +.wy-control-group.wy-control-group-error input[type="color"] { + border: solid 1px #E74C3C +} + +.wy-control-group.wy-control-group-error textarea { + border: solid 1px #E74C3C +} + +.wy-inline-validate { + white-space: nowrap +} + +.wy-inline-validate .wy-input-context { + padding: 0.5em 0.625em; + display: inline-block; + font-size: 80% +} + +.wy-inline-validate.wy-inline-validate-success .wy-input-context { + color: #27AE60 +} + +.wy-inline-validate.wy-inline-validate-danger .wy-input-context { + color: #E74C3C +} + +.wy-inline-validate.wy-inline-validate-warning .wy-input-context { + color: #E67E22 +} + +.wy-inline-validate.wy-inline-validate-info .wy-input-context { + color: #2980B9 +} + +.rotate-90 { + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg) +} + +.rotate-180 { + -webkit-transform: rotate(180deg); + -moz-transform: rotate(180deg); + -ms-transform: rotate(180deg); + -o-transform: rotate(180deg); + transform: rotate(180deg) +} + +.rotate-270 { + -webkit-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -ms-transform: rotate(270deg); + -o-transform: rotate(270deg); + transform: rotate(270deg) +} + +.mirror { + -webkit-transform: scaleX(-1); + -moz-transform: scaleX(-1); + -ms-transform: scaleX(-1); + -o-transform: scaleX(-1); + transform: scaleX(-1) +} + +.mirror.rotate-90 { + -webkit-transform: scaleX(-1) rotate(90deg); + -moz-transform: scaleX(-1) rotate(90deg); + -ms-transform: scaleX(-1) rotate(90deg); + -o-transform: scaleX(-1) rotate(90deg); + transform: scaleX(-1) rotate(90deg) +} + +.mirror.rotate-180 { + -webkit-transform: scaleX(-1) rotate(180deg); + -moz-transform: scaleX(-1) rotate(180deg); + -ms-transform: scaleX(-1) rotate(180deg); + -o-transform: scaleX(-1) rotate(180deg); + transform: scaleX(-1) rotate(180deg) +} + +.mirror.rotate-270 { + -webkit-transform: scaleX(-1) rotate(270deg); + -moz-transform: scaleX(-1) rotate(270deg); + -ms-transform: scaleX(-1) rotate(270deg); + -o-transform: scaleX(-1) rotate(270deg); + transform: scaleX(-1) rotate(270deg) +} + +@media only screen and (max-width: 480px) { + .wy-form button[type="submit"] { + margin: 0.7em 0 0 + } + + .wy-form input[type="text"], + .wy-form input[type="password"], + .wy-form input[type="email"], + .wy-form input[type="url"], + .wy-form input[type="date"], + .wy-form input[type="month"], + .wy-form input[type="time"], + .wy-form input[type="datetime"], + .wy-form input[type="datetime-local"], + .wy-form input[type="week"], + .wy-form input[type="number"], + .wy-form input[type="search"], + .wy-form input[type="tel"], + .wy-form input[type="color"] { + margin-bottom: 0.3em; + display: block + } + + .wy-form label { + margin-bottom: 0.3em; + display: block + } + + .wy-form input[type="password"], + .wy-form input[type="email"], + .wy-form input[type="url"], + .wy-form input[type="date"], + .wy-form input[type="month"], + .wy-form input[type="time"], + .wy-form input[type="datetime"], + .wy-form input[type="datetime-local"], + .wy-form input[type="week"], + .wy-form input[type="number"], + .wy-form input[type="search"], + .wy-form input[type="tel"], + .wy-form input[type="color"] { + margin-bottom: 0 + } + + .wy-form-aligned .wy-control-group label { + margin-bottom: 0.3em; + text-align: left; + display: block; + width: 100% + } + + .wy-form-aligned .wy-control { + margin: 1.5em 0 0 0 + } + + .wy-form .wy-help-inline, + .wy-form-message-inline, + .wy-form-message { + display: block; + font-size: 80%; + padding: 6px 0 + } +} + +@media screen and (max-width: 768px) { + .tablet-hide { + display: none + } +} + +@media screen and (max-width: 480px) { + .mobile-hide { + display: none + } +} + +.float-left { + float: left +} + +.float-right { + float: right +} + +.full-width { + width: 100% +} + +.wy-table, +.rst-content table.docutils, +.rst-content table.field-list { + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin-bottom: 24px +} + +.wy-table caption, +.rst-content table.docutils caption, +.rst-content table.field-list caption { + color: #000; + font: italic 85%/1 arial, sans-serif; + padding: 1em 0; + text-align: center +} + +.wy-table td, +.rst-content table.docutils td, +.rst-content table.field-list td, +.wy-table th, +.rst-content table.docutils th, +.rst-content table.field-list th { + font-size: 90%; + margin: 0; + overflow: visible; + padding: 8px 16px +} + +.wy-table td:first-child, +.rst-content table.docutils td:first-child, +.rst-content table.field-list td:first-child, +.wy-table th:first-child, +.rst-content table.docutils th:first-child, +.rst-content table.field-list th:first-child { + border-left-width: 0 +} + +.wy-table thead, +.rst-content table.docutils thead, +.rst-content table.field-list thead { + color: #000; + text-align: left; + vertical-align: bottom; + white-space: nowrap +} + +.wy-table thead th, +.rst-content table.docutils thead th, +.rst-content table.field-list thead th { + font-weight: bold; + border-bottom: solid 2px #e1e4e5 +} + +.wy-table td, +.rst-content table.docutils td, +.rst-content table.field-list td { + background-color: transparent; + vertical-align: middle +} + +.wy-table td p, +.rst-content table.docutils td p, +.rst-content table.field-list td p { + line-height: 18px +} + +.wy-table td p:last-child, +.rst-content table.docutils td p:last-child, +.rst-content table.field-list td p:last-child { + margin-bottom: 0 +} + +.wy-table .wy-table-cell-min, +.rst-content table.docutils .wy-table-cell-min, +.rst-content table.field-list .wy-table-cell-min { + width: 1%; + padding-right: 0 +} + +.wy-table .wy-table-cell-min input[type=checkbox], +.rst-content table.docutils .wy-table-cell-min input[type=checkbox], +.rst-content table.field-list .wy-table-cell-min input[type=checkbox], +.wy-table .wy-table-cell-min input[type=checkbox], +.rst-content table.docutils .wy-table-cell-min input[type=checkbox], +.rst-content table.field-list .wy-table-cell-min input[type=checkbox] { + margin: 0 +} + +.wy-table-secondary { + color: gray; + font-size: 90% +} + +.wy-table-tertiary { + color: gray; + font-size: 80% +} + +.wy-table-odd td, +.wy-table-striped tr:nth-child(2n-1) td, +.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { + background-color: #f3f6f6 +} + +.wy-table-backed { + background-color: #f3f6f6 +} + +.wy-table-bordered-all, +.rst-content table.docutils { + border: 1px solid #e1e4e5 +} + +.wy-table-bordered-all td, +.rst-content table.docutils td { + border-bottom: 1px solid #e1e4e5; + border-left: 1px solid #e1e4e5 +} + +.wy-table-bordered-all tbody>tr:last-child td, +.rst-content table.docutils tbody>tr:last-child td { + border-bottom-width: 0 +} + +.wy-table-bordered { + border: 1px solid #e1e4e5 +} + +.wy-table-bordered-rows td { + border-bottom: 1px solid #e1e4e5 +} + +.wy-table-bordered-rows tbody>tr:last-child td { + border-bottom-width: 0 +} + +.wy-table-horizontal tbody>tr:last-child td { + border-bottom-width: 0 +} + +.wy-table-horizontal td, +.wy-table-horizontal th { + border-width: 0 0 1px 0; + border-bottom: 1px solid #e1e4e5 +} + +.wy-table-horizontal tbody>tr:last-child td { + border-bottom-width: 0 +} + +.wy-table-responsive { + margin-bottom: 24px; + max-width: 100%; + overflow: auto +} + +.wy-table-responsive table { + margin-bottom: 0 !important +} + +.wy-table-responsive table td, +.wy-table-responsive table th { + white-space: nowrap +} + +a { + color: #2980B9; + text-decoration: none; + cursor: pointer +} + +a:hover { + color: #3091d1 +} + +a:visited { + color: #9B59B6 +} + +html { + height: 100%; + overflow-x: hidden +} + +body { + font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif; + font-weight: normal; + color: #404040; + min-height: 100%; + overflow-x: hidden; + background: #edf0f2 +} + +.wy-text-left { + text-align: left +} + +.wy-text-center { + text-align: center +} + +.wy-text-right { + text-align: right +} + +.wy-text-large { + font-size: 120% +} + +.wy-text-normal { + font-size: 100% +} + +.wy-text-small, +small { + font-size: 80% +} + +.wy-text-strike { + text-decoration: line-through +} + +.wy-text-warning { + color: #E67E22 !important +} + +a.wy-text-warning:hover { + color: #eb9950 !important +} + +.wy-text-info { + color: #2980B9 !important +} + +a.wy-text-info:hover { + color: #409ad5 !important +} + +.wy-text-success { + color: #27AE60 !important +} + +a.wy-text-success:hover { + color: #36d278 !important +} + +.wy-text-danger { + color: #E74C3C !important +} + +a.wy-text-danger:hover { + color: #ed7669 !important +} + +.wy-text-neutral { + color: #404040 !important +} + +a.wy-text-neutral:hover { + color: #595959 !important +} + +h1, +h2, +.rst-content .toctree-wrapper p.caption, +h3, +h4, +h5, +h6, +legend { + margin-top: 0; + font-weight: 700; + font-family: "Roboto Slab", "ff-tisa-web-pro", "Georgia", Arial, sans-serif +} + +p { + line-height: 24px; + margin: 0; + font-size: 16px; + margin-bottom: 24px +} + +h1 { + font-size: 175% +} + +h2, +.rst-content .toctree-wrapper p.caption { + font-size: 150% +} + +h3 { + font-size: 125% +} + +h4 { + font-size: 115% +} + +h5 { + font-size: 110% +} + +h6 { + font-size: 100% +} + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #e1e4e5; + margin: 24px 0; + padding: 0 +} + +code, +.rst-content tt, +.rst-content code { + white-space: nowrap; + max-width: 100%; + background: #fff; + border: solid 1px #e1e4e5; + font-size: 75%; + padding: 0 5px; + font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; + color: #E74C3C; + overflow-x: auto +} + +code.code-large, +.rst-content tt.code-large { + font-size: 90% +} + +.wy-plain-list-disc, +.rst-content .section ul, +.rst-content .toctree-wrapper ul, +article ul { + list-style: disc; + line-height: 24px; + margin-bottom: 24px +} + +.wy-plain-list-disc li, +.rst-content .section ul li, +.rst-content .toctree-wrapper ul li, +article ul li { + list-style: disc; + margin-left: 24px +} + +.wy-plain-list-disc li p:last-child, +.rst-content .section ul li p:last-child, +.rst-content .toctree-wrapper ul li p:last-child, +article ul li p:last-child { + margin-bottom: 0 +} + +.wy-plain-list-disc li ul, +.rst-content .section ul li ul, +.rst-content .toctree-wrapper ul li ul, +article ul li ul { + margin-bottom: 0 +} + +.wy-plain-list-disc li li, +.rst-content .section ul li li, +.rst-content .toctree-wrapper ul li li, +article ul li li { + list-style: circle +} + +.wy-plain-list-disc li li li, +.rst-content .section ul li li li, +.rst-content .toctree-wrapper ul li li li, +article ul li li li { + list-style: square +} + +.wy-plain-list-disc li ol li, +.rst-content .section ul li ol li, +.rst-content .toctree-wrapper ul li ol li, +article ul li ol li { + list-style: decimal +} + +.wy-plain-list-decimal, +.rst-content .section ol, +.rst-content ol.arabic, +article ol { + list-style: decimal; + line-height: 24px; + margin-bottom: 24px +} + +.wy-plain-list-decimal li, +.rst-content .section ol li, +.rst-content ol.arabic li, +article ol li { + list-style: decimal; + margin-left: 24px +} + +.wy-plain-list-decimal li p:last-child, +.rst-content .section ol li p:last-child, +.rst-content ol.arabic li p:last-child, +article ol li p:last-child { + margin-bottom: 0 +} + +.wy-plain-list-decimal li ul, +.rst-content .section ol li ul, +.rst-content ol.arabic li ul, +article ol li ul { + margin-bottom: 0 +} + +.wy-plain-list-decimal li ul li, +.rst-content .section ol li ul li, +.rst-content ol.arabic li ul li, +article ol li ul li { + list-style: disc +} + +.codeblock-example { + border: 1px solid #e1e4e5; + border-bottom: none; + padding: 24px; + padding-top: 48px; + font-weight: 500; + background: #fff; + position: relative +} + +.codeblock-example:after { + content: "Example"; + position: absolute; + top: 0px; + left: 0px; + background: #9B59B6; + color: #fff; + padding: 6px 12px +} + +.codeblock-example.prettyprint-example-only { + border: 1px solid #e1e4e5; + margin-bottom: 24px +} + +.codeblock, +pre.literal-block, +.rst-content .literal-block, +.rst-content pre.literal-block, +div[class^='highlight'] { + border: 1px solid #e1e4e5; + padding: 0px; + overflow-x: auto; + background: #fff; + margin: 1px 0 24px 0 +} + +.codeblock div[class^='highlight'], +pre.literal-block div[class^='highlight'], +.rst-content .literal-block div[class^='highlight'], +div[class^='highlight'] div[class^='highlight'] { + border: none; + background: none; + margin: 0 +} + +div[class^='highlight'] td.code { + width: 100% +} + +.linenodiv pre { + border-right: solid 1px #e6e9ea; + margin: 0; + padding: 12px 12px; + font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; + font-size: 12px; + line-height: 1.5; + color: #d9d9d9 +} + +div[class^='highlight'] pre { + white-space: pre; + margin: 0; + padding: 12px 12px; + font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; + font-size: 12px; + line-height: 1.5; + display: block; + overflow: auto; + color: #404040 +} + +@media print { + + .codeblock, + pre.literal-block, + .rst-content .literal-block, + .rst-content pre.literal-block, + div[class^='highlight'], + div[class^='highlight'] pre { + white-space: pre-wrap + } +} + +.hll { + background-color: #ffc; + margin: 0 -12px; + padding: 0 12px; + display: block +} + +.c { + color: #998; + font-style: italic +} + +.err { + color: #a61717; + background-color: #e3d2d2 +} + +.k { + font-weight: bold +} + +.o { + font-weight: bold +} + +.cm { + color: #998; + font-style: italic +} + +.cp { + color: #999; + font-weight: bold +} + +.c1 { + color: #998; + font-style: italic +} + +.cs { + color: #999; + font-weight: bold; + font-style: italic +} + +.gd { + color: #000; + background-color: #fdd +} + +.gd .x { + color: #000; + background-color: #faa +} + +.ge { + font-style: italic +} + +.gr { + color: #a00 +} + +.gh { + color: #999 +} + +.gi { + color: #000; + background-color: #dfd +} + +.gi .x { + color: #000; + background-color: #afa +} + +.go { + color: #888 +} + +.gp { + color: #555 +} + +.gs { + font-weight: bold +} + +.gu { + color: purple; + font-weight: bold +} + +.gt { + color: #a00 +} + +.kc { + font-weight: bold +} + +.kd { + font-weight: bold +} + +.kn { + font-weight: bold +} + +.kp { + font-weight: bold +} + +.kr { + font-weight: bold +} + +.kt { + color: #458; + font-weight: bold +} + +.m { + color: #099 +} + +.s { + color: #d14 +} + +.n { + color: #333 +} + +.na { + color: teal +} + +.nb { + color: #0086b3 +} + +.nc { + color: #458; + font-weight: bold +} + +.no { + color: teal +} + +.ni { + color: purple +} + +.ne { + color: #900; + font-weight: bold +} + +.nf { + color: #900; + font-weight: bold +} + +.nn { + color: #555 +} + +.nt { + color: navy +} + +.nv { + color: teal +} + +.ow { + font-weight: bold +} + +.w { + color: #bbb +} + +.mf { + color: #099 +} + +.mh { + color: #099 +} + +.mi { + color: #099 +} + +.mo { + color: #099 +} + +.sb { + color: #d14 +} + +.sc { + color: #d14 +} + +.sd { + color: #d14 +} + +.s2 { + color: #d14 +} + +.se { + color: #d14 +} + +.sh { + color: #d14 +} + +.si { + color: #d14 +} + +.sx { + color: #d14 +} + +.sr { + color: #009926 +} + +.s1 { + color: #d14 +} + +.ss { + color: #990073 +} + +.bp { + color: #999 +} + +.vc { + color: teal +} + +.vg { + color: teal +} + +.vi { + color: teal +} + +.il { + color: #099 +} + +.gc { + color: #999; + background-color: #EAF2F5 +} + +.wy-breadcrumbs li { + display: inline-block +} + +.wy-breadcrumbs li.wy-breadcrumbs-aside { + float: right +} + +.wy-breadcrumbs li a { + display: inline-block; + padding: 5px +} + +.wy-breadcrumbs li a:first-child { + padding-left: 0 +} + +.wy-breadcrumbs li code, +.wy-breadcrumbs li .rst-content tt, +.rst-content .wy-breadcrumbs li tt { + padding: 5px; + border: none; + background: none +} + +.wy-breadcrumbs li code.literal, +.wy-breadcrumbs li .rst-content tt.literal, +.rst-content .wy-breadcrumbs li tt.literal { + color: #404040 +} + +.wy-breadcrumbs-extra { + margin-bottom: 0; + color: #b3b3b3; + font-size: 80%; + display: inline-block +} + +@media screen and (max-width: 480px) { + .wy-breadcrumbs-extra { + display: none + } + + .wy-breadcrumbs li.wy-breadcrumbs-aside { + display: none + } +} + +@media print { + .wy-breadcrumbs li.wy-breadcrumbs-aside { + display: none + } +} + +.wy-affix { + position: fixed; + top: 1.618em +} + +.wy-menu a:hover { + text-decoration: none +} + +.wy-menu-horiz { + *zoom: 1 +} + +.wy-menu-horiz:before, +.wy-menu-horiz:after { + display: table; + content: "" +} + +.wy-menu-horiz:after { + clear: both +} + +.wy-menu-horiz ul, +.wy-menu-horiz li { + display: inline-block +} + +.wy-menu-horiz li:hover { + background: rgba(255, 255, 255, 0.1) +} + +.wy-menu-horiz li.divide-left { + border-left: solid 1px #404040 +} + +.wy-menu-horiz li.divide-right { + border-right: solid 1px #404040 +} + +.wy-menu-horiz a { + height: 32px; + display: inline-block; + line-height: 32px; + padding: 0 16px +} + +.wy-menu-vertical { + width: 300px +} + +.wy-menu-vertical header, +.wy-menu-vertical p.caption { + height: 32px; + display: inline-block; + line-height: 32px; + padding: 0 1.618em; + margin-bottom: 0; + display: block; + font-weight: bold; + text-transform: uppercase; + font-size: 80%; + color: #555; + white-space: nowrap +} + +.wy-menu-vertical ul { + margin-bottom: 0 +} + +.wy-menu-vertical li.divide-top { + border-top: solid 1px #404040 +} + +.wy-menu-vertical li.divide-bottom { + border-bottom: solid 1px #404040 +} + +.wy-menu-vertical li.current { + background: #e3e3e3 +} + +.wy-menu-vertical li.current a { + color: gray; + border-right: solid 1px #c9c9c9; + padding: 0.4045em 2.427em +} + +.wy-menu-vertical li.current a:hover { + background: #d6d6d6 +} + +.wy-menu-vertical li code, +.wy-menu-vertical li .rst-content tt, +.rst-content .wy-menu-vertical li tt { + border: none; + background: inherit; + color: inherit; + padding-left: 0; + padding-right: 0 +} + +.wy-menu-vertical li span.toctree-expand { + display: block; + float: left; + margin-left: -1.2em; + font-size: 0.8em; + line-height: 1.6em; + color: #4d4d4d +} + +.wy-menu-vertical li.on a, +.wy-menu-vertical li.current>a { + color: #404040; + padding: 0.4045em 1.618em; + font-weight: bold; + position: relative; + background: #fcfcfc; + border: none; + border-bottom: solid 1px #c9c9c9; + border-top: solid 1px #c9c9c9; + padding-left: 1.618em -4px +} + +.wy-menu-vertical li.on a:hover, +.wy-menu-vertical li.current>a:hover { + background: #fcfcfc +} + +.wy-menu-vertical li.on a:hover span.toctree-expand, +.wy-menu-vertical li.current>a:hover span.toctree-expand { + color: gray +} + +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand { + display: block; + font-size: 0.8em; + line-height: 1.6em; + color: #333 +} + +.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul, +.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul { + display: none +} + +.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul, +.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul { + display: block +} + +.wy-menu-vertical li.toctree-l2.current>a { + background: #c9c9c9; + padding: 0.4045em 2.427em +} + +.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a { + display: block; + background: #c9c9c9; + padding: 0.4045em 4.045em +} + +.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand { + color: gray +} + +.wy-menu-vertical li.toctree-l2 span.toctree-expand { + color: #a3a3a3 +} + +.wy-menu-vertical li.toctree-l3 { + font-size: 0.9em +} + +.wy-menu-vertical li.toctree-l3.current>a { + background: #bdbdbd; + padding: 0.4045em 4.045em +} + +.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a { + display: block; + background: #bdbdbd; + padding: 0.4045em 5.663em; + border-top: none; + border-bottom: none +} + +.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand { + color: gray +} + +.wy-menu-vertical li.toctree-l3 span.toctree-expand { + color: #969696 +} + +.wy-menu-vertical li.toctree-l4 { + font-size: 0.9em +} + +.wy-menu-vertical li.current ul { + display: block +} + +.wy-menu-vertical li ul { + margin-bottom: 0; + display: none +} + +.wy-menu-vertical .local-toc li ul { + display: block +} + +.wy-menu-vertical li ul li a { + margin-bottom: 0; + color: #b3b3b3; + font-weight: normal +} + +.wy-menu-vertical a { + display: inline-block; + line-height: 18px; + padding: 0.4045em 1.618em; + display: block; + position: relative; + font-size: 90%; + color: #b3b3b3 +} + +.wy-menu-vertical a:hover { + background-color: #4e4a4a; + cursor: pointer +} + +.wy-menu-vertical a:hover span.toctree-expand { + color: #b3b3b3 +} + +.wy-menu-vertical a:active { + background-color: #2980B9; + cursor: pointer; + color: #fff +} + +.wy-menu-vertical a:active span.toctree-expand { + color: #fff +} + +.wy-side-nav-search { + display: block; + width: 300px; + padding: 0.809em; + margin-bottom: 0.809em; + z-index: 200; + background-color: #2980B9; + text-align: center; + padding: 0.809em; + display: block; + color: #fcfcfc; + margin-bottom: 0.809em +} + +.wy-side-nav-search input[type=text] { + width: 100%; + border-radius: 50px; + padding: 6px 12px; + border-color: #2472a4 +} + +.wy-side-nav-search img { + display: block; + margin: auto auto 0.809em auto; + height: 45px; + width: 45px; + background-color: #2980B9; + padding: 5px; + border-radius: 100% +} + +.wy-side-nav-search>a, +.wy-side-nav-search .wy-dropdown>a { + color: #fcfcfc; + font-size: 100%; + font-weight: bold; + display: inline-block; + padding: 4px 6px; + margin-bottom: 0.809em +} + +.wy-side-nav-search>a:hover, +.wy-side-nav-search .wy-dropdown>a:hover { + background: rgba(255, 255, 255, 0.1) +} + +.wy-side-nav-search>a img.logo, +.wy-side-nav-search .wy-dropdown>a img.logo { + display: block; + margin: 0 auto; + height: auto; + width: auto; + border-radius: 0; + max-width: 100%; + background: transparent +} + +.wy-side-nav-search>a.icon img.logo, +.wy-side-nav-search .wy-dropdown>a.icon img.logo { + margin-top: 0.85em +} + +.wy-side-nav-search>div.version { + margin-top: -0.4045em; + margin-bottom: 0.809em; + font-weight: normal; + color: rgba(255, 255, 255, 0.3) +} + +.wy-nav .wy-menu-vertical header { + color: #2980B9 +} + +.wy-nav .wy-menu-vertical a { + color: #b3b3b3 +} + +.wy-nav .wy-menu-vertical a:hover { + background-color: #2980B9; + color: #fff +} + +[data-menu-wrap] { + -webkit-transition: all 0.2s ease-in; + -moz-transition: all 0.2s ease-in; + transition: all 0.2s ease-in; + position: absolute; + opacity: 1; + width: 100%; + opacity: 0 +} + +[data-menu-wrap].move-center { + left: 0; + right: auto; + opacity: 1 +} + +[data-menu-wrap].move-left { + right: auto; + left: -100%; + opacity: 0 +} + +[data-menu-wrap].move-right { + right: -100%; + left: auto; + opacity: 0 +} + +.wy-body-for-nav { + background: left repeat-y #fcfcfc; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC); + background-size: 300px 1px +} + +.wy-grid-for-nav { + position: absolute; + width: 100%; + height: 100% +} + +.wy-nav-side { + position: fixed; + top: 0; + bottom: 0; + left: 0; + padding-bottom: 2em; + width: 300px; + overflow-x: hidden; + overflow-y: hidden; + min-height: 100%; + background: #343131; + z-index: 200 +} + +.wy-side-scroll { + width: 320px; + position: relative; + overflow-x: hidden; + overflow-y: scroll; + height: 100% +} + +.wy-nav-top { + display: none; + background: #2980B9; + color: #fff; + padding: 0.4045em 0.809em; + position: relative; + line-height: 50px; + text-align: center; + font-size: 100%; + *zoom: 1 +} + +.wy-nav-top:before, +.wy-nav-top:after { + display: table; + content: "" +} + +.wy-nav-top:after { + clear: both +} + +.wy-nav-top a { + color: #fff; + font-weight: bold +} + +.wy-nav-top img { + margin-right: 12px; + height: 45px; + width: 45px; + background-color: #2980B9; + padding: 5px; + border-radius: 100% +} + +.wy-nav-top i { + font-size: 30px; + float: left; + cursor: pointer; + padding-top: inherit +} + +.wy-nav-content-wrap { + margin-left: 300px; + background: #fcfcfc; + min-height: 100% +} + +.wy-nav-content { + padding: 1.618em 3.236em; + height: 100%; + max-width: 800px; + margin: auto +} + +.wy-body-mask { + position: fixed; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.2); + display: none; + z-index: 499 +} + +.wy-body-mask.on { + display: block +} + +footer { + color: #999 +} + +footer p { + margin-bottom: 12px +} + +footer span.commit code, +footer span.commit .rst-content tt, +.rst-content footer span.commit tt { + padding: 0px; + font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; + font-size: 1em; + background: none; + border: none; + color: #999 +} + +.rst-footer-buttons { + *zoom: 1 +} + +.rst-footer-buttons:before, +.rst-footer-buttons:after { + display: table; + content: "" +} + +.rst-footer-buttons:after { + clear: both +} + +#search-results .search li { + margin-bottom: 24px; + border-bottom: solid 1px #e1e4e5; + padding-bottom: 24px +} + +#search-results .search li:first-child { + border-top: solid 1px #e1e4e5; + padding-top: 24px +} + +#search-results .search li a { + font-size: 120%; + margin-bottom: 12px; + display: inline-block +} + +#search-results .context { + color: gray; + font-size: 90% +} + +@media screen and (max-width: 768px) { + .wy-body-for-nav { + background: #fcfcfc + } + + .wy-nav-top { + display: block + } + + .wy-nav-side { + left: -300px + } + + .wy-nav-side.shift { + width: 85%; + left: 0 + } + + .wy-side-scroll { + width: auto + } + + .wy-side-nav-search { + width: auto + } + + .wy-menu.wy-menu-vertical { + width: auto + } + + .wy-nav-content-wrap { + margin-left: 0 + } + + .wy-nav-content-wrap .wy-nav-content { + padding: 1.618em + } + + .wy-nav-content-wrap.shift { + position: fixed; + min-width: 100%; + left: 85%; + top: 0; + height: 100%; + overflow: hidden + } +} + +@media screen and (min-width: 1400px) { + .wy-nav-content-wrap { + background: rgba(0, 0, 0, 0.05) + } + + .wy-nav-content { + margin: 0; + background: #fcfcfc + } +} + +@media print { + + .rst-versions, + footer, + .wy-nav-side { + display: none + } + + .wy-nav-content-wrap { + margin-left: 0 + } +} + +.rst-versions { + position: fixed; + bottom: 0; + left: 0; + width: 300px; + color: #fcfcfc; + background: #1f1d1d; + border-top: solid 10px #343131; + font-family: "Lato", "proxima-nova", "Helvetica Neue", Arial, sans-serif; + z-index: 400 +} + +.rst-versions a { + color: #2980B9; + text-decoration: none +} + +.rst-versions .rst-badge-small { + display: none +} + +.rst-versions .rst-current-version { + padding: 12px; + background-color: #272525; + display: block; + text-align: right; + font-size: 90%; + cursor: pointer; + color: #27AE60; + *zoom: 1 +} + +.rst-versions .rst-current-version:before, +.rst-versions .rst-current-version:after { + display: table; + content: "" +} + +.rst-versions .rst-current-version:after { + clear: both +} + +.rst-versions .rst-current-version .fa, +.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand, +.rst-versions .rst-current-version .rst-content .admonition-title, +.rst-content .rst-versions .rst-current-version .admonition-title, +.rst-versions .rst-current-version .rst-content h1 .headerlink, +.rst-content h1 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h2 .headerlink, +.rst-content h2 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h3 .headerlink, +.rst-content h3 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h4 .headerlink, +.rst-content h4 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h5 .headerlink, +.rst-content h5 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h6 .headerlink, +.rst-content h6 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content dl dt .headerlink, +.rst-content dl dt .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content p.caption .headerlink, +.rst-content p.caption .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content tt.download span:first-child, +.rst-content tt.download .rst-versions .rst-current-version span:first-child, +.rst-versions .rst-current-version .rst-content code.download span:first-child, +.rst-content code.download .rst-versions .rst-current-version span:first-child, +.rst-versions .rst-current-version .icon { + color: #fcfcfc +} + +.rst-versions .rst-current-version .fa-book, +.rst-versions .rst-current-version .icon-book { + float: left +} + +.rst-versions .rst-current-version .icon-book { + float: left +} + +.rst-versions .rst-current-version.rst-out-of-date { + background-color: #E74C3C; + color: #fff +} + +.rst-versions .rst-current-version.rst-active-old-version { + background-color: #F1C40F; + color: #000 +} + +.rst-versions.shift-up .rst-other-versions { + display: block +} + +.rst-versions .rst-other-versions { + font-size: 90%; + padding: 12px; + color: gray; + display: none +} + +.rst-versions .rst-other-versions hr { + display: block; + height: 1px; + border: 0; + margin: 20px 0; + padding: 0; + border-top: solid 1px #413d3d +} + +.rst-versions .rst-other-versions dd { + display: inline-block; + margin: 0 +} + +.rst-versions .rst-other-versions dd a { + display: inline-block; + padding: 6px; + color: #fcfcfc +} + +.rst-versions.rst-badge { + width: auto; + bottom: 20px; + right: 20px; + left: auto; + border: none; + max-width: 300px +} + +.rst-versions.rst-badge .icon-book { + float: none +} + +.rst-versions.rst-badge .fa-book, +.rst-versions.rst-badge .icon-book { + float: none +} + +.rst-versions.rst-badge.shift-up .rst-current-version { + text-align: right +} + +.rst-versions.rst-badge.shift-up .rst-current-version .fa-book, +.rst-versions.rst-badge.shift-up .rst-current-version .icon-book { + float: left +} + +.rst-versions.rst-badge.shift-up .rst-current-version .icon-book { + float: left +} + +.rst-versions.rst-badge .rst-current-version { + width: auto; + height: 30px; + line-height: 30px; + padding: 0 6px; + display: block; + text-align: center +} + +@media screen and (max-width: 768px) { + .rst-versions { + width: 85%; + display: none + } + + .rst-versions.shift { + display: block + } + + img { + width: 100%; + height: auto + } +} + +.rst-content img { + max-width: 100%; + height: auto !important +} + +.rst-content div.figure { + margin-bottom: 24px +} + +.rst-content div.figure p.caption { + font-style: italic +} + +.rst-content div.figure.align-center { + text-align: center +} + +.rst-content .section>img, +.rst-content .section>a>img { + margin-bottom: 24px +} + +.rst-content blockquote { + margin-left: 24px; + line-height: 24px; + margin-bottom: 24px +} + +.rst-content .note .last, +.rst-content .attention .last, +.rst-content .caution .last, +.rst-content .danger .last, +.rst-content .error .last, +.rst-content .hint .last, +.rst-content .important .last, +.rst-content .tip .last, +.rst-content .warning .last, +.rst-content .seealso .last, +.rst-content .admonition-todo .last { + margin-bottom: 0 +} + +.rst-content .admonition-title:before { + margin-right: 4px +} + +.rst-content .admonition table { + border-color: rgba(0, 0, 0, 0.1) +} + +.rst-content .admonition table td, +.rst-content .admonition table th { + background: transparent !important; + border-color: rgba(0, 0, 0, 0.1) !important +} + +.rst-content .section ol.loweralpha, +.rst-content .section ol.loweralpha li { + list-style: lower-alpha +} + +.rst-content .section ol.upperalpha, +.rst-content .section ol.upperalpha li { + list-style: upper-alpha +} + +.rst-content .section ol p, +.rst-content .section ul p { + margin-bottom: 12px +} + +.rst-content .line-block { + margin-left: 24px +} + +.rst-content .topic-title { + font-weight: bold; + margin-bottom: 12px +} + +.rst-content .toc-backref { + color: #404040 +} + +.rst-content .align-right { + float: right; + margin: 0px 0px 24px 24px +} + +.rst-content .align-left { + float: left; + margin: 0px 24px 24px 0px +} + +.rst-content .align-center { + margin: auto; + display: block +} + +.rst-content h1 .headerlink, +.rst-content h2 .headerlink, +.rst-content .toctree-wrapper p.caption .headerlink, +.rst-content h3 .headerlink, +.rst-content h4 .headerlink, +.rst-content h5 .headerlink, +.rst-content h6 .headerlink, +.rst-content dl dt .headerlink, +.rst-content p.caption .headerlink { + display: none; + visibility: hidden; + font-size: 14px +} + +.rst-content h1 .headerlink:after, +.rst-content h2 .headerlink:after, +.rst-content .toctree-wrapper p.caption .headerlink:after, +.rst-content h3 .headerlink:after, +.rst-content h4 .headerlink:after, +.rst-content h5 .headerlink:after, +.rst-content h6 .headerlink:after, +.rst-content dl dt .headerlink:after, +.rst-content p.caption .headerlink:after { + visibility: visible; + content: ""; + font-family: FontAwesome; + display: inline-block +} + +.rst-content h1:hover .headerlink, +.rst-content h2:hover .headerlink, +.rst-content .toctree-wrapper p.caption:hover .headerlink, +.rst-content h3:hover .headerlink, +.rst-content h4:hover .headerlink, +.rst-content h5:hover .headerlink, +.rst-content h6:hover .headerlink, +.rst-content dl dt:hover .headerlink, +.rst-content p.caption:hover .headerlink { + display: inline-block +} + +.rst-content .sidebar { + float: right; + width: 40%; + display: block; + margin: 0 0 24px 24px; + padding: 24px; + background: #f3f6f6; + border: solid 1px #e1e4e5 +} + +.rst-content .sidebar p, +.rst-content .sidebar ul, +.rst-content .sidebar dl { + font-size: 90% +} + +.rst-content .sidebar .last { + margin-bottom: 0 +} + +.rst-content .sidebar .sidebar-title { + display: block; + font-family: "Roboto Slab", "ff-tisa-web-pro", "Georgia", Arial, sans-serif; + font-weight: bold; + background: #e1e4e5; + padding: 6px 12px; + margin: -24px; + margin-bottom: 24px; + font-size: 100% +} + +.rst-content .highlighted { + background: #F1C40F; + display: inline-block; + font-weight: bold; + padding: 0 6px +} + +.rst-content .footnote-reference, +.rst-content .citation-reference { + vertical-align: super; + font-size: 90% +} + +.rst-content table.docutils.citation, +.rst-content table.docutils.footnote { + background: none; + border: none; + color: #999 +} + +.rst-content table.docutils.citation td, +.rst-content table.docutils.citation tr, +.rst-content table.docutils.footnote td, +.rst-content table.docutils.footnote tr { + border: none; + background-color: transparent !important; + white-space: normal +} + +.rst-content table.docutils.citation td.label, +.rst-content table.docutils.footnote td.label { + padding-left: 0; + padding-right: 0; + vertical-align: top +} + +.rst-content table.docutils.citation tt, +.rst-content table.docutils.citation code, +.rst-content table.docutils.footnote tt, +.rst-content table.docutils.footnote code { + color: #555 +} + +.rst-content table.field-list { + border: none +} + +.rst-content table.field-list td { + border: none; + padding-top: 5px +} + +.rst-content table.field-list td>strong { + display: inline-block; + margin-top: 3px +} + +.rst-content table.field-list .field-name { + padding-right: 10px; + text-align: left; + white-space: nowrap +} + +.rst-content table.field-list .field-body { + text-align: left; + padding-left: 0 +} + +.rst-content tt, +.rst-content tt, +.rst-content code { + color: #000; + padding: 2px 5px +} + +.rst-content tt big, +.rst-content tt em, +.rst-content tt big, +.rst-content code big, +.rst-content tt em, +.rst-content code em { + font-size: 100% !important; + line-height: normal +} + +.rst-content tt.literal, +.rst-content tt.literal, +.rst-content code.literal { + color: #E74C3C +} + +.rst-content tt.xref, +a .rst-content tt, +.rst-content tt.xref, +.rst-content code.xref, +a .rst-content tt, +a .rst-content code { + font-weight: bold; + color: #404040 +} + +.rst-content a tt, +.rst-content a tt, +.rst-content a code { + color: #2980B9 +} + +.rst-content dl { + margin-bottom: 24px +} + +.rst-content dl dt { + font-weight: bold +} + +.rst-content dl p, +.rst-content dl table, +.rst-content dl ul, +.rst-content dl ol { + margin-bottom: 12px !important +} + +.rst-content dl dd { + margin: 0 0 12px 24px +} + +.rst-content dl:not(.docutils) { + margin-bottom: 24px +} + +.rst-content dl:not(.docutils) dt { + display: inline-block; + margin: 6px 0; + font-size: 90%; + line-height: normal; + background: #e7f2fa; + color: #2980B9; + border-top: solid 3px #6ab0de; + padding: 6px; + position: relative +} + +.rst-content dl:not(.docutils) dt:before { + color: #6ab0de +} + +.rst-content dl:not(.docutils) dt .headerlink { + color: #404040; + font-size: 100% !important +} + +.rst-content dl:not(.docutils) dl dt { + margin-bottom: 6px; + border: none; + border-left: solid 3px #ccc; + background: #f0f0f0; + color: #555 +} + +.rst-content dl:not(.docutils) dl dt .headerlink { + color: #404040; + font-size: 100% !important +} + +.rst-content dl:not(.docutils) dt:first-child { + margin-top: 0 +} + +.rst-content dl:not(.docutils) tt, +.rst-content dl:not(.docutils) tt, +.rst-content dl:not(.docutils) code { + font-weight: bold +} + +.rst-content dl:not(.docutils) tt.descname, +.rst-content dl:not(.docutils) tt.descclassname, +.rst-content dl:not(.docutils) tt.descname, +.rst-content dl:not(.docutils) code.descname, +.rst-content dl:not(.docutils) tt.descclassname, +.rst-content dl:not(.docutils) code.descclassname { + background-color: transparent; + border: none; + padding: 0; + font-size: 100% !important +} + +.rst-content dl:not(.docutils) tt.descname, +.rst-content dl:not(.docutils) tt.descname, +.rst-content dl:not(.docutils) code.descname { + font-weight: bold +} + +.rst-content dl:not(.docutils) .optional { + display: inline-block; + padding: 0 4px; + color: #000; + font-weight: bold +} + +.rst-content dl:not(.docutils) .property { + display: inline-block; + padding-right: 8px +} + +.rst-content .viewcode-link, +.rst-content .viewcode-back { + display: inline-block; + color: #27AE60; + font-size: 80%; + padding-left: 24px +} + +.rst-content .viewcode-back { + display: block; + float: right +} + +.rst-content p.rubric { + margin-bottom: 12px; + font-weight: bold +} + +.rst-content tt.download, +.rst-content code.download { + background: inherit; + padding: inherit; + font-family: inherit; + font-size: inherit; + color: inherit; + border: inherit; + white-space: inherit +} + +.rst-content tt.download span:first-child:before, +.rst-content code.download span:first-child:before { + margin-right: 4px +} + +@media screen and (max-width: 480px) { + .rst-content .sidebar { + width: 100% + } +} + +span[id*='MathJax-Span'] { + color: #404040 +} + +.math { + text-align: center +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 400; + src: local("Inconsolata"), local("Inconsolata-Regular"), url(../fonts/Inconsolata-Regular.ttf) format("truetype") +} + +@font-face { + font-family: "Inconsolata"; + font-style: normal; + font-weight: 700; + src: local("Inconsolata Bold"), local("Inconsolata-Bold"), url(../fonts/Inconsolata-Bold.ttf) format("truetype") +} + +@font-face { + font-family: "Lato"; + font-style: normal; + font-weight: 400; + src: local("Lato Regular"), local("Lato-Regular"), url(../fonts/Lato-Regular.ttf) format("truetype") +} + +@font-face { + font-family: "Lato"; + font-style: normal; + font-weight: 700; + src: local("Lato Bold"), local("Lato-Bold"), url(../fonts/Lato-Bold.ttf) format("truetype") +} + +@font-face { + font-family: "Roboto Slab"; + font-style: normal; + font-weight: 400; + src: local("Roboto Slab Regular"), local("RobotoSlab-Regular"), url(../fonts/RobotoSlab-Regular.ttf) format("truetype") +} + +@font-face { + font-family: "Roboto Slab"; + font-style: normal; + font-weight: 700; + src: local("Roboto Slab Bold"), local("RobotoSlab-Bold"), url(../fonts/RobotoSlab-Bold.ttf) format("truetype") +} + +/*# sourceMappingURL=theme.css.map */ \ No newline at end of file diff --git a/docs/themes/sphinx_rtd_theme/static/css/theme.css.map b/docs/themes/sphinx_rtd_theme/static/css/theme.css.map index 96cc9d2..e934780 100644 --- a/docs/themes/sphinx_rtd_theme/static/css/theme.css.map +++ b/docs/themes/sphinx_rtd_theme/static/css/theme.css.map @@ -1,4 +1,4 @@ -{ + { "version": 3, "mappings": "CACE,AAAE,ECQI,iBAAoB,EDPJ,SAAU,ECY1B,cAAiB,EDZD,SAAU,EC2B1B,SAAY,ED3BI,SAAU,EEFlC,uEAAiF,EAC/E,MAAO,EAAE,IAAK,EAEhB,iBAAoB,EAClB,MAAO,EAAE,WAAY,EACrB,OAAQ,EAAE,KAAM,EAChB,IAAK,EAAE,AAAC,EAEV,oBAAqB,EACnB,MAAO,EAAE,GAAI,EAEf,OAAQ,EACN,MAAO,EAAE,GAAI,EAEf,AAAC,EDLO,iBAAoB,ECMd,SAAU,EDDhB,cAAiB,ECCX,SAAU,EDchB,SAAY,ECdN,SAAU,EAExB,GAAI,EACF,QAAS,EAAE,GAAI,EACf,uBAAwB,EAAE,GAAI,EAC9B,mBAAoB,EAAE,GAAI,EAE5B,GAAI,EACF,KAAM,EAAE,AAAC,EAEX,eAAiB,EACf,MAAO,EAAE,AAAC,EAEZ,UAAW,EACT,YAAa,EAAE,SAAU,EAE3B,OAAS,EACP,UAAW,EAAE,GAAI,EAEnB,SAAU,EACR,KAAM,EAAE,AAAC,EAEX,EAAG,EACD,SAAU,EAAE,KAAM,EAGpB,EAAG,EACD,SAAU,EAAE,GAAI,EAChB,IAAK,EAAE,GAAI,EACX,cAAe,EAAE,GAAI,EAEvB,GAAI,EACF,SAAU,EAAE,GAAI,EAChB,IAAK,EAAE,GAAI,EACX,SAAU,EAAE,KAAM,EAClB,UAAW,EAAE,GAAI,EAEnB,kDAAoB,EAClB,UAAW,EAAE,cAAS,EACtB,WAAY,EAAE,sBAAa,EAC3B,QAAS,EAAE,EAAG,EAEhB,EAAG,EACD,UAAW,EAAE,EAAG,EAElB,AAAC,EACC,KAAM,EAAE,GAAI,EAEd,eAAiB,EACf,MAAO,EAAE,CAAE,EACX,MAAO,EAAE,GAAI,EAEf,IAAK,EACH,QAAS,EAAE,EAAG,EAEhB,MAAQ,EACN,QAAS,EAAE,EAAG,EACd,UAAW,EAAE,AAAC,EACd,OAAQ,EAAE,OAAQ,EAClB,aAAc,EAAE,OAAQ,EAE1B,EAAG,EACD,EAAG,EAAE,KAAM,EAEb,EAAG,EACD,KAAM,EAAE,MAAO,EAEjB,OAAU,EACR,KAAM,EAAE,AAAC,EACT,MAAO,EAAE,AAAC,EACV,SAAU,EAAE,GAAI,EAChB,eAAgB,EAAE,GAAI,EAExB,CAAE,EACA,SAAU,EAAE,GAAI,EAElB,CAAE,EACA,KAAM,EAAE,AAAC,EAEX,EAAG,EACD,KAAM,EAAE,AAAC,EACT,qBAAsB,EAAE,MAAO,EAC/B,aAAc,EAAE,KAAM,EACtB,QAAS,EAAE,GAAI,EAEjB,aAAc,EACZ,OAAQ,EAAE,KAAM,EAElB,KAAM,EACJ,KAAM,EAAE,AAAC,EAEX,GAAI,EACF,KAAM,EAAE,AAAC,EAEX,OAAQ,EACN,KAAM,EAAE,AAAC,EACT,KAAM,EAAE,AAAC,EACT,MAAO,EAAE,AAAC,EAEZ,IAAK,EACH,KAAM,EAAE,MAAO,EAEjB,KAAM,EACJ,KAAM,EAAE,AAAC,EACT,WAAY,EAAE,GAAI,EAClB,MAAO,EAAE,AAAC,EACV,UAAW,EAAE,KAAM,EAErB,2BAA+B,EAC7B,QAAS,EAAE,GAAI,EACf,KAAM,EAAE,AAAC,EACT,aAAc,EAAE,OAAQ,EACxB,cAAe,EAAE,KAAM,EAEzB,WAAa,EACX,UAAW,EAAE,KAAM,EAErB,mEAAuE,EACrE,KAAM,EAAE,MAAO,EACf,iBAAkB,EAAE,KAAM,EAC1B,QAAS,EAAE,MAAO,EAEpB,+BAAiC,EAC/B,KAAM,EAAE,MAAO,EAEjB,yCAA2C,EACzC,SAAU,EAAE,SAAU,EACtB,MAAO,EAAE,AAAC,EACV,KAAM,EAAE,GAAI,EACZ,MAAO,EAAE,GAAI,EAEf,mBAAoB,EAClB,iBAAkB,EAAE,QAAS,EAC7B,cAAe,EAAE,UAAW,EAC5B,iBAAkB,EAAE,UAAW,EAC/B,SAAU,EAAE,UAAW,EAEzB,iGAAmG,EACjG,iBAAkB,EAAE,GAAI,EAE1B,+CAAiD,EAC/C,KAAM,EAAE,AAAC,EACT,MAAO,EAAE,AAAC,EAEZ,OAAQ,EACN,OAAQ,EAAE,GAAI,EACd,aAAc,EAAE,EAAG,EACnB,KAAM,EAAE,OAAQ,EAElB,IAAK,EACH,cAAe,EAAE,OAAQ,EACzB,aAAc,EAAE,AAAC,EAEnB,CAAE,EACA,aAAc,EAAE,EAAG,EAErB,WAAY,EACV,KAAM,EAAE,MAAO,EACf,SAAU,EAAE,GAAI,EAChB,IAAK,EAAE,GAAK,EACZ,MAAO,EAAE,MAAO,EAElB,EAAG,EACD,MAAO,EAAE,IAAK,EACd,KAAM,EAAE,AAAC,EACT,UAAW,EAAE,KAAM,EACnB,OAAQ,EAAE,KAAM,EAChB,eAAgB,EAAE,UAAW,EAC7B,gBAAiB,EAAE,QAAS,EAC5B,SAAU,EAAE,GAAI,EAChB,QAAS,EAAE,EAAG,EACd,WAAY,EAAE,AAAC,EAEjB,KAAM,EACJ,MAAO,EAAE,GAAI,EAEf,MAAO,EACL,MAAO,EAAE,cAAe,EACxB,SAAU,EAAE,KAAM,EAEpB,cAAe,EACb,KAAM,EAAE,AAAC,EACT,GAAI,EAAE,YAAa,EACnB,KAAM,EAAE,EAAG,EACX,KAAM,EAAE,GAAI,EACZ,OAAQ,EAAE,KAAM,EAChB,MAAO,EAAE,AAAC,EACV,OAAQ,EAAE,OAAQ,EAClB,IAAK,EAAE,EAAG,EAEZ,+DAAiE,EAC/D,GAAI,EAAE,GAAI,EACV,KAAM,EAAE,GAAI,EACZ,KAAM,EAAE,AAAC,EACT,OAAQ,EAAE,MAAO,EACjB,OAAQ,EAAE,KAAM,EAChB,IAAK,EAAE,GAAI,EAEb,SAAU,EACR,SAAU,EAAE,KAAM,EAEpB,QAAS,EACP,OAAQ,EAAE,OAAQ,EAEpB,QAAU,EACR,QAAS,EAAE,GAAI,EAEjB,WAAY,EACV,gBAAmB,EACjB,SAAU,EAAE,cAAe,EAC7B,AAAC,EACC,SAAU,EAAE,cAAe,EAC3B,UAAW,EAAE,cAAe,EAC5B,KAAM,EAAE,cAAe,EACvB,SAAU,EAAE,cAAe,EAC7B,UAAY,EACV,cAAe,EAAE,QAAS,EAC5B,0DAA6D,EAC3D,MAAO,EAAE,CAAE,EACb,aAAe,EACb,gBAAiB,EAAE,IAAK,EAC1B,IAAK,EACH,MAAO,EAAE,iBAAkB,EAC7B,KAAO,EACL,gBAAiB,EAAE,IAAK,EAC1B,EAAG,EACD,QAAS,EAAE,cAAe,QAE1B,KAAM,EAAE,IAAK,EAEf,8CAAS,EACP,MAAO,EAAE,AAAC,EACV,KAAM,EAAE,AAAC,EACX,4CAAM,EACJ,eAAgB,EAAE,IAAK,GChM3B,ykDAAY,EACV,qBAAsB,EAAE,UAAW,EAqDrC,QAAS,EARP,IAAK,EAAE,AAAC,EACR,+BAAS,EAEP,MAAO,EAAE,IAAK,EACd,MAAO,EAAE,CAAE,EACb,cAAO,EACL,IAAK,EAAE,GAAI;;;GC1Gf,UAUC,CATC,WAAW,CAAE,aAAa,CAC1B,GAAG,CAAE,+CAAgE,CACrE,GAAG,CAAE,sSAAmG,CAKxG,WAAW,CAAE,MAAM,CACnB,UAAU,CAAE,MAAM,CCTpB,kfAAmB,CACjB,OAAO,CAAE,YAAY,CACrB,IAAI,CAAE,uCAAuC,CAC7C,SAAS,CAAE,OAAO,CAClB,cAAc,CAAE,IAAI,CACpB,sBAAsB,CAAE,WAAW,CACnC,uBAAuB,CAAE,SAAS,CCLpC,MAAsB,CACpB,SAAS,CAAE,SAAS,CACpB,WAAW,CAAE,MAAS,CACtB,cAAc,CAAE,IAAI,CAEtB,MAAsB,CAAE,SAAS,CAAE,GAAG,CACtC,MAAsB,CAAE,SAAS,CAAE,GAAG,CACtC,MAAsB,CAAE,SAAS,CAAE,GAAG,CACtC,MAAsB,CAAE,SAAS,CAAE,GAAG,CCVtC,MAAsB,CACpB,KAAK,CAAE,SAAW,CAClB,UAAU,CAAE,MAAM,CCDpB,MAAsB,CACpB,YAAY,CAAE,CAAC,CACf,WAAW,CCIU,SAAS,CDH9B,eAAe,CAAE,IAAI,CACrB,SAAK,CAAE,QAAQ,CAAE,QAAQ,CAE3B,MAAsB,CACpB,QAAQ,CAAE,QAAQ,CAClB,IAAI,CAAE,UAAa,CACnB,KAAK,CCHgB,SAAS,CDI9B,GAAG,CAAE,SAAU,CACf,UAAU,CAAE,MAAM,CAClB,YAAuB,CACrB,IAAI,CAAE,UAA0B,CEbpC,UAA0B,CACxB,OAAO,CAAE,gBAAgB,CACzB,MAAM,CAAE,iBAA4B,CACpC,aAAa,CAAE,IAAI,CAGrB,WAAY,CAAE,KAAK,CAAE,KAAK,CAC1B,UAAW,CAAE,KAAK,CAAE,IAAI,CAGtB,kpBAAY,CAAE,YAAY,CAAE,IAAI,CAChC,kqBAAa,CAAE,WAAW,CAAE,IAAI,CCXlC,QAAwB,CACtB,iBAAiB,CAAE,0BAA0B,CACrC,SAAS,CAAE,0BAA0B,CAG/C,0BASC,CARC,EAAG,CACD,iBAAiB,CAAE,YAAY,CACvB,SAAS,CAAE,YAAY,CAEjC,IAAK,CACH,iBAAiB,CAAE,cAAc,CACzB,SAAS,CAAE,cAAc,EAIrC,kBASC,CARC,EAAG,CACD,iBAAiB,CAAE,YAAY,CACvB,SAAS,CAAE,YAAY,CAEjC,IAAK,CACH,iBAAiB,CAAE,cAAc,CACzB,SAAS,CAAE,cAAc,ECvBrC,aAA8B,CCU5B,MAAM,CAAE,wDAAmE,CAC3E,iBAAiB,CAAE,aAAgB,CAC/B,aAAa,CAAE,aAAgB,CAC3B,SAAS,CAAE,aAAgB,CDZrC,cAA8B,CCS5B,MAAM,CAAE,wDAAmE,CAC3E,iBAAiB,CAAE,cAAgB,CAC/B,aAAa,CAAE,cAAgB,CAC3B,SAAS,CAAE,cAAgB,CDXrC,cAA8B,CCQ5B,MAAM,CAAE,wDAAmE,CAC3E,iBAAiB,CAAE,cAAgB,CAC/B,aAAa,CAAE,cAAgB,CAC3B,SAAS,CAAE,cAAgB,CDTrC,mBAAmC,CCajC,MAAM,CAAE,wDAAmE,CAC3E,iBAAiB,CAAE,YAAoB,CACnC,aAAa,CAAE,YAAoB,CAC/B,SAAS,CAAE,YAAoB,CDfzC,iBAAmC,CCYjC,MAAM,CAAE,wDAAmE,CAC3E,iBAAiB,CAAE,YAAoB,CACnC,aAAa,CAAE,YAAoB,CAC/B,SAAS,CAAE,YAAoB,CDVzC,+GAIuC,CACrC,MAAM,CAAE,IAAI,CEfd,SAAyB,CACvB,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,YAAY,CACrB,KAAK,CAAE,GAAG,CACV,MAAM,CAAE,GAAG,CACX,WAAW,CAAE,GAAG,CAChB,cAAc,CAAE,MAAM,CAExB,yBAAyD,CACvD,QAAQ,CAAE,QAAQ,CAClB,IAAI,CAAE,CAAC,CACP,KAAK,CAAE,IAAI,CACX,UAAU,CAAE,MAAM,CAEpB,YAA4B,CAAE,WAAW,CAAE,OAAO,CAClD,YAA4B,CAAE,SAAS,CAAE,GAAG,CAC5C,WAA2B,CAAE,KAAK,CLXZ,IAAI,CML1B,gBAAgC,CAAE,OAAO,CNwP1B,GAAO,CMvPtB,gBAAgC,CAAE,OAAO,CNkV1B,GAAO,CMjVtB,qCAAiC,CAAE,OAAO,CNyZ1B,GAAO,CMxZvB,qBAAqC,CAAE,OAAO,CN2K1B,GAAO,CM1K3B,gBAAgC,CAAE,OAAO,CNqQ1B,GAAO,CMpQtB,eAA+B,CAAE,OAAO,CNkc1B,GAAO,CMjcrB,iBAAiC,CAAE,OAAO,CNsc1B,GAAO,CMrcvB,eAA+B,CAAE,OAAO,CN0gB1B,GAAO,CMzgBrB,eAA+B,CAAE,OAAO,CN+M1B,GAAO,CM9MrB,mBAAmC,CAAE,OAAO,CN8d1B,GAAO,CM7dzB,aAA6B,CAAE,OAAO,CN4d1B,GAAO,CM3dnB,kBAAkC,CAAE,OAAO,CN6d1B,GAAO,CM5dxB,gBAAgC,CAAE,OAAO,CN+F1B,GAAO,CM9FtB,mDAEgC,CAAE,OAAO,CNge1B,GAAO,CM/dtB,sBAAsC,CAAE,OAAO,CN6Y1B,GAAO,CM5Y5B,uBAAuC,CAAE,OAAO,CN2Y1B,GAAO,CM1Y7B,oBAAoC,CAAE,OAAO,CNqW1B,GAAO,CMpW1B,iBAAiC,CAAE,OAAO,CNwZ1B,GAAO,CMvZvB,8BAC8B,CAAE,OAAO,CNmH1B,GAAO,CMlHpB,kBAAkC,CAAE,OAAO,CNoe1B,GAAO,CMnexB,iCAA+B,CAAE,OAAO,CNqP1B,GAAO,CMpPrB,iBAAiC,CAAE,OAAO,CNmL1B,GAAO,CMlLvB,kBAAkC,CAAE,OAAO,CNqG1B,GAAO,CMpGxB,eAA+B,CAAE,OAAO,CNqX1B,GAAO,CMpXrB,uHAAmC,CAAE,OAAO,CNyI1B,GAAO,CMxIzB,8BAA8C,CAAE,OAAO,CNG1B,GAAO,CMFpC,4BAA4C,CAAE,OAAO,CNK1B,GAAO,CMJlC,gBAAgC,CAAE,OAAO,CNmP1B,GAAO,CMlPtB,wBAAwC,CAAE,OAAO,CNkV1B,GAAO,CMjV9B,yCACiC,CAAE,OAAO,CNyW1B,GAAO,CMxWvB,kBAAkC,CAAE,OAAO,CNoW1B,GAAO,CMnWxB,mBAAmC,CAAE,OAAO,CNiR1B,GAAO,CMhRzB,eAA+B,CAAE,OAAO,CNoR1B,GAAO,CMnRrB,eAA+B,CAAE,OAAO,CNsL1B,GAAO,CMrLrB,qBAAqC,CAAE,OAAO,CNkO1B,GAAO,CMjO3B,qBAAqC,CAAE,OAAO,CNkf1B,GAAO,CMjf3B,sBAAsC,CAAE,OAAO,CNgf1B,GAAO,CM/e5B,oBAAoC,CAAE,OAAO,CNif1B,GAAO,CMhf1B,iBAAiC,CAAE,OAAO,CNiV1B,GAAO,CMhVvB,kBAAkC,CAAE,OAAO,CNU1B,GAAO,CMTxB,cAA8B,CAAE,OAAO,CNkb1B,GAAO,CMjbpB,eAA+B,CAAE,OAAO,CNkb1B,GAAO,CMjbrB,iCAA+B,CAAE,OAAO,CNyB1B,GAAO,CMxBrB,mBAAmC,CAAE,OAAO,CNyB1B,GAAO,CMxBzB,gBAAgC,CAAE,OAAO,CNwU1B,GAAO,CMvUtB,iBAAiC,CAAE,OAAO,CNqC1B,GAAO,CMpCvB,eAA+B,CAAE,OAAO,CNoL1B,GAAO,CMnLrB,eAA+B,CAAE,OAAO,CNiB1B,GAAO,CMhBrB,iBAAiC,CAAE,OAAO,CNqO1B,GAAO,CMpOvB,sBAAsC,CAAE,OAAO,CN+a1B,GAAO,CM9a5B,qBAAqC,CAAE,OAAO,CN+a1B,GAAO,CM9a3B,qBAAqC,CAAE,OAAO,CN3C1B,GAAO,CM4C3B,uBAAuC,CAAE,OAAO,CN9C1B,GAAO,CM+C7B,sBAAsC,CAAE,OAAO,CN5C1B,GAAO,CM6C5B,wBAAwC,CAAE,OAAO,CN/C1B,GAAO,CMgD9B,eAA+B,CAAE,OAAO,CNwP1B,GAAO,CMvPrB,oCACkC,CAAE,OAAO,CN0R1B,GAAO,CMzRxB,iBAAiC,CAAE,OAAO,CNoN1B,GAAO,CMnNvB,uBAAuC,CAAE,OAAO,CNqd1B,GAAO,CMpd7B,sDAEoC,CAAE,OAAO,CNsS1B,GAAO,CMrS1B,iBAAiC,CAAE,OAAO,CN+R1B,GAAO,CM9RvB,qBAAqC,CAAE,OAAO,CN+P1B,GAAO,CM9P3B,iBAAiC,CAAE,OAAO,CN7D1B,GAAO,CM8DvB,eAA+B,CAAE,OAAO,CN4a1B,GAAO,CM3arB,0CAC0C,CAAE,OAAO,CN4R1B,GAAO,CM3RhC,yBAAyC,CAAE,OAAO,CN2V1B,GAAO,CM1V/B,yBAAyC,CAAE,OAAO,CNqC1B,GAAO,CMpC/B,iBAAiC,CAAE,OAAO,CNlC1B,GAAO,CMmCvB,wBAAwC,CAAE,OAAO,CNmY1B,GAAO,CMlY9B,wBAAwC,CAAE,OAAO,CNkH1B,GAAO,CMjH9B,mBAAmC,CAAE,OAAO,CN9B1B,GAAO,CM+BzB,eAA+B,CAAE,OAAO,CNgS1B,GAAO,CM/RrB,gBAAgC,CAAE,OAAO,CN+Q1B,GAAO,CM9QtB,eAA+B,CAAE,OAAO,CNiY1B,GAAO,CMhYrB,kBAAkC,CAAE,OAAO,CNqJ1B,GAAO,CMpJxB,uBAAuC,CAAE,OAAO,CN6G1B,GAAO,CM5G7B,uBAAuC,CAAE,OAAO,CN4X1B,GAAO,CM3X7B,gBAAgC,CAAE,OAAO,CNoF1B,GAAO,CMnFtB,uBAAuC,CAAE,OAAO,CN+B1B,GAAO,CM9B7B,wBAAwC,CAAE,OAAO,CN+B1B,GAAO,CM9B9B,sBAAsC,CAAE,OAAO,CN4R1B,GAAO,CM3R5B,uBAAuC,CAAE,OAAO,CNkP1B,GAAO,CMjP7B,8FAAuC,CAAE,OAAO,CNsZ1B,GAAO,CMrZ7B,+FAAuC,CAAE,OAAO,CNiB1B,GAAO,CMhB7B,0BAA0C,CAAE,OAAO,CNiS1B,GAAO,CMhShC,sBAAsC,CAAE,OAAO,CNuL1B,GAAO,CMtL5B,qBAAqC,CAAE,OAAO,CNuD1B,GAAO,CMtD3B,yBAAyC,CAAE,OAAO,CNkZ1B,GAAO,CMjZ/B,yBAAyC,CAAE,OAAO,CNa1B,GAAO,CMZ/B,cAA8B,CAAE,OAAO,CNhD1B,GAAO,CMiDpB,qBAAqC,CAAE,OAAO,CN5D1B,GAAO,CM6D3B,sBAAsC,CAAE,OAAO,CN5D1B,GAAO,CM6D5B,mBAAmC,CAAE,OAAO,CN5D1B,GAAO,CM6DzB,qBAAqC,CAAE,OAAO,CNhE1B,GAAO,CMiE3B,wCACgC,CAAE,OAAO,CNyT1B,GAAO,CMxTtB,iBAAiC,CAAE,OAAO,CN+E1B,GAAO,CM9EvB,mBAAmC,CAAE,OAAO,CNuC1B,GAAO,CMtCzB,eAA+B,CAAE,OAAO,CNyQ1B,GAAO,CMxQrB,gBAAgC,CAAE,OAAO,CN+N1B,GAAO,CM9NtB,mBAAmC,CAAE,OAAO,CN/D1B,GAAO,CMgEzB,gNAA6C,CAAE,OAAO,CNwE1B,GAAO,CMvEnC,eAA+B,CAAE,OAAO,CNmI1B,GAAO,CMlIrB,eAA+B,CAAE,OAAO,CNqL1B,GAAO,CMpLrB,iCAA+B,CAAE,OAAO,CNyG1B,GAAO,CMxGrB,cAA8B,CAAE,OAAO,CNyE1B,GAAO,CMxEpB,oBAAoC,CAAE,OAAO,CNyE1B,GAAO,CMxE1B,kDAC+C,CAAE,OAAO,CNkE1B,GAAO,CMjErC,gBAAgC,CAAE,OAAO,CNyP1B,GAAO,CMxPtB,mBAAmC,CAAE,OAAO,CNlC1B,GAAO,CMmCzB,iBAAiC,CAAE,OAAO,CN0Q1B,GAAO,CMzQvB,kBAAkC,CAAE,OAAO,CNmB1B,GAAO,CMlBxB,iBAAiC,CAAE,OAAO,CNqM1B,GAAO,CMpMvB,qBAAqC,CAAE,OAAO,CNH1B,GAAO,CMI3B,uBAAuC,CAAE,OAAO,CNP1B,GAAO,CMQ7B,kBAAkC,CAAE,OAAO,CNiR1B,GAAO,CMhRxB,wBAAwC,CAAE,OAAO,CN2S1B,GAAO,CM1S9B,iBAAiC,CAAE,OAAO,CNoG1B,GAAO,CMnGvB,sBAAsC,CAAE,OAAO,CNqG1B,GAAO,CMpG5B,mBAAmC,CAAE,OAAO,CNpF1B,GAAO,CMqFzB,mBAAmC,CAAE,OAAO,CNtF1B,GAAO,CMuFzB,2CACoC,CAAE,OAAO,CNhF1B,GAAO,CMiF1B,yBAAyC,CAAE,OAAO,CNkY1B,GAAO,CMjY/B,0BAA0C,CAAE,OAAO,CNyD1B,GAAO,CMxDhC,uBAAuC,CAAE,OAAO,CN/C1B,GAAO,CMgD7B,cAA8B,CAAE,OAAO,CNsJ1B,GAAO,CMrJpB,gCAC+B,CAAE,OAAO,CNA1B,GAAO,CMCrB,mBAAmC,CAAE,OAAO,CNG1B,GAAO,CMFzB,sBAAsC,CAAE,OAAO,CNiW1B,GAAO,CMhW5B,wBAAwC,CAAE,OAAO,CN+V1B,GAAO,CM9V9B,oBAAoC,CAAE,OAAO,CN2T1B,GAAO,CM1T1B,kBAAkC,CAAE,OAAO,CN4H1B,GAAO,CM3HxB,mBAAmC,CAAE,OAAO,CN2R1B,GAAO,CM1RzB,0BAA0C,CAAE,OAAO,CNiK1B,GAAO,CMhKhC,qBAAqC,CAAE,OAAO,CNwV1B,GAAO,CMvV3B,wBAAwC,CAAE,OAAO,CNsC1B,GAAO,CMrC9B,kBAAkC,CAAE,OAAO,CNsR1B,GAAO,CMrRxB,iBAAiC,CAAE,OAAO,CNyW1B,GAAO,CMxWvB,wBAAwC,CAAE,OAAO,CNiG1B,GAAO,CMhG9B,iBAAiC,CAAE,OAAO,CNyX1B,GAAO,CMxXvB,kBAAkC,CAAE,OAAO,CN+I1B,GAAO,CM9IxB,gBAAgC,CAAE,OAAO,CN6M1B,GAAO,CM5MtB,mBAAmC,CAAE,OAAO,CN2S1B,GAAO,CM1SzB,qBAAqC,CAAE,OAAO,CNjF1B,GAAO,CMkF3B,uBAAuC,CAAE,OAAO,CN2M1B,GAAO,CM1M7B,kBAAkC,CAAE,OAAO,CNyW1B,GAAO,CMxWxB,mBAAmC,CAAE,OAAO,CNgC1B,GAAO,CM/BzB,qCAAiC,CAAE,OAAO,CNsF1B,GAAO,CMrFvB,iBAAiC,CAAE,OAAO,CN6W1B,GAAO,CM5WvB,sBAAsC,CAAE,OAAO,CNb1B,GAAO,CMc5B,cAA8B,CAAE,OAAO,CNmP1B,GAAO,CMlPpB,gBAAgC,CAAE,OAAO,CNoG1B,GAAO,CMnGtB,mBAAmC,CAAE,OAAO,CNpF1B,GAAO,CMqFzB,eAA+B,CAAE,OAAO,CN1G1B,GAAO,CM2GrB,sBAAsC,CAAE,OAAO,CN7D1B,GAAO,CM8D5B,uBAAuC,CAAE,OAAO,CN8F1B,GAAO,CM7F7B,sBAAsC,CAAE,OAAO,CN4F1B,GAAO,CM3F5B,oBAAoC,CAAE,OAAO,CN6F1B,GAAO,CM5F1B,sBAAsC,CAAE,OAAO,CNyF1B,GAAO,CMxF5B,2DAA4C,CAAE,OAAO,CN5I1B,GAAO,CM6IlC,6DAA6C,CAAE,OAAO,CNxI1B,GAAO,CMyInC,0BAA0C,CAAE,OAAO,CNxI1B,GAAO,CMyIhC,4BAA4C,CAAE,OAAO,CNhJ1B,GAAO,CMiJlC,gBAAgC,CAAE,OAAO,CN2E1B,GAAO,CM1EtB,iBAAiC,CAAE,OAAO,CNqX1B,GAAO,CMpXvB,gBAAgC,CAAE,OAAO,CNgT1B,GAAO,CM/StB,iBAAiC,CAAE,OAAO,CNuC1B,GAAO,CMtCvB,oBAAoC,CAAE,OAAO,CNxG1B,GAAO,CMyG1B,qBAAqC,CAAE,OAAO,CNzI1B,GAAO,CM0I3B,iCACgC,CAAE,OAAO,CN8V1B,GAAO,CM7VtB,kDAC+B,CAAE,OAAO,CNwH1B,GAAO,CMvHrB,gBAAgC,CAAE,OAAO,CNxD1B,GAAO,CMyDtB,gBAAgC,CAAE,OAAO,CNsC1B,GAAO,CMrCtB,kCACmC,CAAE,OAAO,CN+N1B,GAAO,CM9NzB,kCACkC,CAAE,OAAO,CNyB1B,GAAO,CMxBxB,oBAAoC,CAAE,OAAO,CN8J1B,GAAO,CM7J1B,mCACmC,CAAE,OAAO,CNiC1B,GAAO,CMhCzB,iBAAiC,CAAE,OAAO,CNkQ1B,GAAO,CMjQvB,qDAE+B,CAAE,OAAO,CN9I1B,GAAO,CM+IrB,kBAAkC,CAAE,OAAO,CNiH1B,GAAO,CMhHxB,kBAAkC,CAAE,OAAO,CN+G1B,GAAO,CM9GxB,wBAAwC,CAAE,OAAO,CN4Q1B,GAAO,CM3Q9B,oBAAoC,CAAE,OAAO,CNgU1B,GAAO,CM/T1B,gBAAgC,CAAE,OAAO,CNkR1B,GAAO,CMjRtB,gBAAgC,CAAE,OAAO,CNmH1B,GAAO,CMlHtB,gBAAgC,CAAE,OAAO,CNmT1B,GAAO,CMlTtB,oBAAoC,CAAE,OAAO,CNgK1B,GAAO,CM/J1B,2BAA2C,CAAE,OAAO,CNgK1B,GAAO,CM/JjC,6BAA6C,CAAE,OAAO,CN8C1B,GAAO,CM7CnC,sBAAsC,CAAE,OAAO,CN4C1B,GAAO,CM3C5B,gBAAgC,CAAE,OAAO,CNgI1B,GAAO,CM/HtB,wEAAqC,CAAE,OAAO,CNxH1B,GAAO,CMyH3B,mBAAmC,CAAE,OAAO,CNlH1B,GAAO,CMmHzB,qBAAqC,CAAE,OAAO,CNzH1B,GAAO,CM0H3B,sBAAsC,CAAE,OAAO,CNzH1B,GAAO,CM0H5B,kBAAkC,CAAE,OAAO,CN3E1B,GAAO,CM4ExB,mCAC+B,CAAE,OAAO,CN4N1B,GAAO,CM3NrB,yCACoC,CAAE,OAAO,CNgO1B,GAAO,CM/N1B,sCACmC,CAAE,OAAO,CN6N1B,GAAO,CM5NzB,mBAAmC,CAAE,OAAO,CN/C1B,GAAO,CMgDzB,mBAAmC,CAAE,OAAO,CNmF1B,GAAO,CMlFzB,sCAC+B,CAAE,OAAO,CN0S1B,GAAO,CMzSrB,iCACgC,CAAE,OAAO,CNW1B,GAAO,CMVtB,0CACqC,CAAE,OAAO,CN0P1B,GAAO,CMzP3B,oBAAoC,CAAE,OAAO,CNxF1B,GAAO,CMyF1B,qBAAqC,CAAE,OAAO,CNvF1B,GAAO,CMwF3B,gCAC+B,CAAE,OAAO,CNlK1B,GAAO,CMmKrB,kBAAkC,CAAE,OAAO,CNoM1B,GAAO,CMnMxB,mBAAmC,CAAE,OAAO,CN8R1B,GAAO,CM7RzB,qCACoC,CAAE,OAAO,CN9G1B,GAAO,CM+G1B,sBAAsC,CAAE,OAAO,CNiE1B,GAAO,CMhE5B,mBAAmC,CAAE,OAAO,CN1D1B,GAAO,CM2DzB,yBAAyC,CAAE,OAAO,CN7G1B,GAAO,CM8G/B,uBAAuC,CAAE,OAAO,CN7G1B,GAAO,CM8G7B,kBAAkC,CAAE,OAAO,CNkS1B,GAAO,CMjSxB,sBAAsC,CAAE,OAAO,CNgO1B,GAAO,CM/N5B,mBAAmC,CAAE,OAAO,CNqO1B,GAAO,CMpOzB,iBAAiC,CAAE,OAAO,CNxL1B,GAAO,CMyLvB,iBAAiC,CAAE,OAAO,CN7G1B,GAAO,CM8GvB,kBAAkC,CAAE,OAAO,CN3F1B,GAAO,CM4FxB,sBAAsC,CAAE,OAAO,CNpC1B,GAAO,CMqC5B,qBAAqC,CAAE,OAAO,CNzK1B,GAAO,CM0K3B,qBAAqC,CAAE,OAAO,CNqB1B,GAAO,CMpB3B,oBAAoC,CAAE,OAAO,CN3O1B,GAAO,CM4O1B,iBAAiC,CAAE,OAAO,CN4E1B,GAAO,CM3EvB,sBAAsC,CAAE,OAAO,CNxD1B,GAAO,CMyD5B,eAA+B,CAAE,OAAO,CNrM1B,GAAO,CMsMrB,mBAAmC,CAAE,OAAO,CNG1B,GAAO,CMFzB,sBAAsC,CAAE,OAAO,CNuH1B,GAAO,CMtH5B,4BAA4C,CAAE,OAAO,CN5O1B,GAAO,CM6OlC,6BAA6C,CAAE,OAAO,CN5O1B,GAAO,CM6OnC,0BAA0C,CAAE,OAAO,CN5O1B,GAAO,CM6OhC,4BAA4C,CAAE,OAAO,CNhP1B,GAAO,CMiPlC,qBAAqC,CAAE,OAAO,CN5O1B,GAAO,CM6O3B,sBAAsC,CAAE,OAAO,CN5O1B,GAAO,CM6O5B,mBAAmC,CAAE,OAAO,CN5O1B,GAAO,CM6OzB,qBAAqC,CAAE,OAAO,CNhP1B,GAAO,CMiP3B,kBAAkC,CAAE,OAAO,CNxG1B,GAAO,CMyGxB,iBAAiC,CAAE,OAAO,CNyB1B,GAAO,CMxBvB,iBAAiC,CAAE,OAAO,CNmN1B,GAAO,CMlNvB,yCACiC,CAAE,OAAO,CNmE1B,GAAO,CMlEvB,mBAAmC,CAAE,OAAO,CNlJ1B,GAAO,CMmJzB,qBAAqC,CAAE,OAAO,CNiH1B,GAAO,CMhH3B,sBAAsC,CAAE,OAAO,CNiH1B,GAAO,CMhH5B,kBAAkC,CAAE,OAAO,CNiL1B,GAAO,CMhLxB,iBAAiC,CAAE,OAAO,CNvJ1B,GAAO,CMwJvB,sCACgC,CAAE,OAAO,CNyH1B,GAAO,CMxHtB,qBAAqC,CAAE,OAAO,CN9B1B,GAAO,CM+B3B,mBAAmC,CAAE,OAAO,CNjD1B,GAAO,CMkDzB,wBAAwC,CAAE,OAAO,CNhD1B,GAAO,CMiD9B,kBAAkC,CAAE,OAAO,CN2J1B,GAAO,CM1JxB,kBAAkC,CAAE,OAAO,CN9C1B,GAAO,CM+CxB,gBAAgC,CAAE,OAAO,CN+C1B,GAAO,CM9CtB,kBAAkC,CAAE,OAAO,CN9C1B,GAAO,CM+CxB,qBAAqC,CAAE,OAAO,CNI1B,GAAO,CMH3B,iBAAiC,CAAE,OAAO,CN9D1B,GAAO,CM+DvB,yBAAyC,CAAE,OAAO,CNhE1B,GAAO,CMiE/B,mBAAmC,CAAE,OAAO,CNsM1B,GAAO,CMrMzB,eAA+B,CAAE,OAAO,CN1J1B,GAAO,CM2JrB,8CACoC,CAAE,OAAO,CN4G1B,GAAO,CM3G1B,2EAEsC,CAAE,OAAO,CNwK1B,GAAO,CMvK5B,yBAAyC,CAAE,OAAO,CNmB1B,GAAO,CMlB/B,eAA+B,CAAE,OAAO,CNjJ1B,GAAO,CMkJrB,oBAAoC,CAAE,OAAO,CNjK1B,GAAO,CMkK1B,yCACuC,CAAE,OAAO,CN9L1B,GAAO,CM+L7B,mBAAmC,CAAE,OAAO,CNmF1B,GAAO,CMlFzB,eAA+B,CAAE,OAAO,CNvB1B,GAAO,CMwBrB,sBAAsC,CAAE,OAAO,CNvH1B,GAAO,CMwH5B,sBAAsC,CAAE,OAAO,CN6K1B,GAAO,CM5K5B,oBAAoC,CAAE,OAAO,CNyK1B,GAAO,CMxK1B,iBAAiC,CAAE,OAAO,CN9H1B,GAAO,CM+HvB,uBAAuC,CAAE,OAAO,CN0E1B,GAAO,CMzE7B,qBAAqC,CAAE,OAAO,CNwB1B,GAAO,CMvB3B,2BAA2C,CAAE,OAAO,CNwB1B,GAAO,CMvBjC,iBAAiC,CAAE,OAAO,CNqH1B,GAAO,CMpHvB,qBAAqC,CAAE,OAAO,CN9N1B,GAAO,CM+N3B,4BAA4C,CAAE,OAAO,CN1F1B,GAAO,CM2FlC,iBAAiC,CAAE,OAAO,CN2F1B,GAAO,CM1FvB,iBAAiC,CAAE,OAAO,CNc1B,GAAO,CMbvB,8BAA8C,CAAE,OAAO,CNtM1B,GAAO,CMuMpC,+BAA+C,CAAE,OAAO,CNtM1B,GAAO,CMuMrC,4BAA4C,CAAE,OAAO,CNtM1B,GAAO,CMuMlC,8BAA8C,CAAE,OAAO,CN1M1B,GAAO,CM2MpC,gBAAgC,CAAE,OAAO,CN7C1B,GAAO,CM8CtB,eAA+B,CAAE,OAAO,CNtK1B,GAAO,CMuKrB,iBAAiC,CAAE,OAAO,CN9S1B,GAAO,CM+SvB,qBAAqC,CAAE,OAAO,CN+M1B,GAAO,CM9M3B,mBAAmC,CAAE,OAAO,CN/O1B,GAAO,CMgPzB,qBAAqC,CAAE,OAAO,CNtJ1B,GAAO,CMuJ3B,qBAAqC,CAAE,OAAO,CNtJ1B,GAAO,CMuJ3B,qBAAqC,CAAE,OAAO,CNmF1B,GAAO,CMlF3B,sBAAsC,CAAE,OAAO,CN6C1B,GAAO,CM5C5B,iBAAiC,CAAE,OAAO,CN0K1B,GAAO,CMzKvB,uBAAuC,CAAE,OAAO,CNO1B,GAAO,CMN7B,wIAAyC,CAAE,OAAO,CNO1B,GAAO,CMN/B,mBAAmC,CAAE,OAAO,CN/B1B,GAAO,CMgCzB,qBAAqC,CAAE,OAAO,CNjC1B,GAAO,CMkC3B,uBAAuC,CAAE,OAAO,CN3N1B,GAAO,CM4N7B,wBAAwC,CAAE,OAAO,CNyB1B,GAAO,CMxB9B,+BAA+C,CAAE,OAAO,CNlJ1B,GAAO,CMmJrC,uBAAuC,CAAE,OAAO,CNuF1B,GAAO,CMtF7B,kBAAkC,CAAE,OAAO,CN9L1B,GAAO,CM+LxB,qDAC8C,CAAE,OAAO,CNnP1B,GAAO,CMoPpC,iDAC4C,CAAE,OAAO,CNlP1B,GAAO,CMmPlC,uDAC+C,CAAE,OAAO,CNrP1B,GAAO,CMsPrC,8BAC8B,CAAE,OAAO,CNpK1B,GAAO,CMqKpB,cAA8B,CAAE,OAAO,CNzG1B,GAAO,CM0GpB,gCAC8B,CAAE,OAAO,CNwL1B,GAAO,CMvLpB,+BAC8B,CAAE,OAAO,CNrE1B,GAAO,CMsEpB,2DAG8B,CAAE,OAAO,CNnE1B,GAAO,CMoEpB,iDAE8B,CAAE,OAAO,CNqD1B,GAAO,CMpDpB,6BAC8B,CAAE,OAAO,CNpE1B,GAAO,CMqEpB,iCAC8B,CAAE,OAAO,CN1R1B,GAAO,CM2RpB,eAA+B,CAAE,OAAO,CNlK1B,GAAO,CMmKrB,oBAAoC,CAAE,OAAO,CNtJ1B,GAAO,CMuJ1B,yBAAyC,CAAE,OAAO,CN4E1B,GAAO,CM3E/B,0BAA0C,CAAE,OAAO,CN4E1B,GAAO,CM3EhC,0BAA0C,CAAE,OAAO,CN4E1B,GAAO,CM3EhC,2BAA2C,CAAE,OAAO,CN4E1B,GAAO,CM3EjC,2BAA2C,CAAE,OAAO,CN+E1B,GAAO,CM9EjC,4BAA4C,CAAE,OAAO,CN+E1B,GAAO,CM9ElC,oBAAoC,CAAE,OAAO,CN+H1B,GAAO,CM9H1B,sBAAsC,CAAE,OAAO,CN2H1B,GAAO,CM1H5B,yBAAyC,CAAE,OAAO,CN4L1B,GAAO,CM3L/B,kBAAkC,CAAE,OAAO,CNyL1B,GAAO,CMxLxB,eAA+B,CAAE,OAAO,CNmL1B,GAAO,CMlLrB,sBAAsC,CAAE,OAAO,CNmL1B,GAAO,CMlL5B,uBAAuC,CAAE,OAAO,CNuL1B,GAAO,CMtL7B,kBAAkC,CAAE,OAAO,CN/M1B,GAAO,CMgNxB,yBAAyC,CAAE,OAAO,CNgF1B,GAAO,CM/E/B,oBAAoC,CAAE,OAAO,CNjG1B,GAAO,CMkG1B,iBAAiC,CAAE,OAAO,CNxJ1B,GAAO,CMyJvB,cAA8B,CAAE,OAAO,CNhX1B,GAAO,CMiXpB,2CAAoC,CAAE,OAAO,CNzT1B,GAAO,CM0T1B,2BAA2C,CAAE,OAAO,CNzT1B,GAAO,CM0TjC,iBAAiC,CAAE,OAAO,CNqI1B,GAAO,CMpIvB,wBAAwC,CAAE,OAAO,CNqI1B,GAAO,CMpI9B,0BAA0C,CAAE,OAAO,CNrE1B,GAAO,CMsEhC,wBAAwC,CAAE,OAAO,CNnE1B,GAAO,CMoE9B,0BAA0C,CAAE,OAAO,CNtE1B,GAAO,CMuEhC,2BAA2C,CAAE,OAAO,CNtE1B,GAAO,CMuEjC,gBAAgC,CAAE,OAAO,CNxW1B,GAAO,CMyWtB,kBAAkC,CAAE,OAAO,CN8J1B,GAAO,CM7JxB,kBAAkC,CAAE,OAAO,CNpX1B,GAAO,CMqXxB,gBAAgC,CAAE,OAAO,CNnF1B,GAAO,CMoFtB,mBAAmC,CAAE,OAAO,CNjO1B,GAAO,CMkOzB,gBAAgC,CAAE,OAAO,CNsC1B,GAAO,CMrCtB,qBAAqC,CAAE,OAAO,CNhK1B,GAAO,CMiK3B,iBAAiC,CAAE,OAAO,CNmH1B,GAAO,CMlHvB,iBAAiC,CAAE,OAAO,CNxM1B,GAAO,CMyMvB,eAA+B,CAAE,OAAO,CNzE1B,GAAO,CM0ErB,iBAAiC,CAAE,OAAO,CNrJ1B,GAAO,CMsJvB,gBAAgC,CAAE,OAAO,CN2E1B,GAAO,CM1EtB,iBAAiC,CAAE,OAAO,CN7D1B,GAAO,CM8DvB,kBAAkC,CAAE,OAAO,CNpX1B,GAAO,CMqXxB,cAA8B,CAAE,OAAO,CNpU1B,GAAO,CMqUpB,aAA6B,CAAE,OAAO,CNsI1B,GAAO,CMrInB,gBAAgC,CAAE,OAAO,CN2I1B,GAAO,CM1ItB,iBAAiC,CAAE,OAAO,CNX1B,GAAO,CMYvB,oBAAoC,CAAE,OAAO,CN5D1B,GAAO,CM6D1B,yBAAyC,CAAE,OAAO,CNgD1B,GAAO,CM/C/B,+BAA+C,CAAE,OAAO,CNrX1B,GAAO,CMsXrC,8BAA8C,CAAE,OAAO,CNvX1B,GAAO,CMwXpC,qDAC8C,CAAE,OAAO,CN5T1B,GAAO,CM6TpC,uBAAuC,CAAE,OAAO,CNvP1B,GAAO,CMwP7B,qBAAqC,CAAE,OAAO,CNoI1B,GAAO,CMnI3B,uBAAuC,CAAE,OAAO,CNyH1B,GAAO,CMxH7B,sCAC8B,CAAE,OAAO,CNiG1B,GAAO,CMhGpB,wEAAwC,CAAE,OAAO,CNzC1B,GAAO,CM0C9B,wBAAwC,CAAE,OAAO,CN+B1B,GAAO,CM9B9B,gBAAgC,CAAE,OAAO,CNa1B,GAAO,CMZtB,0BAA0C,CAAE,OAAO,CNnP1B,GAAO,CMoPhC,oBAAoC,CAAE,OAAO,CNgI1B,GAAO,CM/H1B,iBAAiC,CAAE,OAAO,CN9E1B,GAAO,CM+EvB,4DAEqC,CAAE,OAAO,CNmG1B,GAAO,CMlG3B,iDACyC,CAAE,OAAO,CN3K1B,GAAO,CM4K/B,gBAAgC,CAAE,OAAO,CN6H1B,GAAO,CM5HtB,iBAAiC,CAAE,OAAO,CNjL1B,GAAO,CMkLvB,iBAAiC,CAAE,OAAO,CNxC1B,GAAO,CMyCvB,wBAAwC,CAAE,OAAO,CNxC1B,GAAO,CMyC9B,6BAA6C,CAAE,OAAO,CNuC1B,GAAO,CMtCnC,sBAAsC,CAAE,OAAO,CNqC1B,GAAO,CMpC5B,oBAAoC,CAAE,OAAO,CNlR1B,GAAO,CMmR1B,eAA+B,CAAE,OAAO,CNhR1B,GAAO,CMiRrB,qBAAqC,CAAE,OAAO,CNxE1B,GAAO,CMyE3B,yBAAyC,CAAE,OAAO,CNxE1B,GAAO,CMyE/B,iBAAiC,CAAE,OAAO,CN7Q1B,GAAO,CM8QvB,iBAAiC,CAAE,OAAO,CN3J1B,GAAO,CM4JvB,mBAAmC,CAAE,OAAO,CNtJ1B,GAAO,CMuJzB,cAA8B,CAAE,OAAO,CNtP1B,GAAO,CMuPpB,mBAAmC,CAAE,OAAO,CN3W1B,GAAO,CM4WzB,gBAAgC,CAAE,OAAO,CNjU1B,GAAO,CMkUtB,cAA8B,CAAE,OAAO,CN1F1B,GAAO,CM2FpB,gBAAgC,CAAE,OAAO,CNM1B,GAAO,CMLtB,eAA+B,CAAE,OAAO,CNrS1B,GAAO,CMsSrB,gBAAgC,CAAE,OAAO,CNrS1B,GAAO,CMsStB,kBAAkC,CAAE,OAAO,CNtY1B,GAAO,CMuYxB,yBAAyC,CAAE,OAAO,CNtY1B,GAAO,CMuY/B,gBAAgC,CAAE,OAAO,CNa1B,GAAO,CMZtB,uBAAuC,CAAE,OAAO,CNa1B,GAAO,CMZ7B,kBAAkC,CAAE,OAAO,CN/D1B,GAAO,CMgExB,oCAC8B,CAAE,OAAO,CN5W1B,GAAO,CM6WpB,8BAC+B,CAAE,OAAO,CN2B1B,GAAO,CM1BrB,eAA+B,CAAE,OAAO,CNoD1B,GAAO,CMnDrB,kBAAkC,CAAE,OAAO,CNN1B,GAAO,CMOxB,qBAAqC,CAAE,OAAO,CNzS1B,GAAO,CM0S3B,qBAAqC,CAAE,OAAO,CNZ1B,GAAO,CMa3B,mBAAmC,CAAE,OAAO,CN/S1B,GAAO,CMgTzB,qBAAqC,CAAE,OAAO,CNhQ1B,GAAO,CMiQ3B,sBAAsC,CAAE,OAAO,CNzP1B,GAAO,CM0P5B,uBAAuC,CAAE,OAAO,CNtQ1B,GAAO,CMuQ7B,4BAA4C,CAAE,OAAO,CNhQ1B,GAAO,CMiQlC,yEAEuC,CAAE,OAAO,CNzQ1B,GAAO,CM0Q7B,+CACyC,CAAE,OAAO,CN/Q1B,GAAO,CMgR/B,+CACuC,CAAE,OAAO,CNhR1B,GAAO,CMiR7B,+CACuC,CAAE,OAAO,CNrQ1B,GAAO,CMsQ7B,sBAAsC,CAAE,OAAO,CNlR1B,GAAO,CMmR5B,eAA+B,CAAE,OAAO,CN4D1B,GAAO,CM3DrB,kBAAkC,CAAE,OAAO,CNrV1B,GAAO,CMsVxB,mBAAmC,CAAE,OAAO,CNhM1B,GAAO,CMiMzB,uGAIoC,CAAE,OAAO,CNtL1B,GAAO,CMuL1B,yBAAyC,CAAE,OAAO,CNvW1B,GAAO,CMwW/B,8BACgC,CAAE,OAAO,CNlG1B,GAAO,CMmGtB,+BACiC,CAAE,OAAO,CN1T1B,GAAO,CM2TvB,qBAAqC,CAAE,OAAO,CNpP1B,GAAO,CMqP3B,cAA8B,CAAE,OAAO,CNtP1B,GAAO,CMuPpB,sBAAsC,CAAE,OAAO,CNxO1B,GAAO,CMyO5B,wBAAwC,CAAE,OAAO,CNR1B,GAAO,CMS9B,aAA6B,CAAE,OAAO,CNjH1B,GAAO,CMkHnB,mCACiC,CAAE,OAAO,CNiD1B,GAAO,CMhDvB,sCACsC,CAAE,OAAO,CNrJ1B,GAAO,CMsJ5B,0CACwC,CAAE,OAAO,CNtJ1B,GAAO,CMuJ9B,kBAAkC,CAAE,OAAO,CNvO1B,GAAO,CMwOxB,sBAAsC,CAAE,OAAO,CNvX1B,GAAO,CMwX5B,iBAAiC,CAAE,OAAO,CN7O1B,GAAO,CM8OvB,oBAAoC,CAAE,OAAO,CNxJ1B,GAAO,CMyJ1B,kBAAkC,CAAE,OAAO,CNvE1B,GAAO,CMwExB,oBAAoC,CAAE,OAAO,CNtF1B,GAAO,CMuF1B,2BAA2C,CAAE,OAAO,CNtF1B,GAAO,CMuFjC,eAA+B,CAAE,OAAO,CNnb1B,GAAO,CMobrB,4CACmC,CAAE,OAAO,CNjR1B,GAAO,CMkRzB,cAA8B,CAAE,OAAO,CNI1B,GAAO,CMHpB,qBAAqC,CAAE,OAAO,CN9b1B,GAAO,CM+b3B,eAA+B,CAAE,OAAO,CN5I1B,GAAO,CM6IrB,qBAAqC,CAAE,OAAO,CN/E1B,GAAO,CMgF3B,iBAAiC,CAAE,OAAO,CNI1B,GAAO,CMHvB,eAA+B,CAAE,OAAO,CNuC1B,GAAO,CMtCrB,sBAAsC,CAAE,OAAO,CN7K1B,GAAO,CM8K5B,eAA+B,CAAE,OAAO,CN6B1B,GAAO,CM5BrB,qBAAqC,CAAE,OAAO,CNjb1B,GAAO,CMkb3B,iBAAiC,CAAE,OAAO,CNpK1B,GAAO,CMqKvB,wBAAwC,CAAE,OAAO,CNzQ1B,GAAO,CM0Q9B,kBAAkC,CAAE,OAAO,CNha1B,GAAO,CMiaxB,wBAAwC,CAAE,OAAO,CNpa1B,GAAO,CMqa9B,sBAAsC,CAAE,OAAO,CNta1B,GAAO,CMua5B,kBAAkC,CAAE,OAAO,CNxa1B,GAAO,CMyaxB,oBAAoC,CAAE,OAAO,CNta1B,GAAO,CMua1B,oBAAoC,CAAE,OAAO,CNta1B,GAAO,CMua1B,qBAAqC,CAAE,OAAO,CNjd1B,GAAO,CMkd3B,uBAAuC,CAAE,OAAO,CNjd1B,GAAO,CMkd7B,gBAAgC,CAAE,OAAO,CNtB1B,GAAO,CMuBtB,oBAAoC,CAAE,OAAO,CN9X1B,GAAO,CM+X1B,aAA6B,CAAE,OAAO,CNne1B,GAAO,CMoenB,qBAAqC,CAAE,OAAO,CNtV1B,GAAO,CMuV3B,sBAAsC,CAAE,OAAO,CN1L1B,GAAO,CM2L5B,wBAAwC,CAAE,OAAO,CNpd1B,GAAO,CMqd9B,qBAAqC,CAAE,OAAO,CNzf1B,GAAO,CM0f3B,oBAAoC,CAAE,OAAO,CN7K1B,GAAO,CM8K1B,qBAAqC,CAAE,OAAO,CNzO1B,GAAO,CM0O3B,iBAAiC,CAAE,OAAO,CNtP1B,GAAO,CMuPvB,wBAAwC,CAAE,OAAO,CNtP1B,GAAO,CMuP9B,qBAAqC,CAAE,OAAO,CNrC1B,GAAO,CMsC3B,oBAAoC,CAAE,OAAO,CNrC1B,GAAO,CMsC1B,kBAAkC,CAAE,OAAO,CN9d1B,GAAO,CM+dxB,cAA8B,CAAE,OAAO,CN5c1B,GAAO,CM6cpB,kBAAkC,CAAE,OAAO,CNtQ1B,GAAO,CMuQxB,oBAAoC,CAAE,OAAO,CN9gB1B,GAAO,CM+gB1B,aAA6B,CAAE,OAAO,CN/b1B,GAAO,CMgcnB,kDAE8B,CAAE,OAAO,CNpR1B,GAAO,CMqRpB,mBAAmC,CAAE,OAAO,CN/N1B,GAAO,COtUzB,swBAAK,CACH,WAAW,CAAE,OAAO,CACpB,y5BAAQ,CACN,WAAW,CC+BuB,aAAa,CD9B/C,OAAO,CAAE,YAAY,CACrB,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,MAAM,CACnB,WAAW,CAAE,CAAC,CACd,eAAe,CAAE,OAAO,CAM5B,86BAAkB,CAChB,OAAO,CAAE,YAAY,CACrB,eAAe,CAAE,OAAO,CAGxB,muEAAgB,CACd,OAAO,CAAE,MAAM,CACf,2wEAAuB,CACrB,WAAW,CAAE,KAAI,CACnB,utEAAsB,CACpB,OAAO,CAAE,YAAY,CAE3B,2iBAA2B,CACzB,OAAO,CAAE,GAAE,CfpBL,kBAAoB,CAAE,qBAAM,CAK5B,eAAiB,CAAE,qBAAM,CAezB,UAAY,CAAE,qBAAM,CeE5B,+nBAAiC,CAC/B,OAAO,CAAE,CAAC,CAGV,mtCAAuB,CACrB,SAAS,CAAE,IAAI,CACf,cAAc,CAAE,IAAI,CEpBxB,0PAAS,CACP,OAAO,CAAE,IAAqB,CAC9B,WAAW,CDayB,IAAI,CCZxC,aAAa,CDYuB,IAAI,CCXxC,UAAU,CAAE,OAAmB,CAEjC,8CAAe,CACb,KAAK,CCY+B,IAAM,CDX1C,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,KAAK,CACd,KAAK,CCS+B,IAAM,CDR1C,UAAU,CAAE,OAAkB,CAC9B,MAAM,CAAE,KAAsB,CAC9B,OAAO,CAAE,QAA2C,CACpD,aAAa,CAAE,IAAqB,CAEtC,0ZAAyB,CACvB,UAAU,CAAE,OAAkB,CAC9B,mxCAAe,CACb,UAAU,CAAE,OAAiB,CACjC,kYAA0B,CACxB,UAAU,CAAE,OAAmB,CAC/B,ouCAAe,CACb,UAAU,CAAE,OAAoB,CAEpC,sYAAuB,CACrB,UAAU,CAAE,OAAmB,CAC/B,yuCAAe,CACb,UAAU,CAAE,OAAkB,CAElC,mZAA0B,CACxB,UAAU,CAAE,OAAuB,CACnC,swCAAe,CACb,UAAU,CAAE,OAAqB,CAErC,scAA0B,CACxB,UAAU,CCL0B,OAAmB,CDMvD,42CAAe,CACb,KAAK,CCvB6B,OAAW,CDwB7C,UAAU,CCNwB,OAAmB,CDOvD,8dAAC,CACC,KAAK,CChB6B,OAAK,CDkB3C,sZAAsB,CACpB,aAAa,CAAE,CAAC,CAsBlB,kBAAkB,CAChB,QAAQ,CAAE,KAAK,CACf,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,CAAC,CACP,OAAO,CDG6B,GAAG,CCFvC,qBAAE,CACA,OAAO,CAAE,KAAK,CACd,KAAK,CDT6B,KAAK,CCUvC,UAAU,CAAE,WAAW,CACvB,KAAK,CCxD6B,IAAM,CDyDxC,UAAU,CAAE,MAAM,CAClB,UAAU,CAAE,2BAA0B,CACtC,OAAO,CAAE,MAAmB,CAC5B,SAAS,CAAE,GAAG,CACd,OAAO,CAAE,CAAC,CACV,MAAM,CAAE,CAAC,CACT,WAAW,CAAE,IAAI,CACjB,QAAQ,CAAE,MAAM,CjB3FZ,kBAAoB,CAAE,gBAAM,CAK5B,eAAiB,CAAE,gBAAM,CAezB,UAAY,CAAE,gBAAM,CiByExB,0CAAsB,CACpB,UAAU,CC5FsB,OAAM,CD6FxC,uCAAmB,CACjB,UAAU,CC/DsB,OAAK,CDgEvC,0CAAsB,CACpB,UAAU,CDnFsB,OAAO,CCoFzC,yCAAqB,CACnB,UAAU,CDtEsB,OAAI,CCuEtC,wBAAI,CACF,OAAO,CAAE,CAAC,CACV,MAAM,CAAE,IAAI,CEhFd,oCAAsB,CFmFxB,kBAAkB,CAChB,MAAM,CAAE,IAAI,CACZ,GAAG,CAAE,CAAC,CACN,KAAK,CAAE,IAAI,CACX,qBAAE,CACA,KAAK,CAAE,IAAI,EG3FjB,MAAM,CACJ,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,CAAC,CACT,cAAc,CAAE,QAAQ,CACxB,eAAe,CAAE,MAAM,CACvB,MAAM,CAAE,OAAO,CACf,WAAW,CAAE,MAAM,CACnB,kBAAkB,CAAE,MAAM,CAC1B,SAAS,CAAE,OAAO,CACpB,gDAAiD,CAC/C,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CACZ,gBAAgB,CACd,MAAM,CAAE,OAAO,CAEjB,IAAI,CAEF,OAAO,CAAE,YAAY,CACrB,aAAa,CAAE,GAAG,CAClB,WAAW,CAAE,MAAM,CACnB,WAAW,CAAE,MAAM,CACnB,UAAU,CAAE,MAAM,CAClB,MAAM,CAAE,OAAO,CACf,SAAS,CAAE,IAAI,CACf,OAAO,CAAE,iBAA6F,CACtG,KAAK,CFlB+B,IAAM,CEmB1C,MAAM,CAAE,yBAAyB,CACjC,gBAAgB,CF7CoB,OAAM,CE8C1C,eAAe,CAAE,IAAI,CACrB,WAAW,CAAE,MAAM,CACnB,WAAW,CFJyB,uDAAM,CEK1C,UAAU,CAAE,mFAA8C,CAC1D,YAAY,CAAE,KAAK,CACnB,cAAc,CAAE,MAAM,CACtB,QAAQ,CAAE,MAAM,CAChB,IAAI,CAAE,CAAC,CACP,iBAAiB,CAAE,IAAI,CpBxDjB,mBAAoB,CoByDb,IAAI,CpBpDX,gBAAiB,CoBoDV,IAAI,CpB/CX,eAAgB,CoB+CT,IAAI,CpBrCX,WAAY,CoBqCL,IAAI,CpBzDX,kBAAoB,CAAE,eAAM,CAK5B,eAAiB,CAAE,eAAM,CAezB,UAAY,CAAE,eAAM,CoByC5B,UAAU,CACR,UAAU,CAAE,OAAwB,CACpC,KAAK,CFpC+B,IAAM,CEuC1C,UAAO,CACL,UAAU,CAAE,OAAqC,CACjD,KAAK,CFzC6B,IAAM,CE0C1C,UAAO,CACL,UAAU,CAAE,OAAqC,CACjD,OAAO,CAAE,CAAC,CACZ,WAAQ,CACN,UAAU,CAAE,6EAAyC,CACrD,OAAO,CAAE,iBAA6F,CACxG,YAAS,CACP,KAAK,CFjD6B,IAAM,CEkD1C,aAAU,CACR,gBAAgB,CAAE,IAAI,CACtB,MAAM,CAAE,2DAA2D,CACnE,MAAM,CAAE,iBAAmB,CAC3B,OAAO,CAAE,GAAG,CACZ,MAAM,CAAE,WAAW,CACnB,UAAU,CAAE,IAAI,CAEpB,aAAa,CACX,gBAAgB,CAAE,IAAI,CACtB,MAAM,CAAE,2DAA2D,CACnE,MAAM,CAAE,iBAAmB,CAC3B,OAAO,CAAE,GAAG,CACZ,MAAM,CAAE,WAAW,CACnB,UAAU,CAAE,IAAI,CAChB,4DAA0B,CACxB,gBAAgB,CAAE,IAAI,CACtB,MAAM,CAAE,2DAA2D,CACnE,MAAM,CAAE,iBAAmB,CAC3B,OAAO,CAAE,GAAI,CACb,MAAM,CAAE,WAAW,CACnB,UAAU,CAAE,IAAI,CAGpB,sBAAsB,CACpB,OAAO,CAAE,CAAC,CACV,MAAM,CAAE,CAAC,CAEX,UAAU,CACR,SAAS,CAAE,GAAG,CAEhB,SAAS,CACP,gBAAgB,CAAE,kBAAgB,CAClC,eAAO,CACL,gBAAgB,CAAE,kBAA6B,CAEnD,YAAY,CACV,gBAAgB,CAAE,kBAA2C,CAC7D,KAAK,CAAE,kBAAsB,CAC7B,kBAAO,CACL,gBAAgB,CAAE,kBAAuD,CACzE,KAAK,CF/F6B,OAAW,CEgG/C,oBAAS,CACP,KAAK,CAAE,kBAAsB,CAEjC,YAAY,CACV,gBAAgB,CAAE,kBAAiB,CACnC,kBAAO,CACL,gBAAgB,CAAE,eAA6B,CAEnD,WAAW,CACT,gBAAgB,CAAE,kBAAe,CACjC,iBAAO,CACL,gBAAgB,CAAE,kBAA4B,CAElD,YAAY,CACV,gBAAgB,CAAE,kBAAkB,CACpC,kBAAO,CACL,gBAAgB,CAAE,kBAA+B,CACrD,WAAW,CACT,gBAAgB,CJvIoB,IAAI,CIwIxC,iBAAO,CACL,gBAAgB,CAAE,kBAAoC,CAE1D,SAAS,CACP,gBAAgB,CAAE,sBAAsB,CACxC,KAAK,CF9G+B,OAAK,CE+GzC,UAAU,CAAE,IAAI,CAChB,YAAY,CAAE,sBAAsB,CACpC,eAAO,CACL,gBAAgB,CAAE,sBAAsB,CACxC,KAAK,CAAE,kBAAoC,CAC3C,UAAU,CAAE,IAAI,CAClB,gBAAQ,CACN,gBAAgB,CAAE,sBAAsB,CACxC,KAAK,CAAE,kBAAoC,CAC3C,UAAU,CAAE,IAAI,CAClB,iBAAS,CACP,KAAK,CFzH6B,OAAO,CE2H7C,mCAAoC,CAClC,cAAc,CAAE,MAAM,CAExB,aAAa,CACX,aAAa,CJ1IuB,IAAI,CduExC,KAAK,CAAE,CAAC,CACR,wCAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,mBAAO,CACL,KAAK,CAAE,IAAI,CmB3Ff,YAAY,CACV,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,YAAY,CAIvB,qCAAqC,CACnC,OAAO,CAAE,KAAK,CAChB,iBAAiB,CACf,QAAQ,CAAE,QAAQ,CAClB,IAAI,CAAE,CAAC,CACP,OAAO,CAAE,IAAI,CACb,KAAK,CAAE,IAAI,CACX,GAAG,CAAE,IAAI,CACT,SAAS,CAAE,IAAI,CACf,UAAU,CHQ0B,OAAyB,CGP7D,OAAO,CLmD6B,GAAG,CKlDvC,MAAM,CAAE,iBAAgC,CACxC,UAAU,CAAE,2BAA0B,CACtC,OAAO,CAAE,IAAqB,CAC9B,sBAAQ,CACN,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,IAAI,CACX,KAAK,CHT6B,OAAW,CGU7C,WAAW,CAAE,MAAM,CACnB,SAAS,CAAE,GAAG,CACd,OAAO,CAAE,MAAuB,CAChC,MAAM,CAAE,OAAO,CACf,4BAAO,CACL,UAAU,CHLsB,OAAK,CGMrC,KAAK,CHZ2B,IAAM,CGa1C,4BAAY,CACV,UAAU,CAAE,iBAAgC,CAC5C,MAAM,CAAE,KAAuB,CACjC,2BAAW,CACT,cAAc,CAAE,IAAqB,CACrC,gDAAoB,CAClB,KAAK,CAAE,IAAI,CACf,mCAAmB,CACjB,UAAU,CAAE,OAA4B,CACxC,cAAc,CAAE,SAAS,CACzB,WAAW,CAAE,GAAG,CAChB,SAAS,CAAE,GAAG,CACd,yCAAO,CACL,UAAU,CAAE,OAA4B,CAC1C,wCAAI,CACF,KAAK,CH5B2B,IAAM,CG8B5C,6CAA6C,CAC3C,MAAM,CAAE,IAAI,CACZ,GAAG,CAAE,IAAI,CACT,IAAI,CAAE,IAAI,CACV,KAAK,CAAE,CAAC,CAGR,iDAAiB,CACf,UAAU,CHjCwB,OAAyB,CGkC3D,UAAU,CAAE,GAAG,CACjB,mDAAmB,CACjB,OAAO,CAAE,QAA2C,CACpD,yDAAO,CACL,UAAU,CHrCsB,OAAK,CGsCrC,KAAK,CH5C2B,IAAM,CG8C5C,+CAA+C,CAC7C,KAAK,CAAE,CAAC,CACR,IAAI,CAAE,IAAI,CACV,UAAU,CAAE,KAAK,CAGjB,yBAAQ,CACN,OAAO,CAAE,GAAG,CACZ,aAAa,CAAE,iBAA0B,CACzC,WAAW,CAAE,qBAAqB,CAClC,YAAY,CAAE,qBAAqB,CACnC,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,KAAK,CACd,GAAG,CAAE,IAAI,CACT,IAAI,CAAE,GAAG,CACT,WAAW,CAAE,IAAI,CACnB,gDAA+B,CAC7B,IAAI,CAAE,IAAI,CCtEZ,uBAAM,CACJ,OAAO,CAAE,KAAK,CAEhB,gIAA+C,CAC7C,OAAO,CAAE,YAAY,CACrB,QAAQ,CAAE,MAAM,CAChB,KAAK,CAAE,CAAC,CACR,cAAc,CAAE,MAAM,CAItB,wCAAO,CACL,OAAO,CAAE,YAAY,CACrB,cAAc,CAAE,MAAM,CACtB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,YAA+C,CACvD,KAAK,CAAE,IAAI,CACf,4BAAW,CACT,KAAK,CAAE,IAAI,CACX,kCAAK,CACH,OAAO,CAAE,KAAK,CAChB,mCAAM,CACJ,UAAU,CAAE,GAAqB,CAEvC,QAAQ,CACN,MAAM,CAAE,CAAC,CACT,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CACZ,MAAM,CACJ,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CACV,WAAW,CAAE,MAAM,CACnB,aAAa,CN/BuB,IAAI,CMgCxC,SAAS,CAAE,IAAI,CACf,YAAY,CAAE,IAAI,CACpB,KAAK,CACH,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,cAAa,CACrB,KAAK,CNR+B,IAAU,CMS9C,SAAS,CAAE,GAAG,CAEhB,qBAAuB,CACrB,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,CAAC,CACT,cAAc,CAAE,QAAQ,CACxB,eAAe,CAAE,MAAM,CAGzB,iBAAiB,CACf,aAAa,CNhDuB,IAAI,CduExC,KAAK,CAAE,CAAC,CqBrGR,SAAS,CCCC,IAAQ,CDChB,WAAI,CAAE,IAAI,CACV,YAAK,CAAE,IAAI,CrBkGb,KAAK,CAAE,CAAC,CACR,gDAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,uBAAO,CACL,KAAK,CAAE,IAAI,CALb,gDAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,uBAAO,CACL,KAAK,CAAE,IAAI,CoBzBf,uDAAyD,CACvD,OAAO,CAAE,IAAI,CACb,KAAK,CN/C+B,OAAI,CMoDxC,mGAA+C,CAC7C,cAAc,CAAE,IAAqB,CACrC,wHAAM,CACJ,KAAK,CAAE,IAAI,CAEX,0tEAAqP,CACnP,KAAK,CAAE,IAAI,CACnB,+BAA+B,CGlF3B,KAAK,CAAE,IAAsB,CAG3B,OAAO,CAAE,KAAK,CAed,YAAoB,CAAE,QAA+B,CACrD,KAAK,CAAE,IAAuC,CCnB5C,YAAoB,CAAE,CAAC,CDqBzB,0CAAa,CACX,YAAoB,CAAE,CAAC,CHgE/B,iCAAiC,CGtF7B,KAAK,CAAE,IAAsB,CAG3B,OAAO,CAAE,KAAK,CAed,YAAoB,CAAE,QAA+B,CACrD,KAAK,CAAE,SAAuC,CAE9C,4CAAa,CACX,YAAoB,CAAE,CAAC,CCA7B,iDAAwB,CACtB,YAAoB,CAAE,CAAC,CAEvB,mDAA0B,CACxB,KAAK,CALY,IAAkC,CJqEzD,iCAAiC,CG1F7B,KAAK,CAAE,IAAsB,CAG3B,OAAO,CAAE,KAAK,CAed,YAAoB,CAAE,QAA+B,CACrD,KAAK,CAAE,SAAuC,CAE9C,4CAAa,CACX,YAAoB,CAAE,CAAC,CCA7B,iDAAwB,CACtB,YAAoB,CAAE,CAAC,CAEvB,mDAA0B,CACxB,KAAK,CALY,IAAkC,CJ0EzD,uDAAuD,CACrD,MAAM,CAAE,SAA2B,CACnC,SAAS,CAAE,GAAG,CAEhB,oBAAoB,CAClB,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,SAA2B,CACnC,SAAS,CAAE,GAAG,CAOZ,osBAAqP,CACnP,KAAK,CAAE,IAAI,CAIjB,uBAAuB,CACrB,OAAO,CAAE,YAAY,CACrB,YAAY,CAAE,KAAK,CACnB,KAAK,CAAE,IAAI,CACX,cAAc,CAAE,MAAM,CACtB,SAAS,CAAE,GAAG,CAEhB,gBAAgB,CACd,OAAO,CAAE,KAAK,CACd,KAAK,CJxH+B,IAAW,CIyH/C,SAAS,CAAE,GAAG,CACd,UAAU,CAAE,QAAO,CACnB,UAAU,CAAE,MAAM,CAClB,kBAAC,CACC,SAAS,CAAE,OAAO,CAClB,UAAU,CAAE,MAAM,CAClB,aAAa,CAAE,GAAqB,CACtC,6BAAY,CACV,aAAa,CAAE,CAAC,CA4DpB,KAAK,CACH,WAAW,CAAE,MAAM,CAGnB,6DAAmD,CACjD,kBAAkB,CAAE,MAAM,CAC1B,MAAM,CAAE,OAAO,CACf,WAAW,CJhKuB,uDAAM,CIiKxC,SAAS,CAAE,OAAO,CACpB,gSAAqP,CACnP,kBAAkB,CAAE,IAAI,CACxB,OAAO,CAAE,GAAqB,CAC9B,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,cAA6B,CACrC,SAAS,CAAE,GAAG,CACd,WAAW,CJxKuB,uDAAM,CIyKxC,UAAU,CAAE,oBAAmC,CAC/C,aAAa,CAAE,CAAC,CtBxNZ,kBAAoB,CAAE,kBAAM,CAK5B,eAAiB,CAAE,kBAAM,CAezB,UAAY,CAAE,kBAAM,CsBuM1B,4BAAwB,CACtB,OAAO,CAAE,iBAAkB,CAC7B,eAAW,CACT,MAAM,CAAE,OAAO,CACjB,0CAAmC,CtB/N7B,kBAAoB,CsBgOZ,UAAU,CtB3NlB,eAAiB,CsB2NT,UAAU,CtB5MlB,UAAY,CsB4MJ,UAAU,CACtB,OAAO,CAAE,CAAC,CACV,YAAY,CAAE,QAAO,CACrB,OAAO,CAAE,IAAI,CACb,MAAM,CAAE,IAAI,CACd,oBAAgB,CtBrOV,kBAAoB,CsBsOZ,UAAU,CtBjOlB,eAAiB,CsBiOT,UAAU,CtBlNlB,UAAY,CsBkNJ,UAAU,CACtB,kGAA6D,CAC3D,kBAAkB,CAAE,IAAI,CAC5B,oXAAyU,CACvU,OAAO,CAAE,CAAC,CACV,OAAO,CAAE,cAAc,CACvB,YAAY,CNxLsB,IAAU,CMyL9C,oBAAgB,CACd,YAAY,CAAE,eAA8B,CAC9C,+EAAqE,CACnE,OAAO,CAAE,gBAAsB,CAC/B,OAAO,CAAE,gBAAgB,CAC3B,4aAAiY,CAC/X,MAAM,CAAE,WAAW,CACnB,gBAAgB,CAAE,OAAmC,CAEzD,+DAAiE,CAC/D,KAAK,CNzN+B,OAAI,CM0NxC,MAAM,CAAE,iBAAc,CACxB,iFAAmF,CACjF,YAAY,CN5NwB,OAAI,CM8NxC,yHAA+G,CAC7G,aAAa,CN/NqB,OAAI,CMiO1C,oBAAoB,CAClB,OAAO,CAAE,IAAqB,CAC9B,SAAS,CAAE,IAAI,CAKjB,QAAQ,CACN,QAAQ,CAAE,IAAI,CACd,cAAc,CAAE,GAAG,CACnB,KAAK,CAAE,IAAI,CACX,WAAW,CJ5NyB,uDAAM,CI6N5C,eAAgB,CACd,OAAO,CAAE,aAAgB,CACzB,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,cAA6B,CACrC,SAAS,CAAE,GAAG,CACd,UAAU,CAAE,oBAAmC,CtBhRzC,kBAAoB,CAAE,kBAAM,CAK5B,eAAiB,CAAE,kBAAM,CAezB,UAAY,CAAE,kBAAM,CsB+P5B,MAAM,CACJ,MAAM,CAAE,cAA6B,CACrC,gBAAgB,CJ1PoB,IAAM,CI2P1C,gBAAW,CACT,MAAM,CAAE,IAAI,CAChB,2BAA4B,CAC1B,OAAO,CAAE,CAAC,CACZ,uFAA2F,CACzF,MAAM,CAAE,WAAW,CACnB,gBAAgB,CAAE,OAAmC,CAKrD,8DAAuD,CACrD,MAAM,CAAE,WAAW,CACvB,sBAAuB,CACrB,MAAM,CAAE,KAAuB,CAE/B,KAAK,CJ/Q+B,OAAW,CIgR/C,OAAO,CAAE,KAAK,CACd,kCAAK,CACH,cAAc,CAAE,QAAQ,CAI5B,uBAAuB,CACrB,OAAO,CAAE,YAAY,CACrB,QAAQ,CAAE,MAAM,CAChB,KAAK,CAAE,CAAC,CACR,cAAc,CAAE,MAAM,CAuBxB,iCAAkC,CAChC,WAAW,CAAE,MAAM,CACnB,OAAO,CAAE,GAAqB,CAC9B,qEAAiB,CACf,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,YAAY,CACrB,SAAS,CAAE,GAAG,CACd,gBAAgB,CJzSkB,OAAmB,CI0SrD,MAAM,CAAE,cAA6B,CACrC,KAAK,CJxU6B,IAAW,CI0UjD,kCAAkC,CAChC,WAAW,CAAE,CAAC,CAChB,kCAAkC,CAChC,YAAY,CAAE,CAAC,CAcjB,UAAU,CACR,KAAK,CAAE,IAAuB,CAC9B,MAAM,CAAE,IAAqB,CAC7B,MAAM,CAAE,MAAwB,CAChC,QAAQ,CAAE,QAAQ,CAClB,aAAa,CAAE,GAAG,CAClB,UAAU,CNrW0B,IAAI,CMsWxC,MAAM,CAAE,OAAO,CtB5WT,kBAAoB,CAAE,oBAAM,CAK5B,eAAiB,CAAE,oBAAM,CAezB,UAAY,CAAE,oBAAM,CsB0V1B,iBAAQ,CACN,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,EAAE,CACX,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,aAAa,CAAE,GAAG,CAClB,UAAU,CJ3WwB,IAAW,CI4W7C,IAAI,CAAE,IAAI,CACV,GAAG,CAAE,IAAI,CtBvXL,kBAAoB,CAAE,oBAAM,CAK5B,eAAiB,CAAE,oBAAM,CAezB,UAAY,CAAE,oBAAM,CsBqW1B,gBAAO,CACL,OAAO,CAAE,OAAO,CAChB,QAAQ,CAAE,QAAQ,CAClB,IAAI,CAAE,IAAqB,CAC3B,OAAO,CAAE,KAAK,CACd,SAAS,CAAE,IAAI,CACf,KAAK,CNzX6B,IAAI,CM0X1C,iBAAiB,CACf,UAAU,CAAE,OAAmB,CAC/B,wBAAQ,CACN,IAAI,CN5W8B,IAAI,CM6WtC,UAAU,CJlYwB,OAAM,CImY1C,uBAAO,CACL,OAAO,CAAE,MAAM,CAEnB,8CAA+C,CAC7C,MAAM,CAAE,WAAW,CAiDnB,wGAAyB,CACvB,KAAK,CN7Z6B,OAAI,CM+ZtC,81BAAqP,CACnP,MAAM,CAAE,iBAAc,CAC1B,iDAAQ,CACN,MAAM,CAAE,iBAAc,CAE1B,mBAAmB,CACjB,WAAW,CAAE,MAAM,CACnB,qCAAiB,CACf,OAAO,CAAE,aAAgB,CACzB,OAAO,CAAE,YAAY,CACrB,SAAS,CAAE,GAAG,CAClB,gEAAgE,CAC9D,KAAK,CJvc+B,OAAM,CI0c5C,+DAA+D,CAC7D,KAAK,CN/a+B,OAAI,CMkb1C,gEAAgE,CAC9D,KAAK,CNlc+B,OAAO,CMqc7C,6DAA6D,CAC3D,KAAK,CJpb+B,OAAK,CI0b3C,UAAU,CtB3dF,iBAAoB,CAAE,aAAM,CAK5B,cAAiB,CAAE,aAAM,CAKzB,aAAgB,CAAE,aAAM,CAKxB,YAAe,CAAE,aAAM,CAKvB,SAAY,CAAE,aAAM,CsByc5B,WAAW,CtB7dH,iBAAoB,CAAE,cAAM,CAK5B,cAAiB,CAAE,cAAM,CAKzB,aAAgB,CAAE,cAAM,CAKxB,YAAe,CAAE,cAAM,CAKvB,SAAY,CAAE,cAAM,CsB2c5B,WAAW,CtB/dH,iBAAoB,CAAE,cAAM,CAK5B,cAAiB,CAAE,cAAM,CAKzB,aAAgB,CAAE,cAAM,CAKxB,YAAe,CAAE,cAAM,CAKvB,SAAY,CAAE,cAAM,CsB6c5B,OAAO,CtBjeC,iBAAoB,CAAE,UAAM,CAK5B,cAAiB,CAAE,UAAM,CAKzB,aAAgB,CAAE,UAAM,CAKxB,YAAe,CAAE,UAAM,CAKvB,SAAY,CAAE,UAAM,CsB+c1B,iBAAW,CtBneL,iBAAoB,CsBoeL,wBAAwB,CtB/dvC,cAAiB,CsB+dF,wBAAwB,CtB1dvC,aAAgB,CsB0dD,wBAAwB,CtBrdvC,YAAe,CsBqdA,wBAAwB,CtBhdvC,SAAY,CsBgdG,wBAAwB,CAC7C,kBAAY,CtBreN,iBAAoB,CsBseL,yBAAyB,CtBjexC,cAAiB,CsBieF,yBAAyB,CtB5dxC,aAAgB,CsB4dD,yBAAyB,CtBvdxC,YAAe,CsBudA,yBAAyB,CtBldxC,SAAY,CsBkdG,yBAAyB,CAC9C,kBAAY,CtBveN,iBAAoB,CsBweL,yBAAyB,CtBnexC,cAAiB,CsBmeF,yBAAyB,CtB9dxC,aAAgB,CsB8dD,yBAAyB,CtBzdxC,YAAe,CsBydA,yBAAyB,CtBpdxC,SAAY,CsBodG,yBAAyB,CAEhD,yCAAyC,CAErC,8BAAqB,CACnB,MAAM,CAAE,SAAS,CAEjB,8ZAAqP,CACnP,aAAa,CAAE,KAAK,CACpB,OAAO,CAAE,KAAK,CAClB,cAAK,CACH,aAAa,CAAE,KAAK,CACpB,OAAO,CAAE,KAAK,CAEhB,kYAAqO,CACnO,aAAa,CAAE,CAAC,CAElB,wCAAuB,CACrB,aAAa,CAAE,KAAK,CACpB,UAAU,CAAE,IAAI,CAChB,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,IAAI,CACb,4BAAW,CACT,MAAM,CAAE,WAAW,CACvB,iEAAmE,CACjE,OAAO,CAAE,KAAK,CACd,SAAS,CAAE,GAAG,CACd,OAAO,CAAE,KAAuB,EH5ehC,oCAAsB,CQhC1B,YAAY,CAER,OAAO,CAAE,IAAI,ER8Bb,oCAAsB,CQ5B1B,YAAY,CAER,OAAO,CAAE,IAAI,EAEjB,WAAW,CACT,KAAK,CAAE,IAAI,CAEb,YAAY,CACV,KAAK,CAAE,KAAK,CAEd,WAAW,CACT,KAAK,CAAE,IAAI,CC4Cb,mEAAS,CACP,eAAe,CAAE,QAAQ,CACzB,cAAc,CAAE,CAAC,CACjB,WAAW,CAAE,IAAI,CACjB,aAAa,CZ/BuB,IAAI,CYgCxC,2FAAO,CACL,KAAK,CAAE,IAAI,CACX,IAAI,CAAE,6BAAkB,CACxB,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,MAAM,CACpB,yJAAM,CACJ,SAAS,CZjByB,GAAG,CYkBrC,MAAM,CAAE,CAAC,CACT,QAAQ,CAAE,OAAO,CACjB,OAAO,CZnB2B,QAAmC,CYoBvE,iOAA8B,CAC5B,iBAAiB,CAAE,CAAC,CACtB,qFAAK,CACH,KAAK,CAAE,IAAI,CACX,UAAU,CAAE,IAAI,CAChB,cAAc,CAAE,MAAM,CACtB,WAAW,CAAE,MAAM,CACnB,8FAAE,CACA,WAAW,CZnDqB,IAAI,CYoDpC,aAAa,CAAE,iBAA6B,CAChD,4EAAE,CACA,gBAAgB,CAAE,WAAW,CAC7B,cAAc,CAAE,MAAM,CAE1B,kFAAc,CACZ,WAAW,CAAE,IAAuB,CACpC,mHAAY,CACV,aAAa,CAAE,CAAC,CACpB,4HAA4B,CAC1B,KAAK,CAAE,EAAE,CACT,aAAa,CAAE,CAAC,CAChB,uXAA0C,CACxC,MAAM,CAAE,CAAC,CAEb,mBAAmB,CACjB,KAAK,CVjE+B,IAAY,CUkEhD,SAAS,CAAE,GAAG,CAChB,kBAAkB,CAChB,KAAK,CVpE+B,IAAY,CUqEhD,SAAS,CAAE,GAAG,CAIhB,2HAAyD,CACvD,gBAAgB,CV5DoB,OAAmB,CU8DzD,gBAAgB,CACd,gBAAgB,CV/DoB,OAAmB,CUoEzD,kDAAsB,CACpB,MAAM,CAAE,iBAA6B,CACrC,wDAAE,CACA,aAAa,CAAE,iBAA6B,CAC5C,WAAW,CAAE,iBAA6B,CAC5C,gGAAwB,CACtB,mBAAmB,CAAE,CAAC,CAE1B,kBAAkB,CAChB,MAAM,CAAE,iBAA6B,CAGrC,0BAAE,CACA,aAAa,CAAE,iBAA6B,CAC9C,8CAAwB,CACtB,mBAAmB,CAAE,CAAC,CAGxB,2CAAwB,CACtB,mBAAmB,CAAE,CAAC,CACxB,+CAAM,CACJ,YAAY,CAAE,SAAS,CACvB,aAAa,CAAE,iBAA6B,CAC9C,2CAAwB,CACtB,mBAAmB,CAAE,CAAC,CAG1B,oBAAoB,CAClB,aAAa,CZhHuB,IAAI,CYiHxC,SAAS,CAAE,IAAI,CACf,QAAQ,CAAE,IAAI,CACd,0BAAK,CACH,aAAa,CAAE,YAAY,CAC3B,2DAAM,CACJ,WAAW,CAAE,MAAM,CCzIzB,CAAC,CACC,KAAK,CX4B+B,OAAK,CW3BzC,eAAe,CAAE,IAAI,CACrB,MAAM,CAAE,OAAO,CACf,OAAO,CACL,KAAK,CbgD6B,OAAwB,Ca/C5D,SAAS,CACP,KAAK,CXuB6B,OAAO,CWG7C,IAAI,CACF,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,MAAM,CAEpB,IAAI,CACF,WAAW,CXIyB,uDAAM,CWH1C,WAAW,CAAE,MAAM,CACnB,KAAK,CXrB+B,OAAW,CWsB/C,UAAU,CAAE,IAAI,CAChB,UAAU,CAAE,MAAM,CAClB,UAAU,CbnD0B,OAAO,CaqD7C,aAAa,CACX,UAAU,CAAE,IAAI,CAElB,eAAe,CACb,UAAU,CAAE,MAAM,CAEpB,cAAc,CACZ,UAAU,CAAE,KAAK,CAEnB,cAAc,CACZ,SAAS,CAAE,IAAI,CAEjB,eAAe,CACb,SAAS,CAAE,IAAI,CAEjB,oBAAqB,CACnB,SAAS,CAAE,GAAG,CAEhB,eAAe,CACb,eAAe,CAAE,YAAY,CAE/B,gBAAgB,CACd,KAAK,CAAE,kBAAkB,CAC3B,uBAAuB,CACrB,KAAK,CAAE,kBAAgC,CACzC,aAAa,CACX,KAAK,CAAE,kBAAgB,CACzB,oBAAoB,CAClB,KAAK,CAAE,kBAA8B,CACvC,gBAAgB,CACd,KAAK,CAAE,kBAAiB,CAC1B,uBAAuB,CACrB,KAAK,CAAE,kBAA+B,CACxC,eAAe,CACb,KAAK,CAAE,kBAAe,CACxB,sBAAsB,CACpB,KAAK,CAAE,kBAA6B,CACtC,gBAAgB,CACd,KAAK,CAAE,kBAAsB,CAC/B,uBAAuB,CACrB,KAAK,CAAE,kBAAoC,CAkB7C,gEAAyB,CACvB,UAAU,CAAE,CAAC,CACb,WAAW,CAAE,GAAG,CAChB,WAAW,CX/DyB,0DAAa,CWiEnD,CAAC,CACC,WAAW,Cb1FyB,IAAI,Ca2FxC,MAAM,CAAE,CAAC,CACT,SAAS,Cb/F2B,IAAI,CagGxC,aAAa,Cb7FuB,IAAI,Ca+F1C,EAAE,CACA,SAAS,CAAE,IAAI,CAEjB,0CAAE,CACA,SAAS,CAAE,IAAI,CAEjB,EAAE,CACA,SAAS,CAAE,IAAI,CAEjB,EAAE,CACA,SAAS,CAAE,IAAI,CAEjB,EAAE,CACA,SAAS,CAAE,IAAI,CAEjB,EAAE,CACA,SAAS,CAAE,IAAI,CAEjB,EAAE,CACA,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,MAAM,CAAE,CAAC,CACT,UAAU,CAAE,iBAA6B,CACzC,MAAM,CAAE,MAAmB,CAC3B,OAAO,CAAE,CAAC,CAEZ,sCAAI,CACF,WAAW,CAAE,MAAM,CACnB,SAAS,CAAE,IAAI,CACf,UAAU,CXxH0B,IAAM,CWyH1C,MAAM,CAAE,iBAAiC,CACzC,SAAS,CAAE,GAAG,CACd,OAAO,CAAE,KAAK,CACd,WAAW,CXtGyB,wMAAQ,CWuG5C,KAAK,Cb1H+B,OAAI,Ca2HxC,UAAU,CAAE,IAAI,CAChB,0CAAY,CACV,SAAS,CAAE,GAAG,CAmClB,wFAAmB,CACjB,UAAU,CAAE,IAAI,CAChB,WAAW,CbzKyB,IAAI,Ca0KxC,aAAa,Cb1KuB,IAAI,Ca2KxC,oGAAE,CACA,UAAU,CAAE,IAAI,CAChB,WAAW,Cb7KuB,IAAI,Ca8KtC,wJAAY,CACV,aAAa,CAAE,CAAC,CAClB,gHAAE,CACA,aAAa,CAAE,CAAC,CAClB,gHAAE,CACA,UAAU,CAAE,MAAM,CAClB,4HAAE,CACA,UAAU,CAAE,MAAM,CACtB,4HAAK,CACH,UAAU,CAAE,OAAO,CAEzB,iFAAsB,CACpB,UAAU,CAAE,OAAO,CACnB,WAAW,Cb3LyB,IAAI,Ca4LxC,aAAa,Cb5LuB,IAAI,Ca6LxC,6FAAE,CACA,UAAU,CAAE,OAAO,CACnB,WAAW,Cb/LuB,IAAI,CagMtC,iJAAY,CACV,aAAa,CAAE,CAAC,CAClB,yGAAE,CACA,aAAa,CAAE,CAAC,CAChB,qHAAE,CACA,UAAU,CAAE,IAAI,CCrOxB,kBAAkB,CAChB,MAAM,CAAE,iBAA6B,CACrC,aAAa,CAAE,IAAI,CACnB,OAAO,Cd6B6B,IAAI,Cc5BxC,WAAW,CAAE,IAAqB,CAClC,WAAW,CAAE,GAAG,CAChB,UAAU,CZ8B0B,IAAM,CY7B1C,QAAQ,CAAE,QAAQ,CAClB,wBAAO,CACL,OAAO,CAAE,SAAS,CAClB,QAAQ,CAAE,QAAQ,CAClB,GAAG,CAAE,GAAG,CACR,IAAI,CAAE,GAAG,CACT,UAAU,CZ8BwB,OAAO,CY7BzC,KAAK,CAAE,IAAoB,CAC3B,OAAO,CAAE,QAA2C,CACtD,2CAA0B,CACxB,MAAM,CAAE,iBAA6B,CACrC,aAAa,CdcqB,IAAI,CcZ1C,+GAAmC,CACjC,MAAM,CAAE,iBAA6B,CACrC,OAAO,CAAE,GAAG,CACZ,UAAU,CAAE,IAAI,CAChB,UAAU,CZY0B,IAAM,CYV1C,MAAM,CAAE,YAAyB,CACjC,gLAAuB,CACrB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,IAAI,CAChB,MAAM,CAAE,CAAC,CAEb,+BAA+B,CAC7B,KAAK,CAAE,IAAI,CACb,cAAc,CACZ,YAAY,CAAE,iBAA0C,CACxD,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,SAA2C,CACpD,WAAW,CZoByB,wMAAQ,CYnB5C,SAAS,CAAE,IAAI,CACf,WAAW,CAAE,GAAG,CAChB,KAAK,CdI+B,OAAwB,CcH9D,2BAA2B,CACzB,WAAW,CAAE,GAAG,CAChB,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,SAA2C,CACpD,WAAW,CZYyB,wMAAQ,CYX5C,SAAS,CAAE,IAAI,CACf,WAAW,CAAE,GAAG,CAChB,OAAO,CAAE,KAAK,CACd,QAAQ,CAAE,IAAI,CACd,KAAK,CZnB+B,OAAW,CYuBjD,YAAY,CACV,2IAAgE,CAC9D,WAAW,CAAE,QAAQ,ECzDzB,IAAI,CACF,gBAAgB,CAAE,IAAO,CACzB,MAAM,CAAE,OAAO,CACf,OAAO,CAAE,MAAM,CACf,OAAO,CAAE,KAAK,CAChB,EAAE,CACA,KAAK,CAAE,IAAO,CACd,UAAU,CAAE,MAAM,CACpB,IAAI,CACF,KAAK,CAAE,OAAO,CACd,gBAAgB,CAAE,OAAO,CAC3B,EAAE,CACA,WAAW,CAAE,IAAI,CACnB,EAAE,CACA,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,UAAU,CAAE,MAAM,CACpB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,UAAU,CAAE,MAAM,CACpB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,WAAW,CAAE,IAAI,CACjB,UAAU,CAAE,MAAM,CACpB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,gBAAgB,CAAE,IAAO,CAC3B,MAAM,CACJ,KAAK,CAAE,IAAO,CACd,gBAAgB,CAAE,IAAO,CAC3B,GAAG,CACD,UAAU,CAAE,MAAM,CACpB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,gBAAgB,CAAE,IAAO,CAC3B,MAAM,CACJ,KAAK,CAAE,IAAO,CACd,gBAAgB,CAAE,IAAO,CAC3B,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,MAAO,CACd,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,WAAW,CAAE,IAAI,CACnB,EAAE,CACA,KAAK,CAAE,IAAO,CAChB,EAAE,CACA,KAAK,CAAE,IAAO,CAChB,EAAE,CACA,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,KAAK,CAAE,OAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,KAAK,CAAE,MAAM,CACf,GAAG,CACD,KAAK,CAAE,IAAO,CACd,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAO,CACd,WAAW,CAAE,IAAI,CACnB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,WAAW,CAAE,IAAI,CACnB,EAAE,CACA,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,OAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,OAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,KAAK,CAAE,IAAI,CACb,GAAG,CACD,KAAK,CAAE,IAAO,CAChB,GAAG,CACD,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,OAAO,CCjJ3B,kBAAkB,CAChB,OAAO,CAAE,YAAY,CACrB,uCAAsB,CACpB,KAAK,CAAE,KAAK,CACd,oBAAC,CACC,OAAO,CAAE,YAAY,CACrB,OAAO,CAAE,GAAG,CACZ,gCAAa,CACX,YAAY,CAAE,CAAC,CACnB,6FAAI,CACF,OAAO,CAAE,GAAG,CACZ,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,IAAI,CAChB,qHAAS,CACP,KAAK,CdkB2B,OAAW,CcjBjD,qBAAqB,CACnB,aAAa,CAAE,CAAC,CAChB,KAAK,CdkB+B,OAAW,CcjB/C,SAAS,CAAE,GAAG,CACd,OAAO,CAAE,YAAY,CbanB,oCAAsB,CaTxB,qBAAqB,CACnB,OAAO,CAAE,IAAI,CACf,uCAAuC,CACrC,OAAO,CAAE,IAAI,EAEjB,YAAY,CACV,uCAAuC,CACrC,OAAO,CAAE,IAAI,EC9BjB,SAAS,CACP,QAAQ,CAAE,KAAK,CACf,GAAG,CCAO,OAAO,CDGjB,gBAAO,CACL,eAAe,CAAE,IAAI,CAEzB,cAAc,C/B+FZ,KAAK,CAAE,CAAC,CACR,0CAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,oBAAO,CACL,KAAK,CAAE,IAAI,C+BnGb,mCAAM,CACJ,OAAO,CAAE,YAAY,CACvB,uBAAQ,CACN,UAAU,CAAE,qBAAoB,CAEhC,6BAAa,CACX,WAAW,CAAE,iBAAyB,CACxC,8BAAc,CACZ,YAAY,CAAE,iBAAyB,CAC3C,gBAAC,CACC,MAAM,CAAE,IAAmB,CAC3B,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,IAAmB,CAChC,OAAO,CAAE,MAAiB,CAE9B,iBAAiB,CACf,KAAK,CjBuD+B,KAAK,CiBtDzC,oDAAiB,CACf,MAAM,CAAE,IAAmB,CAC3B,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,IAAmB,CAChC,OAAO,CAAE,SAAS,CAClB,aAAa,CAAE,CAAC,CAChB,OAAO,CAAE,KAAK,CACd,WAAW,CAAE,IAAI,CACjB,cAAc,CAAE,SAAS,CACzB,SAAS,CAAE,GAAG,CACd,KAAK,CfZ6B,IAAK,CeavC,WAAW,CAAE,MAAM,CAErB,oBAAE,CACA,aAAa,CAAE,CAAC,CAEhB,+BAAY,CACV,UAAU,CAAE,iBAAyB,CACvC,kCAAe,CACb,aAAa,CAAE,iBAAyB,CAC1C,4BAAS,CACP,UAAU,CAAE,OAA4C,CACxD,8BAAC,CACC,KAAK,CfhByB,IAAY,CeiB1C,YAAY,CAAE,iBAAsD,CACpE,OAAO,CAAE,gBAAyB,CAClC,oCAAO,CACL,UAAU,CAAE,OAA4C,CAC9D,mGAAI,CACF,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,OAAO,CACnB,KAAK,CAAE,OAAO,CACd,YAAY,CAAE,CAAC,CACf,aAAa,CAAE,CAAC,CAElB,wCAAmB,CACjB,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,IAAI,CACX,WAAW,CAAE,MAAM,CAGnB,SAAS,CAAE,KAAI,CACf,WAAW,CAAE,KAAK,CAClB,KAAK,CAAE,OAA8B,CAGzC,wDAAuB,CACrB,KAAK,Cf1C6B,OAAW,Ce2C7C,OAAO,CAAE,gBAAmB,CAC5B,WAAW,CAAE,IAAI,CACjB,QAAQ,CAAE,QAAQ,CAClB,UAAU,CfrCwB,OAAyB,CesC3D,MAAM,CAAE,IAAI,CACZ,aAAa,CAAE,iBAAsD,CACrE,UAAU,CAAE,iBAAsD,CAClE,YAAY,CAAE,YAAY,CAE1B,oEAAO,CACL,UAAU,Cf5CsB,OAAyB,Ce6CzD,4GAAmB,CACjB,KAAK,CfrDyB,IAAY,CesD9C,gGAAmB,CAGjB,OAAO,CAAE,KAAK,CACd,SAAS,CAAE,KAAI,CACf,WAAW,CAAE,KAAK,CAClB,KAAK,CAAE,IAA8B,CAIvC,iHAAI,CACF,OAAO,CAAE,IAAI,CACf,iIAAc,CACZ,OAAO,CAAE,KAAK,CAGd,yCAAG,CACD,UAAU,CAAE,OAA4C,CACxD,OAAO,CAAE,gBAAyB,CACpC,uDAAiB,CACf,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,OAA4C,CACxD,OAAO,CAAE,gBAAyB,CACtC,2DAA2B,CACzB,KAAK,Cf9E2B,IAAY,Ce+E9C,mDAAmB,CACjB,KAAK,CAAE,OAA4C,CACvD,+BAAa,CACX,SAAS,CAAE,KAAI,CAEb,yCAAG,CACD,UAAU,CAAE,OAA4C,CACxD,OAAO,CAAE,gBAAyB,CACpC,uDAAiB,CACf,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,OAA4C,CACxD,OAAO,CAAE,gBAAyB,CAClC,UAAU,CAAE,IAAI,CAChB,aAAa,CAAE,IAAI,CACvB,2DAA2B,CACzB,KAAK,Cf9F2B,IAAY,Ce+F9C,mDAAmB,CACjB,KAAK,CAAE,OAA4C,CACvD,+BAAa,CACX,SAAS,CAAE,KAAI,CAEjB,+BAAa,CACX,OAAO,CAAE,KAAK,CAChB,uBAAK,CACH,aAAa,CAAE,CAAC,CAChB,OAAO,CAAE,IAAI,CAEb,kCAAK,CACH,OAAO,CAAE,KAAK,CAClB,4BAAU,CACR,aAAa,CAAE,CAAC,CAChB,KAAK,Cf7G6B,OAAW,Ce8G7C,WAAW,CAAE,MAAM,CACrB,mBAAC,CACC,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,gBAAmB,CAC5B,OAAO,CAAE,KAAK,CACd,QAAQ,CAAE,QAAQ,CAClB,SAAS,CAAE,GAAG,CACd,KAAK,CftH6B,OAAW,CeuH7C,yBAAO,CACL,gBAAgB,CAAE,OAAoC,CACtD,MAAM,CAAE,OAAO,CACf,6CAAmB,CACjB,KAAK,Cf3HyB,OAAW,Ce4H7C,0BAAQ,CACN,gBAAgB,CftHgB,OAAK,CeuHrC,MAAM,CAAE,OAAO,CACf,KAAK,Cf9H2B,IAAM,Ce+HtC,8CAAmB,CACjB,KAAK,CfhIyB,IAAM,CekI5C,mBAAmB,CACjB,OAAO,CAAE,KAAK,CACd,KAAK,CjBvF+B,KAAK,CiBwFzC,OAAO,CAAE,OAAW,CACpB,aAAa,CAAE,OAAW,CAC1B,OAAO,CjBrF6B,GAAG,CiBsFvC,gBAAgB,CflIoB,OAAK,CemIzC,UAAU,CAAE,MAAM,CAClB,OAAO,CAAE,OAAW,CACpB,OAAO,CAAE,KAAK,CACd,KAAK,CfvI+B,OAAyB,CewI7D,aAAa,CAAE,OAAW,CAC1B,oCAAgB,CACd,KAAK,CAAE,IAAI,CACX,aAAa,CAAE,IAAI,CACnB,OAAO,CAAE,QAAQ,CACjB,YAAY,CAAE,OAAuB,CACvC,uBAAG,CACD,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,sBAA0B,CAClC,MAAM,CAAE,IAAI,CACZ,KAAK,CAAE,IAAI,CACX,gBAAgB,CflJkB,OAAK,CemJvC,OAAO,CAAE,GAAG,CACZ,aAAa,CAAE,IAAI,CACrB,wDAAqB,CACnB,KAAK,CfvJ6B,OAAyB,CewJ3D,SAAS,CAAE,IAAI,CACf,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,YAAY,CACrB,OAAO,CAAE,OAA2C,CACpD,aAAa,CAAE,OAAW,CAE1B,oEAAO,CACL,UAAU,CAAE,qBAAoB,CAClC,0EAAQ,CACN,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,MAAM,CACd,MAAM,CAAE,IAAI,CACZ,KAAK,CAAE,IAAI,CACX,aAAa,CAAE,CAAC,CAChB,SAAS,CAAE,IAAI,CACf,UAAU,CAAE,WAAa,CAEzB,oFAAQ,CACN,UAAU,CAAE,MAAM,CACxB,+BAAa,CACX,UAAU,CAAE,SAAkB,CAC9B,aAAa,CAAE,OAAW,CAC1B,WAAW,CAAE,MAAM,CACnB,KAAK,CAAE,qBAAoB,CAI7B,gCAAM,CACJ,KAAK,CfnL6B,OAAK,CeoLzC,2BAAC,CACC,KAAK,Cf5L6B,OAAW,Ce6L7C,iCAAO,CACL,gBAAgB,CfvLgB,OAAK,CewLrC,KAAK,Cf9L2B,IAAM,CegM5C,gBAAgB,CjC3NR,kBAAoB,CAAE,gBAAM,CAK5B,eAAiB,CAAE,gBAAM,CAezB,UAAY,CAAE,gBAAM,CiCyM1B,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,CAAC,CACV,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,CAAC,CACV,4BAAa,CACX,IAAI,CAAE,CAAC,CACP,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,CAAC,CACZ,0BAAW,CACT,KAAK,CAAE,IAAI,CACX,IAAI,CAAE,KAAK,CACX,OAAO,CAAE,CAAC,CACZ,2BAAY,CACV,KAAK,CAAE,KAAK,CACZ,IAAI,CAAE,IAAI,CACV,OAAO,CAAE,CAAC,CAGd,gBAAgB,CACd,UAAU,CAAE,qBAAuC,CACnD,gBAAgB,CAAE,2uCAA2uC,CAC7vC,eAAe,CAAE,SAAsB,CAEzC,gBAAgB,CACd,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CAEd,YAAY,CACV,QAAQ,CAAE,KAAK,CACf,GAAG,CAAE,CAAC,CACN,MAAM,CAAE,CAAC,CACT,IAAI,CAAE,CAAC,CACP,cAAc,CAAE,GAAG,CACnB,KAAK,CjBvL+B,KAAK,CiBwLzC,UAAU,CAAE,MAAM,CAClB,UAAU,CAAE,MAAM,CAClB,UAAU,CAAE,IAAI,CAChB,UAAU,CfrO0B,OAAsB,CesO1D,OAAO,CjBvL6B,GAAG,CiByLzC,eAAe,CACb,KAAK,CAAE,KAAyB,CAChC,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,MAAM,CAClB,UAAU,CAAE,MAAM,CAClB,MAAM,CAAE,IAAI,CAEd,WAAW,CACT,OAAO,CAAE,IAAI,CACb,UAAU,Cf9O0B,OAAK,Ce+OzC,KAAK,CfrP+B,IAAM,CesP1C,OAAO,CAAE,gBAAuB,CAChC,QAAQ,CAAE,QAAQ,CAClB,WAAW,CAAE,IAAI,CACjB,UAAU,CAAE,MAAM,CAClB,SAAS,CAAE,IAAI,C/BvLf,KAAK,CAAE,CAAC,CACR,oCAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,iBAAO,CACL,KAAK,CAAE,IAAI,C+BmLb,aAAC,CACC,KAAK,Cf7P6B,IAAM,Ce8PxC,WAAW,CAAE,IAAI,CAEnB,eAAG,CACD,YAAY,CAAE,IAAqB,CACnC,MAAM,CAAE,IAAI,CACZ,KAAK,CAAE,IAAI,CACX,gBAAgB,Cf9PkB,OAAK,Ce+PvC,OAAO,CAAE,GAAG,CACZ,aAAa,CAAE,IAAI,CACrB,aAAC,CACC,SAAS,CAAE,IAAI,CACf,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,OAAO,CAEnB,oBAAoB,CAClB,WAAW,CjBhOyB,KAAK,CiBiOzC,UAAU,CfzQ0B,OAAyB,Ce0Q7D,UAAU,CAAE,IAAI,CAElB,eAAe,CACb,OAAO,CAAE,eAAmB,CAC5B,MAAM,CAAE,IAAI,CACZ,SAAS,CAAE,KAAK,CAChB,MAAM,CAAE,IAAI,CAEd,aAAa,CACX,QAAQ,CAAE,KAAK,CACf,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,eAAc,CAC1B,OAAO,CAAE,IAAI,CACb,OAAO,CAAE,GAAkB,CAC3B,gBAAI,CACF,OAAO,CAAE,KAAK,CAClB,MAAM,CACJ,KAAK,CflT+B,IAAW,CemT/C,QAAC,CACC,aAAa,CAAE,IAAqB,CACtC,6FAAgB,CACd,OAAO,CAAE,GAAG,CACZ,WAAW,CfhRuB,wMAAQ,CeiR1C,SAAS,CAAE,GAAG,CACd,UAAU,CAAE,IAAI,CAChB,MAAM,CAAE,IAAI,CACZ,KAAK,Cf3T6B,IAAW,Ce6TjD,mBAAmB,C/BzOjB,KAAK,CAAE,CAAC,CACR,oDAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,yBAAO,CACL,KAAK,CAAE,IAAI,C+BuOb,0BAAU,CACR,aAAa,CjBrTqB,IAAI,CiBsTtC,aAAa,CAAE,iBAA6B,CAC5C,cAAc,CjBvToB,IAAI,CiBwTxC,sCAAsB,CACpB,UAAU,CAAE,iBAA6B,CACzC,WAAW,CjB1TuB,IAAI,CiB2TxC,4BAAY,CACV,SAAS,CAAE,IAAI,CACf,aAAa,CAAE,IAAqB,CACpC,OAAO,CAAE,YAAY,CACvB,wBAAQ,CACN,KAAK,Cf9T6B,IAAY,Ce+T9C,SAAS,CAAE,GAAG,CdjUd,oCAAsB,CcqUxB,gBAAgB,CACd,UAAU,Cf7TwB,OAAyB,Ce8T7D,WAAW,CACT,OAAO,CAAE,KAAK,CAChB,YAAY,CAER,IAAI,CAAE,MAAmB,CAG3B,kBAAO,CACL,KAAK,CAAE,GAAG,CACV,IAAI,CAAE,CAAC,CACX,eAAe,CACb,KAAK,CAAE,IAAI,CACb,mBAAmB,CACjB,KAAK,CAAE,IAAI,CACb,yBAAyB,CACvB,KAAK,CAAE,IAAI,CACb,oBAAoB,CAClB,WAAW,CAAE,CAAC,CACd,oCAAe,CACb,OAAO,CCxXD,OAAO,CDyXf,0BAAO,CACL,QAAQ,CAAE,KAAK,CACf,SAAS,CAAE,IAAI,CACf,IAAI,CAAE,GAAG,CACT,GAAG,CAAE,CAAC,CACN,MAAM,CAAE,IAAI,CACZ,QAAQ,CAAE,MAAM,EdjWlB,qCAAsB,CcoWxB,oBAAoB,CAClB,UAAU,CAAE,gBAAe,CAC7B,eAAe,CACb,MAAM,CAAE,CAAC,CACT,UAAU,Cf/VwB,OAAyB,EeiW/D,YAAY,CACV,iCAAmC,CACjC,OAAO,CAAE,IAAI,CACf,oBAAoB,CAClB,WAAW,CAAE,CAAC,EE9YlB,aAAa,CACX,QAAQ,CAAE,KAAK,CACf,MAAM,CAAE,CAAC,CACT,IAAI,CAAE,CAAC,CACP,KAAK,CnB6E+B,KAAK,CmB5EzC,KAAK,CjBoC+B,OAAyB,CiBnC7D,UAAU,CAAE,OAAkC,CAC9C,UAAU,CAAE,kBAAiC,CAC7C,WAAW,CjB+CyB,uDAAM,CiB9C1C,OAAO,CnB+E6B,GAAG,CmB9EvC,eAAC,CACC,KAAK,CjB+B6B,OAAK,CiB9BvC,eAAe,CAAE,IAAI,CACvB,8BAAgB,CACd,OAAO,CAAE,IAAI,CACf,kCAAoB,CAClB,OAAO,CAAE,IAAqB,CAC9B,gBAAgB,CAAE,OAAkC,CACpD,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,KAAK,CACjB,SAAS,CAAE,GAAG,CACd,MAAM,CAAE,OAAO,CACf,KAAK,CjBX6B,OAAM,ChB4F1C,KAAK,CAAE,CAAC,CACR,kFAAS,CAEP,OAAO,CAAE,KAAK,CACd,OAAO,CAAE,EAAE,CACb,wCAAO,CACL,KAAK,CAAE,IAAI,CiCrFX,uqDAAG,CACD,KAAK,CjBgB2B,OAAyB,CiBf3D,yFAAQ,CACN,KAAK,CAAE,IAAI,CACb,6CAAU,CACR,KAAK,CAAE,IAAI,CACb,kDAAiB,CACf,gBAAgB,CnBQgB,OAAI,CmBPpC,KAAK,CjBI2B,IAAM,CiBHxC,yDAAwB,CACtB,gBAAgB,CjBmBgB,OAAO,CiBlBvC,KAAK,CnBzB2B,IAAI,CmB0BxC,0CAA8B,CAC5B,OAAO,CAAE,KAAK,CAChB,iCAAmB,CACjB,SAAS,CAAE,GAAG,CACd,OAAO,CAAE,IAAqB,CAC9B,KAAK,CjBP6B,IAAY,CiBQ9C,OAAO,CAAE,IAAI,CACb,oCAAE,CACA,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,MAAM,CAAE,CAAC,CACT,MAAM,CAAE,MAAM,CACd,OAAO,CAAE,CAAC,CACV,UAAU,CAAE,iBAA6C,CAC3D,oCAAE,CACA,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,CAAC,CACT,sCAAC,CACC,OAAO,CAAE,YAAY,CACrB,OAAO,CAAE,GAAqB,CAC9B,KAAK,CjBfyB,OAAyB,CiBgB7D,uBAAW,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,KAAK,CAAE,IAAI,CACX,IAAI,CAAE,IAAI,CACV,MAAM,CAAE,IAAI,CACZ,SAAS,CnBkByB,KAAK,CmBjBvC,kCAAU,CACR,KAAK,CAAE,IAAI,CACb,mEAAQ,CACN,KAAK,CAAE,IAAI,CACb,qDAA+B,CAC7B,UAAU,CAAE,KAAK,CACjB,+HAAQ,CACN,KAAK,CAAE,IAAI,CACb,gEAAU,CACR,KAAK,CAAE,IAAI,CACf,4CAAoB,CAClB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,KAAuB,CAChC,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,MAAM,ChBhDpB,oCAAsB,CgBmDxB,aAAa,CACX,KAAK,CAAE,GAAG,CACV,OAAO,CAAE,IAAI,CACb,mBAAO,CACL,OAAO,CAAE,KAAK,CAClB,GAAG,CACD,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,ECzEd,gBAAG,CACD,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,eAAe,CAEzB,uBAAU,CACR,aAAa,CpBUqB,IAAI,CoBTtC,iCAAS,CACP,UAAU,CAAE,MAAM,CAEtB,oCAAuB,CACrB,UAAU,CAAE,MAAM,CAGpB,qDAAoC,CAClC,aAAa,CpBCqB,IAAI,CoBUxC,uBAAU,CACR,WAAW,CpBXuB,IAAI,CoBYtC,WAAW,CpBZuB,IAAI,CoBatC,aAAa,CpBbqB,IAAI,CoBmBtC,kTAAK,CACH,aAAa,CAAE,CAAC,CAKlB,qCAAQ,CACN,YAAY,CAAE,GAAG,CAUrB,8BAAiB,CACf,YAAY,CAAE,eAAc,CAC5B,mEAAM,CACJ,UAAU,CAAE,sBAAsB,CAClC,YAAY,CAAE,0BAAyB,CAG3C,0EAAiD,CAC/C,UAAU,CAAE,WAAW,CACzB,0EAAiD,CAC/C,UAAU,CAAE,WAAW,CAGzB,qDAA4B,CAC1B,aAAa,CAAE,IAAqB,CACtC,wBAAW,CACT,WAAW,CpBpDuB,IAAI,CoBuDxC,yBAAY,CACV,WAAW,CAAE,IAAI,CACjB,aAAa,CAAE,IAAqB,CACtC,yBAAY,CACV,KAAK,ClB3D6B,OAAW,CkB4D/C,yBAAY,CACV,KAAK,CAAE,KAAK,CACZ,MAAM,CAAE,iBAA2C,CACrD,wBAAW,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,iBAA2C,CACrD,0BAAa,CACX,MAAM,CAAE,IAAI,CACZ,OAAO,CAAE,KAAK,CAMd,6RAAW,CACT,OAAO,CAAE,IAAI,CACb,UAAU,CAAE,MAAM,CAClB,SAAS,CAAE,IAAI,CAEf,mVAAO,CACL,UAAU,CAAE,OAAO,CACnB,OAAO,CAAE,GAAO,CAChB,WAAW,CAAE,WAAW,CACxB,OAAO,CAAE,YAAY,CACzB,mVAAmB,CACjB,OAAO,CAAE,YAAY,CAGzB,qBAAQ,CACN,KAAK,CAAE,KAAK,CACZ,KAAK,CAAE,GAAG,CACV,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,aAAuC,CAC/C,OAAO,CpB7F2B,IAAI,CoB8FtC,UAAU,ClB9EwB,OAAmB,CkB+ErD,MAAM,CAAE,iBAA+B,CAEvC,yEAAS,CACP,SAAS,CAAE,GAAG,CAChB,2BAAK,CACH,aAAa,CAAE,CAAC,CAClB,oCAAc,CACZ,OAAO,CAAE,KAAK,CACd,WAAW,ClB/EqB,0DAAa,CkBgF7C,WAAW,CAAE,IAAI,CACjB,UAAU,ClBvFsB,OAAmB,CkBwFnD,OAAO,CAAE,QAA2C,CACpD,MAAM,CAAE,KAAkB,CAC1B,aAAa,CpB5GmB,IAAI,CoB6GpC,SAAS,CAAE,IAAI,CAEnB,yBAAY,CACV,UAAU,ClB3FwB,OAAO,CkB4FzC,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,KAAuB,CAGlC,iEAAwC,CACtC,cAAc,CAAE,KAAK,CACrB,SAAS,CAAE,GAAG,CAIhB,yEAAgD,CAC9C,UAAU,CAAE,IAAI,CAChB,MAAM,CAAE,IAAI,CACZ,KAAK,ClB5I6B,IAAW,CkB6I7C,+JAAM,CACJ,MAAM,CAAE,IAAI,CACZ,gBAAgB,CAAE,sBAAsB,CACxC,WAAW,CAAE,MAAM,CACrB,2FAAQ,CACN,YAAY,CAAE,CAAC,CACf,aAAa,CAAE,CAAC,CAChB,cAAc,CAAE,GAAG,CACrB,mKAAI,CACF,KAAK,ClBhJ2B,IAAK,CkBuJzC,6BAAgB,CAEd,MAAM,CAAE,IAAI,CACZ,gCAAE,CACA,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,GAAG,CAClB,uCAAW,CACT,OAAO,CAAE,YAAY,CACrB,UAAU,CAAE,GAAG,CACjB,yCAAW,CACT,aAAa,CAAE,IAAI,CACnB,UAAU,CAAE,IAAI,CAChB,WAAW,CAAE,MAAM,CACrB,yCAAW,CACT,UAAU,CAAE,IAAI,CAChB,YAAY,CAAE,CAAC,CAGnB,iDAAQ,CAEN,KAAK,CpB1L6B,IAAI,CoB2LtC,OAAO,CAAE,OAAO,CAChB,wHAAO,CACL,SAAS,CAAE,eAAe,CAC1B,WAAW,CAAE,MAAM,CAErB,yEAAS,CACP,KAAK,CpBpK2B,OAAI,CoBqKtC,wHAAW,CACT,WAAW,CAAE,IAAI,CACjB,KAAK,ClB9K2B,OAAW,CkBgL/C,uDAAY,CACV,KAAK,ClBvK6B,OAAK,CkBwKzC,eAAE,CACA,aAAa,CpBnLqB,IAAI,CoBoLtC,kBAAE,CACA,WAAW,CAAE,IAAI,CAEnB,6EAAgB,CACd,aAAa,CAAE,eAAgC,CAEjD,kBAAE,CACA,MAAM,CAAE,aAA4C,CAMxD,8BAAiB,CACf,aAAa,CpBlMqB,IAAI,CoBoMtC,iCAAE,CACA,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,KAAuB,CAC/B,SAAS,CAAE,GAAG,CACd,WAAW,CAAE,MAAM,CACnB,UAAU,CAAE,OAA0B,CACtC,KAAK,ClBhM2B,OAAK,CkBiMrC,UAAU,CAAE,iBAAoC,CAChD,OAAO,CAAE,GAAqB,CAC9B,QAAQ,CAAE,QAAQ,CAClB,wCAAQ,CACN,KAAK,CAAE,OAA0B,CACnC,6CAAW,CACT,KAAK,ClBjNyB,OAAW,CkBkNzC,SAAS,CAAE,eAAe,CAE9B,oCAAK,CACH,aAAa,CAAE,GAAqB,CACpC,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,cAAuB,CACpC,UAAU,CAAE,OAAa,CACzB,KAAK,ClBhO2B,IAAK,CkBiOrC,gDAAW,CACT,KAAK,ClB3NyB,OAAW,CkB4NzC,SAAS,CAAE,eAAe,CAC9B,6CAAc,CACZ,UAAU,CAAE,CAAC,CAEf,uGAAQ,CACN,WAAW,CAAE,IAAI,CACjB,oRAA2B,CACzB,gBAAgB,CAAE,WAAW,CAC7B,MAAM,CAAE,IAAI,CACZ,OAAO,CAAE,CAAC,CACV,SAAS,CAAE,eAAe,CAC5B,kIAAU,CACR,WAAW,CAAE,IAAI,CAErB,wCAAS,CACP,OAAO,CAAE,YAAY,CACrB,OAAO,CAAE,KAAK,CACd,KAAK,CpBnQ2B,IAAI,CoBoQpC,WAAW,CAAE,IAAI,CACnB,wCAAS,CACP,OAAO,CAAE,YAAY,CACrB,aAAa,CAAE,GAAG,CAEtB,uDAA8B,CAC5B,OAAO,CAAE,YAAY,CACrB,KAAK,ClB1Q6B,OAAM,CkB2QxC,SAAS,CAAE,GAAG,CACd,YAAY,CpBvPsB,IAAI,CoBwPxC,2BAAc,CACZ,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,KAAK,CACd,qBAAQ,CACN,aAAa,CAAE,IAAI,CACnB,WAAW,CAAE,IAAI,CAEnB,mDAAa,CACX,UAAU,CAAE,OAAO,CACnB,OAAO,CAAE,OAAO,CAChB,WAAW,CAAE,OAAO,CACpB,SAAS,CAAE,OAAO,CAClB,KAAK,CAAE,OAAO,CACd,MAAM,CAAE,OAAO,CACf,WAAW,CAAE,OAAO,CAIlB,mGAAQ,CACN,YAAY,CAAE,GAAG,CjB3QrB,oCAAsB,CiBgRtB,qBAAQ,CACN,KAAK,CAAE,IAAI,ECjTjB,wBAAwB,CACtB,KAAK,CnB+B+B,OAAW,CmB7BjD,KAAK,CACH,UAAU,CAAE,MAAM,YCHlB,WAAW,CAAE,aAAa,CAC1B,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,GAAG,CAChB,GAAG,CAAE,0GAAoB,YAGzB,WAAW,CAAE,aAAa,CAC1B,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,GAAG,CAChB,GAAG,CAAE,yGAAyB,YAG9B,WAAW,CAAE,MAAM,CACnB,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,GAAG,CAChB,GAAG,CAAE,6FAAqB,YAG1B,WAAW,CAAE,MAAM,CACnB,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,GAAG,CAChB,GAAG,CAAE,oFAAkB,YAGvB,WAAW,CAAE,aAAa,CAC1B,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,GAAG,CAChB,GAAG,CAAE,gHAA4B,YAGjC,WAAW,CAAE,aAAa,CAC1B,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,GAAG,CAChB,GAAG,CAAE,uGAAyB", "sources": ["../../../bower_components/neat/app/assets/stylesheets/grid/_grid.scss","../../../bower_components/bourbon/dist/addons/_prefixer.scss","../../../bower_components/wyrm/sass/wyrm_core/_reset.sass","../../../bower_components/wyrm/sass/wyrm_core/_mixin.sass","../../../bower_components/font-awesome/scss/_path.scss","../../../bower_components/font-awesome/scss/_core.scss","../../../bower_components/font-awesome/scss/_larger.scss","../../../bower_components/font-awesome/scss/_fixed-width.scss","../../../bower_components/font-awesome/scss/_list.scss","../../../bower_components/font-awesome/scss/_variables.scss","../../../bower_components/font-awesome/scss/_bordered-pulled.scss","../../../bower_components/font-awesome/scss/_spinning.scss","../../../bower_components/font-awesome/scss/_rotated-flipped.scss","../../../bower_components/font-awesome/scss/_mixins.scss","../../../bower_components/font-awesome/scss/_stacked.scss","../../../bower_components/font-awesome/scss/_icons.scss","../../../bower_components/wyrm/sass/wyrm_core/_font_icon_defaults.sass","../../../bower_components/wyrm/sass/wyrm_core/_wy_variables.sass","../../../bower_components/wyrm/sass/wyrm_core/_alert.sass","../../../sass/_theme_variables.sass","../../../bower_components/neat/app/assets/stylesheets/grid/_media.scss","../../../bower_components/wyrm/sass/wyrm_core/_button.sass","../../../bower_components/wyrm/sass/wyrm_core/_dropdown.sass","../../../bower_components/wyrm/sass/wyrm_core/_form.sass","../../../bower_components/neat/app/assets/stylesheets/grid/_outer-container.scss","../../../bower_components/neat/app/assets/stylesheets/settings/_grid.scss","../../../bower_components/neat/app/assets/stylesheets/grid/_span-columns.scss","../../../bower_components/wyrm/sass/wyrm_core/_neat_extra.sass","../../../bower_components/wyrm/sass/wyrm_core/_generic.sass","../../../bower_components/wyrm/sass/wyrm_core/_table.sass","../../../bower_components/wyrm/sass/wyrm_core/_type.sass","../../../bower_components/wyrm/sass/wyrm_addons/pygments/_pygments.sass","../../../bower_components/wyrm/sass/wyrm_addons/pygments/_pygments_light.sass","../../../sass/_theme_breadcrumbs.sass","../../../sass/_theme_layout.sass","../../../bower_components/neat/app/assets/stylesheets/grid/_private.scss","../../../sass/_theme_badge.sass","../../../sass/_theme_rst.sass","../../../sass/_theme_mathjax.sass","../../../sass/_theme_font_local.sass"], diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb new file mode 100644 index 0000000..5c54eb1 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb @@ -0,0 +1,111 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "18ad6013", + "metadata": {}, + "source": [ + "\"HPE" + ] + }, + { + "cell_type": "markdown", + "id": "20da06d1", + "metadata": {}, + "source": [ + "

    Scripts related to BIOS

    " + ] + }, + { + "cell_type": "markdown", + "id": "fa8b0fad", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Change BIOS SettingsUpdate BIOS Settings for iLO serverPATCHBIOS_ChangeSettings
    BIOS DefaultUpdate BIOS to default settingPOSTBIOS_RevertToDefault
    \n" + ] + }, + { + "cell_type": "markdown", + "id": "81721043", + "metadata": {}, + "source": [ + "

    Scripts related to Users

    " + ] + }, + { + "cell_type": "markdown", + "id": "cf10b943", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Add User AccountAdd new user accountPATCHAdd user account
    \n" + ] + }, + { + "cell_type": "markdown", + "id": "5e16cdec", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb new file mode 100644 index 0000000..2d7d55f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb @@ -0,0 +1,285 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25002fd3", + "metadata": {}, + "source": [ + "

    Change BIOS Settings

    " + ] + }, + { + "cell_type": "markdown", + "id": "6a14567a", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to change BIOS settings. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b0a99221", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb04ead1", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "8505c876", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our change bios settings function overview, in the end this will be able to change the bios settings.

    \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in systems_response.\n", + " Then we set the systems_members_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", + "
    \n", + "\n", + "5. Then if bios password is present, then we will update the bios password. Finally we will send patch request from redfish object using bios_setting_uri. \n", + "\n", + " Ultimately if the operation was successfull without any errors then we will get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "243405a4", + "metadata": {}, + "outputs": [], + "source": [ + "def change_bios_setting(_redfishobj, bios_property, property_value, bios_password):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if bios_uri:\n", + " #BIOS settings URI is needed\n", + " \n", + " bios_settings_uri = bios_data.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " body = {'Attributes': {bios_property: property_value}}\n", + " \n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " resp = _redfishobj.patch(bios_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " #uncomment if you would like to see the full list of attributes\n", + " #print(\"\\n\\nShowing BIOS attributes after changes:\\n\\n\")\n", + " #bios_data = _redfishobj.get(bios_uri)\n", + " #print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "2c62673d", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.


    \n", + " Please enter iLO url, username, password, bios.attribute, attribute_value and bios password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "1f44368d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14547cd7", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " BIOS_PASSWORD = getpass.getpass(\"Enter bios password: \")\n", + " \n", + " #provide the attribute name and the associated attribute value. Note: some, values may\n", + " #be containers (arrays or dictionaries) so keep this in mind.\n", + " \n", + " ATTRIBUTE = input(\"Enter bios property you wish to change (Example: AdminName): \")\n", + " ATTRIBUTE_VAL = input(\"Enter Value of the property to change (Example: Luigi): \")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_bios_setting(REDFISHOBJ, ATTRIBUTE, ATTRIBUTE_VAL, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "91b6f3c6", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba53975e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb new file mode 100644 index 0000000..783c9d5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb @@ -0,0 +1,331 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ad9eed9d", + "metadata": {}, + "source": [ + "

    Reverting the BIOS to it's default values

    " + ] + }, + { + "cell_type": "markdown", + "id": "9bdc5c94", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b6adafee", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2c1c9a1c", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_5976/2509830492.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "# Import the required libraries\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "# Import the helper function\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as inut securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "397110c8", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our reset bios to default function overview, in the end this will set the bios settings to default.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the bios_revert_default function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an HTTP GET request is made and response is stored in bios_response.\n", + " Then we set the resret_action_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios settings of the user through redfish object and then then set the path to post the action we will perform\n", + "
    \n", + "\n", + "5. Then we set the bios settings to default using the action type as Bios.ResetBios and say set it to default\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91157e79", + "metadata": {}, + "outputs": [], + "source": [ + "def bios_revert_default(_redfishobj):\n", + " # Initialize the BIOS reset action URI (Uniform Resource Identifier)\n", + " bios_reset_action_uri = None\n", + " \n", + " # Get the resource directory to find the relevant URI\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " # If resource directory is not available or not to be used, find the relevant URI\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " # Get the systems URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " \n", + " # Get the systems members URI\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " \n", + " # Get the BIOS URI\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " \n", + " # Get the BIOS reset action URI\n", + " bios_reset_action_uri = bios_response.obj['Actions']['#Bios.ResetBios']['target']\n", + " else:\n", + " # Use resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_data.obj['Actions']['#Bios.ResetBios']['target']\n", + " break\n", + " \n", + " # Define the body for the POST request\n", + " body = {'Action': 'Bios.ResetBios', 'ResetType': 'default'}\n", + " \n", + " # Send the POST request\n", + " resp = _redfishobj.post(bios_reset_action_uri, body)\n", + " \n", + " # Check the response status\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b26b9819", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f9886e56", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fbdb430d", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: ncs\n", + "Enter Login account: bsdk\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_5976/2691500454.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mSYSTEM_URL\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter System URL: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mLOGIN_ACCOUNT\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter Login account: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mLOGIN_PASSWORD\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetpass\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter your password: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m# flag to force disable resource directory. Resource directory and associated operations are\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36mgetpass\u001b[1;34m(self, prompt, stream)\u001b[0m\n\u001b[0;32m 986\u001b[0m \u001b[0mstacklevel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 987\u001b[0m )\n\u001b[1;32m--> 988\u001b[1;33m return self._input_request(\n\u001b[0m\u001b[0;32m 989\u001b[0m \u001b[0mprompt\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 990\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"shell\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[1;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[0;32m 1049\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1050\u001b[0m \u001b[1;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1051\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Interrupted by user\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1052\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1053\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Invalid Message:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: Interrupted by user" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " # Call the function to revert BIOS to default values\n", + " bios_revert_default(REDFISHOBJ)\n", + "\n", + " # Logout from the Redfish client\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "2f8583d9", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0f8133c1", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f31a351", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb new file mode 100644 index 0000000..3144945 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/bios_revert_default-checkpoint.ipynb @@ -0,0 +1,259 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Reverting the BIOS to default values" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to reset your bios to default settings!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "658962be-a0df-4696-ab9e-73f844703ff9", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  125. sys \n", + "
  126. \n", + "
  127. json
  128. \n", + "
  129. redfish
  130. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "53341fc4-f674-4781-bcb1-04bb06d3d1fb", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    This is our reset bios to default function overview, in the end this will set the bios settings to default.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the bios_revert_default function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in bios_response.\n", + " Then we set the resret_action_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios settings of the user through redfish object and then then set the path to post the action we will perform\n", + "
    \n", + "\n", + "5. Then we set the bios settings to default using the action type as Bios.ResetBios and say set it to default\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a5f7d7b2-6ab5-473d-ba19-113d603f9e2d", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def bios_revert_default(_redfishobj):\n", + "\n", + " bios_reset_action_uri = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_response.obj['Actions']['#Bios.ResetBios']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_data.obj['Actions']['#Bios.ResetBios']['target']\n", + " break\n", + "\n", + " body = {'Action': 'Bios.ResetBios', 'ResetType':'default'}\n", + " resp = _redfishobj.post(bios_reset_action_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " bios_revert_default(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d0ded655-d8e4-452d-b181-783a6b1788f5", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb new file mode 100644 index 0000000..2d7d55f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb @@ -0,0 +1,285 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25002fd3", + "metadata": {}, + "source": [ + "

    Change BIOS Settings

    " + ] + }, + { + "cell_type": "markdown", + "id": "6a14567a", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to change BIOS settings. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b0a99221", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb04ead1", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "8505c876", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our change bios settings function overview, in the end this will be able to change the bios settings.

    \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in systems_response.\n", + " Then we set the systems_members_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", + "
    \n", + "\n", + "5. Then if bios password is present, then we will update the bios password. Finally we will send patch request from redfish object using bios_setting_uri. \n", + "\n", + " Ultimately if the operation was successfull without any errors then we will get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "243405a4", + "metadata": {}, + "outputs": [], + "source": [ + "def change_bios_setting(_redfishobj, bios_property, property_value, bios_password):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if bios_uri:\n", + " #BIOS settings URI is needed\n", + " \n", + " bios_settings_uri = bios_data.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " body = {'Attributes': {bios_property: property_value}}\n", + " \n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " resp = _redfishobj.patch(bios_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " #uncomment if you would like to see the full list of attributes\n", + " #print(\"\\n\\nShowing BIOS attributes after changes:\\n\\n\")\n", + " #bios_data = _redfishobj.get(bios_uri)\n", + " #print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "2c62673d", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.


    \n", + " Please enter iLO url, username, password, bios.attribute, attribute_value and bios password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "1f44368d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14547cd7", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " BIOS_PASSWORD = getpass.getpass(\"Enter bios password: \")\n", + " \n", + " #provide the attribute name and the associated attribute value. Note: some, values may\n", + " #be containers (arrays or dictionaries) so keep this in mind.\n", + " \n", + " ATTRIBUTE = input(\"Enter bios property you wish to change (Example: AdminName): \")\n", + " ATTRIBUTE_VAL = input(\"Enter Value of the property to change (Example: Luigi): \")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_bios_setting(REDFISHOBJ, ATTRIBUTE, ATTRIBUTE_VAL, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "91b6f3c6", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba53975e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb new file mode 100644 index 0000000..783c9d5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb @@ -0,0 +1,331 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ad9eed9d", + "metadata": {}, + "source": [ + "

    Reverting the BIOS to it's default values

    " + ] + }, + { + "cell_type": "markdown", + "id": "9bdc5c94", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b6adafee", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2c1c9a1c", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_5976/2509830492.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "# Import the required libraries\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "# Import the helper function\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as inut securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "397110c8", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our reset bios to default function overview, in the end this will set the bios settings to default.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the bios_revert_default function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an HTTP GET request is made and response is stored in bios_response.\n", + " Then we set the resret_action_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios settings of the user through redfish object and then then set the path to post the action we will perform\n", + "
    \n", + "\n", + "5. Then we set the bios settings to default using the action type as Bios.ResetBios and say set it to default\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91157e79", + "metadata": {}, + "outputs": [], + "source": [ + "def bios_revert_default(_redfishobj):\n", + " # Initialize the BIOS reset action URI (Uniform Resource Identifier)\n", + " bios_reset_action_uri = None\n", + " \n", + " # Get the resource directory to find the relevant URI\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " # If resource directory is not available or not to be used, find the relevant URI\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " # Get the systems URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " \n", + " # Get the systems members URI\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " \n", + " # Get the BIOS URI\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " \n", + " # Get the BIOS reset action URI\n", + " bios_reset_action_uri = bios_response.obj['Actions']['#Bios.ResetBios']['target']\n", + " else:\n", + " # Use resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_data.obj['Actions']['#Bios.ResetBios']['target']\n", + " break\n", + " \n", + " # Define the body for the POST request\n", + " body = {'Action': 'Bios.ResetBios', 'ResetType': 'default'}\n", + " \n", + " # Send the POST request\n", + " resp = _redfishobj.post(bios_reset_action_uri, body)\n", + " \n", + " # Check the response status\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b26b9819", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f9886e56", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fbdb430d", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: ncs\n", + "Enter Login account: bsdk\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_5976/2691500454.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mSYSTEM_URL\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter System URL: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mLOGIN_ACCOUNT\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter Login account: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mLOGIN_PASSWORD\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetpass\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter your password: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m# flag to force disable resource directory. Resource directory and associated operations are\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36mgetpass\u001b[1;34m(self, prompt, stream)\u001b[0m\n\u001b[0;32m 986\u001b[0m \u001b[0mstacklevel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 987\u001b[0m )\n\u001b[1;32m--> 988\u001b[1;33m return self._input_request(\n\u001b[0m\u001b[0;32m 989\u001b[0m \u001b[0mprompt\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 990\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"shell\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[1;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[0;32m 1049\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1050\u001b[0m \u001b[1;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1051\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Interrupted by user\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1052\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1053\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Invalid Message:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: Interrupted by user" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " # Call the function to revert BIOS to default values\n", + " bios_revert_default(REDFISHOBJ)\n", + "\n", + " # Logout from the Redfish client\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "2f8583d9", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0f8133c1", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f31a351", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb new file mode 100644 index 0000000..524a7a2 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

    Add new user account by iLO privileges or redfish standard roles

    " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will help you to add new user account by iLO privileges or redfish standard roles. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy.
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen\n", + "\n", + "#to take password inputs securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally, use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
    \n", + "
    Instructions
    \n", + "
      \n", + "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", + "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", + "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", + "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b99181a4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: f\n", + "Enter Login account: f\n", + "Enter your password: ········\n", + "Enter Account Login Name: f\n", + "Enter Account User Name: f\n", + "Enter Account password: ········\n", + "Enter ROLE_ID: f\n", + "For the below privilages enter 'True' if that privilages needs to be set for the user else enter 'False'\n", + "Truef\n", + "Truef\n", + "Truef\n", + "Truef\n" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " #account login name (iLO GUI actually considers this to be 'UserName', but\n", + " #this is the redfish standard username)\n", + " ACCOUNT_LOGIN_NAME = input(\"Enter Account Login Name: \")\n", + "\n", + " #account user name (iLO GUI actually considers this to be 'LoginName', but\n", + " #this is the redfish login)\n", + " ACCOUNT_USER_NAME = input(\"Enter Account User Name: \")\n", + "\n", + " #account password\n", + " ACCOUNT_PASSWORD = getpass.getpass(\"Enter Account password: \")\n", + "\n", + " #A predefined role for the user, (The redfish standard method for accounts).\n", + " #This is a translated to a pre-configured arrangement of privileges on HPE servers\n", + " ROLE_ID = input(\"Enter ROLE_ID: \") #Administrator, ReadOnly or Operator are available\n", + "\n", + " #Dictionary of modifiable privileges for HPE servers (modify this if you wish to directly set\n", + " #an account with specific privileges\n", + " \n", + " PRIVILEGE_DICT = {\"iLOConfigPriv\": True, \"VirtualMediaPriv\": True, \"RemoteConsolePriv\": True, \"UserConfigPriv\": True, \"VirtualPowerAndResetPriv\": True, \\\n", + " \"SystemRecoveryConfigPriv\": True, \"LoginPriv\": True, \"HostStorageConfigPriv\": True, \"HostNICConfigPriv\": True,\n", + " \"HostBIOSConfigPriv\": True}\n", + " \n", + " print(\"For the below privilages enter 'True' if that privilages needs to be set for the user else enter 'False'\")\n", + " \n", + " for key in PRIVILEGE_DICT.keys():\n", + " PRIVILEGE_DICT[key] = input(f\"{key}\")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " ca_cert_data = {}\n", + " ca_cert_data[\"cert_file\"] = \"c:\\\\test\\\\ppcacuser.crt\"\n", + " ca_cert_data[\"key_file\"] = \"c:\\\\test\\\\ppcacuserpriv.key\"\n", + " ca_cert_data[\"key_password\"] = \"password\"\n", + " LOGIN_ACCOUNT = None\n", + " LOGIN_PASSWORD = None\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD, ca_cert_data=ca_cert_data)\n", + " #REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, ca_cert_data=ca_cert_data)\n", + " # Login with the Redfish client\n", + " if ca_cert_data is None:\n", + " REDFISHOBJ.login()\n", + " else:\n", + " REDFISHOBJ.login(auth='certificate')\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " #obtain all account instances, by navigating set paths and keys to find the relevant URI\n", + " #(account_collection_uri, accounts, rd) = get_accounts(redfishobj, DISABLE_RESOURCE_DIR)\n", + " #print(\"\\n\\nShowing accounts before changes:\\n\\n\")\n", + " #show_accounts(redfishobj, accounts)\n", + "\n", + " #if account_collection_uri and accounts:\n", + " #add specified account\n", + " (ilogen,_) = get_gen(REDFISHOBJ)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " add_ilo_user_account(REDFISHOBJ,ACCOUNT_LOGIN_NAME,ACCOUNT_USER_NAME,ACCOUNT_PASSWORD,ROLE_ID,PRIVILEGE_DICT)\n", + " else:\n", + " add_ilo_user_account_gen9(REDFISHOBJ,ACCOUNT_LOGIN_NAME,ACCOUNT_USER_NAME,ACCOUNT_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b490052", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb similarity index 52% rename from examples/Jupyter_notebooks/HPECTY/index.ipynb rename to examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb index 4c277c2..5c54eb1 100644 --- a/examples/Jupyter_notebooks/HPECTY/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb @@ -8,6 +8,14 @@ "\"HPE" ] }, + { + "cell_type": "markdown", + "id": "20da06d1", + "metadata": {}, + "source": [ + "

    Scripts related to BIOS

    " + ] + }, { "cell_type": "markdown", "id": "fa8b0fad", @@ -24,33 +32,58 @@ " \n", " \n", " \n", - " BIOS Settings\n", + " Change BIOS Settings\n", " Update BIOS Settings for iLO server\n", " PATCH\n", - " change_bios_setting\n", + " BIOS_ChangeSettings\n", " \n", " \n", " BIOS Default\n", " Update BIOS to default setting\n", - " PATCH\n", - " revert_bios_default\n", + " POST\n", + " BIOS_RevertToDefault\n", + " \n", + " \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "81721043", + "metadata": {}, + "source": [ + "

    Scripts related to Users

    " + ] + }, + { + "cell_type": "markdown", + "id": "cf10b943", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Powermetrics AverageGet powewr measurement average of serversGETget_powermetrics_average
    Add User AccountAdd new user accountPATCHAdd user account
    \n" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "62458584", + "cell_type": "markdown", + "id": "5e16cdec", "metadata": {}, - "outputs": [], "source": [] } ], diff --git a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb index 98e679b..024bc9d 100644 --- a/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/examples/.ipynb_checkpoints/change_bios_settings-checkpoint.ipynb @@ -319,7 +319,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.9.7" } }, "nbformat": 4, diff --git a/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb b/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb index aa96161..3144945 100644 --- a/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb +++ b/examples/Jupyter_notebooks/examples/bios_revert_default.ipynb @@ -15,7 +15,7 @@ "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", "metadata": {}, "source": [ - "

    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�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

    \n", + "
    \n", "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to reset your bios to default settings!!
    As you are here let's get it done easily.
    \n", " To perform this u need to have python-ilorest-library installed in your machine.
    \n", " And please keep your username and password handy!\n", @@ -251,7 +251,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.9.7" } }, "nbformat": 4, diff --git a/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb b/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb index 98e679b..024bc9d 100644 --- a/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb +++ b/examples/Jupyter_notebooks/examples/change_bios_settings.ipynb @@ -319,7 +319,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.9.7" } }, "nbformat": 4, From 256a9a18eb2f6771ea274f430b3039853d93fc8c Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:12:14 +0530 Subject: [PATCH 006/159] Create Dharitri --- examples/Jupyter_notebooks/HPECTY/Dharitri | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri b/examples/Jupyter_notebooks/HPECTY/Dharitri new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri @@ -0,0 +1 @@ + From 9d504c7a478d05680b6de3c4a450b342d09021b3 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:12:58 +0530 Subject: [PATCH 007/159] Delete Dharitri --- examples/Jupyter_notebooks/HPECTY/Dharitri | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri b/examples/Jupyter_notebooks/HPECTY/Dharitri deleted file mode 100644 index 8b13789..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri +++ /dev/null @@ -1 +0,0 @@ - From 49339589adba0ddc74de1be67a6654dc81fe974e Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:13:39 +0530 Subject: [PATCH 008/159] Create index.ipynb --- examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb @@ -0,0 +1 @@ + From b6493691e127fdb6c4e9c0a96ed9d0a33bc0d109 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:18:19 +0530 Subject: [PATCH 009/159] Add files via upload --- .../HPECTY/Dharitri/clear_ahs_data.ipynb | 254 ++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb new file mode 100644 index 0000000..8d3ee2f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d7d850", + "metadata": { + "tags": [] + }, + "source": [ + "# Clearing AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "88f096f8", + "metadata": {}, + "source": [ + "
    \n", + "Welcome to python-iLOrest-library
    Here is an example to Clearing AHS(Active Health System) data!!!
    \n", + " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " Please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d1525f25", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
  131. sys \n", + "
  132. \n", + "
  133. json
  134. \n", + "
  135. redfish
  136. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ce9142d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b9615aea", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


    \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", + " Then we set the active_health_system_clear_log_uri.\n", + "
    \n", + "\n", + "4. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", + "
    \n", + "\n", + "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", + "\n", + " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "16042277", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ahs_data(_redfishobj):\n", + "\n", + " active_health_system_clear_log_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " break\n", + "\n", + " if active_health_system_clear_log_uri:\n", + " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", + " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "6e7543eb", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
    \n", + "
    \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270f99bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ahs_data(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "1557bfee", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e685a623", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ec1827cff6f45dfd2ddefd6bc188151e199831a5 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:18:57 +0530 Subject: [PATCH 010/159] Delete clear_ahs_data.ipynb --- .../HPECTY/Dharitri/clear_ahs_data.ipynb | 254 ------------------ 1 file changed, 254 deletions(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb deleted file mode 100644 index 8d3ee2f..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/clear_ahs_data.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e2d7d850", - "metadata": { - "tags": [] - }, - "source": [ - "# Clearing AHS data for HPE iLO systems" - ] - }, - { - "cell_type": "markdown", - "id": "88f096f8", - "metadata": {}, - "source": [ - "
    \n", - "Welcome to python-iLOrest-library
    Here is an example to Clearing AHS(Active Health System) data!!!
    \n", - " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " Please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "d1525f25", - "metadata": { - "tags": [] - }, - "source": [ - "
    \n", - "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", - "
  137. sys \n", - "
  138. \n", - "
  139. json
  140. \n", - "
  141. redfish
  142. \n", - " \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ce9142d", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory\n", - "import getpass" - ] - }, - { - "cell_type": "markdown", - "id": "b9615aea", - "metadata": {}, - "source": [ - "
    \n", - "

    2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


    \n", - " \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", - "\n", - "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
    \n", - " \n", - "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", - "
    \n", - "\n", - "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", - " Then we set the active_health_system_clear_log_uri.\n", - "
    \n", - "\n", - "4. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", - "
    \n", - "\n", - "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", - "\n", - " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "16042277", - "metadata": {}, - "outputs": [], - "source": [ - "def clear_ahs_data(_redfishobj):\n", - "\n", - " active_health_system_clear_log_uri = None\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", - " ['ActiveHealthSystem']['@odata.id']\n", - " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", - " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", - " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", - " active_health_system_uri = instance['@odata.id']\n", - " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", - " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", - " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", - " break\n", - "\n", - " if active_health_system_clear_log_uri:\n", - " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", - " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", - "\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", - " sort_keys=True))\n", - " except Exception:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" - ] - }, - { - "cell_type": "markdown", - "id": "6e7543eb", - "metadata": {}, - "source": [ - "
    \n", - "

    3. This is Main function overview.

    \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", - "\n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", - "
    \n", - " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", - "
    \n", - "\n", - "3. Once you enter everything a redfish object is created with the help of RedfishClient class.
    \n", - "
    \n", - "\n", - "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", - "
    \n", - "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
    \n", - "
    \n", - "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "270f99bf", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", - " \n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " clear_ahs_data(REDFISHOBJ)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "1557bfee", - "metadata": {}, - "source": [ - "
    \n", - " When running on the server locally : use the following values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " \"https://10.0.0.100\"
    \n", - " \"https://ilo.hostname\"\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "e685a623", - "metadata": {}, - "source": [ - "
    In case you need help 🔗 links to relevant resources :\n", - "
    \n", - " 1.Python-ilorest-library:LINK
    \n", - " 2.Hpe ilorest-api explorer:LINK
    \n", - " 3.Rest api: LINK
    \n", - " \n", - "
    " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From e7a9f37c0cbc2328f50c18858bb380078c82a3af Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:19:27 +0530 Subject: [PATCH 011/159] Create clear_ahs_data --- examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data b/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data @@ -0,0 +1 @@ + From 2dcdb2252a7f9bcec1abd9e3b27efa319fb41291 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:19:46 +0530 Subject: [PATCH 012/159] Add files via upload --- .../HPECTY/Dharitri/AHS/clear_ahs_data.ipynb | 254 ++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb new file mode 100644 index 0000000..8d3ee2f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d7d850", + "metadata": { + "tags": [] + }, + "source": [ + "# Clearing AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "88f096f8", + "metadata": {}, + "source": [ + "
    \n", + "Welcome to python-iLOrest-library
    Here is an example to Clearing AHS(Active Health System) data!!!
    \n", + " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " Please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d1525f25", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
  143. sys \n", + "
  144. \n", + "
  145. json
  146. \n", + "
  147. redfish
  148. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ce9142d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b9615aea", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


    \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
    \n", + "\n", + "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", + " Then we set the active_health_system_clear_log_uri.\n", + "
    \n", + "\n", + "4. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", + "
    \n", + "\n", + "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", + "\n", + " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "16042277", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ahs_data(_redfishobj):\n", + "\n", + " active_health_system_clear_log_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " break\n", + "\n", + " if active_health_system_clear_log_uri:\n", + " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", + " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "6e7543eb", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
    \n", + "
    \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270f99bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ahs_data(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "1557bfee", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e685a623", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 0469f13749d86bbe0feb9f3c9c7baf6b7f8caf49 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:20:17 +0530 Subject: [PATCH 013/159] Delete clear_ahs_data --- examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data b/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data deleted file mode 100644 index 8b13789..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data +++ /dev/null @@ -1 +0,0 @@ - From 58b0621cd4fb9666cc1f6fbcfab7f56fc61873a9 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:21:44 +0530 Subject: [PATCH 014/159] Create iLO --- examples/Jupyter_notebooks/HPECTY/Dharitri/iLO | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/iLO diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO b/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO @@ -0,0 +1 @@ + From a29097093ea377b2d9e7efa25324832d34aa8c2a Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:22:07 +0530 Subject: [PATCH 015/159] Delete iLO --- examples/Jupyter_notebooks/HPECTY/Dharitri/iLO | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/iLO diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO b/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO deleted file mode 100644 index 8b13789..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO +++ /dev/null @@ -1 +0,0 @@ - From d83f8d78de07b6d6fac853c40d80a6ecaf1119de Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Wed, 3 May 2023 02:23:02 +0530 Subject: [PATCH 016/159] Add files via upload --- .../Dharitri/COMPUTER/computer_details.ipynb | 230 ++++++++++++++++ .../Dharitri/iLO/clear_ilo_iel_iml_log.ipynb | 246 ++++++++++++++++++ .../HPECTY/Dharitri/index.ipynb | 133 +++++++++- 3 files changed, 608 insertions(+), 1 deletion(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb new file mode 100644 index 0000000..5051b63 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb @@ -0,0 +1,230 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a38bafdc", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering the computer system details" + ] + }, + { + "cell_type": "markdown", + "id": "cfe2e2b6", + "metadata": {}, + "source": [ + "
    \n", + " Welcome to python-iLOrest-library
    Here is an example to get_computer_details!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b3fec1a9", + "metadata": {}, + "source": [ + "
    \n", + "

    1. We are importing all the necessary modules from the ilorest library!


    \n", + "
  149. sys \n", + "
  150. \n", + "
  151. json
  152. \n", + "
  153. redfish
  154. \n", + "
  155. get_resource_directory
  156. \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab7125e9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "8d23d990", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is the function to get the computer details requested.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the computer_details function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about computer is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the computer data of iLO system.\n", + "
    \n", + "\n", + "3. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if computerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.\n", + " \n", + "
    \n", + " \n", + "5. Finally print the Computer Details through systems_members_response.\n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1b4d0494", + "metadata": {}, + "outputs": [], + "source": [ + "def computer_details(_redfishobj):\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " print(\"\\n\\nPrinting computer system details:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0de7de8", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " Enter iLO url, Username, Password
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, but if Server is not avaialbe we get an error saying \"server unreachable\".
    \n", + "
    \n", + "5. Then we call computer_details with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f538059", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " computer_details(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "bd337e8f", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f7fd2c36", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb new file mode 100644 index 0000000..19de2bd --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "89dc5655", + "metadata": { + "tags": [] + }, + "source": [ + "# CLEAR iLO LOGS" + ] + }, + { + "cell_type": "markdown", + "id": "898cbb84", + "metadata": {}, + "source": [ + "
    \n", + "Welcome to python-iLOrest-library
    Here is an example to for clearing out the iLO event log and management log at server side!
    As you are here let's get it done easily.
    \n", + " To perform this you need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "98f3c2dd", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
  157. sys \n", + "
  158. \n", + "
  159. json
  160. \n", + "
  161. redfish
  162. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "935d8f7c", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "ef3013ef", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This cell gives overview about of the function used to clear event logs such as IML and IEL logs.


    \n", + "The IML provides a record of historical events that have occurred on the server and the IEL is the iLO event log provides record of significant events detected by iLO.\n", + " \n", + "1. When the resource directory is disabled then we simply navigate through the API for obtaining the relevant uri.\n", + " The series of HTTP get requests aims to extracts log_services_response so as to get the path of the directory for which IEL and IML logs need to be cleared.\n", + "
    \n", + "2. Else if the resource directory enabled then rather we can simply extract the uri by #LogService.attribute inside the instance['odatatype'] dictionary and again make a HTTP get request to obtain the required uri.\n", + "
    \n", + "3. After obtaining the uri we just need to make changes on the same location using a post request so as to clear IEL and IML logs successfully. For this body dictionary contains the attribute to be changed and IEL/IML are searched in the path of clear_log_services_uri and the respective changes are made by redfishobj.post(path,body).\n", + "
    \n", + " \n", + "4. Later we also check for the response returned by the server side. If the response is anything outside of status code with 200 then error message gets rendered on the webpage else the success message is printed out with the response dictionary returned by the server.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a7abae2a", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ilo_event_log(_redfishobj, clear_IML_IEL):\n", + "\n", + " clear_log_services_uri = []\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " log_services_uri = systems_members_response.obj['LogServices']['@odata.id']\n", + " log_services_response = _redfishobj.get(log_services_uri)\n", + " log_services_uris = log_services_response.obj['Members']\n", + " for log_services_uri in log_services_uris:\n", + " log_services_response = _redfishobj.get(log_services_uri['@odata.id'])\n", + " clear_log_services_uri.append(log_services_response.obj['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#LogService.' in instance['@odata.type']:\n", + " log_service_uri = instance['@odata.id']\n", + " clear_log_services_uri.append(_redfishobj.get(log_service_uri).dict['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + "\n", + " if clear_log_services_uri:\n", + " body = {\"Action\": \"LogService.ClearLog\"}\n", + " for path in clear_log_services_uri:\n", + " if (\"IEL\" in clear_IML_IEL and \"IEL\" in path) or (\"IML\" in clear_IML_IEL and \\\n", + " \"IML\" in path):\n", + " if \"IEL\" in path:\n", + " sys.stdout.write(\"Clearing IEL log.\\n\")\n", + " else:\n", + " sys.stdout.write(\"Clearing IML log.\\n\")\n", + " resp = _redfishobj.post(path, body)\n", + " else:\n", + " continue\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "331b8289", + "metadata": {}, + "source": [ + "
    \n", + "

    3. The Main function


    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + " \n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.

    \n", + "4. If server is down or Unreachable we get server not reachable message!

    \n", + "5. Else if no error is encountered a function call is made i.e. clear_ilo_event_log(REDFISHOBJ, CLEAR_IEL_IML)that is responsible for handling clearing all the IEL and IML logs at the server side.

    \n", + "6. Lastly, REDFISHOBJ.logout logs us out of the system and ends the session.\n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4143942b", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " CLEAR_IML_IEL = \"IML\" # provide either the string IML or IEL\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ilo_event_log(REDFISHOBJ, CLEAR_IML_IEL)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "f120e784", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f702c0ae", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb index 8b13789..06dfc1f 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb @@ -1 +1,132 @@ - +{ + "cells": [ + { + "cell_type": "markdown", + "id": "18ad6013", + "metadata": {}, + "source": [ + "\"HPE" + ] + }, + { + "cell_type": "markdown", + "id": "20da06d1", + "metadata": {}, + "source": [ + "

    Scripts related to AHS

    " + ] + }, + { + "cell_type": "markdown", + "id": "fa8b0fad", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Clear AHS dataClear active health state data of iLO serverDELETEclear_ahs_data
    \n" + ] + }, + { + "cell_type": "markdown", + "id": "81721043", + "metadata": {}, + "source": [ + "

    Scripts related to Computer

    " + ] + }, + { + "cell_type": "markdown", + "id": "cf10b943", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Computer DetailsGet all the available computer/hosts details in iLO\tGETcomputer_details
    \n" + ] + }, + { + "cell_type": "markdown", + "id": "01ee71dd", + "metadata": {}, + "source": [ + "

    Scripts related to iLO

    " + ] + }, + { + "cell_type": "markdown", + "id": "fbce5754", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Clear iLO IEL IML log\tClearing out the iLO event log and management log at server sideDELETEclear_ilo_iel_iml_log
    \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 63670b0d2c2e78dc01d82a9fb087fd13384a822c Mon Sep 17 00:00:00 2001 From: tanveer128 <123229272+tanveer128@users.noreply.github.com> Date: Wed, 3 May 2023 10:40:57 +0530 Subject: [PATCH 017/159] Add files via upload --- .../HPECTY/Tanveer/account_remove.ipynb | 250 ++++++++++++ .../HPECTY/Tanveer/reboot_server (1).ipynb | 236 +++++++++++ .../HPECTY/Tanveer/reset_ESKM_eventlog.ipynb | 378 ++++++++++++++++++ .../HPECTY/Tanveer/reset_ilo.ipynb | 267 +++++++++++++ .../HPECTY/Tanveer/reset_serve.ipynb | 304 ++++++++++++++ 5 files changed, 1435 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/account_remove.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ESKM_eventlog.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ilo.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/account_remove.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/account_remove.ipynb new file mode 100644 index 0000000..7907409 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/account_remove.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remove iLO User Account" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to a particular user account on HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + "
    In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + " for proper execution of our code.
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of removing a user account from the HPE iLO systems\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    2.
    \n", + "
    \n", + " Below is the remove_ilo_user_account function, after sucessful execution of this function we will be able to delete the information of any user account that is present on the HPE iLO system.\n", + " \n", + "
    \n", + "Let me give you a walk through of it!\n", + "
    \n", + " \n", + "For removal of any general account from the system we will first have to search for the accounts that we wan't to delete based on any attribute or property that uniquely identifies the account. Upon finding that account we can just make http delete request and we are done!\n", + " \n", + "1. In the remove_ilo_user_account function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In case the resource directory was disabled we are navigating to the actual location where the all the member account information is stored by using DELETErequest.\n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources to obtain the account_collection_uri.\n", + "
    \n", + "4.
      \n", + "
    • Now we are having the location at which all the member accounts are present.
    • Simply we just find out what user account matches the account that has to be deleted based on username of the accounts.
    • If we do not find the required account after completion of iteration we print out a message that required acccount was not found on the server side.
    • \n", + "
    • After this we simply make a DELETE request to delete that particular account and save the response obtained in resp variable.
    If the http status code returned was 200, then we simply print a message that delete operation was success.
    \n", + " Else if the status code returned was anything else we print out the status code with an error message to get idea about what went wrong.\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def remove_ilo_user_account(_redfishobj, username_to_delete):\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " break\n", + "\n", + " #find the account to delete\n", + " account_uri_to_delete = None\n", + " #collection of account URIs located at the account_collection_uri endpoint using the HTTP GET method\n", + " account_uris = _redfishobj.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " # retrieving the account object located at the URI specified by account_uri['@odata.id'] using \n", + " #the HTTP GET method\n", + " account = _redfishobj.get(account_uri['@odata.id'])\n", + " #checking whether username is matching with the username_to_delete\n", + " if account.dict['UserName'] == username_to_delete:\n", + " account_uri_to_delete = account_uri['@odata.id']\n", + " break\n", + " #deleting a resource located at the account_uri_to_delete endpoint \n", + " if not account_uri_to_delete:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + " #deleting account found in the account_uri_to_delete\n", + " resp = _redfishobj.delete(account_uri_to_delete)\n", + " #checking the status for post request\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    3.
    \n", + "
    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • The ACCOUNT_TO_DELETE contains the username of the account that we need to delete. We are passing the same as an argument while making a call to remove_ilo_user_account function.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to remove_ilo_user_account function .
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + " \n", + " \n", + " # The username of the account to remove\n", + " ACCOUNT_TO_DELETE = \"joker\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " #calling function \n", + " remove_ilo_user_account(REDFISHOBJ, ACCOUNT_TO_DELETE)\n", + "\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb new file mode 100644 index 0000000..1dfae9f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb @@ -0,0 +1,236 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# REBOOTING A SERVER" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to perform rebooting of a server.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "
    \n", + "

    1

    \n", + "In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    2

    \n", + "In below cell is the reboot_server function.\n", + "Current cell is the overview of it, utimately at the end this will reboot the server and provide the response for the same.\n", + "
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. In the reboot server function we are first using system_members_response variable to obtain information about the path at which server related information is stored by using couple of get requests.\n", + "
    \n", + "2. If the resource directory was accessible then we simply search for '#ComputerSystem' key (as this is the place comprising of server related information inside the instance['odata.type'] dictionary and finally making a get request to that location.\n", + "
    \n", + " \n", + "3. If we obtain systems_response successfully then a ressettype list is created specifying the parameters that how we want to restart.\n", + " \n", + "\n", + "4. Later both the parameters are passed into a new dictionary named body and post request is created to make changes on the server side.\n", + " A successful HTTP post request will set the values at server end so that a server gets rebooted.\n", + " \n", + "\n", + "5. Lastly, we also save response status inside resp variable and check what is the status code returned to confirm whether the post request was success or not. If success then response by server is printed and if not then error message is printed.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def reboot_server(_redfishobj):\n", + "\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj.get_resource_directory)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_uri = instance['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " #code check for determines whether a systems_response object is present, finds the URI for resetting a computer \n", + " #system, builds a request body describing the reset action and type, then sends a POST request with the provided \n", + " #reset type to restart the system.\n", + " if systems_response:\n", + " system_reboot_uri = systems_response.obj['Actions']['#ComputerSystem.Reset']['target']\n", + " body = dict()\n", + " resettype = ['ForceRestart','GracefulRestart']\n", + " body['Action'] = 'ComputerSystem.Reset'\n", + " for reset in resettype:\n", + " if reset.lower() == \"forcerestart\":\n", + " body['ResetType'] = \"ForceRestart\"\n", + " resp = _redfishobj.post(system_reboot_uri, body)\n", + " elif reset.lower() == \"gracefulrestart\":\n", + " body['ResetType'] = \"GracefulRestart\"\n", + " resp = _redfishobj.post(system_reboot_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    3

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + " \n", + "
    • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to reboot_server function to perform rebooting of server.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " #login credentials\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " #function call\n", + " reboot_server(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ESKM_eventlog.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ESKM_eventlog.ipynb new file mode 100644 index 0000000..1ac340b --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ESKM_eventlog.ipynb @@ -0,0 +1,378 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d4d890e", + "metadata": { + "tags": [] + }, + "source": [ + "# Reset_ESKM_eventlog" + ] + }, + { + "cell_type": "markdown", + "id": "62aaa233", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to resetting the ESKM event log (ESKM stand for Enterprise Secure Key Manager)
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "fbfec992", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  163. sys \n", + "
  164. \n", + "
  165. json
  166. \n", + "
  167. redfish
  168. \n", + "
  169. RedfishClient
  170. \n", + "
  171. ServerDownOrUnreachableError
  172. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ee51abfe", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Collecting redfish\n", + " Downloading redfish-3.1.9-py3-none-any.whl (40 kB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.5/40.5 KB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting jsonpatch\n", + " Downloading jsonpatch-1.32-py2.py3-none-any.whl (12 kB)\n", + "Requirement already satisfied: jsonpointer in /home/tanveer/.local/lib/python3.10/site-packages (from redfish) (2.3)\n", + "Collecting requests-toolbelt\n", + " Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 KB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: requests in /usr/lib/python3/dist-packages (from redfish) (2.25.1)\n", + "Collecting jsonpath-rw\n", + " Downloading jsonpath-rw-1.4.0.tar.gz (13 kB)\n", + " Preparing metadata (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25hCollecting requests-unixsocket\n", + " Downloading requests_unixsocket-0.3.0-py2.py3-none-any.whl (11 kB)\n", + "Requirement already satisfied: decorator in /home/tanveer/.local/lib/python3.10/site-packages (from jsonpath-rw->redfish) (5.1.1)\n", + "Requirement already satisfied: ply in /usr/lib/python3/dist-packages (from jsonpath-rw->redfish) (3.11)\n", + "Requirement already satisfied: six in /usr/lib/python3/dist-packages (from jsonpath-rw->redfish) (1.16.0)\n", + "Building wheels for collected packages: jsonpath-rw\n", + " Building wheel for jsonpath-rw (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for jsonpath-rw: filename=jsonpath_rw-1.4.0-py3-none-any.whl size=15149 sha256=adb33a2925919ff914e1e8d37078e269f133f5a20afb9ba6d09a5f3a2cb743b7\n", + " Stored in directory: /home/tanveer/.cache/pip/wheels/e3/76/6f/c25be6a9e6cc9985b96e8c95997d46790242c6426ef68e754c\n", + "Successfully built jsonpath-rw\n", + "Installing collected packages: requests-unixsocket, requests-toolbelt, jsonpath-rw, jsonpatch, redfish\n", + "Successfully installed jsonpatch-1.32 jsonpath-rw-1.4.0 redfish-3.1.9 requests-toolbelt-1.0.0 requests-unixsocket-0.3.0\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install redfish" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9688b9d5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Collecting redfish-client\n", + " Downloading redfish_client-0.3.9-py2.py3-none-any.whl (13 kB)\n", + "Requirement already satisfied: requests>=2.16 in /usr/lib/python3/dist-packages (from redfish-client) (2.25.1)\n", + "Installing collected packages: redfish-client\n", + "Successfully installed redfish-client-0.3.9\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install redfish-client" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9b53ecf2", + "metadata": {}, + "outputs": [ + { + "ename": "ImportError", + "evalue": "cannot import name 'RedfishClient' from 'redfish' (/home/tanveer/.local/lib/python3.10/site-packages/redfish/__init__.py)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01msys\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mjson\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mredfish\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RedfishClient\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mredfish\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mrest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mv1\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ServerDownOrUnreachableError\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mget_resource_directory\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m get_resource_directory\n", + "\u001b[0;31mImportError\u001b[0m: cannot import name 'RedfishClient' from 'redfish' (/home/tanveer/.local/lib/python3.10/site-packages/redfish/__init__.py)" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b8c9efd9", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    Below is the overview of reset_ESKM_eventlog function. In this function we are providing secure management of cryptographic keys for various purposes for example encryption and authentication.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present for secure key manager.\n", + "\n", + "1. In the function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "\n", + "
    \n", + "\n", + "2. If the resource directory is enabled or we want to force it's non-use then navigate to the directory where managers members data is present. \n", + " Utilising the HPE (Hewlett Packard Enterprise) OEM Redfish implementation to retrieve the URI for the ESKM (Enterprise Security Key Manager) service.\n", + " By making a Redfish API call to reset the event log of the HPE Enterprise Secure Key Manager (ESKM) security service of an HPE server. It first tries to obtain the URI for the ESKM service using the HPE-specific resource directory, but if that is not available or disabled, it falls back to navigating the Redfish API object model to find the necessary URIs for the relevant managers and security service.\n", + " Once the URI for the ESKM service is obtained, a POST request is sent to the ClearESKMLog action using the post() method of the Redfish API object, with an empty dictionary in the body of the request.\n", + " \n", + "
    \n", + "\n", + "3. Else It iterates through a list of resource instances and checks if the instance type contains #HpeESKM in it. If found, it sets the URI of that resource instance as the ESKM URI and breaks out of the loop. \n", + " \n", + " \n", + "
    \n", + " \n", + "4. If above function retrive the URI for the ESKM service from the HPE-specific Links object then we retrieves the URI for a specific action to clear the ESKM log on an HPE server's Security Service ESKM resource, using the Redfish API. It then sets the action to be executed on the server in the request body.\n", + " \n", + "
    \n", + " \n", + " If the response of this POST request was 400 it means there was some error from server-side while doing the same operation and we inform the user about the error by It attempts to extract and pretty-print the extended error message information, but if this fails, it writes an error message to the standard error stream indicating that it was unable to access the iLO Extended Message Info.\n", + "
    \n", + " Else there can also be an error which we aren't aware of, in that case we print out the response status code alongwith erro message .
    \n", + " Ultimately, if everything went properly we print out the response object along with success message.\n", + " \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "93003c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def reset_ESKM_eventlog(_redfishobj):\n", + "\n", + " body = dict()\n", + " security_service_eskm_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " security_service_eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " security_service_eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if security_service_eskm_uri:\n", + " security_service_eskm_uri = _redfishobj.get(security_service_uri).obj.Links\\\n", + " ['ESKM']['@odata.id']\n", + " security_service_eskm_resp = _redfishobj.get(security_service_eskm_uri)\n", + " security_service_eskm_clearlog_uri = security_service_eskm_resp.obj['Actions']\\\n", + " ['#HpeESKM.ClearESKMLog']['target']\n", + " body[\"Action\"] = \"HpeESKM.ClearESKMLog\"\n", + " #We pass the URI and the dictionary as a POST command (part of the redfish object)\n", + " resp = _redfishobj.post(security_service_eskm_clearlog_uri, body)\n", + " #If iLO responds with something outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5a583e0e", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient object is being created mainly to log into the system with valid credentials.\n", + " \n", + "
    \n", + "\n", + "3. We try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "4. Then we call reset_ESKM_eventlogfunction with our redfish object and the function does the reset the ESKM_eventlog.\n", + " \n", + "
    \n", + " \n", + "\n", + "5. Lastly, REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "85745d7d", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " reset_ESKM_eventlog(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "69132144", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "ea6fce6f", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ilo.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ilo.ipynb new file mode 100644 index 0000000..5f8af82 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_ilo.ipynb @@ -0,0 +1,267 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d7d850", + "metadata": { + "tags": [] + }, + "source": [ + "# Resetting the Manager" + ] + }, + { + "cell_type": "markdown", + "id": "88f096f8", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to Resetting the Manager
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "d1525f25", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  173. sys \n", + "
  174. \n", + "
  175. json
  176. \n", + "
  177. redfish
  178. \n", + "
  179. ServerDownOrUnreachableError
  180. \n", + "
  181. get_resource_directory
  182. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "8ce9142d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b9615aea", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our clear_ahs_data to function overview, in the end this will clear ahs data.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the resetting a manager function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. If the resource instance is not empty then the code fetches information about a manager from a collection of \"Managers\" resources on a target system, using a Redfish client object. It retrieves the first member's URI, and then gets more details about that specific member.\n", + "
    \n", + "\n", + "3. Else i.e; then iterates through a collection of Redfish resource instances and checks if the type of each instance is #Manager. If it is, the code retrieves more information about that specific instance using the Redfish client object _redfishobj.\n", + "
    \n", + "\n", + "4. If manager_members_respone is ture then it retrieves the URI for the Reset action on a specific Redfish manager using the managers_members_response variable, and then creates a request body containing the Action key with the value Manager.Reset. Finally, it sends a POSTrequest to the retrieved URI using the Redfish client object _redfishobj to initiate a reset operation on the target system.\n", + "
    \n", + " 5.Next is to check the status of the response received from the previous POST request sent using the Redfish client object _redfishobj.\n", + "
    \n", + " 1.If the status is 400, it attempts to print the extended error message associated with the response.\n", + "
    \n", + " 2.If the response status is not 400 and not 200, an error message is printed to the standard error stream.\n", + "
    \n", + " 3.If the response status is 200, it indicates that the reset operation was successful. The code then prints a success message and prints the JSON response received from the server in a formatted way.\n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "16042277", + "metadata": {}, + "outputs": [], + "source": [ + "def reset_ilo(_redfishobj, DISABLE_RESOURCE_DIR):\n", + "\n", + " managers_members_response = None\n", + " \n", + " #function get_resource_directory returns Redfish resource instances from client object.\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " #checking target resource is empty are not \n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Manager.' in instance['@odata.type']:\n", + " managers_members_uri = instance['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " #checking the managers_members_response true or not\n", + " if managers_members_response:\n", + " reset_ilo_uri = managers_members_response.obj['Actions']['#Manager.Reset']['target']\n", + " body = {'Action': 'Manager.Reset'}\n", + " resp = _redfishobj.post(reset_ilo_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "6e7543eb", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call reset_ilofunction with two parameters redfish object,DISABLE_RESOURCE_DIR with our redfish object and rest the settings to default.\n", + "
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270f99bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " reset_ilo(REDFISHOBJ, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "1557bfee", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e685a623", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb new file mode 100644 index 0000000..9356919 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb @@ -0,0 +1,304 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Reset_server" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to reseting the server!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + " Declared a global variable i.e; DISABLE_RESOURCE_DIR.
    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  183. sys \n", + "
  184. \n", + "
  185. json
  186. \n", + "
  187. redfish
  188. \n", + "
  189. RedfishClient
  190. \n", + "
  191. ServerDownOrUnreachableError
  192. \n", + "
  193. get_resource_directory
  194. \n", + "
  195. get_gen
  196. \n", + " \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import argparse\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    This is our resetting_server function overview, in the end this function the server get restarted.

    \n", + "

    Let me give you a walk through of it!

    \n", + " 1.If either of no resource instance or DISABLE_RESOURCE_DIR flag is set then it retrieve the URI for systems from the root object, get the response for the systems URI using the Redfish API object, retrieve the URI for the members from the systems response object, and then get the response for the members URI using the Redfish API object.\n", + "
    \n", + "
    \n", + " 2.Else i.e;iterates through the resource instances, checking if the @odata.type value contains ComputerSystem. If found, it assigns the @odata.id value to managers_members_uri and retrieves the response using the Redfish API object.\n", + "
    \n", + "
    \n", + " 3.This code gets the URI for the computer system reset action, builds a dictionary with an action value and reset type, iterates through reset types, then posts the body to the URI for each reset type using the Redfish API object if managers_members_response exists.\n", + "
    \n", + "
    \n", + " 4.Next is to check the status of the response received from the previous POST request sent using the Redfish client object _redfishobj.\n", + "
    \n", + " 1.If the status is 400, it attempts to print the extended error message associated with the response.\n", + "
    \n", + " 2.If the response status is not 400 and not 200, an error message is printed to the standard error stream.\n", + "
    \n", + " 3.If the response status is 200, it indicates that the reset operation was successful. The code then prints a success message and prints the JSON response received from the server in a formatted way.\n", + "
    \n", + "
    \n", + " 5. Again function call reset_server_gen9(_redfishobj) uses the Redfish API object to retrieve the response for the managers URI, the response object to retrieve the URI for the computer system reset action, etc. The action value and reset type are created in a dictionary,and the reset type is changed to ForceRestart after printing the URI.\n", + "
    \n", + " Again the POST request sent by using RedFish client object is again checked.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def reset_server(_redfishobj):\n", + " \n", + " managers_members_response = None\n", + " #Assigns resource directory to variable using Redfish API object\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " #checking if no resource instance or DISABLE_RESOURCE_DIR flag is set \n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if \"ComputerSystem.\" in instance['@odata.type']:\n", + " managers_members_uri = instance['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " \n", + " if managers_members_response:\n", + " path = managers_members_response.obj[\"Actions\"][\"#ComputerSystem.Reset\"][\"target\"]\n", + " body = dict()\n", + " resettype = ['ForceRestart','GracefulRestart']\n", + " body[\"Action\"] = \"ComputerSystem.Reset\"\n", + " for reset in resettype:\n", + " if reset.lower() == \"forcerestart\":\n", + " body['ResetType'] = \"ForceRestart\"\n", + " resp = _redfishobj.post(path, body)\n", + " elif reset.lower() == \"gracefulrestart\":\n", + " body['ResetType'] = \"GracefulRestart\"\n", + " resp = _redfishobj.post(path, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " \n", + "#creates a dictionary containing an action value and reset type, then posts the dictionary to the \n", + "#computer system reset action URI to reset a server using the Redfish API.\n", + "def reset_server_gen9(_redfishobj):\n", + " \n", + " managers_uri = \"/redfish/v1/Systems/1/\"\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " system_path = managers_response.obj[\"Actions\"][\"#ComputerSystem.Reset\"][\"target\"]\n", + " print(system_path)\n", + " body = dict()\n", + " body[\"Action\"] = \"Reset\"\n", + " body[\"ResetType\"] = \"ForceRestart\"\n", + "\n", + " resp = _redfishobj.post(system_path, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    The Main function:

    \n", + "
      \n", + "
    • After initilize the parser and adds argument such as the iLO IP address, username, and password as three command-line options to the parser. Each argument has a corresponding default value and help text.
    • \n", + "
    • In try section of code ;utilising the supplied iLO IP address, login, and password, to create a Redfish client object. If the login is successful, the get_gen function is used to check the server generation, and based on the generation number, the proper reset method is selected. The reset_server function is called if the server is a Gen5 server; otherwise, the reset_server_gen9 function is called. An error message is printed to the console and the script terminates if the server cannot be reached or does not support Redfish.
    • \n", + "
    • REDFISHOBJ.logout() will take care of logging you out of the ilo.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'argparse' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;18m__name__\u001b[39m \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__main__\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# Initialize parser \u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m parser \u001b[38;5;241m=\u001b[39m \u001b[43margparse\u001b[49m\u001b[38;5;241m.\u001b[39mArgumentParser(description \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mScript to upload and flash NVMe FW\u001b[39m\u001b[38;5;124m\"\u001b[39m) \n\u001b[1;32m 5\u001b[0m parser\u001b[38;5;241m.\u001b[39madd_argument(\n\u001b[1;32m 6\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-i\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m 7\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m--ilo\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 10\u001b[0m help\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miLO IP of the server\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 11\u001b[0m default\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m 12\u001b[0m parser\u001b[38;5;241m.\u001b[39madd_argument(\n\u001b[1;32m 13\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-u\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m 14\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m--user\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 17\u001b[0m help\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miLO username to login\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 18\u001b[0m default\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'argparse' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # Initialize parser \n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\") \n", + "\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + " #stroing namespace object in options\n", + " options = parser.parse_args()\n", + " #getting namespaceobject ilo_ip address\n", + " system_url = \"https://\" + options.ilo_ip\n", + " #printing the url obtain by ip\n", + " print (system_url)\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " \n", + " (ilogen,_) = get_gen(redfish_obj)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " reset_server(redfish_obj)\n", + " else:\n", + " reset_server_gen9(redfish_obj)\n", + " redfish_obj.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a91b90ee07bdb734756eae7c73bba86728d8c36b Mon Sep 17 00:00:00 2001 From: venkatrahul2003 <104755146+venkatrahul2003@users.noreply.github.com> Date: Wed, 3 May 2023 14:00:13 +0530 Subject: [PATCH 018/159] Create B VENKAT RAHUL --- examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL @@ -0,0 +1 @@ + From 188210fbe3d0bb2af97fdc822bc635ad7e820ffe Mon Sep 17 00:00:00 2001 From: venkatrahul2003 <104755146+venkatrahul2003@users.noreply.github.com> Date: Wed, 3 May 2023 14:00:33 +0530 Subject: [PATCH 019/159] Delete B VENKAT RAHUL --- examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL deleted file mode 100644 index 8b13789..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL +++ /dev/null @@ -1 +0,0 @@ - From bf7b207000b40002cc34d0e12431f1e0d97b10c5 Mon Sep 17 00:00:00 2001 From: venkatrahul2003 <104755146+venkatrahul2003@users.noreply.github.com> Date: Wed, 3 May 2023 14:11:48 +0530 Subject: [PATCH 020/159] Add files via upload --- .../eject_virtual_media_iso.ipynb | 263 +++++++++++++++ .../B VENKAT RAHUL/enable_secure_boot-.ipynb | 250 ++++++++++++++ .../B VENKAT RAHUL/enabling_ntp_server.ipynb | 309 ++++++++++++++++++ .../B VENKAT RAHUL/find_ilo_mac_address.ipynb | 228 +++++++++++++ .../HPECTY/B VENKAT RAHUL/generate_csr.ipynb | 279 ++++++++++++++++ 5 files changed, 1329 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb new file mode 100644 index 0000000..9556027 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "45dd47a5", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of mounting virtual media for HPE iLO systems
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "23eeb2bf", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92ec68a2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "10a8e977", + "metadata": {}, + "source": [ + "

    2.

    This is our mount_virtual_media_iso function overview, in the end this will give us with virtual media related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the virtual media information.\n", + "\n", + "1. In the mount_virtual_media_iso function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about virtual media is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The virtual media information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if virtual media is present in @odata.type attribute then we will store information about virtual media in virtual_media_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if virtual_media_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f034ef9c", + "metadata": {}, + "outputs": [], + "source": [ + "def mount_virtual_media_iso(_redfishobj, media_type,):\n", + "\n", + " virtual_media_uri = None\n", + " virtual_media_response = []\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", + " virtual_media_uri = instance['@odata.id']\n", + "\n", + " if virtual_media_uri:\n", + " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", + " for virtual_media_slot in virtual_media_response.obj['Members']:\n", + " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", + " if media_type in data.dict['MediaTypes']:\n", + " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.EjectMedia']['target']\n", + " post_body = {\"Action\": \"HpeiLOVirtualMedia.EjectVirtualMedia\"}\n", + " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "268b5a18", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab494baf", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 25\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 26\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 27\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 31\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 30\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 31\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 32\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 33\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " \n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #specify the type of content the media represents\n", + " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + "\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " mount_virtual_media_iso(REDFISHOBJ, MEDIA_TYPE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "90621a8a", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a839daaa", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + " \n", + "
    \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb new file mode 100644 index 0000000..3bcdf99 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b44c9aad", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of enabling secure boot
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "74ee46a2", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below
    \n", + " \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3b9ca27", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "d0e073c6", + "metadata": {}, + "source": [ + "

    2.

    This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", + "\n", + "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", + " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", + "
    \n", + "\n", + "3. In the systems response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in systems_members_response.\n", + " The secure boot information is ultimately present in the systems_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d60549e", + "metadata": {}, + "outputs": [], + "source": [ + "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", + "\n", + " secure_boot_uri = None\n", + " secure_boot_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#SecureBoot.' in instance['@odata.type']:\n", + " secure_boot_uri = instance['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + "\n", + " if secure_boot_data:\n", + " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if secure_boot_uri:\n", + " body = {'SecureBootEnable': secure_boot_enable}\n", + " resp = _redfishobj.patch(secure_boot_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b227f8f6", + "metadata": {}, + "source": [ + "
    \n", + "

    The Main function:

    \n", + "

    Please enter your login credentials here to proceed further:

    \n", + "
      \n", + "
    • Once your credentials are entered, a Redfish object is created with the help of the RedfishClient class, and a session is created to log you in to the server.
    • \n", + "
    • If the server is down or unreachable, we get a \"server not reachable\" message.
    • \n", + "
    • If not, we make a call to the enable_secure_boot function to obtain secure boot-related information of the system.
    • \n", + "
    • After getting the required information, Redfish.logout() closes the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8028b4ff", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Properties:\n", + " #secure boot enable property\n", + " SECURE_BOOT_ENABLE = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "28cb201c", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cf8a164b", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb new file mode 100644 index 0000000..656cc07 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb @@ -0,0 +1,309 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ENABLING NTP SERVER " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to enable ntp servers .
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    2

    \n", + "Below function describes the process how to enable NTP servers for HPE ilo systems. NTP or Network Time Protocol is an internet protocol used to synchronize with computer clokc time sources in a network. \n", + "Current cell is the explains the processes performed inside the below function.\n", + "
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. Initially, to obtain NTP server related information for HPE ilo systems a series of HTTP GET requests are being made so as to navigate to that path inside the iLO rest api where required information is stored.\n", + "After completion of these get requests we will be having the relevant uri in manager_ethernet_interfaces_members.\n", + "
    \n", + "2. Else if resource directory is enabled we can just use the resource directory to and then again navigate through the api to find relevant uri.\n", + "
    \n", + " \n", + "3. Whatever changes need to be made to enable the NTP server are being enclosed inside the dictionary named as body. Next up for all the instances of ethernet in ethernet_data we simply make a HTTP PATCH request by passing the ethernet instance and body dictionary with the PATCH request. \n", + " \n", + "\n", + "4. Following the patch request, the response returned by server is being saved inside resp variable and later if the server returns proper response it means there is no error else error is returned with error information. A reference for json.dumps\n", + "function as it is used multiple times - click here.\n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def enable_ntp(_redfishobj, ntp_servers, DISABLE_RESOURCE_DIR):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " print(json.dumps(ethernet_data, indent=4, sort_keys=True))\n", + "\n", + " body = {\"Oem\": {\"Hpe\": {\"DHCPv4\": {\"UseNTPServers\": ntp_servers}, \\\n", + " \"DHCPv6\": {\"UseNTPServers\": ntp_servers}}}}\n", + " for ethernet in ethernet_data:\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " _data = _redfishobj.get(ethernet).dict\n", + " sys.stdout.write(\"\\nShowing \\'%s\\' interface after changes:\\n\" % ethernet)\n", + " print(json.dumps(_data, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    3

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + " \n", + "
    • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to enable_ntp function by passing parameters such as redfishclient object and enable flag to perform required operation.
    • \n", + "
    • After getting required information Redfish.logout() closes the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'ilorest'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mgetpass\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m redfish_client\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mredfish_object\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RedfishClient\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mexceptions\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ServerDownOrUnreachableError\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'ilorest'" + ] + } + ], + "source": [ + "import getpass\n", + "from ilorest import redfish_client\n", + "from ilorest.redfish_object import RedfishClient\n", + "from ilorest.exceptions import ServerDownOrUnreachableError\n", + "\n", + "def main():\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n", + "if __name__ == \"__main__\":\n", + " main()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb new file mode 100644 index 0000000..cfd4a78 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb @@ -0,0 +1,228 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Finding iLo Mac address" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to find_ilo_mac_address!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    This is our find_ilo_mac_address function overview, in the end this will give us about finding ilo mac address related information.

    \n", + "

    Let me give you a walk through of it!

    \n", + "
      \n", + "
    1. For the identification of a device, its mac address is very much required. If you have the Systems Management Homepage installed, you can find out by clicking \"Management Processor\" and then check the Physical Address field.
    2. \n", + "
    3. If we don't have a resource directory, information about the ethernet data is stored inside the managers json object. Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.
    4. \n", + "
    5. Ethernet interface gives the response for that member about the ilo mac address
    6. \n", + "
    7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the ethernet interface is present in @odata.type attribute then we will store information about ethernet interface in ethernet_data dictionary and break out of iteration.
    8. \n", + "
    9. Finally, we get iLo Network Manager Interface and iLO Mac Address as output.
    10. \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def find_ilo_mac_address(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " for iface in ethernet_data:\n", + " sys.stdout.write(\"iLO Network Manager Interface: \\'%s\\'\\n\" % ethernet_data[iface]['Id'])\n", + " sys.stdout.write(\"\\tiLO Mac Address: \\'%s\\'\\n\" % ethernet_data[iface].get('MACAddress'))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    The Main function:
    PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • If server is down or Unreachable we get \"server not reachable\" message!
    • \n", + "
    • and Once everything is done you are automatically logged out with .logout() 😁.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " find_ilo_mac_address(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + " \n", + "
    \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb new file mode 100644 index 0000000..83a9be5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "042acf39", + "metadata": { + "tags": [] + }, + "source": [ + "# Generating a certificate signing request for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "7b34599c", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to generate_csr!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e7338dfb", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c9837f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "034daf66", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    This is our generate csr function overview, in the end we will be able to make a certificate signing request.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the generate_csr function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about Http certificates is stored inside the managers json object.\n", + " And now through managers_response variable, we are making a http GET operation to and trying to obtain the certificates of signing of iLO system.\n", + "
    \n", + "\n", + "3. In the system managers members response object with different odata_id we get a security service uri .\n", + " Then again an http GET request is made and response is stored in security_service_response.\n", + " Then we will make a http_cert_response by using csr_uri through security_service_response and then using http_cert_response we will get generate_csr_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeHttpsCert attribute is present in @odata.type attribute then we'll set csr_uri and get generate csr uri of the target.\n", + "
    \n", + "\n", + "5. If generate_csr_uri exists, then we will define the body and send a post request through redfish object. After generating the csr, we can obtain the csr_response using get method for csr_uri. csr_response contains CertificateSigningRequest. \n", + "\n", + "
    \n", + "6. If you get the result, then it is successful. if you don't get the result, then there is an error.\n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "644bd708", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_csr(_redfishobj, csr_file, csr_properties):\n", + "\n", + " csr_uri = None\n", + " generate_csr_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " csr_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", + " https_cert_response = _redfishobj.get(csr_uri)\n", + " generate_csr_uri = https_cert_response.obj['Actions']['#HpeHttpsCert.GenerateCSR']\\\n", + " ['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeHttpsCert.' in instance['@odata.type']:\n", + " csr_uri = instance['@odata.id']\n", + " generate_csr_uri = _redfishobj.get(csr_uri).obj['Actions']\\\n", + " ['#HpeHttpsCert.GenerateCSR']['target']\n", + " break\n", + "\n", + " if generate_csr_uri:\n", + " body = dict()\n", + " body[\"Action\"] = \"HpeHttpsCert.GenerateCSR\"\n", + " body[\"City\"] = csr_properties[\"City\"]\n", + " body[\"CommonName\"] = csr_properties[\"CommonName\"]\n", + " body[\"Country\"] = csr_properties[\"Country\"]\n", + " body[\"OrgName\"] = csr_properties[\"OrgName\"]\n", + " body[\"OrgUnit\"] = csr_properties[\"OrgUnit\"]\n", + " body[\"State\"] = csr_properties[\"State\"]\n", + " resp = _redfishobj.post(generate_csr_uri, body)\n", + " if resp.status in [200, 201]:\n", + " sys.stdout.write(\"Generating CSR, this may take a few minutes\\n\")\n", + " sys.stdout.write(\"Sleeping for 5 minutes...\\n\")\n", + " time.sleep(600)\n", + " csr_resp = _redfishobj.get(csr_uri).dict['CertificateSigningRequest']\n", + " with open(csr_file, 'wb') as csroutput:\n", + " csroutput.write(csr_resp)\n", + " sys.stdout.write(\"CSR Data saved to file: '%s'\\n\" % csr_file)\n", + " else:\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", + " #info error message to see what went wrong\n", + " if resp.status not in [200, 201]:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2da11ba0", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter your ilo url,Username,Password here.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call generate_csr with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46b3e899", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #CSR Dictionary, each value should be updated to reflect the desired CSR\n", + " CSR_DICT = {\"City\" : input(\"Enter city:\"), \"CommonName\": input(\"Enter name:\"), \"Country\": input(\"Enter country :\"), \\\n", + " \"OrgName\": input(\"Enter organization :\"), \"OrgUnit\": input(\"Enter unit :\"), \"State\": input(\"Enter state:\")}\n", + "\n", + " #After CSR is generated, a file will be created and the CSR will be downloaded\n", + " CSR_FILE = \"csr.txt\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " generate_csr(REDFISHOBJ, CSR_FILE, CSR_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "06934cbc", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "12c33902", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + " \n", + "
    \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 65a03353b29aa35f3338f15efebd5e82a632117a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 May 2023 22:20:20 +0530 Subject: [PATCH 021/159] Bhuvan - added 4 scripts --- .../.ipynb_checkpoints/index-checkpoint.ipynb | 41 +++ .../BIOS_RevertToDefault-checkpoint.ipynb | 2 +- .../Bhuvan/BIOS/BIOS_RevertToDefault.ipynb | 2 +- .../Change_Boot_Order-checkpoint.ipynb | 283 ++++++++++++++++++ .../Change_Temp_Boot_Order-checkpoint.ipynb | 260 ++++++++++++++++ .../Bhuvan/BOOT/Change_Boot_Order.ipynb | 283 ++++++++++++++++++ .../Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb | 260 ++++++++++++++++ .../HPECTY/Bhuvan/index.ipynb | 41 +++ 8 files changed, 1170 insertions(+), 2 deletions(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb index 5c54eb1..2f001ea 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb @@ -84,6 +84,47 @@ "cell_type": "markdown", "id": "5e16cdec", "metadata": {}, + "source": [ + "

    Scripts related to Booting

    " + ] + }, + { + "cell_type": "markdown", + "id": "616fef86", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Change Boot OrderChange iLOs boot ordertPATCHChange_Boot_Order
    Change Temporary Boot OrderChange iLOs temporary boot ordertPATCHChange_Temp_Boot_Order
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cdb7878", + "metadata": {}, + "outputs": [], "source": [] } ], diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb index 783c9d5..d2ec941 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb @@ -69,7 +69,7 @@ "# Import the helper function\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as inut securely\n", + "#This is to take passwords as input securely\n", "import getpass" ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb index 783c9d5..d2ec941 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb @@ -69,7 +69,7 @@ "# Import the helper function\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as inut securely\n", + "#This is to take passwords as input securely\n", "import getpass" ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb new file mode 100644 index 0000000..63881cd --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8359fe6", + "metadata": {}, + "source": [ + "

    Change Boot Order

    " + ] + }, + { + "cell_type": "markdown", + "id": "8cb46c69", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "6557d8e3", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9dc3d6d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "7753861c", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our change boot order function overview, in the end this will change the boot order by one position.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. This function initializes bios_boot_uri and bios_boot_response variables to None.\n", + "
    \n", + " \n", + "2. Call get_resource_directory() function by passing the \"_redfishobj\" as parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If resource directory is available, find the relevant URI from the resource directory.\n", + "
    \n", + "\n", + "3. Then we navigate through the hirerachy to find bios_boot_uri. If bios_boot_uri is not None, retrieve the BIOS boot settings using get() method. Then Retrieve the URI for BIOS boot settings from the response.\n", + "\n", + "
    \n", + "\n", + "4. If bios_password is provided, update the BIOS password with it.\n", + "
    \n", + "\n", + "5. Print the current boot order. Rotate the first boot device to the end of the boot order. Update the boot order using the patch() method with the new boot order.\n", + "
    \n", + "\n", + "6. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the updated BIOS boot settings.\n", + " \n", + "
    \n", + "\n", + "7. If bios_boot_uri is None, print an error message.\n", + " \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9740789", + "metadata": {}, + "outputs": [], + "source": [ + "def change_boot_order(_redfishobj, bios_password):\n", + "\n", + " bios_boot_uri = None\n", + " bios_boot_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " bios_boot_uri = bios_response.obj.Oem.Hpe.Links.Boot['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeServerBootSettings.' in instance['@odata.type']:\n", + " bios_boot_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if bios_boot_uri:\n", + " bios_boot_response = _redfishobj.get(bios_boot_uri)\n", + " #Bios boot settings URI is needed\n", + " bios_boot_settings_uri = bios_boot_response.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " sys.stdout.write(\"Rotating the first boot device to the end of the boot order.\\n\")\n", + " sys.stdout.write('Current Order:\\n')\n", + " boot_order = bios_boot_response.obj['DefaultBootOrder']\n", + " for indx, boot_device in enumerate(boot_order):\n", + " sys.stdout.write('Pos ' + str(indx) + ' : ' + boot_device + '\\n')\n", + " device = boot_order.pop(0)\n", + " sys.stdout.write(\"Rotating device: \\'%s\\' to the end of the boot order.\\n\" % device)\n", + " boot_order.append(device)\n", + "\n", + " body = {'DefaultBootOrder': boot_order}\n", + " resp = _redfishobj.patch(bios_boot_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! Your system may need to be restarted.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " else:\n", + " sys.stderr.write(\"Unable to find Boot Order URI.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "17889355", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the boot order.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call change_boot_order function with our redfish object and BIOS Password as parameters
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "73d96a09", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7cba1616", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " BIOS_PASSWORD = None\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_boot_order(REDFISHOBJ, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2f00caf4", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d6810680", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb new file mode 100644 index 0000000..f494564 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a9b0b4a", + "metadata": {}, + "source": [ + "

    Change Temporary Boot Order

    " + ] + }, + { + "cell_type": "markdown", + "id": "e04e1b75", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to temporarily change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f33ca630", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0058d42d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "d69021c8", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our change temporary boot order function overview, in the end this will set the boot order temporarily to the device stored in \"boottarget\" variable.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + " \n", + "2. This function first calls get_resource_directory() function by passing the \"_redfishobj\" as parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If resource directory is available, find the relevant URI from the resource directory.\n", + "
    \n", + "\n", + "3. Then we navigate through the hirerachy to find systems_members_uri where we can set the temporary boot target. If systems_members_uri is not None, then set the attribute 'BootSourceOverrideTarget' to 'boottarget' varible.\n", + "\n", + "
    \n", + "\n", + "6. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the updated boot override target.\n", + " \n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aaba46fd", + "metadata": {}, + "outputs": [], + "source": [ + "def change_temporary_boot_order(_redfishobj, boottarget):\n", + "\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict.get('Boot'), indent=4, sort_keys=True))\n", + " body = {'Boot': {'BootSourceOverrideTarget': boottarget}}\n", + " resp = _redfishobj.patch(systems_members_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " if systems_members_response:\n", + " print(\"\\n\\nShowing boot override target:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict.get('Boot'), indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "2405f770", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the temporary boot order.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of _REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + " \n", + "4. When asked to enter Temporary Boot Device, enter desired temporary boot device (Example: Hdd)
    \n", + " \n", + "
    \n", + " \n", + "5. Then we call change_temporary_boot_order function with our redfish object and chosen temporary boot device as parameters
    \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "4d5f0843", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b43b7a95", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # string to represent the selected temporary boot device\n", + " TEMP_DEVICE = input(\"Enter temporary boot device: \")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_temporary_boot_order(REDFISHOBJ, TEMP_DEVICE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "9784ce2a", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e50e59c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb new file mode 100644 index 0000000..63881cd --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8359fe6", + "metadata": {}, + "source": [ + "

    Change Boot Order

    " + ] + }, + { + "cell_type": "markdown", + "id": "8cb46c69", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "6557d8e3", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9dc3d6d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "7753861c", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our change boot order function overview, in the end this will change the boot order by one position.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. This function initializes bios_boot_uri and bios_boot_response variables to None.\n", + "
    \n", + " \n", + "2. Call get_resource_directory() function by passing the \"_redfishobj\" as parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If resource directory is available, find the relevant URI from the resource directory.\n", + "
    \n", + "\n", + "3. Then we navigate through the hirerachy to find bios_boot_uri. If bios_boot_uri is not None, retrieve the BIOS boot settings using get() method. Then Retrieve the URI for BIOS boot settings from the response.\n", + "\n", + "
    \n", + "\n", + "4. If bios_password is provided, update the BIOS password with it.\n", + "
    \n", + "\n", + "5. Print the current boot order. Rotate the first boot device to the end of the boot order. Update the boot order using the patch() method with the new boot order.\n", + "
    \n", + "\n", + "6. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the updated BIOS boot settings.\n", + " \n", + "
    \n", + "\n", + "7. If bios_boot_uri is None, print an error message.\n", + " \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9740789", + "metadata": {}, + "outputs": [], + "source": [ + "def change_boot_order(_redfishobj, bios_password):\n", + "\n", + " bios_boot_uri = None\n", + " bios_boot_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " bios_boot_uri = bios_response.obj.Oem.Hpe.Links.Boot['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeServerBootSettings.' in instance['@odata.type']:\n", + " bios_boot_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if bios_boot_uri:\n", + " bios_boot_response = _redfishobj.get(bios_boot_uri)\n", + " #Bios boot settings URI is needed\n", + " bios_boot_settings_uri = bios_boot_response.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " sys.stdout.write(\"Rotating the first boot device to the end of the boot order.\\n\")\n", + " sys.stdout.write('Current Order:\\n')\n", + " boot_order = bios_boot_response.obj['DefaultBootOrder']\n", + " for indx, boot_device in enumerate(boot_order):\n", + " sys.stdout.write('Pos ' + str(indx) + ' : ' + boot_device + '\\n')\n", + " device = boot_order.pop(0)\n", + " sys.stdout.write(\"Rotating device: \\'%s\\' to the end of the boot order.\\n\" % device)\n", + " boot_order.append(device)\n", + "\n", + " body = {'DefaultBootOrder': boot_order}\n", + " resp = _redfishobj.patch(bios_boot_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! Your system may need to be restarted.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " else:\n", + " sys.stderr.write(\"Unable to find Boot Order URI.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "17889355", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the boot order.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call change_boot_order function with our redfish object and BIOS Password as parameters
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "73d96a09", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7cba1616", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " BIOS_PASSWORD = None\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_boot_order(REDFISHOBJ, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2f00caf4", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d6810680", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb new file mode 100644 index 0000000..f494564 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a9b0b4a", + "metadata": {}, + "source": [ + "

    Change Temporary Boot Order

    " + ] + }, + { + "cell_type": "markdown", + "id": "e04e1b75", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to temporarily change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f33ca630", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0058d42d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "d69021c8", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our change temporary boot order function overview, in the end this will set the boot order temporarily to the device stored in \"boottarget\" variable.


    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + " \n", + "2. This function first calls get_resource_directory() function by passing the \"_redfishobj\" as parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If resource directory is available, find the relevant URI from the resource directory.\n", + "
    \n", + "\n", + "3. Then we navigate through the hirerachy to find systems_members_uri where we can set the temporary boot target. If systems_members_uri is not None, then set the attribute 'BootSourceOverrideTarget' to 'boottarget' varible.\n", + "\n", + "
    \n", + "\n", + "6. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the updated boot override target.\n", + " \n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aaba46fd", + "metadata": {}, + "outputs": [], + "source": [ + "def change_temporary_boot_order(_redfishobj, boottarget):\n", + "\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict.get('Boot'), indent=4, sort_keys=True))\n", + " body = {'Boot': {'BootSourceOverrideTarget': boottarget}}\n", + " resp = _redfishobj.patch(systems_members_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " if systems_members_response:\n", + " print(\"\\n\\nShowing boot override target:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict.get('Boot'), indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "2405f770", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the temporary boot order.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. Now we try to Login with the help of _REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + " \n", + "4. When asked to enter Temporary Boot Device, enter desired temporary boot device (Example: Hdd)
    \n", + " \n", + "
    \n", + " \n", + "5. Then we call change_temporary_boot_order function with our redfish object and chosen temporary boot device as parameters
    \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "4d5f0843", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b43b7a95", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # string to represent the selected temporary boot device\n", + " TEMP_DEVICE = input(\"Enter temporary boot device: \")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_temporary_boot_order(REDFISHOBJ, TEMP_DEVICE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "9784ce2a", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e50e59c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb index 5c54eb1..2f001ea 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb @@ -84,6 +84,47 @@ "cell_type": "markdown", "id": "5e16cdec", "metadata": {}, + "source": [ + "

    Scripts related to Booting

    " + ] + }, + { + "cell_type": "markdown", + "id": "616fef86", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Change Boot OrderChange iLOs boot ordertPATCHChange_Boot_Order
    Change Temporary Boot OrderChange iLOs temporary boot ordertPATCHChange_Temp_Boot_Order
    \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cdb7878", + "metadata": {}, + "outputs": [], "source": [] } ], From 08bf5dcfd44b2da75ef3c654a0b7d8efa5807189 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Fri, 5 May 2023 00:52:10 +0530 Subject: [PATCH 022/159] Add files via upload --- .../HPECTY/Dharitri/SNMP/configure_snmp.ipynb | 282 ++++++++++++++++++ .../SNMP/configure_snmp_trap_source.ipynb | 225 ++++++++++++++ .../HPECTY/Dharitri/index.ipynb | 39 +++ 3 files changed, 546 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb new file mode 100644 index 0000000..0b052cd --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb @@ -0,0 +1,282 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "979defcc", + "metadata": {}, + "source": [ + "# Configuring SNMP for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
    \n", + " Welcome to python-iLOrest-library
    This is an example of configuring SNMP for HPE iLO systems.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.

    \n", + "
  197. sys \n", + "
  198. \n", + "
  199. json
  200. \n", + "
  201. redfish
  202. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ccd0447f", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/2418169914.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import " + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

    2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
    \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alerts):\n", + "\n", + " snmp_service_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

    3. This is Main function overview.


    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or unreachable we get server not reachable message.
    • \n", + "
    • If not then we make a call to configure_snmp function to obtain snmp related information of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "faa032c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 172.1,14\n", + "Enter Username: hhello\n", + "Enter password: 1245\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[1;31m# Create a Redfish client object\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 27\u001b[1;33m REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n\u001b[0m\u001b[0;32m 28\u001b[0m password=LOGIN_PASSWORD)\n", + "\u001b[1;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;31m# Login with the Redfish client\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 31\u001b[1;33m \u001b[1;32mexcept\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mexcp\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 32\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"ERROR: server not reachable or does not support RedFish.\\n\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 33\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " ALERTS_ENABLED = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_ENABLED, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb new file mode 100644 index 0000000..94afb3c --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb @@ -0,0 +1,225 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0a6c95aa", + "metadata": {}, + "source": [ + "# Configuring SNMP trap source for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "594a0e06", + "metadata": {}, + "source": [ + "
    \n", + "Welcome to python-iLOrest-library
    This is an example of configuring SNMP trap source for HPE iLO systems.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "25be0e98", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
  203. sys \n", + "
  204. \n", + "
  205. json
  206. \n", + "
  207. redfish
  208. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f16a98ad", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError" + ] + }, + { + "cell_type": "markdown", + "id": "8c2b4d45", + "metadata": {}, + "source": [ + "

    2. This is our configure_snmp function overview, in the end this will give us with snmp service related information.

    \n", + " \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the snmp service information.\n", + "\n", + " \n", + "\n", + " \n", + "1. In the ILO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
    \n", + "\n", + "2. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if power snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
    \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b53e8e73", + "metadata": {}, + "outputs": [], + "source": [ + " def configure_snmp(_redfishobj):\n", + "\n", + " snmp_service_uri = None\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " # print(managers_members_response.obj['Oem']['Hpe']['Links'])\n", + " # exit(0)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['SNMPService']['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " # resp = _redfishobj.get(snmp_service_uri)\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " # exit(0)\n", + " # TrapSourceHostname : Manager or System\n", + " body = {\"TrapSourceHostname\": \"System\"}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b852d783", + "metadata": {}, + "source": [ + "

    3. This is Main function overview.


    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or unreachable we get server not reachable message.
    • \n", + "
    • If not then we make a call to configure_snmp function to obtain snmp related info of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "610979dd", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " if len(sys.argv) <= 3:\n", + " sys.stderr.write(\"ERROR: We need 3 arguments. \\nUsage: change-snmp.py \"\n", + " \"ILOIPADDR ILOUSER ILOPASSWORD \\n\")\n", + " sys.exit()\n", + "\n", + " SYSTEM_URL = \"https://\" + sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " try:\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT,\n", + " password=LOGIN_PASSWORD)\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "80f7da07", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "00b5c8a5", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb index 06dfc1f..29ee814 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb @@ -106,6 +106,45 @@ " \n", "\n" ] + }, + { + "cell_type": "markdown", + "id": "0140b004", + "metadata": {}, + "source": [ + "

    Scripts related to SNMP

    " + ] + }, + { + "cell_type": "markdown", + "id": "d60f6ff8", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    OPERATIONDESCRIPTIONMETHODLOCATION
    Configure SNMPConfiguring SNMP for HPE iLO systemsPATCHconfigure_snmp
    Configure SNMP trap sourceConfiguring SNMP trap source for HPE iLO systemsPATCHconfigure_snmp_trap_source
    \n" + ] } ], "metadata": { From dcf5124f0ceccd0abe3e135fcf3ab61d87942fb8 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Fri, 5 May 2023 00:56:20 +0530 Subject: [PATCH 023/159] Add files via upload --- .../HPECTY/Dharitri/SNMP/configure_snmp.ipynb | 8 ++++---- .../HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb index 0b052cd..a7eeb2c 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb @@ -51,7 +51,7 @@ "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/2418169914.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_4196/1287542820.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" ] } @@ -61,8 +61,8 @@ "import json\n", "from redfish import RedfishClient\n", "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "#from get_resource_directory import " + "from get_resource_directory import get_resource_directory \n", + "import getpass" ] }, { @@ -198,7 +198,7 @@ " # \"https://ilo.hostname\"\n", " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", - " LOGIN_PASSWORD = input(\"Enter password: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", "\n", " #Properties:\n", " #read communities array\n", diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb index 94afb3c..6f1b164 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb @@ -48,7 +48,9 @@ "import sys\n", "import json\n", "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError" + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" ] }, { From 6b411f9f9eba625ae5322d2a814d463ada94b3aa Mon Sep 17 00:00:00 2001 From: ShrilakshmiUpadhya <84468750+ShrilakshmiUpadhya@users.noreply.github.com> Date: Tue, 9 May 2023 22:25:41 +0530 Subject: [PATCH 024/159] Add files via upload --- .../HPECTY/Shrilakshmi/get_ahs_data.ipynb | 264 ++++++++++++++++ .../Shrilakshmi/get_base_registry.ipynb | 175 +++++++++++ .../Shrilakshmi/get_bios_settings.ipynb | 244 +++++++++++++++ .../HPECTY/Shrilakshmi/get_ilo_ip.ipynb | 158 ++++++++++ .../HPECTY/Shrilakshmi/get_ilo_nic.ipynb | 164 ++++++++++ .../set_ESKM_PrimaryKeyServer.ipynb | 207 +++++++++++++ .../Shrilakshmi/set_ESKM_username_pass.ipynb | 213 +++++++++++++ .../Shrilakshmi/set_ethernet_management.ipynb | 288 ++++++++++++++++++ 8 files changed, 1713 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ahs_data.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_base_registry.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_bios_settings.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_ip.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_nic.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_PrimaryKeyServer.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_username_pass.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ethernet_management.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ahs_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ahs_data.ipynb new file mode 100644 index 0000000..7427901 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ahs_data.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a597eefb", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "28da61c7", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to get_ahs_data!!!
    As you are here let's get it done easily.
    \n", + " To perform this you need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy, we'll be needing it in a while!\n", + "
    \n", + " Follow the guide below to execute without any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "6c29a405", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  209. sys \n", + "
  210. \n", + "
  211. json
  212. \n", + "
  213. redfish
  214. \n", + "
  215. get_resource_directory
  216. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "29082d3a", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    2.

    This is our ahs gathering data function overview, in the end we will get the Active Health System data.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the get_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about the Active Health System is stored inside the managers json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the ahs data of iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object with different odata_id we get the managers members uri .\n", + " Then again an http GET request is made and response is stored in managers_response_response.\n", + " Then we set the active_health_system_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeiLOActiveHealthSystem attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_log_resp through redfish object.\n", + "
    \n", + "\n", + "5. If this is successful, then we will open a logfile and write active_health_system_log_resp.ori which is the get_ahs_data to that logfile.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ahs_data(_redfishobj, logfile=\"data.ahs\"):\n", + "\n", + " active_health_system_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + "\n", + " if active_health_system_uri:\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_log_uri = active_health_system_response.obj.Links['AHSLocation']\\\n", + " ['extref']\n", + " active_health_system_log_resp = _redfishobj.get(active_health_system_log_uri)\n", + " if active_health_system_log_resp.status == 400:\n", + " try:\n", + " print(json.dumps(active_health_system_log_resp.obj['error']\\\n", + " ['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif active_health_system_log_resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % active_health_system_log_resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " with open(logfile, 'wb') as ahsoutput:\n", + " ahsoutput.write(active_health_system_log_resp.ori)\n", + " ahsoutput.close()\n", + " sys.stdout.write(\"AHS Data saved successfully as: \\'%s\\'\" % logfile)\n" + ] + }, + { + "cell_type": "markdown", + "id": "155fb958", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    3.

    This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter ilo url,username,password, and the path of log file
    \n", + " \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call get_ahs_data with our redfish object and logfile.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # logfile path and filename\n", + " LOGFILE = input(\"Enter log file path and file name: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_ahs_data(REDFISHOBJ, LOGFILE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " LOGFILE = data.ahs
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "10a528a3", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_base_registry.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_base_registry.ipynb new file mode 100644 index 0000000..2f93530 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_base_registry.ipynb @@ -0,0 +1,175 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b6a26458", + "metadata": {}, + "source": [ + "
    \n", + "Hello User!
    \n", + "Welcome to python-iLOrest-library
    \n", + "This script can be used to retrieve the base registry information from an HPE iLO (Integrated Lights Out) server.
    \n", + "To perform this you need to have python-ilorest-library installed in your machine.
    \n", + "And please keep your username and password handy!\n", + "
    \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "1dc8cc16", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " First, we need to \"import\" certain files that provide us the functionality to get the base registry.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "from redfish import LegacyRestClient\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "1087550c", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the get_base_registry function. The get_base_registry function serves the purpose of retrieving the base registry information from an HPE iLO server using the HPE iLO REST API.
    \n", + " It performs the following steps to accomplish this:

    \n", + "1. The get_base_registry function sends a GET request to the /rest/v1/Registries endpoint of the HPE iLO server to retrieve the registry data.\n", + "

    \n", + "2. It iterates through the response entries, checking for the \"Id\" field or extracting the schema name.\n", + "

    \n", + "3. For each entry, it makes additional GET requests to the specified URIs to retrieve the registry information.\n", + "

    \n", + "4. If successful, it displays a message and stores the registry messages in a dictionary. The function returns the dictionary containing the registry messages.\n", + "

    \n", + "In summary, the get_base_registry function retrieves the base registry information by making requests to specific URIs, extracting relevant data, and storing it for further analysis and management.\n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def get_base_registry(restobj):\n", + " response = restobj.get(\"/rest/v1/Registries\")\n", + " messages = {}\n", + "\n", + " identifier = None\n", + "\n", + " for entry in response.dict[\"Items\"]:\n", + " if \"Id\" in entry:\n", + " identifier = entry[\"Id\"]\n", + " else:\n", + " identifier = entry[\"Schema\"].split(\".\")[0]\n", + "\n", + " if identifier not in [\"Base\", \"iLO\"]:\n", + " continue\n", + "\n", + " for location in entry[\"Location\"]:\n", + " reg_resp = restobj.get(location[\"Uri\"][\"extref\"])\n", + "\n", + " if reg_resp.status == 200:\n", + " sys.stdout.write(\"\\tFound \" + identifier + \" at \" + \\\n", + " location[\"Uri\"][\"extref\"] + \"\\n\")\n", + " messages[identifier] = reg_resp.dict[\"Messages\"]\n", + " else:\n", + " sys.stdout.write(\"\\t\" + identifier + \" not found at \"\\\n", + " + location[\"Uri\"][\"extref\"] + \"\\n\")\n", + "\n", + " return messages" + ] + }, + { + "cell_type": "markdown", + "id": "167d47fe", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "The following code establishes a connection to an HPE iLO server using the HPE iLO REST API. It sets up the necessary parameters for either local or remote server connection, creates a REST client object, logs into the iLO server, executes an example function to retrieve registry information, and logs out from the server. This code showcases how to interact with the iLO server programmatically, demonstrating the usage of the HPE iLO REST API for server management tasks.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Create a REST object\n", + " REST_OBJ = LegacyRestClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " REST_OBJ.login()\n", + " sys.stdout.write(\"\\nEXAMPLE 2: Find and return registry \" + \"\\n\")\n", + " get_base_registry(REST_OBJ)\n", + " REST_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_bios_settings.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_bios_settings.ipynb new file mode 100644 index 0000000..6102d64 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_bios_settings.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GETTING BIOS SETTINGS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to getting bios(basic input/output system) settings about HPE iLO system.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " In the beginning, we are having some import statements that are actually providing us with the required modules and libraries\n", + "for proper execution of our code.
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of retrieving bios settings from iLO servers.\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the get_bios_settings function, after everything is done this function will give details about bios settings of system.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the get_bios_setting function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In case the resource directory was disabled we are using systems making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
      \n", + "
    • The information about bios settings is present inside a particular json object of iLO rest api.
    • We just need to navigate to that directory so as to obtain info about bios settings.
    • For that purpose simply we are making series of get requests.
    • \n", + " We make a final get operation by at the location bios_uri and save the response inside bios_data.\n", + "
    \n", + "
    \n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately, if bios_data variable is not null we print out information about bios settings. \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "def get_bios_setting(_redfishobj):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing bios attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to get_bios_settings function to obtain information about bios settings of system.
    • \n", + "
    • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 10.0.2.15\n", + "Enter Username: Administrator\n", + "Enter password: 12iso*help\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 13\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 12\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 13\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 14\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 15\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 17\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 16\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 17\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 18\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 19\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_bios_setting(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_ip.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_ip.ipynb new file mode 100644 index 0000000..c765281 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_ip.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "27676c26", + "metadata": {}, + "source": [ + "
    \n", + "Hello User!
    \n", + "Welcome to python-iLOrest-library

    \n", + "This script demonstrates how to retrieve the IP address of an HPE iLO (Integrated Lights-Out) server locally.
    It uses the HPE iLO REST API to interact with the server and obtain the IP address information. The script establishes a connection to the iLO server, retrieves the resource directory, identifies the manager path, and retrieves the Ethernet NIC information. It then extracts the IPv4 address from the NIC information and displays it. Overall, this code focuses on obtaining the iLO IP address using the HPE iLO REST API for local server management purposes.\n", + "

    \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "8ad60173", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " First, we need to \"import\" certain files that provide us the functionality to retrieve the IP address of our HPE iLO server.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "from redfish import LegacyRestClient\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "bf3194e3", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the get_ilo_ip function. \n", + "The get_ilo_ip function retrieves the IP address of an HPE iLO (Integrated Lights-Out) server.
    Here's a breakdown of its functionality:
    \n", + "\n", + "The function starts by obtaining the resource directory from the provided restobj, which represents the REST object.

    \n", + "It then iterates over the resource instances in the directory to find the manager path that corresponds to the iLO server.

    \n", + "Once the manager path is obtained, a GET request is made to retrieve the manager information.\n", + "The function then retrieves the Ethernet NIC information by following the link provided in the manager response.

    \n", + "It iterates over the Ethernet NIC items and checks if the IPv4 address is not \"0.0.0.0\". If a valid IPv4 address is found, it is written to the standard output.

    \n", + "In summary, the get_ilo_ip function utilizes the HPE iLO REST API to locate and retrieve the IP address of an iLO server. It provides a convenient way to programmatically obtain the server's network information.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ilo_ip(restobj):\n", + " resource_instances = get_resource_directory(restobj)\n", + " if resource_instances:\n", + " #Get URI from resource directory\n", + " for instance in resource_instances:\n", + " if \"Manager.\" in instance.Type:\n", + " manager_path = instance.href\n", + " break\n", + "\n", + " response = restobj.get(manager_path)\n", + " ethernet_rsp = restobj.get(response.dict[\"links\"][\"EthernetNICs\"][\"href\"])\n", + " for item in ethernet_rsp.dict[\"Items\"]:\n", + " if not item[\"IPv4Addresses\"][0][\"Address\"] == \"0.0.0.0\":\n", + " sys.stdout.write(\"\\t\" + item[\"IPv4Addresses\"][0][\"Address\"] + \"\\n\")\n", + " sys.stdout.write(\"%s\" % response)" + ] + }, + { + "cell_type": "markdown", + "id": "c3318f0a", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "The following code establishes a connection to an HPE iLO server using the HPE iLO REST API. It sets up the necessary parameters for either local or remote server connection, creates a REST client object, logs into the iLO server, executes an example function to retrieve registry information, and logs out from the server.

    \n", + "This code demonstrates a simple implementation to retrieve the IP address of an HPE iLO server locally. It initializes the necessary variables, creates a REST client object, logs in to the server, retrieves and prints the IP address, and finally logs out. This example showcases the usage of the HPE iLO REST API for basic server interaction." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " SYSTEM_URL = None\n", + " LOGIN_ACCOUNT = None\n", + " LOGIN_PASSWORD = None\n", + "\n", + " #Create a REST object\n", + " REST_OBJ = LegacyRestClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " REST_OBJ.login()\n", + " sys.stdout.write(\"\\nEXAMPLE 52: Get iLO IP locally\\n\")\n", + " get_ilo_ip(REST_OBJ)\n", + " REST_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_nic.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_nic.ipynb new file mode 100644 index 0000000..d177abd --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/get_ilo_nic.ipynb @@ -0,0 +1,164 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "41a1448b", + "metadata": {}, + "source": [ + "
    \n", + "Hello User!
    \n", + "Welcome to python-iLOrest-library
    \n", + "This script provides an example implementation that allows you to retrieve the network interface card (NIC) configuration of your HPE iLO server.
    \n", + "To perform this you need to have python-ilorest-library installed in your machine.
    \n", + "And please keep your username and password handy!\n", + "
    \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "25c830bd", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " First, we are importing certain files that provide us the functionality to get the nic configuration of the server.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import LegacyRestClient\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "64642b12", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + " Below is the get_ilo_nic function. The get_ilo_nic function is responsible for retrieving the network interface card (NIC) configuration of an HPE iLO server. It takes a REST object and a parameter indicating whether to retrieve active or inactive NICs as input. Here's a brief overview of the function's steps:
    \n", + "
      The function first obtains the resource directory of the iLO server using the provided REST object. This directory contains information about the server's available resources, including the NICs.
    \n", + "
      It then searches for the NIC-related information within the resource directory by iterating through the instances and identifying the ones related to the server's manager.\n", + "Using the obtained NIC information, the function retrieves the NIC configuration data from the server.
    \n", + "
      Depending on the value of the get_active parameter, the function filters the retrieved NICs to either active or inactive ones.
    \n", + "
      Finally, the function outputs the relevant NIC information, including the NIC's self URL and its JSON representation.
    \n", + "

    In summary, the get_ilo_nic function allows you to fetch and categorize the NIC configuration of an HPE iLO server based on its active or inactive status. This information can be useful for monitoring and managing your server's network settings.

    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ilo_nic(restobj, get_active):\n", + " resource_instances = get_resource_directory(restobj)\n", + " if resource_instances:\n", + " #Get URI from resource directory\n", + " for instance in resource_instances:\n", + " if \"Manager.\" in instance.Type:\n", + " manager_path = instance.href\n", + " break\n", + "\n", + " tmp = restobj.get(manager_path)\n", + " response = restobj.get(tmp.dict[\"links\"][\"EthernetNICs\"][\"href\"])\n", + "\n", + " for nic in response.dict[\"Items\"]:\n", + " if get_active and nic[\"Status\"][\"State\"] == \"Enabled\":\n", + " sys.stdout.write(\"Active\\t\" + nic[\"links\"][\"self\"][\"href\"] + \\\n", + " \": \" + json.dumps(nic) + \"\\n\")\n", + " elif get_active == False and nic[\"Status\"][\"State\"] == \"Disabled\":\n", + " sys.stdout.write(\"InActive\\t\" + nic[\"links\"][\"self\"][\"href\"] + \\\n", + " \": \" + json.dumps(nic) + \"\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "5531c99f", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + " \n", + "This script establishes a connection to an HPE iLO server using the provided URL, login account, and password. It then logs in to the server and retrieves the NIC configuration. The script specifically fetches active NICs and displays their information. Finally, it logs out from the server.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Create a REST object\n", + " REST_OBJ = LegacyRestClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " REST_OBJ.login()\n", + " sys.stdout.write(\"\\nEXAMPLE 20: Get iLO's NIC configuration\\n\")\n", + " get_ilo_nic(REST_OBJ, True)\n", + " REST_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_PrimaryKeyServer.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_PrimaryKeyServer.ipynb new file mode 100644 index 0000000..cf366b6 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_PrimaryKeyServer.ipynb @@ -0,0 +1,207 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "67d9df4f", + "metadata": {}, + "source": [ + "
    \n", + "Hello User!
    \n", + "Welcome to python-iLOrest-library
    \n", + "This script can be used to manage and configure the ESKM key server for HPE iLO systems.
    \n", + "To perform this you need to have python-ilorest-library installed in your machine.
    \n", + "And please keep your username and password handy!\n", + "
    \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "7350e15b", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " First, we are importing certain files that enable us to manage and configure the ESKM key server.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "26b4fe53", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + "

    Below is the set_ESKM_PrimaryKeyServer function. The function takes a Redfish client object, the primary key server address, and the primary key server port as input. It uses the Redfish API to configure the primary ESKM(Enterprise Secure Key Manager) key server on the iLO system.

    \n", + "
    It achieves this by the following steps:
    \n", + "\n", + "1. It first retrieves the relevant URI for the ESKM service by either using the resource directory or by navigating through the Redfish API endpoints.
    \n", + "The function then constructs a request body with the primary key server address and port.\n", + "2. It sends a POST request to the ESKM URI with the request body to update the primary key server configuration.
    \n", + "3. If the response is successful, it displays the updated configuration in JSON format.\n", + "If there are any errors or exceptions, it provides appropriate error messages or status codes.
    \n", + "4. Finally, it logs out from the iLO server.\n", + "

    \n", + "The set_ESKM_PrimaryKeyServer function enables the configuration of the primary ESKM key server for HPE iLO systems. It retrieves the relevant URI, sets the primary key server address and port, and updates the configuration via a POST request. It provides feedback on the success or failure of the operation and allows for proper error handling.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ESKM_PrimaryKeyServer(_redfishobj, primary_key_server_address, primary_key_server_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + "\n", + " body[\"PrimaryKeyServerAddress\"] = primary_key_server_address\n", + " body[\"PrimaryKeyServerPort\"] = int(primary_key_server_port)\n", + "\n", + " resp = _redfishobj.post(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "601ab339", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + " \n", + "The code below establishes a connection with an iLO server using the specified system URL, login account, and password. It then sets the primary ESKM key server address and port. The script utilizes the Redfish protocol to communicate with the server and performs the necessary operations to configure the key server. Finally, it logs out from the iLO server.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " PRIMARY_KEY_SERVER_ADDRESS = \"192.168.1.1\"\n", + " PRIMARY_KEY_SERVER_PORT = \"9000\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ESKM_PrimaryKeyServer(REDFISHOBJ, PRIMARY_KEY_SERVER_ADDRESS, PRIMARY_KEY_SERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_username_pass.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_username_pass.ipynb new file mode 100644 index 0000000..bc533d9 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ESKM_username_pass.ipynb @@ -0,0 +1,213 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "54face1f", + "metadata": {}, + "source": [ + "
    \n", + "Hello User!
    \n", + "Welcome to python-iLOrest-library
    \n", + "This script demonstrates how to set the ESKM (Enterprise Secure Key Manager) username, password, and other related configurations for HPE iLO systems.
    \n", + "To perform this you need to have python-ilorest-library installed in your machine.
    \n", + "And please keep your username and password handy!\n", + "
    \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "7350e15b", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " First, we are importing certain files that enable us to manage and configure the ESKM key server.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e2d3008", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "6234f26f", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + "

    The code below defines a function called ESKM_username_pass that is responsible for configuring the ESKM (Enterprise Secure Key Manager) settings on an HPE iLO system using the Redfish API. The function takes several parameters, including the ESKM username, password, account group, primary key server address, and primary key server port.

    \n", + "
    The following steps explain this function:
    \n", + "\n", + "1. Get the resource directory to find the URI for the ESKM service.\n", + "2. If the resource directory is not available or disabled, manually search for the relevant URI by navigating through the API hierarchy.\n", + "3. If the URI for the ESKM service is found, create a dictionary object with the login name, password, account group, ESKM local CA certificate name, primary key server address, and primary key server port.\n", + "4. Use the HTTP PATCH method to update the ESKM service configuration with the dictionary object.\n", + "5. Check the response status code to determine if the update was successful or if an error occurred. If there was an error, print the error message or status code. If the update was successful, print the response body.\n", + "

    \n", + "The ESKM_username_pass function is used to configure the ESKM settings on an HPE iLO system. It retrieves the ESKM URI, populates the configuration data, sends a PATCH request to update the settings, and handles the response accordingly. Upon successful update, it prints a success message along with the response details.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38d43c16", + "metadata": {}, + "outputs": [], + "source": [ + "def ESKM_username_pass(_redfishobj, eskm_username, eskm_password, eskm_accountgroup, \\\n", + " eskm_primarykeyserver_addr, eskm_primarykeyserver_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " body[\"KeyManagerConfig\"] = dict()\n", + " body[\"KeyManagerConfig\"][\"LoginName\"] = eskm_username\n", + " body[\"KeyManagerConfig\"][\"Password\"] = eskm_password\n", + " body[\"KeyManagerConfig\"][\"AccountGroup\"] = eskm_accountgroup\n", + " body[\"KeyManagerConfig\"][\"ESKMLocalCACertificateName\"] = \"\"\n", + " body[\"PrimaryKeyServerAddress\"] = eskm_primarykeyserver_addr\n", + " body[\"PrimaryKeyServerPort\"] = eskm_primarykeyserver_port\n", + " resp = _redfishobj.patch(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "601ab339", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + " \n", + "The code below establishes a connection with an iLO server using the specified system URL, login account, and password. It then sets the primary ESKM key server address and port. The script utilizes the Redfish protocol to communicate with the server and performs the necessary operations to configure the key server. Finally, it logs out from the iLO server.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40aabbdc", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " ESKM_USERNAME = \"admin\"\n", + " ESKM_PASSWORD = \"password\"\n", + " ESKM_ACCOUNTGROUP = \"group\"\n", + " ESKM_PRIMARYKEYSERVER_ADDR = \"192.168.1.10\"\n", + " ESKM_PRIMARYKEYSERVER_PORT = 5927\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \\\n", + " ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ethernet_management.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ethernet_management.ipynb new file mode 100644 index 0000000..618ff4d --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ethernet_management.ipynb @@ -0,0 +1,288 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "22c6d15e", + "metadata": {}, + "source": [ + "
    \n", + "Hello User!
    \n", + "Welcome to python-iLOrest-library
    \n", + "The objective of this script is to demonstrate how to set the static IP configuration for the Manager ethernet interface of an HPE iLO system using the Redfish API.
    \n", + "To perform this you need to have python-ilorest-library installed in your machine.
    \n", + "And please keep your username and password handy!\n", + "
    \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0b53f42d", + "metadata": {}, + "source": [ + "
    \n", + "
    1.
    \n", + "
    \n", + " First, we are importing certain files that can help us to manage the ethernet interface of our server.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e2d3008", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "c32f009a", + "metadata": {}, + "source": [ + "
    \n", + "
    2.

    \n", + "

    The following code defines the set_ilo_static_ipv4 function. This function is used to set the static IPv4 configuration for the Manager ethernet interface in an iLO (Integrated Lights-Out) server.


    \n", + "\n", + "1. Retrieve the resource directory to find the URI for the ethernet interfaces or manually search for the relevant URI if the resource directory is disabled.\n", + "2. Retrieve the current configuration of the ethernet interfaces, including DHCPv4 settings, IPv4 addresses, and static name servers, and display them.\n", + "3. Iterate through each ethernet interface and prompt the user to choose which interface to modify.\n", + "4. Disable the UseDNSServers and UseGateway options if they are enabled in the DHCPv4 settings.\n", + "5. Update the IPv4Addresses and StaticNameServers with the provided values in the function parameters, or create a new body with the DNS servers if StaticNameServers are not available.\n", + "6. Send a PATCH request to update the ethernet interface configuration with the new settings.\n", + "Call the ilo_response function to handle the response and display any error messages or the updated configuration.\n", + "7. Exit the loop after processing the first ethernet interface.

    \n", + "Overall, the function retrieves the current ethernet interface configuration, allows the user to choose which interface to modify, and updates the configuration with the provided IPv4 and DNS settings.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38d43c16", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ilo_static_ipv4(_redfishobj, ipv4_dict, dns_dict):\n", + "\n", + " ethernet_data = {}\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " for interface in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Management Inteface \\'%s\\'\\n\" % ethernet_data\\\n", + " [interface].get('Id'))\n", + "\n", + " sys.stdout.write(\"\\'DHCPv4\\':\\n\")\n", + " if ethernet_data[interface].get('DHCPv4'):\n", + " print(json.dumps(ethernet_data[interface].get('DHCPv4'), indent=4, sort_keys=True))\n", + " else:\n", + " print(json.dumps(ethernet_data[interface]['Oem']['Hpe'].get('DHCPv4'), indent=4, \\\n", + " sort_keys=True))\n", + " sys.stdout.write(\"\\'IPv4\\':\\n\")\n", + " if ethernet_data[interface].get('IPv4StaticAddresses'):\n", + " print(json.dumps(ethernet_data[interface].get('IPv4Addresses'), indent=4, \\\n", + " sort_keys=True))\n", + " sys.stdout.write(\"\\'StaticNameServers\\':\\n\")\n", + " if ethernet_data[interface].get('StaticNameServers'):\n", + " print(json.dumps(ethernet_data[interface].get('StaticNameServers'), indent=4, \\\n", + " sort_keys=True))\n", + "\n", + " for ethernet in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Interface: %s\\n\" % ethernet)\n", + " ans = input(\"Would you like to modify this interface? (y/n)\\n\")\n", + " if \"n\" in ans:\n", + " continue\n", + " if 'DHCPv4' in ethernet_data[ethernet]:\n", + " if ethernet_data[ethernet]['DHCPv4'].get('UseDNSServers'):\n", + " resp = _redfishobj.patch(ethernet, {\"DHCPv4\": {\"UseDNSServers\": False}})\n", + " ilo_response(_redfishobj, resp)\n", + " if ethernet_data[ethernet]['DHCPv4'].get('UseGateway'):\n", + " resp = _redfishobj.pathc(ethernet, {\"DHCPv4\": {\"UseGateway\": False}})\n", + " ilo_response(_redfishobj, resp)\n", + " if 'IPv4StaticAddresses' in ethernet_data[ethernet]:\n", + " body.update({\"IPv4Addresses\": [ipv4_dict]})\n", + " if 'StaticNameServers' in ethernet_data[ethernet]:\n", + " body.update({\"StaticNameServers\" : [dns_dict.get('PrimaryDNS'), \\\n", + " dns_dict.get('SecondaryDNS')]})\n", + " else:\n", + " body.update({\"Oem\": {\"Hpe\": {\"IPv4\": {\"DNSServers\": [dns_dict.get('PrimaryDNS'), \\\n", + " dns_dict.get('SecondaryDNS')]}}}})\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " ilo_response(_redfishobj, resp)\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "c9017ca5", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + "

    The following code defines the ilo_response function. This function is used to handle the response from an iLO (Integrated Lights-Out) server after sending a PATCH request to update the configuration.


    \n", + "1. Check if the response status is 400. If it is, try to access the extended error message from the response object and print it in a formatted JSON representation.\n", + "2. If an exception occurs while accessing the extended error message, print a generic error message indicating that the extended message info cannot be accessed.\n", + "3. If the response status is not 400 (indicating an error), write a stderr message indicating the HTTP response status.\n", + "4. If the response status is 200 (indicating success), print a success message suggesting to reset iLO for the settings to take effect.\n", + "5. Print the response dictionary in a formatted JSON representation.\n", + "

    \n", + "Overall, the function retrieves the current ethernet interface configuration, allows the user to choose which interface to modify, and updates the configuration with the provided IPv4 and DNS settings.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7aa4cac1", + "metadata": {}, + "outputs": [], + "source": [ + "def ilo_response(_redfishobj, resp):\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! Suggest to reset iLO for settings to take effect.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "c1dc3e7f", + "metadata": {}, + "source": [ + "
    \n", + "
    4.

    \n", + " \n", + "Next is the main function. The code establishes a connection with a target server using Redfish, a standardized API for server management. It sets the URL, login credentials, and defines dictionaries for IPv4 and DNS settings. It creates a Redfish client object and attempts to log in using the provided credentials. If successful, it calls the set_ilo_static_ipv4 function to configure the IPv4 and DNS settings for a specific Ethernet interface on the server. The function retrieves the necessary information, displays the current settings, and prompts the user to choose an interface for modification. If selected, it updates the DHCPv4 and IPv4 static address settings based on the provided dictionaries and sends the changes to the server. Finally, the code logs out of the Redfish session.\n", + "

    \n", + "In summary, the code establishes a connection with a server, configures network settings using Redfish, and performs the necessary operations to modify the IPv4 and DNS settings for a specific Ethernet interface on the server.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40aabbdc", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #IPv4 settings for Address, Gateway and SubnetMask as well as DNS.\n", + " IPV4_DICT = {'Address':'16.83.61.123', \\\n", + " 'Gateway':'16.83.60.1', \\\n", + " 'SubnetMask':'255.255.252.0' \\\n", + " }\n", + " DNS_DICT = {'PrimaryDNS':'16.110.135.52', \\\n", + " 'SecondaryDNS':'16.110.135.51' \\\n", + " }\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ilo_static_ipv4(REDFISHOBJ, IPV4_DICT, DNS_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ca134fbe73cc40a2b3a1a017f014349a1d6e5ce6 Mon Sep 17 00:00:00 2001 From: ShrilakshmiUpadhya <84468750+ShrilakshmiUpadhya@users.noreply.github.com> Date: Wed, 10 May 2023 14:44:42 +0530 Subject: [PATCH 025/159] Add files via upload --- .../Shrilakshmi/set_ilo_ntp_servers.ipynb | 278 ++++++++++++++++++ .../HPECTY/Shrilakshmi/set_ilo_timezone.ipynb | 241 +++++++++++++++ 2 files changed, 519 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_ntp_servers.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_timezone.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_ntp_servers.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_ntp_servers.ipynb new file mode 100644 index 0000000..59c3e3a --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_ntp_servers.ipynb @@ -0,0 +1,278 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "57e65617", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting NTP Servers for HPE iLO Systems" + ] + }, + { + "cell_type": "markdown", + "id": "826e692d", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to set the ilo NTP server!
    As you are here let's get it done easily.
    \n", + " To perform this you need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy, we'll be needing it in a while!\n", + "
    \n", + " Follow the guide below to execute without any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "5bf83867", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library tp set up the ilo NTP server!
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "from reset_ilo import reset_ilo\n", + "from enable_ntp_servers import enable_ntp" + ] + }, + { + "cell_type": "markdown", + "id": "87dd8456", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "
    2.

    \n", + "

    The script begins by defining the necessary dependencies and helper functions. The set_ilo_ntp_servers function is responsible for updating the NTP server settings for the iLO system.

    \n", + "
    Steps involved are:
    \n", + "\n", + "\n", + "1. The function set_ilo_ntp_servers sets the NTP (Network Time Protocol) servers for an HPE iLO system. It first retrieves the URI for the date and time service using the get_resource_directory function. If the resource directory is disabled or not available, it finds the URI by traversing the managers' hierarchy.\n", + "\n", + "2. Once the URI is obtained, the function sends a GET request to retrieve the current NTP server settings. If the StaticNTPServers property is present, it sends a PATCH request to update the NTP server list with the provided ntp_server_list.\n", + "\n", + "3. If any error occurs during the process, the function handles it accordingly. If the response status is 400, it attempts to access the iLO extended error information and prints it. If the response status is not 200 or 400, it prints an error message.\n", + "\n", + "4. If the NTP server update is successful, it prints a success message and the updated NTP server information.\n", + "\n", + "

    \n", + "In summary, the function retrieves the URI for the date and time service, updates the NTP server settings, and handles any errors that may occur during the process.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ilo_ntp_servers(_redfishobj, ntp_server_list):\n", + "\n", + " date_time_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " date_time_uri = managers_members_response.obj.Oem.Hpe.Links['DateTimeService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLODateTime.' in instance['@odata.type']:\n", + " date_time_uri = instance['@odata.id']\n", + "\n", + " if date_time_uri:\n", + " data = _redfishobj.get(date_time_uri)\n", + " if data.dict.get('StaticNTPServers'):\n", + " resp = _redfishobj.patch(date_time_uri, {'StaticNTPServers': ntp_server_list})\n", + " else:\n", + " raise Exception(\"\\'StaticNTPServers\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " ntp_data = _redfishobj.get(date_time_uri).dict.get('StaticNTPServers')\n", + " print(\"Printing updated NTP Servers:\\n\")\n", + " print(json.dumps(ntp_data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5a12f202", + "metadata": {}, + "source": [ + "
    \n", + "
    3.

    \n", + " The following code defines the give_client function, which creates a client object and performs the login operation through the following steps:
    \n", + "1. The function give_client creates a Redfish client object by instantiating the RedfishClient class. It provides the base URL, username, and password for the Redfish service as parameters.\n", + "\n", + "2. The function attempts to log in to the Redfish service using the created client object. It sends the login request with the provided credentials.\n", + "\n", + "3. If the login is successful, the function returns the instantiated Redfish client object. If there is an error connecting to the server or if the server does not support Redfish, an error message is printed, and the program exits.\n", + "

    \n", + "In summary, the give_client function creates a Redfish client object, performs the login process, and returns the client object if the login is successful.
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a963c789", + "metadata": {}, + "outputs": [], + "source": [ + "def give_client():\n", + " try:\n", + " # Create a Redfish client object\n", + " rf_obj = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " rf_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " return rf_obj" + ] + }, + { + "cell_type": "markdown", + "id": "1d393dbe", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "
    4.

    \n", + " This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "

    \n", + " The main section of the script sets the system URL, login account, and password. It creates a Redfish client object, logs in to the iLO system, enables NTP servers for the primary iLO management interface, resets the iLO, and waits for 60 seconds. Afterward, it logs out, creates a new Redfish client object, and calls the set_ilo_ntp_servers function to configure the NTP servers using the specified list. Finally, it logs out again.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # logfile path and filename\n", + " LOGFILE = input(\"Enter log file path and file name: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_ahs_data(REDFISHOBJ, LOGFILE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " LOGFILE = data.ahs
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "10a528a3", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_timezone.ipynb b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_timezone.ipynb new file mode 100644 index 0000000..f4fa3b7 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Shrilakshmi/set_ilo_timezone.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e9c3d898", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting the timezone for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "10884361", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is a script that demonstrates how to set the timezone for HPE iLO (Integrated Lights-Out) systems using the Redfish API.
    As you are here let's get it done easily.
    \n", + " To perform this you need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy, we'll be needing it in a while!\n", + "
    \n", + " Follow the guide below to execute without any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "2ef56c73", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "
    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library tp set up the ilo NTP server!
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "6a1ae9ce", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "
    2.

    \n", + "

    The function set_timezone is defined below. It provides a convenient way to set the timezone for an HPE iLO system using the Redfish API, utilizing the resource directory or direct URI retrieval methods to locate the relevant DateTime service and perform the timezone update.

    \n", + "
    Here's a summary of the function:
    \n", + "\n", + "1. Resource Directory Retrieval: The function retrieves the resource directory information using the _redfishobj Redfish client object. If the resource directory is not available or the DISABLE_RESOURCE_DIR flag is set, it retrieves the URI for the DateTime service from the server's Managers and Members resources.\n", + "\n", + "2. Finding the Relevant URI: If the resource directory is available, the function searches for the relevant URI for the DateTime service within the resource instances. It looks for an instance with the '#HpeiLODateTime.' substring in its @odata.type.\n", + "\n", + "3. Updating the Timezone: After obtaining the DateTime service URI, the function sends a GET request to retrieve the current data for the service. If the retrieved data contains the 'TimeZone' property, it constructs a JSON payload to update the timezone to the specified value. A PATCH request is then sent to the DateTime service URI with the timezone payload to modify the timezone.\n", + "\n", + "4. Handling Responses: The function handles different response scenarios. If the response status code is 400, indicating a client-side error, it attempts to print the extended error information and the available timezone list. For response status codes other than 200 or 201, indicating an HTTP error, an appropriate error message is printed. If the response status is 200, indicating a successful update, the function prints a success message along with the updated timezone information.\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def set_timezone(_redfishobj, timezone):\n", + "\n", + " date_time_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " date_time_uri = managers_members_response.obj.Oem.Hpe.Links['DateTimeService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLODateTime.' in instance['@odata.type']:\n", + " date_time_uri = instance['@odata.id']\n", + "\n", + " if date_time_uri:\n", + " data = _redfishobj.get(date_time_uri)\n", + " if data.dict.get('TimeZone'):\n", + " _data = {'TimeZone': {\"Name\": timezone}}\n", + " resp = _redfishobj.patch(date_time_uri, _data)\n", + " else:\n", + " raise Exception(\"\\'TimeZone\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " print(json.dumps(data.obj.get('TimeZoneList'), indent=4, sort_keys=True))\n", + " sys.stderr.write(\"Check the TimeZone value...\\n\")\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " ntp_data = _redfishobj.get(date_time_uri).dict.get('TimeZone')\n", + " print(\"Printing updated NTP Servers:\\n\")\n", + " print(json.dumps(ntp_data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5b943b2e", + "metadata": { + "tags": [] + }, + "source": [ + "
    \n", + "
    3.

    \n", + " This is Main function overview.
    \n", + " Let me give you a walk through of it!\n", + "

    \n", + " The main section of the script proceeds to create a Redfish client object using the specified system URL, login account, and password. This client object allows communication with the remote system via Redfish APIs. After successfully creating the client object, it logs in to the system to establish an authenticated session.\n", + "

    \n", + "If any server connectivity issues occur or the server does not support RedFish, an error message is displayed, and the script exits. Otherwise, the set_timezone function is called, passing the Redfish client object and the desired timezone value as parameters. This function handles the task of setting the timezone on the system using the Redfish API.\n", + "
    \n", + "Upon completion, the script logs out from the system, terminating the authenticated session.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #timezone property (review the list of timezones ('TimeZoneList') within the DateTime URI.\n", + " TIMEZONE = \"US/Central\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_timezone(REDFISHOBJ, TIMEZONE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " LOGFILE = data.ahs
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "0e4573cc", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From d0d5cca53fc7a88074be777ed3dca70d414853ca Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Thu, 11 May 2023 02:41:20 +0530 Subject: [PATCH 026/159] Add files via upload --- .../Dharitri/LicenseKey/set_license_key.ipynb | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb new file mode 100644 index 0000000..7fc2ed0 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d91ced6", + "metadata": {}, + "source": [ + "# Setting license key " + ] + }, + { + "cell_type": "markdown", + "id": "11b0fe9d", + "metadata": {}, + "source": [ + "
    \n", + " Welcome to python-iLOrest-library
    This is an example of setting license key.
    As you are here let's get it done easily.
    \n", + " To perform this you need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "6cbd5f7c", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.

    \n", + "
  217. sys \n", + "
  218. \n", + "
  219. json
  220. \n", + "
  221. redfish
  222. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0fa1574", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "7daccb24", + "metadata": {}, + "source": [ + "

    2. This is our set_license_key function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the set_license_key function we are taking two parameters i.e. _redfishobj and ilo_key. In the set_license_key function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the iLO rest api the information about license key is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the license service about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The license service information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeiLOLicense type is present in @odata.type attribute then we will store information about license key in ilo_lic_uri and break out of iteration.\n", + "
    \n", + "5. If ilo_lic_uri is not null after making above operations, we can perform the required actions to set license key. \n", + "
      \n", + "
    • The function sends a GET request to the iLO license service to retrieve the current license data. If the ConfirmationRequest field exists, it is printed to the console; otherwise, the LicenseKey field is printed.
    • \n", + "
    • The function sends a POST request to the iLO license service with the new license key provided in the ilo_key argument.
    • \n", + "
    • The job of post request here is to set the license key at the provided location and send a response whether the job was done properly or not.
    • \n", + "
    • If the response status is 400, the function attempts to print the extended error message provided by iLO. If the status is not 200 or 201, the function prints an error message to the console.
    • \n", + "
    • If the response status is 200, the function prints a success message to the console along with the response JSON.
    • \n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bacca62e", + "metadata": {}, + "outputs": [], + "source": [ + "def set_license_key(_redfishobj, ilo_key):\n", + "\n", + " ilo_lic_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " ilo_lic_uri = managers_members_response.obj.Oem.Hpe.Links['LicenseService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOLicense.' in instance['@odata.type']:\n", + " ilo_lic_uri = instance['@odata.id']\n", + "\n", + " if ilo_lic_uri:\n", + " ilo_license_collection = _redfishobj.get(ilo_lic_uri)\n", + " ilo_license_member_uri = next(iter(ilo_license_collection.obj['Members']))['@odata.id']\n", + " try:\n", + " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['ConfirmationRequest']\\\n", + " ['EON']\n", + " except KeyError:\n", + " sys.stdout.write(\"This machine will not show the full License Key.\\n\")\n", + " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['LicenseKey']\n", + "\n", + " sys.stdout.write(\"Current iLO License Data:\\n\")\n", + " print(json.dumps(ilo_license_data, indent=4, sort_keys=True))\n", + " resp = _redfishobj.post(ilo_lic_uri, {'LicenseKey' : ilo_key})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " sys.stderr.write(\"Check the validity of your license key...\\n\")\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \" \\\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "abfa5bd8", + "metadata": {}, + "source": [ + "

    3. This is Main function overview.


    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials are entered a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or unreachable we get server not reachable message.
    • \n", + "
    • If not then we make a call to set_license_key function to set license key of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38798e69", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # Must be a valid iLO License Key\n", + " ILO_LICENSE_KEY = \"XXXX-XXXX-XXXX-XXXX-XXXXX\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_license_key(REDFISHOBJ, ILO_LICENSE_KEY)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "7d4c55f5", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b3be89a3", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 2126bb452edae2cd52a76a9aae529ef8204b4b56 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Thu, 11 May 2023 03:13:23 +0530 Subject: [PATCH 027/159] Add files via upload --- .../HPECTY/Dharitri/SNMP/configure_snmp.ipynb | 2 +- .../SNMP/configure_snmp_trap_source.ipynb | 29 +- .../HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb | 315 ++++++++++++++++++ 3 files changed, 340 insertions(+), 6 deletions(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb index a7eeb2c..d8cbe37 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb @@ -146,7 +146,7 @@ "

    3. This is Main function overview.


    \n", "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", "
      \n", - "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", "
    • If server is down or unreachable we get server not reachable message.
    • \n", "
    • If not then we make a call to configure_snmp function to obtain snmp related information of system.
    • \n", "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb index 6f1b164..f7941cf 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb @@ -40,17 +40,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "f16a98ad", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25528/1522814575.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], "source": [ "import sys\n", "import json\n", "from redfish import RedfishClient\n", "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" + "from get_resource_directory import get_resource_directory\n" ] }, { @@ -130,7 +141,7 @@ "

      3. This is Main function overview.


      \n", "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", "
        \n", - "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", "
      • If server is down or unreachable we get server not reachable message.
      • \n", "
      • If not then we make a call to configure_snmp function to obtain snmp related info of system.
      • \n", "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", @@ -138,6 +149,14 @@ "
      " ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9cf5c73", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb new file mode 100644 index 0000000..5dbdafa --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb @@ -0,0 +1,315 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "80ca2bf5", + "metadata": {}, + "source": [ + "# Setting SNMP alert destination" + ] + }, + { + "cell_type": "markdown", + "id": "647c7374", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting SNMP alert destination.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "ce2b4b70", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6a53c06", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "cfd0ef73", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "269747d5", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alertdestinations, DISABLE_RESOURCE_DIR):\n", + " snmp_service_uri = None\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " #body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " body = {\"AlertDestinations\": snmp_alertdestinations}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "ca33ee48", + "metadata": {}, + "source": [ + "

      3. This is our set_snmp_alert_destination function overview.

      \n", + "
      \n", + "1. The set_snmp_alert_destination function sets the SNMP alert destinations on an iLO device. The function takes three parameters: _redfishobj, snmp_service_uri, and alert_destination_list. \n", + "
        \n", + "
      • _redfishobj is the Redfish client object.
      • \n", + "
      • snmp_service_uri is the URI for the SNMP service on the iLO device.
      • \n", + "
      • alert_destination_list is a list of dictionaries containing the SNMP alert destinations to set.
      • \n", + "

      \n", + "2. The function gets the current SNMP service data using _redfishobj.get() and checks if the AlertDestinations property is available/modifyable.

      \n", + "3. If the property is available/modifyable, the function sends a PATCH request with the updated alert destinations using _redfishobj.patch().

      \n", + "4. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", + "5. If the patch operation is successful, the function prints the response and gets the updated SNMP alert destination data using _redfishobj.get().

      \n", + "6. The updated SNMP alert destination data is printed to the console using json.dumps() and print().

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c91c0fb8", + "metadata": {}, + "outputs": [], + "source": [ + "def set_snmp_alert_destination(_redfishobj, snmp_service_uri, alert_destination_list):\n", + " data = _redfishobj.get(snmp_service_uri)\n", + " if data.dict.get(\"AlertDestinations\"):\n", + " resp = _redfishobj.patch(snmp_service_uri, {'AlertDestinations': alert_destination_list})\n", + " else:\n", + " raise Exception(\"\\'AlertDestinations\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nPatch operation successful!\\n\\nResponse:\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " snmp_service_response = _redfishobj.get(snmp_service_uri).dict.get('AlertDestinations')\n", + " print(\"\\n\\nPrinting updated SNMP alert destination:\\n\")\n", + " print(json.dumps(snmp_service_response, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "9fdd0d40", + "metadata": {}, + "source": [ + "

      4. This is Main function overview.


      \n", + "The Main function \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • It checks the generation of iLO by calling the get_gen function and prints the iLO generation.\n", + "
      • If the iLO generation is 5, it calls the configure_snmp function to configure the SNMP service with the read communities and alerts destination, and disable resource directory flag.
      • \n", + "
      • If the iLO generation is not 5, it calls the set_snmp_alert_destination function to set the SNMP alert destination with the alert destination list for iLO4.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27378983", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " #SYSTEM_URL = \"https://15.146.46.45\"\n", + " #LOGIN_ACCOUNT = \"admin\"\n", + " #LOGIN_PASSWORD = \"admin123\"\n", + "\n", + " SYSTEM_URL = sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " #ALERTS_ENABLED = True\n", + " #Alert Destination\n", + " ALERTS_DESTINATION = [\"1.1.1.1\",\"2.2.2.2\"]\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " snmp_service_uri = \"/redfish/v1/Managers/1/SNMPService/\"\n", + "\n", + " # Number of max alert destination supported on iLO4 and iLO5 is different\n", + " alert_destination_list = [\"ILOCN771702NJ\", \"15.146.46.55\" , \"15.146.46.58\"]\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " (ilogen,_) = get_gen(REDFISHOBJ)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_DESTINATION, DISABLE_RESOURCE_DIR)\n", + " else:\n", + " set_snmp_alert_destination(REDFISHOBJ, snmp_service_uri, alert_destination_list)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "5a2f6ba5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "28ec396f", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 7ee56e1af690f13159c3287ccf7759056c7ecf82 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Thu, 11 May 2023 03:42:15 +0530 Subject: [PATCH 028/159] Add files via upload --- .../COMPUTER/set_server_asset_tag.ipynb | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb new file mode 100644 index 0000000..002f766 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb @@ -0,0 +1,248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c3169c50", + "metadata": {}, + "source": [ + "# Setting server asset tag" + ] + }, + { + "cell_type": "markdown", + "id": "70635f68", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting server asset tag.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f176e2a7", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbe979de", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "616c5812", + "metadata": {}, + "source": [ + "

      3. This is our set_server_asset_tag function overview.

      \n", + "
      \n", + "1. The set_server_asset_tag function sets the server asset tag on an iLO device. The function takes two parameters: _redfishobj and tag. \n", + "
        \n", + "
      • _redfishobj is a Redfish client object that represents the connection to the server
      • \n", + "
      • tag is a string that represents the asset tag to be set for the server.
      • \n", + "

      \n", + "2. In the set_server_asset_tag function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.

      \n", + "3. In the ILO rest api the information about server asset tag is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the server asset tag of iLO system.

      \n", + "4. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "

      \n", + "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #ComputerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.

      \n", + "6.The function then calls the patch() method to update the system's AssetTag property with the new tag provided as input to the function.

      \n", + "7. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", + "8. If the patch() operation is successful, the updated asset tag is printed to the console. The function then waits for 10 seconds before retrieving and displaying the updated asset tag.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4e166b2", + "metadata": {}, + "outputs": [], + "source": [ + "def set_server_asset_tag(_redfishobj, tag):\n", + "\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response and systems_members_uri and tag:\n", + " print(\"Current Asset Tag: \\'%s\\'\\n\" % systems_members_response.dict.get(\"AssetTag\"))\n", + "\n", + " resp = _redfishobj.patch(systems_members_uri, {\"AssetTag\" : tag})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", + " sys.stdout.write(\"\\nUpdated Asset Tag: \\'%s\\'\\n\" % _redfishobj.\\\n", + " get(systems_members_uri).dict.get(\"AssetTag\"))" + ] + }, + { + "cell_type": "markdown", + "id": "ef4f1fb5", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to set_server_asset_tag to set server asset tag of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "606190a9", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #asset tag property in computer systems\n", + " ASSET_TAG = \"Asset01\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_server_asset_tag(REDFISHOBJ, ASSET_TAG)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "bf946980", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "63db964c", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ea26d1d1bad60a706fd25217f5f5bf7e6eb3e488 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Thu, 11 May 2023 04:11:03 +0530 Subject: [PATCH 029/159] Add files via upload --- .../Dharitri/COMPUTER/set_uid_light.ipynb | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb new file mode 100644 index 0000000..b98d251 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb @@ -0,0 +1,270 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8ce5d6a0", + "metadata": {}, + "source": [ + "# Setting the UID light\n" + ] + }, + { + "cell_type": "markdown", + "id": "5b76e816", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting UID light
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set uid light. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0581e350", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "62892493", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25868/3349352274.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "1eb087ac", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our set_uid_light to function overview, in the end this will set uid light.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "1. This is a function that uses the Redfish API to toggle the UID (Universal Identification) LED on a computer system.\n", + " The function takes a Redfish connection object _redfishobj as its only argument.

      \n", + "2. In the set_uid_light function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "

      \n", + "3. In the iLO rest api the information about UID light is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the UID light settings of iLO system.\n", + "

      \n", + "4. In the system members response object with different odata_id we get a system uri . Then again an http GET request is made and response is stored in system_response. Then we set the system_members_uri.

      \n", + "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources and if #ComputerSystem attribute is present in @odata.type attribute then we'll set system_members_uri and get system_members_response settings of the user through redfish object.

      \n", + "6.It sets the body[\"IndicatorLED\"] key to Lit if the current value of the IndicatorLED property is Off, or to \"Off\" otherwise.

      \n", + "7. It sends an HTTP PATCH request to the obtained URI with the body payload to update the IndicatorLED property.

      \n", + "8. If the response status code is not 200 (OK) or 201 (Created), it prints an error message and exits.

      \n", + "9. If the response status code is 200 or 201, it waits for 10 seconds to allow the firmware to update the LED status, and then sends a GET request to the same URI to obtain the updated resource representation of the computer system.

      \n", + "10. It prints the updated value of the IndicatorLED property.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07276165", + "metadata": {}, + "outputs": [], + "source": [ + "def set_uid_light(_redfishobj):\n", + "\n", + " body = dict()\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response and systems_members_uri:\n", + " print(\"Current Indicator LED Status: \\'%s\\'\\n\" % systems_members_response.dict.\\\n", + " get(\"IndicatorLED\"))\n", + " if \"Off\" in systems_members_response.dict.get(\"IndicatorLED\"):\n", + " print(\"Will illuminate indicator LED.\\n\")\n", + " body[\"IndicatorLED\"] = \"Lit\"\n", + " else:\n", + " print(\"Will extinguish indicator LED.\\n\")\n", + " body[\"IndicatorLED\"] = \"Off\"\n", + "\n", + " resp = _redfishobj.patch(systems_members_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", + " sys.stdout.write(\"\\nUpdated Indicator LED Status: \\'%s\\'\\n\" % _redfishobj.\\\n", + " get(systems_members_uri).dict['IndicatorLED'])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "70d73b57", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. The rest opertions are handled by Redfish object which is created by Redfish Client
      \n", + "
      \n", + " \n", + "2. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of Redfish Client class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call set_uid_light with our redfish object to set UID light.
      \n", + "
      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea7ed17c", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_uid_light(REDFISHOBJ)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "3e4a9804", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "377dc76a", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 22074bdee3ee6454759572f6e112532e58037288 Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Thu, 11 May 2023 04:59:27 +0530 Subject: [PATCH 030/159] Add files via upload --- .../Dharitri/Syslog/set_syslogserver.ipynb | 283 ++++++++++++++++++ .../HPECTY/Dharitri/index.ipynb | 84 ++++++ 2 files changed, 367 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb new file mode 100644 index 0000000..14a772b --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b92b79fb", + "metadata": {}, + "source": [ + "# Setting remote syslog server" + ] + }, + { + "cell_type": "markdown", + "id": "2ed959e3", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting remote syslog server
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set remote syslog server. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3a91bf91", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • ilorest_util
    • \n", + "
    • argparse
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6eed1f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import argparse\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "6393e74d", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our set_syslog function overview


      \n", + " This function sets the remote syslog server and enables remote syslog on an iLO system.

      \n", + "1. It takes two parameters:\n", + "
        \n", + "
      • _redfishobj: an object representing the connection to the iLO device through the Redfish API.
      • \n", + "
      • syslog_server: a string representing the IP address or hostname of the remote syslog server.

      \n", + "2. The function first retrieves the model information of the system, which is used to determine the Oem (Original equipment manufacturer) name, as the endpoint structure and payload might differ based on the manufacturer. It determines the model of the server by sending a GET request to the /redfish/v1/Systems/1/ URI and extracting the Model attribute from the response.

      \n", + "3. It checks if the model contains \"Gen9\" or \"Gen8\". If either of them is present, it sets the \"hp\" variable to \"Hp\". Otherwise, it sets it to \"Hpe\".

      \n", + "4. It then constructs the URI for the syslog configuration resource and sends a PATCH request with the request body to set the remote syslog server and enable remote syslog.

      \n", + " 5. Finally, it calls the ilo_response, passing the _redfishobj and resp (response) as arguments. This function handles response from the server.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2971240e", + "metadata": {}, + "outputs": [], + "source": [ + "def set_syslog(_redfishobj, syslog_server):\n", + "\n", + " model_uri = \"/redfish/v1/Systems/1/\"\n", + " model = _redfishobj.get(model_uri).obj['Model']\n", + " print (model)\n", + " if \"Gen9\" in model or 'Gen8' in model:\n", + " hp = \"Hp\"\n", + " else:\n", + " hp = \"Hpe\"\n", + "\n", + " syslog_uri = \"/redfish/v1/Managers/1/NetworkService/\"\n", + "\n", + " body = {\"Oem\": {hp: {\"RemoteSyslogServer\": syslog_server, \"RemoteSyslogEnabled\": True}}}\n", + " resp = _redfishobj.patch(syslog_uri, body)\n", + " ilo_response(_redfishobj, resp)" + ] + }, + { + "cell_type": "markdown", + "id": "1fdc6d56", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is ilo_response function overview


      \n", + " The ilo_response function is responsible for handling the response from the iLO server.

      \n", + "1. It takes two parameters: _redfishobj (Redfish client object) and resp (response object).

      \n", + "2. It checks the status code of the response. If it is equal to 400, it indicates a client error.

      \n", + "3. It tries to extract and print the extended error information from the response using the key error ['@Message.ExtendedInfo'].\n", + "If there is an exception while accessing the extended error information, it writes an error message to the standard error stream.

      \n", + "4. If the status code is not 400 but is not equal to 200 either, it indicates an HTTP response error.\n", + "It writes an error message to the standard error stream, indicating the HTTP response status.

      \n", + "5. If the status code is 200, it indicates a successful response.\n", + "It prints the message \"Success\" to indicate the operation was successful.
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2db998f", + "metadata": {}, + "outputs": [], + "source": [ + "def ilo_response(_redfishobj, resp):\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success\")" + ] + }, + { + "cell_type": "markdown", + "id": "d95a2d40", + "metadata": {}, + "source": [ + "
      \n", + "

      4. This is Main function overview.

      \n", + "1. An argument parser is initialized to parse the command-line arguments passed to the script. The parser expects arguments such as iLO url, username, password, and syslog server IP.

      \n", + "2.The rest opertions are handled by Redfish object which is created by Redfish Client

      \n", + "3. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object. Once you enter everything a redfish object is created with the help of Redfish Client class.

      \n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"

      \n", + "5. The get_gen function is called to retrieve the iLO generation number of the server.\n", + " Depending on the iLO generation number, the set_syslog function is called with the Redfish client object and the syslog server IP address.

      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3681c0d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-s',\n", + " '--syslog_server',\n", + " dest='syslog_server',\n", + " action=\"store\",\n", + " required=True,\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " (ilogen,_) = get_gen(redfish_obj)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " set_syslog(redfish_obj, options.syslog_server)\n", + " else:\n", + " set_syslog(redfish_obj, options.syslog_server)\n", + " redfish_obj.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "750b6ae8", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f91c6419", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb index 29ee814..161b91f 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb @@ -70,6 +70,18 @@ " GET\n", " computer_details\n", " \n", + " \n", + " Set Server Asset Tag\n", + " Setting server asset tag\t\n", + " PATCH\n", + " set_server_asset_tag\n", + " \n", + " \n", + " Set UID Light\n", + " Setting UID Light\n", + " PATCH\n", + " set_uid_light\n", + " \n", " \n", "\n" ] @@ -142,6 +154,78 @@ " PATCH\n", " configure_snmp_trap_source\n", " \n", + " \n", + " Set SNMP alert destination\n", + " Setting SNMP alert destination for HPE iLO systems\n", + " PATCH\n", + " set_snmp_alert\n", + " \n", + " \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "aff5c9ed", + "metadata": {}, + "source": [ + "

      Scripts related to License Key

      " + ] + }, + { + "cell_type": "markdown", + "id": "c9cfb10a", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Set License Key\tSetting License KeyPATCHset_license_key
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "2c6d7156", + "metadata": {}, + "source": [ + "

      Scripts related to Syslog

      " + ] + }, + { + "cell_type": "markdown", + "id": "bcae99e1", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Set remote syslog server\tSetting Remote syslog Server for an HPE iLO management processor.PATCHset_syslogserver
      \n" ] From f1bf42f7831e719b6164f7f843b622acb0c2379e Mon Sep 17 00:00:00 2001 From: venkatrahul2003 <104755146+venkatrahul2003@users.noreply.github.com> Date: Thu, 11 May 2023 22:04:22 +0530 Subject: [PATCH 031/159] Add files via upload --- .../flash_firmware_by_uefi.ipynb | 398 ++++++++++++++++++ .../HPECTY/B VENKAT RAHUL/sessions.ipynb | 252 +++++++++++ .../set_ESKM_PrimaryKeyServer.ipynb | 296 +++++++++++++ .../set_ESKM_username_password.ipynb | 289 +++++++++++++ .../B VENKAT RAHUL/set_active_ilo_nic.ipynb | 295 +++++++++++++ 5 files changed, 1530 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb new file mode 100644 index 0000000..e951cf7 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb @@ -0,0 +1,398 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Uploading Firmware to the iLO Repository For Flashing

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of uploading firmware to the iLO Repository for flashings
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "import argparse\n", + "from random import randint\n", + "\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "import logging\n", + "from redfish import redfish_logger\n", + "\n", + "from ilorest_util import get_resource_directory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "102138e9", + "metadata": {}, + "outputs": [], + "source": [ + "LOGGERFILE = \"RedfishApiExamples.log\"\n", + "LOGGERFORMAT = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n", + "LOGGER = redfish_logger(LOGGERFILE, LOGGERFORMAT, logging.DEBUG)" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about upload_firmware function

      \n", + " \n", + "1. The function upload_firmware takes in parameters such as _redfishobj, firmware_loc, comp_type, update_repo, and update_target..
      \n", + "
      \n", + " \n", + "2. It uploads firmware to a specified location using the Redfish API and HTTP POST request.
      \n", + "
      \n", + "\n", + "3. The function first obtains the UpdateService URI and HttpPushUri using the _redfishobj and then reads the firmware file as binary data.
      \n", + "
      \n", + "\n", + "4. It creates a payload containing the session key, JSON data, and the firmware file in multipart-form data format..
      \n", + "
      \n", + "5. Finally, the function sends the payload as an HTTP POST request to the specified path and returns an appropriate response based on the HTTP status code.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, comp_type, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " print (update_service_uri)\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + " print (path)\n", + "\n", + " body = []\n", + "\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " #ImageLocation = \"c:\\\\test\"\n", + " #filename = \"I41_2.40_08_10_2020.fwpkg\"\n", + " #ImagePath = os.path.join(ImageLocation, filename)\n", + " #file_name = os.path.basename(firmware_loc)\n", + " #print (ImagePath)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(file_tuple)\n", + " #print (body)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " print ('Begin upload....please wait...')\n", + " # We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2b320019", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is about create task function

      \n", + " \n", + "1. The function create_task takes in parameters such as _redfishobj, firmware_loc, and tpm_flag.
      \n", + "
      \n", + " \n", + "2. It creates a new task for applying firmware updates using the Redfish API and HTTP POST request.
      \n", + "
      \n", + "\n", + "3. The function first obtains the session key and creates the necessary header dictionary for the HTTP request.It then checks if there are any current tasks in the task queue before creating a new task with a random ID and the given firmware file name.
      \n", + "
      \n", + "\n", + "4. The task is created using the update_task dictionary and sent as an HTTP POST request to the specified path.
      \n", + "
      \n", + "5. Finally, the function returns an appropriate response based on the HTTP status code.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09f2bc6b", + "metadata": {}, + "outputs": [], + "source": [ + "def create_task(_redfishobj, firmware_loc, tpm_flag=True):\n", + "\n", + " session_key = _redfishobj.session_key\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " updatable_by = ['Uefi']\n", + " task_path = '/redfish/v1/UpdateService/UpdateTaskQueue/'\n", + " file_name = os.path.basename(firmware_loc)\n", + "\n", + " task_resp = _redfishobj.get(task_path)\n", + " if not task_resp.obj[\"Members@odata.count\"]:\n", + " print (\"No current tasks, proceed to create new task\")\n", + "\n", + "\n", + " update_task = {'Name': 'Update-%s-%s' % (str(randint(0, 1000000)), \\\n", + " file_name), 'Command': 'ApplyUpdate',\\\n", + " 'Filename': file_name, 'UpdatableBy': updatable_by, 'TPMOverride': tpm_flag}\n", + "\n", + " resp = _redfishobj.post(task_path, update_task, headers=header)\n", + " #print (resp)\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to create update task queue...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Task Queue Creation complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "bcac4f85", + "metadata": {}, + "source": [ + "
      \n", + "

      4.

      \n", + " The Main function:
      PLEASE PROVIDE THE FOLLOWING CREDENTIALS HERE TO PROCEED FURTHER

      \n", + "
        \n", + "
      • The path to the firmware file to upload (-c/--component)
      • \n", + "
      • The iLO IP of the server (-i/--ilo)
      • \n", + "
      • The iLO username to login (-u/--user)
      • \n", + "
      • The iLO password to log in (-p/--password)
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-c',\n", + " '--component',\n", + " dest='comp_path',\n", + " action=\"store\",\n", + " required=True,\n", + " help=\"The path to the firmware file to upload\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-s',\n", + " '--session_key',\n", + " dest='session_key',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"Http session key for the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # Upload the firmware file to the iLO Repository\n", + " update_repo_flag = True\n", + " # Update the system with the firmware file\n", + " update_target_flag = False\n", + "\n", + " comp_type = 'C'\n", + " tpm_flag = True\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + " #system_url = \"https://\" + \"15.146.46.49\"\n", + " #session_id = \"515b196969f7d879886ee4a2da4ccba8\"\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " if options.session_key:\n", + " redfish_obj = RedfishClient(base_url=system_url, session_key= options.session_key)\n", + " else:\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(redfish_obj, options.comp_path, comp_type, update_repo_flag, update_target_flag)\n", + " if comp_type == 'C':\n", + " create_task(redfish_obj, options.comp_path, tpm_flag)\n", + "\n", + " redfish_obj.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb new file mode 100644 index 0000000..fc1f0bb --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb @@ -0,0 +1,252 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Manually Managing Sessions With Redfish

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of manually managing sessions with Redfish
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from six.moves import urllib\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about sessions function

      \n", + " \n", + "1. This function creates a new session with an iLO server using provided login credentials..
      \n", + "
      \n", + " \n", + "2. The function sends a POST request to the /redfish/v1/Sessions endpoint to create the session..
      \n", + "
      \n", + "\n", + "3. If the session is created successfully (response code 201), the function prints the session URI and X-Auth Token key..
      \n", + "
      \n", + "\n", + "4. The function also sends a DELETE request to the session URI to terminate the session.
      \n", + "
      \n", + "5. If the session creation fails, the function prints an error message and tries to access the iLO Extended Message Info for more details..
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def sessions(_redfishobj, login_account, login_password):\n", + "\n", + " new_session = {\"UserName\": login_account, \"Password\": login_password}\n", + " response = _redfishobj.post('/redfish/v1/Sessions', new_session)\n", + "\n", + " if response.status == 201:\n", + " print(\"Success!\\n\")\n", + " session_uri = response.getheader(\"location\")\n", + " session_uri = urllib.parse.urlparse(session_uri)\n", + " sys.stdout.write(\"\\tSession \" + session_uri.path + \" created.\\n\")\n", + " x_auth_token = response.getheader(\"x-auth-token\")\n", + " sys.stdout.write(\"\\tThis is the session X-Auth Token key \" + x_auth_token + \".\\n\")\n", + " print(json.dumps(response.dict, indent=4, sort_keys=True))\n", + "\n", + " # Delete the created session\n", + " sys.stdout.write(\"\\tTerminating this session.\\n\")\n", + " sessresp = _redfishobj.delete(session_uri.path)\n", + " print(json.dumps(sessresp.dict, indent=4, sort_keys=True))\n", + " else:\n", + " sys.stderr.write(\"ERROR: failed to create a session.\\n\")\n", + " try:\n", + " print(json.dumps(sessresp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended\"\n", + " \" Message Info...\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " sessions(REDFISHOBJ, LOGIN_ACCOUNT, LOGIN_PASSWORD)#calling sessions function" + ] + }, + { + "cell_type": "markdown", + "id": "316c3f0e", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb new file mode 100644 index 0000000..7c760bb --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb @@ -0,0 +1,296 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Set_ESKM_PrimaryKeyServer

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of set_ESKM_PrimaryKeyServer
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about set_ESKM_PrimaryKeyServer function

      \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "1. This function sets the primary key server for the HPE ESKM service.
      \n", + "
      \n", + " \n", + "2. It takes three arguments: _redfishobj (an object representing the Redfish service), primary_key_server_address (a string representing the IP address or hostname of the primary key server), and primary_key_server_port (an integer representing the port number of the primary key server).
      \n", + "
      \n", + "\n", + "3. It uses the get_resource_directory function to find the relevant ESKM URI, which is used to make a POST request to set the primary key server.
      \n", + "
      \n", + "\n", + "4. If the POST request is successful (returns an HTTP status code of 200), the function prints a success message and the JSON response from the server.
      \n", + "
      \n", + "5. If the POST request is unsuccessful, the function prints an error message and, if available, the extended error information from the server response.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ESKM_PrimaryKeyServer(_redfishobj, primary_key_server_address, primary_key_server_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + "\n", + " body[\"PrimaryKeyServerAddress\"] = primary_key_server_address\n", + " body[\"PrimaryKeyServerPort\"] = int(primary_key_server_port)\n", + "\n", + " resp = _redfishobj.post(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      3.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      4.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " PRIMARY_KEY_SERVER_ADDRESS = \"192.168.1.1\"\n", + " PRIMARY_KEY_SERVER_PORT = \"9000\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ESKM_PrimaryKeyServer(REDFISHOBJ, PRIMARY_KEY_SERVER_ADDRESS, PRIMARY_KEY_SERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb new file mode 100644 index 0000000..f38c417 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb @@ -0,0 +1,289 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Setting the ESKM username and password for HPE iLO systems

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of setting the ESKM username and password for HPE iLO systems
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about ESKM_username_pass function

      \n", + " \n", + "1. The function sets up an Electronic Software Key Manager (ESKM) on an iLO (Integrated Lights Out) server using the Redfish API.
      \n", + "
      \n", + " \n", + "2. It takes several input parameters including ESKM username, password, account group, primary key server address, and primary key server port.
      \n", + "
      \n", + "\n", + "3. It first attempts to locate the URI for the ESKM resource either by using the Redfish Resource Directory or by manually navigating through the Redfish API.br>\n", + "
      \n", + "\n", + "4. If the ESKM URI is found, the function constructs a JSON payload containing the ESKM configuration information and primary key server details and sends it as a PATCH request to the ESKM resource.
      \n", + "
      \n", + "5. If the PATCH request is successful (i.e., returns an HTTP status code of 200), the function prints out a success message along with the response payload, otherwise it prints out an error message.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def ESKM_username_pass(_redfishobj, eskm_username, eskm_password, eskm_accountgroup, \\\n", + " eskm_primarykeyserver_addr, eskm_primarykeyserver_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " body[\"KeyManagerConfig\"] = dict()\n", + " body[\"KeyManagerConfig\"][\"LoginName\"] = eskm_username\n", + " body[\"KeyManagerConfig\"][\"Password\"] = eskm_password\n", + " body[\"KeyManagerConfig\"][\"AccountGroup\"] = eskm_accountgroup\n", + " body[\"KeyManagerConfig\"][\"ESKMLocalCACertificateName\"] = \"\"\n", + " body[\"PrimaryKeyServerAddress\"] = eskm_primarykeyserver_addr\n", + " body[\"PrimaryKeyServerPort\"] = eskm_primarykeyserver_port\n", + " resp = _redfishobj.patch(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      3.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      4.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " ESKM_USERNAME = \"admin\"\n", + " ESKM_PASSWORD = \"password\"\n", + " ESKM_ACCOUNTGROUP = \"group\"\n", + " ESKM_PRIMARYKEYSERVER_ADDR = \"192.168.1.10\"\n", + " ESKM_PRIMARYKEYSERVER_PORT = 5927\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \\\n", + " ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb new file mode 100644 index 0000000..e0299c5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Setting the active Manager NIC

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of setting the active Manager NIC
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about set_active_ilo_nic function

      \n", + " \n", + "\n", + "1. This function is used to enable/disable Ethernet interfaces on an iLO (Integrated Lights Out) management interface.
      \n", + "
      \n", + " \n", + "2. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
      \n", + "
      \n", + "\n", + "3. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
      \n", + "
      \n", + "\n", + "4. If the PATCH request is successful (HTTP status 200), the function prints a success message and the response body, which contains information about the updated Ethernet interface.
      \n", + "
      \n", + "5. Finally, the function reminds the user that they need to reset iLO for the change to take effect.
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def set_active_ilo_nic(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " for interface in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Management Inteface \\'%s\\'\\n\" % ethernet_data\\\n", + " [interface].get('Id'))\n", + " sys.stdout.write(\"\\t\\'Interface Enabled\\': %s\\n\" % ethernet_data[interface].\\\n", + " get('InterfaceEnabled'))\n", + "\n", + " for ethernet in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Interface: %s\\n\" % ethernet)\n", + " ans = input(\"Would you like to enable/disable this interface? (enable/disable)\\n\")\n", + " if \"en\" in ans:\n", + " body = {\"InterfaceEnabled\": True}\n", + " else:\n", + " body = {\"InterfaceEnabled\": False}\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! You will need to reset iLO for this change to take effect.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_active_ilo_nic(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "316c3f0e", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From dfb621a1b6ba05d25948ba035f68e42febe2365a Mon Sep 17 00:00:00 2001 From: tanveer128 <123229272+tanveer128@users.noreply.github.com> Date: Fri, 12 May 2023 14:04:21 +0530 Subject: [PATCH 032/159] Add files via upload --- .../HPECTY/Tanveer/import_ssl.ipynb | 257 ++++++++++++++ .../HPECTY/Tanveer/modify_user_account.ipynb | 326 ++++++++++++++++++ .../Tanveer/mount_virtual_media_iso.ipynb | 322 +++++++++++++++++ .../HPECTY/Tanveer/quickstart_redfish.ipynb | 168 +++++++++ 4 files changed, 1073 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/import_ssl.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/modify_user_account.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/mount_virtual_media_iso.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/quickstart_redfish.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/import_ssl.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/import_ssl.ipynb new file mode 100644 index 0000000..37cf7fe --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/import_ssl.ipynb @@ -0,0 +1,257 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4bff53aa", + "metadata": { + "tags": [] + }, + "source": [ + "# Import_ssl" + ] + }, + { + "cell_type": "markdown", + "id": "5d4e9abe", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to importing secure socket layer
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "76d83083", + "metadata": {}, + "source": [ + "
      \n", + "

      1

      \n", + "In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code\n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • getpass
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a54980c8", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError" + ] + }, + { + "cell_type": "markdown", + "id": "5ca097d3", + "metadata": {}, + "source": [ + "
      \n", + "

      2

      \n", + "This cell gives overview about of the function SSL(secure socket layer)\n", + "
      \n", + "1. It will retrieves the URI for the security service, sends a GET request to retrieve the security service object, and then retrieves the URI for the HTTPS certificate object linked to from the security service object.\n", + "
      \n", + "2. Else it searches the Redfish API resource directory for an instance of a HPE HTTPS certificate object. If found, it retrieves the URI for the HTTPS certificate object and breaks out of the loop.\n", + "
      \n", + "3. If the uri is not none then it retrieves the HTTPS certificate import URI from the HTTPS certificate object and then sends a POST request to import an SSL certificate using the Redfish API. The SSL certificate is passed in the request body.\n", + "
      \n", + "4.Handling the error after inserting the iso image in slot \n", + " If status code is 400 the code attempts to retrieve and print extended error message .\n", + " If status code is 200 OK then it will print error meassage and status code.\n", + " Else the insertion is success then code print result in JSON format and aslo printing the import is successfully done.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d3002f22", + "metadata": {}, + "outputs": [], + "source": [ + "def import_ssl(_redfishobj, ssl_file_path):\n", + " # intialize to None\n", + " https_cert_uri = None\n", + " body = dict()\n", + " #Retrieving resource directory instances using Redfish API client.\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " \n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " https_cert_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeHttpsCert.' in instance['@odata.type']:\n", + " https_cert_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if https_cert_uri:\n", + " https_cert_import_uri = _redfishobj.get(https_cert_uri).obj['Actions']\\\n", + " ['#HpeHttpsCert.ImportCertificate']['target']\n", + " body = dict()\n", + " body[\"Action\"] = \"HpeHttpsCert.ImportCertificate\"\n", + " body[\"Certificate\"] = ssl_cert\n", + " resp = _redfishobj.post(https_cert_import_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " print(\"\\nImporting SSL Certificate may take a few minutes...\\n \"\\\n", + " \"iLO will reset with new changes.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "d911eb18", + "metadata": {}, + "source": [ + "
      \n", + "

      3

      \n", + "The Main function overview .
      \n", + "
        \n", + "
      • When you are running server locally or running in remotely connect using secured connection then you need to enter proper login cerdentials.
      • \n", + "
      • Creating redfish object and trying to establish connection with server using redfish object.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • Read the content of an SSL certificate file at SSL_FILE_PATH.
      • \n", + "
      • Lastly, Redfishobj.logout logs us out of the system and ends the session.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4a26864f", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " SSL_FILE_PATH = \"certificate.txt\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " with open(SSL_FILE_PATH, 'r') as csr_data:\n", + " ssl_cert = csr_data.read()\n", + " csr_data.close()\n", + "\n", + " if ssl_cert:\n", + " import_ssl(REDFISHOBJ, ssl_cert)\n", + " else:\n", + " raise Exception(\"Invalid SSL certificate.\\n\")\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "29439599", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "7e838742", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/modify_user_account.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/modify_user_account.ipynb new file mode 100644 index 0000000..f16ab22 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/modify_user_account.ipynb @@ -0,0 +1,326 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "22cbd656", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "#modify_user_account" + ] + }, + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is a example modify_user_account.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccd0447f", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

      2.

      This is our modify_ilo_user_account function overview, in the end this will help you to modify the account.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings..\n", + "\n", + "1. In the modify_user_account function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. Retrieves the account service URI, sends a GET request to the account service, and obtains the account collection URI. If a role_id is provided, it creates a request body with the modified RoleId parameter.\n", + "
      \n", + " \n", + "3. Else Iterate over resource instances to find the account collection URI. Modify privileges and/or login name if specified for an HPE server.\n", + "
      \n", + " \n", + "4. If new User name is there then modified the new user name and password in the body.\n", + " Iterate over account URIs to find the one with a matching username. If found, modify the account using a PATCH request to the identified URI.\n", + "
      \n", + " \n", + "5.Handling the error after inserting the iso image in slot \n", + "If status code is 400 the code attempts to retrieve and print extended error message .\n", + "If status code is 200 OK then it will print error meassage and status code.\n", + "Else the modification is success then code print result in JSON format.\n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "def modify_ilo_user_account(_redfishobj, username_to_modify, new_loginname, new_username, \\\n", + " new_password, role_id, privilege_dict):\n", + "\n", + " account_collection_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " #modify role id\n", + " if role_id:\n", + " body = {\"RoleId\": role_id}\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " if privilege_dict:\n", + " #HPE server, so modify privileges\n", + " body = {\"Oem\": {\"Hpe\": {\"Privileges\": {}}}}\n", + " for priv in privilege_dict:\n", + " body[\"Oem\"][\"Hpe\"][\"Privileges\"][priv] = privilege_dict[priv]\n", + " if new_loginname:\n", + " #modify login name\n", + " body[\"Oem\"][\"Hpe\"][\"LoginName\"] = new_loginname\n", + "\n", + " if new_username:\n", + " body[\"UserName\"] = new_username\n", + " if new_password:\n", + " body[\"Password\"] = new_password\n", + "\n", + " #find the account to modify\n", + " account_uri_to_modify = None\n", + " account_uris = REDFISHOBJ.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " account = REDFISHOBJ.get(account_uri['@odata.id'])\n", + " if account.dict['UserName'] == username_to_modify:\n", + " account_uri_to_modify = account_uri['@odata.id']\n", + " break\n", + "\n", + " if not account_uri_to_modify:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + "\n", + " #modify the account by sending patch request\n", + " resp = REDFISHOBJ.patch(account_uri_to_modify, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER BASED WHERE YOU ARE RUUNIG THE SERVER
      \n", + "
        \n", + "
      • The variables USERNAME_TO_MODIFY, NEW_LOGINNAME, NEW_USERNAME, NEW_PASSWORD, and ROLE_ID have been assigned with the specified values.
      • \n", + "
      • PRIVILEGE_DICT represents a dictionary where each key corresponds to a specific privilege and the corresponding value indicates whether that privilege is enabled or disabled.
      • \n", + "
      • Using the redfish object we are trying to establish the connection with the server.After establish the connection we try to login .If the server is unreachable we noftify the user with error message.
      • \n", + "
      • If login is successful then we are calling the function with proper parameter.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "faa032c5", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 43\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 42\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 43\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 44\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 45\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 47\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 46\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 47\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 48\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 49\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #username of the account to modify\n", + " USERNAME_TO_MODIFY = \"bruce_wayne\"\n", + "\n", + " #account login name to change the account to\n", + " NEW_LOGINNAME = \"joker\"\n", + "\n", + " #account user name to change the account to\n", + " NEW_USERNAME = \"joker\"\n", + "\n", + " #account password to change the account to\n", + " NEW_PASSWORD = \"joker123\"\n", + "\n", + " #role to change account to\n", + " ROLE_ID = \"ReadOnly\" #Administrator, ReadOnly or Operator are available\n", + "\n", + " #update HPE account privileges\n", + " PRIVILEGE_DICT = {\"iLOConfigPriv\": False, \"VirtualMediaPriv\": False, \"RemoteConsolePriv\": True,\\\n", + " \"UserConfigPriv\": False, \"VirtualPowerAndResetPriv\": False, \\\n", + " \"SystemRecoveryConfigPriv\": False, \"LoginPriv\": True, \\\n", + " \"HostStorageConfigPriv\": False, \"HostNICConfigPriv\": False, \\\n", + " \"HostBIOSConfigPriv\": False}\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " modify_ilo_user_account(REDFISHOBJ, USERNAME_TO_MODIFY, NEW_LOGINNAME, NEW_USERNAME, \\\n", + " NEW_PASSWORD, ROLE_ID, PRIVILEGE_DICT)\n", + "\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/mount_virtual_media_iso.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/mount_virtual_media_iso.ipynb new file mode 100644 index 0000000..cfa0710 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/mount_virtual_media_iso.ipynb @@ -0,0 +1,322 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "266e8885", + "metadata": { + "tags": [] + }, + "source": [ + "# Mount_virtual-media_iso" + ] + }, + { + "cell_type": "markdown", + "id": "358b08b4", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to mount_virtual_media_iso
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "578dfc4d", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c82681e9", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/1390777471.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'get_resource_directory'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "84274de2", + "metadata": {}, + "source": [ + "
      \n", + "

      2.

      This is our mount_virtual-media_iso function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present.
      \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. Retrieving information on the server's management interfaces using the Redfish API client, including members and their properties and retrieving URI for virtual media using Redfish API client.\n", + "
      \n", + "\n", + "3. Else Using the Redfish API client and the Resource Directory, iterating through resource instances, and obtaining the URI for the virtual media collection.\n", + "
      \n", + "4. If virtual_media_uri is not None then If a slot matches, the program fetches the URI for adding media into that slot and then sends a POST request to the supplied URL to insert the ISO image. Additionally, the code sends a PATCH request to set the option if a parameter is provided for the server to restart from the virtual media.\n", + "
      \n", + "\n", + "5. Handling the error after inserting the iso image in slot \n", + " If status code is 400 the code attempts to retrieve and print extended error message .\n", + " If status code is 200 OK then it will print error meassage and status code.\n", + " Else the insertion is success then code print result in JSON format.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc680e58", + "metadata": {}, + "outputs": [], + "source": [ + "def mount_virtual_media_iso(_redfishobj, iso_url, media_type, boot_on_next_server_reset):\n", + " #Initializing variables for virtual media API responses.\n", + " virtual_media_uri = None\n", + " virtual_media_response = []\n", + "#Retrieving resource directory instances using Redfish API client.\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", + " virtual_media_uri = instance['@odata.id']\n", + "\n", + " if virtual_media_uri:\n", + " #retriving information Virtual media using redfish object and specified parameter\n", + " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", + " #iterates through each virtual media to find proper slot\n", + " for virtual_media_slot in virtual_media_response.obj['Members']:\n", + " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", + " if media_type in data.dict['MediaTypes']:\n", + " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.InsertMedia']['target']\n", + " post_body = {\"Image\": iso_url}\n", + "\n", + " if iso_url:\n", + " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", + " if boot_on_next_server_reset is not None:\n", + " patch_body = {}\n", + " patch_body[\"Oem\"] = {\"Hpe\": {\"BootOnNextServerReset\": \\\n", + " boot_on_next_server_reset}}\n", + " boot_resp = _redfishobj.patch(data.obj['@odata.id'], patch_body)\n", + " if not boot_resp.status == 200:\n", + " sys.stderr.write(\"Failure setting BootOnNextServerReset\")\n", + " #handling error after inserting iso image in slot \n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "567eb3f8", + "metadata": {}, + "source": [ + "
      \n", + "

      3.

      This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + "
      \n", + "1. If server is runnig in locally then url,login_account,Login-password will be None.\n", + " Else then we need to enter the proper credential.\n", + "
      \n", + "
      \n", + " \n", + "2. media_url will provide access and mount the iso image in server side and we initial media_type to CD.
      \n", + "
      \n", + "\n", + "3. Utilising the Redfish API to create a Redfish client object with the provided login information and log in to the server.
      \n", + "
      \n", + "\n", + "4. resolving the exception that is thrown when the server cannot be reached or does not implement the Redfish API, printing a message of error to standard error output, and terminating the program
      \n", + "
      \n", + "5. Using the Redfish API client object and the given arguments to mount a virtual media ISO image on a server.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7c01d222", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: 120.1.114.51\n", + "Enter Name: tann\n", + "Enter password: none\n", + "Enter bios password: noen\n", + "Enter bios property you wish to change: yes\n", + "Enter Value of the property to change: none\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 17\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 16\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 17\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 19\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 21\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 20\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 21\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 22\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 23\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + " # used to access and mount iso image on server side\n", + " MEDIA_URL = \"http:///media.iso\"\n", + "\n", + " #specify the type of content the media represents\n", + " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", + " #specify if the server should attempt to boot this media on system restart\n", + " BOOT_ON_NEXT_SERVER_RESET = True\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " mount_virtual_media_iso(REDFISHOBJ, MEDIA_URL, MEDIA_TYPE, BOOT_ON_NEXT_SERVER_RESET)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "9d0181a9", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "9e9f0846", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/quickstart_redfish.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/quickstart_redfish.ipynb new file mode 100644 index 0000000..55fe2c6 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/quickstart_redfish.ipynb @@ -0,0 +1,168 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Quickstart_redfish" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Quickstart-redfish
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "658962be-a0df-4696-ab9e-73f844703ff9", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • redfish
    • \n", + " \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "53341fc4-f674-4781-bcb1-04bb06d3d1fb", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import redfish\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
      \n", + "

      2.

      Code overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " 1.When you are running server locally the login and password will be None.\n", + "
      \n", + " 2.When server is running in remotely connect using iLO account name and iLO address then iLO host and login credentials.\n", + "
      \n", + " 3.Creating redfish object which will use to communicate with the server.\n", + "
      \n", + " 4.By using redfish object we can login to server and start the session.\n", + "
      \n", + " 5.Next we make a http request to retrive the information about a system and printing the respone.\n", + "
      \n", + " 6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "# When running on the server locally use the following commented values\n", + "# iLO_host = \"blobstore://.\"\n", + "# LOGIN_ACCOUNT = \"None\"\n", + "# LOGIN_PASSWORD = \"None\"\n", + "\n", + "# When running remotely connect using the iLO address, iLO account name, \n", + "# and password to send https requests\n", + "iLO_host = \"https://10.0.0.100\"\n", + "login_account = \"admin\"\n", + "login_password = \"password\"\n", + "\n", + "## Create a REDFISH object\n", + "REDFISH_OBJ = redfish.RedfishClient(base_url=iLO_host,username=login_account, \\\n", + " password=login_password)\n", + "\n", + "# Login into the server and create a session\n", + "REDFISH_OBJ.login()\n", + "\n", + "# Do a GET on a given path\n", + "response = REDFISH_OBJ.get(\"/redfish/v1/systems/1\")\n", + "\n", + "# Print out the response\n", + "sys.stdout.write(\"%s\\n\" % response)\n", + "\n", + "# Logout of the current session\n", + "REDFISH_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "d0ded655-d8e4-452d-b181-783a6b1788f5", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ef6dc0ab685fdfc7aa251cce979f903b20f95ef0 Mon Sep 17 00:00:00 2001 From: tanveer128 <123229272+tanveer128@users.noreply.github.com> Date: Fri, 12 May 2023 14:25:53 +0530 Subject: [PATCH 033/159] Add files via upload --- .../HPECTY/Tanveer/ilorest_util.ipynb | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/ilorest_util.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/ilorest_util.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/ilorest_util.ipynb new file mode 100644 index 0000000..90ea81c --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/ilorest_util.ipynb @@ -0,0 +1,193 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "fdd0f83f", + "metadata": {}, + "outputs": [], + "source": [ + "#ilorest-util" + ] + }, + { + "cell_type": "markdown", + "id": "45dd47a5", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of ilorest_util
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "23eeb2bf", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92ec68a2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "10a8e977", + "metadata": {}, + "source": [ + "

      2.

      This is our get_resource_directory function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present.\n", + "
      \n", + "1.Using the phrase redfishobj.root.obj.Oem.Hpe.Links.ResourceDirectory['@odata.id'], it attempts to retrieve the resource directory URI. The resource directory is not accessible on non-HPE servers if the key @odata.id is missing from the ResourceDirectory dictionary. Then, a message indicating the error is printed, and None is returned.\n", + "
      \n", + "2.Redfishobj.get(resource_uri) is used by the code to send a GET request to the resource directory URI if it was successfully fetched.\n", + "
      \n", + "3.Then we extracts the list of resource instances from the response dictionary (response.dict[\"Instances\"]) and assigns it to the resources variable if the response status is 200 (OK), which means that the resource directory was found at the specified URI (/redfish/v1/resourcedirectory).\n", + "
      \n", + "4.If the response status is not 200, an error message is printed, indicating that the resource directory is missing at the specified URI.\n", + "
      \n", + "5.Atlast the function return the list of resources.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f034ef9c", + "metadata": {}, + "outputs": [], + "source": [ + "def get_resource_directory(redfishobj):\n", + "\n", + " try:\n", + " resource_uri = redfishobj.root.obj.Oem.Hpe.Links.ResourceDirectory['@odata.id']\n", + " except KeyError:\n", + " sys.stderr.write(\"Resource directory is only available on HPE servers.\\n\")\n", + " return None\n", + "\n", + " response = redfishobj.get(resource_uri)\n", + " resources = []\n", + "\n", + " if response.status == 200:\n", + " sys.stdout.write(\"\\tFound resource directory at /redfish/v1/resourcedirectory\" + \"\\n\\n\")\n", + " resources = response.dict[\"Instances\"]\n", + " else:\n", + " sys.stderr.write(\"\\tResource directory missing at /redfish/v1/resourcedirectory\" + \"\\n\")\n", + "\n", + " return resources" + ] + }, + { + "cell_type": "markdown", + "id": "268b5a18", + "metadata": {}, + "source": [ + "

      3.

      \n", + "This is the overview of the get_gen function .\n", + "
      \n", + "
        \n", + "
      • It starts by accessing the root object of the Redfish API response using _redfishobj.root.obj.
      • \n", + "
      • Determines whether the response has the key Hpe or Hp beneath the Oem key. If so, it is assumed to be an HPE or HP server.
      • \n", + "
      • Based on the value of gencompany, it initialises the comp variable. Comp sets to 'Hp' if gencompany is True; otherwise, it stays None.Additionally, it looks for the key 'Hpe' under the 'Oem' key in the response. If so, it changes comp to 'Hpe'.
      • \n", + "
      • The code verifies whether the key ManagerType under the Manager key of the Oem dictionary is present in the response. If so, it gets the ManagerType value, which stands for the generation of the iLO.
      • \n", + "
      • The ManagerFirmwareVersion key is also used to access the iLO firmware version .Ilogen is set to 4 and iloversion is set to None if the iLO generation terminates in CM.
      • \n", + "
      • The second element is used as the iLO generation number once the iLO generation string has been divided by spaces. Additionally, it adds a dot to the final component of the iLO firmware version to create the iLO version number.
      • \n", + "
      • It returns a tuple (ilogen, iloversion) containing the determined iLO generation and version.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab494baf", + "metadata": {}, + "outputs": [], + "source": [ + "def get_gen(_redfishobj):\n", + "\trootresp = _redfishobj.root.obj\n", + "\t#Default iLO 5\n", + "\tilogen = 5\n", + "\tgencompany = next(iter(rootresp.get(\"Oem\", {}).keys()), None) in ('Hpe', 'Hp')\n", + "\tcomp = 'Hp' if gencompany else None\n", + "\tcomp = 'Hpe' if rootresp.get(\"Oem\", {}).get('Hpe', None) else comp\n", + "\tif comp and next(iter(rootresp.get(\"Oem\", {}).get(comp, {}).get(\"Manager\", {}))).\\\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tget('ManagerType', None):\n", + "\t\tilogen = next(iter(rootresp.get(\"Oem\", {}).get(comp, {}).get(\"Manager\", {})))\\\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.get(\"ManagerType\")\n", + "\t\tilover = next(iter(rootresp.get(\"Oem\", {}).get(comp, {}).get(\"Manager\", {}))).\\\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t get(\"ManagerFirmwareVersion\")\n", + "\t\tif ilogen.split(' ')[-1] == \"CM\":\n", + "\t\t\t# Assume iLO 4 types in Moonshot\n", + "\t\t\tilogen = 4\n", + "\t\t\tiloversion = None\n", + "\t\telse:\n", + "\t\t\tilogen = ilogen.split(' ')[1]\n", + "\t\t\tiloversion = float(ilogen.split(' ')[-1] + '.' + \\\n", + "\t\t\t\t\t\t\t\t\t\t\t''.join(ilover.split('.')))\n", + "\treturn (ilogen, iloversion)\n" + ] + }, + { + "cell_type": "markdown", + "id": "a839daaa", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 21405cd597a0c0b4a744f8388aeb9a5230f7bf29 Mon Sep 17 00:00:00 2001 From: Rajeevalochana Kallur Date: Fri, 12 May 2023 16:02:22 +0530 Subject: [PATCH 034/159] scripts_classified --- .../ahs_syslog_iml/clear_ahs_data.ipynb | 254 ++++++++++++ .../clear_ilo_iel_iml_log.ipynb | 246 ++++++++++++ .../ahs_syslog_iml/get_ahs_data.ipynb | 264 ++++++++++++ .../ahs_syslog_iml/set_syslogserver.ipynb | 283 +++++++++++++ .../bios/BIOS_ChangeSettings.ipynb | 285 +++++++++++++ .../bios/BIOS_RevertToDefault.ipynb | 331 +++++++++++++++ .../bios/get_base_registry.ipynb | 175 ++++++++ .../bios/get_bios_settings.ipynb | 244 +++++++++++ .../boot/Change_Boot_Order.ipynb | 283 +++++++++++++ .../boot/Change_Temp_Boot_Order.ipynb | 260 ++++++++++++ .../eskm/reset_ESKM_eventlog.ipynb | 378 ++++++++++++++++++ .../eskm/set_ESKM_PrimaryKeyServer.ipynb | 207 ++++++++++ .../eskm/set_ESKM_username_pass.ipynb | 213 ++++++++++ .../ilo_license/set_license_key.ipynb | 262 ++++++++++++ example_jupyter_notebooks/index.ipynb | 152 +++++++ .../nic_network/get_ilo_ip.ipynb | 158 ++++++++ .../nic_network/get_ilo_nic.ipynb | 164 ++++++++ .../nic_network/set_ethernet_management.ipynb | 288 +++++++++++++ .../ntp_timezone/set_ilo_ntp_servers.ipynb | 278 +++++++++++++ .../ntp_timezone/set_ilo_timezone.ipynb | 241 +++++++++++ .../server_manager/computer_details.ipynb | 230 +++++++++++ .../server_manager/reboot_server.ipynb | 0 .../server_manager/reset_server.ipynb | 0 .../server_manager/set_server_asset_tag.ipynb | 248 ++++++++++++ .../server_manager/set_uid_light.ipynb | 270 +++++++++++++ .../snmp/configure_snmp.ipynb | 282 +++++++++++++ .../snmp/configure_snmp_trap_source.ipynb | 246 ++++++++++++ .../snmp/set_snmp_alert.ipynb | 315 +++++++++++++++ .../users_and_sessions/account_remove.ipynb | 250 ++++++++++++ .../modify_user_account.ipynb | 326 +++++++++++++++ .../mount_virtual_media_iso.ipynb | 322 +++++++++++++++ .../HPECTY/Tanveer/reboot_server.ipynb | 236 +++++++++++ .../HPECTY/Tanveer/reset_server.ipynb | 304 ++++++++++++++ 33 files changed, 7995 insertions(+) create mode 100644 example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb create mode 100644 example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb create mode 100644 example_jupyter_notebooks/ahs_syslog_iml/get_ahs_data.ipynb create mode 100644 example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb create mode 100644 example_jupyter_notebooks/bios/BIOS_ChangeSettings.ipynb create mode 100644 example_jupyter_notebooks/bios/BIOS_RevertToDefault.ipynb create mode 100644 example_jupyter_notebooks/bios/get_base_registry.ipynb create mode 100644 example_jupyter_notebooks/bios/get_bios_settings.ipynb create mode 100644 example_jupyter_notebooks/boot/Change_Boot_Order.ipynb create mode 100644 example_jupyter_notebooks/boot/Change_Temp_Boot_Order.ipynb create mode 100644 example_jupyter_notebooks/eskm/reset_ESKM_eventlog.ipynb create mode 100644 example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer.ipynb create mode 100644 example_jupyter_notebooks/eskm/set_ESKM_username_pass.ipynb create mode 100644 example_jupyter_notebooks/ilo_license/set_license_key.ipynb create mode 100644 example_jupyter_notebooks/index.ipynb create mode 100644 example_jupyter_notebooks/nic_network/get_ilo_ip.ipynb create mode 100644 example_jupyter_notebooks/nic_network/get_ilo_nic.ipynb create mode 100644 example_jupyter_notebooks/nic_network/set_ethernet_management.ipynb create mode 100644 example_jupyter_notebooks/ntp_timezone/set_ilo_ntp_servers.ipynb create mode 100644 example_jupyter_notebooks/ntp_timezone/set_ilo_timezone.ipynb create mode 100644 example_jupyter_notebooks/server_manager/computer_details.ipynb rename examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb => example_jupyter_notebooks/server_manager/reboot_server.ipynb (100%) rename examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb => example_jupyter_notebooks/server_manager/reset_server.ipynb (100%) create mode 100644 example_jupyter_notebooks/server_manager/set_server_asset_tag.ipynb create mode 100644 example_jupyter_notebooks/server_manager/set_uid_light.ipynb create mode 100644 example_jupyter_notebooks/snmp/configure_snmp.ipynb create mode 100644 example_jupyter_notebooks/snmp/configure_snmp_trap_source.ipynb create mode 100644 example_jupyter_notebooks/snmp/set_snmp_alert.ipynb create mode 100644 example_jupyter_notebooks/users_and_sessions/account_remove.ipynb create mode 100644 example_jupyter_notebooks/users_and_sessions/modify_user_account.ipynb create mode 100644 example_jupyter_notebooks/virtual_media/mount_virtual_media_iso.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/reset_server.ipynb diff --git a/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb new file mode 100644 index 0000000..8d3ee2f --- /dev/null +++ b/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d7d850", + "metadata": { + "tags": [] + }, + "source": [ + "# Clearing AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "88f096f8", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Clearing AHS(Active Health System) data!!!
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "d1525f25", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ce9142d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b9615aea", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
      \n", + "\n", + "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", + " Then we set the active_health_system_clear_log_uri.\n", + "
      \n", + "\n", + "4. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", + "
      \n", + "\n", + "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", + "\n", + " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "16042277", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ahs_data(_redfishobj):\n", + "\n", + " active_health_system_clear_log_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " break\n", + "\n", + " if active_health_system_clear_log_uri:\n", + " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", + " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "6e7543eb", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
      \n", + "
      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270f99bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ahs_data(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "1557bfee", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "e685a623", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb new file mode 100644 index 0000000..19de2bd --- /dev/null +++ b/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "89dc5655", + "metadata": { + "tags": [] + }, + "source": [ + "# CLEAR iLO LOGS" + ] + }, + { + "cell_type": "markdown", + "id": "898cbb84", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to for clearing out the iLO event log and management log at server side!
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "98f3c2dd", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "935d8f7c", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "ef3013ef", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This cell gives overview about of the function used to clear event logs such as IML and IEL logs.


      \n", + "The IML provides a record of historical events that have occurred on the server and the IEL is the iLO event log provides record of significant events detected by iLO.\n", + " \n", + "1. When the resource directory is disabled then we simply navigate through the API for obtaining the relevant uri.\n", + " The series of HTTP get requests aims to extracts log_services_response so as to get the path of the directory for which IEL and IML logs need to be cleared.\n", + "
      \n", + "2. Else if the resource directory enabled then rather we can simply extract the uri by #LogService.attribute inside the instance['odatatype'] dictionary and again make a HTTP get request to obtain the required uri.\n", + "
      \n", + "3. After obtaining the uri we just need to make changes on the same location using a post request so as to clear IEL and IML logs successfully. For this body dictionary contains the attribute to be changed and IEL/IML are searched in the path of clear_log_services_uri and the respective changes are made by redfishobj.post(path,body).\n", + "
      \n", + " \n", + "4. Later we also check for the response returned by the server side. If the response is anything outside of status code with 200 then error message gets rendered on the webpage else the success message is printed out with the response dictionary returned by the server.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a7abae2a", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ilo_event_log(_redfishobj, clear_IML_IEL):\n", + "\n", + " clear_log_services_uri = []\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " log_services_uri = systems_members_response.obj['LogServices']['@odata.id']\n", + " log_services_response = _redfishobj.get(log_services_uri)\n", + " log_services_uris = log_services_response.obj['Members']\n", + " for log_services_uri in log_services_uris:\n", + " log_services_response = _redfishobj.get(log_services_uri['@odata.id'])\n", + " clear_log_services_uri.append(log_services_response.obj['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#LogService.' in instance['@odata.type']:\n", + " log_service_uri = instance['@odata.id']\n", + " clear_log_services_uri.append(_redfishobj.get(log_service_uri).dict['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + "\n", + " if clear_log_services_uri:\n", + " body = {\"Action\": \"LogService.ClearLog\"}\n", + " for path in clear_log_services_uri:\n", + " if (\"IEL\" in clear_IML_IEL and \"IEL\" in path) or (\"IML\" in clear_IML_IEL and \\\n", + " \"IML\" in path):\n", + " if \"IEL\" in path:\n", + " sys.stdout.write(\"Clearing IEL log.\\n\")\n", + " else:\n", + " sys.stdout.write(\"Clearing IML log.\\n\")\n", + " resp = _redfishobj.post(path, body)\n", + " else:\n", + " continue\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "331b8289", + "metadata": {}, + "source": [ + "
      \n", + "

      3. The Main function


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + " \n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.

      \n", + "4. If server is down or Unreachable we get server not reachable message!

      \n", + "5. Else if no error is encountered a function call is made i.e. clear_ilo_event_log(REDFISHOBJ, CLEAR_IEL_IML)that is responsible for handling clearing all the IEL and IML logs at the server side.

      \n", + "6. Lastly, REDFISHOBJ.logout logs us out of the system and ends the session.\n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4143942b", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " CLEAR_IML_IEL = \"IML\" # provide either the string IML or IEL\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ilo_event_log(REDFISHOBJ, CLEAR_IML_IEL)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "f120e784", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f702c0ae", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ahs_syslog_iml/get_ahs_data.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/get_ahs_data.ipynb new file mode 100644 index 0000000..7427901 --- /dev/null +++ b/example_jupyter_notebooks/ahs_syslog_iml/get_ahs_data.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a597eefb", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "28da61c7", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to get_ahs_data!!!
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy, we'll be needing it in a while!\n", + "
      \n", + " Follow the guide below to execute without any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "6c29a405", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "29082d3a", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      2.

      This is our ahs gathering data function overview, in the end we will get the Active Health System data.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the get_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about the Active Health System is stored inside the managers json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the ahs data of iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object with different odata_id we get the managers members uri .\n", + " Then again an http GET request is made and response is stored in managers_response_response.\n", + " Then we set the active_health_system_uri.\n", + "
      \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeiLOActiveHealthSystem attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_log_resp through redfish object.\n", + "
      \n", + "\n", + "5. If this is successful, then we will open a logfile and write active_health_system_log_resp.ori which is the get_ahs_data to that logfile.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ahs_data(_redfishobj, logfile=\"data.ahs\"):\n", + "\n", + " active_health_system_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + "\n", + " if active_health_system_uri:\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_log_uri = active_health_system_response.obj.Links['AHSLocation']\\\n", + " ['extref']\n", + " active_health_system_log_resp = _redfishobj.get(active_health_system_log_uri)\n", + " if active_health_system_log_resp.status == 400:\n", + " try:\n", + " print(json.dumps(active_health_system_log_resp.obj['error']\\\n", + " ['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif active_health_system_log_resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % active_health_system_log_resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " with open(logfile, 'wb') as ahsoutput:\n", + " ahsoutput.write(active_health_system_log_resp.ori)\n", + " ahsoutput.close()\n", + " sys.stdout.write(\"AHS Data saved successfully as: \\'%s\\'\" % logfile)\n" + ] + }, + { + "cell_type": "markdown", + "id": "155fb958", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      3.

      This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " Enter ilo url,username,password, and the path of log file
      \n", + " \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call get_ahs_data with our redfish object and logfile.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # logfile path and filename\n", + " LOGFILE = input(\"Enter log file path and file name: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_ahs_data(REDFISHOBJ, LOGFILE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " LOGFILE = data.ahs
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "10a528a3", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb new file mode 100644 index 0000000..14a772b --- /dev/null +++ b/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b92b79fb", + "metadata": {}, + "source": [ + "# Setting remote syslog server" + ] + }, + { + "cell_type": "markdown", + "id": "2ed959e3", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting remote syslog server
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set remote syslog server. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3a91bf91", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • ilorest_util
    • \n", + "
    • argparse
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6eed1f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import argparse\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "6393e74d", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our set_syslog function overview


      \n", + " This function sets the remote syslog server and enables remote syslog on an iLO system.

      \n", + "1. It takes two parameters:\n", + "
        \n", + "
      • _redfishobj: an object representing the connection to the iLO device through the Redfish API.
      • \n", + "
      • syslog_server: a string representing the IP address or hostname of the remote syslog server.

      \n", + "2. The function first retrieves the model information of the system, which is used to determine the Oem (Original equipment manufacturer) name, as the endpoint structure and payload might differ based on the manufacturer. It determines the model of the server by sending a GET request to the /redfish/v1/Systems/1/ URI and extracting the Model attribute from the response.

      \n", + "3. It checks if the model contains \"Gen9\" or \"Gen8\". If either of them is present, it sets the \"hp\" variable to \"Hp\". Otherwise, it sets it to \"Hpe\".

      \n", + "4. It then constructs the URI for the syslog configuration resource and sends a PATCH request with the request body to set the remote syslog server and enable remote syslog.

      \n", + " 5. Finally, it calls the ilo_response, passing the _redfishobj and resp (response) as arguments. This function handles response from the server.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2971240e", + "metadata": {}, + "outputs": [], + "source": [ + "def set_syslog(_redfishobj, syslog_server):\n", + "\n", + " model_uri = \"/redfish/v1/Systems/1/\"\n", + " model = _redfishobj.get(model_uri).obj['Model']\n", + " print (model)\n", + " if \"Gen9\" in model or 'Gen8' in model:\n", + " hp = \"Hp\"\n", + " else:\n", + " hp = \"Hpe\"\n", + "\n", + " syslog_uri = \"/redfish/v1/Managers/1/NetworkService/\"\n", + "\n", + " body = {\"Oem\": {hp: {\"RemoteSyslogServer\": syslog_server, \"RemoteSyslogEnabled\": True}}}\n", + " resp = _redfishobj.patch(syslog_uri, body)\n", + " ilo_response(_redfishobj, resp)" + ] + }, + { + "cell_type": "markdown", + "id": "1fdc6d56", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is ilo_response function overview


      \n", + " The ilo_response function is responsible for handling the response from the iLO server.

      \n", + "1. It takes two parameters: _redfishobj (Redfish client object) and resp (response object).

      \n", + "2. It checks the status code of the response. If it is equal to 400, it indicates a client error.

      \n", + "3. It tries to extract and print the extended error information from the response using the key error ['@Message.ExtendedInfo'].\n", + "If there is an exception while accessing the extended error information, it writes an error message to the standard error stream.

      \n", + "4. If the status code is not 400 but is not equal to 200 either, it indicates an HTTP response error.\n", + "It writes an error message to the standard error stream, indicating the HTTP response status.

      \n", + "5. If the status code is 200, it indicates a successful response.\n", + "It prints the message \"Success\" to indicate the operation was successful.
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2db998f", + "metadata": {}, + "outputs": [], + "source": [ + "def ilo_response(_redfishobj, resp):\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success\")" + ] + }, + { + "cell_type": "markdown", + "id": "d95a2d40", + "metadata": {}, + "source": [ + "
      \n", + "

      4. This is Main function overview.

      \n", + "1. An argument parser is initialized to parse the command-line arguments passed to the script. The parser expects arguments such as iLO url, username, password, and syslog server IP.

      \n", + "2.The rest opertions are handled by Redfish object which is created by Redfish Client

      \n", + "3. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object. Once you enter everything a redfish object is created with the help of Redfish Client class.

      \n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"

      \n", + "5. The get_gen function is called to retrieve the iLO generation number of the server.\n", + " Depending on the iLO generation number, the set_syslog function is called with the Redfish client object and the syslog server IP address.

      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3681c0d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-s',\n", + " '--syslog_server',\n", + " dest='syslog_server',\n", + " action=\"store\",\n", + " required=True,\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " (ilogen,_) = get_gen(redfish_obj)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " set_syslog(redfish_obj, options.syslog_server)\n", + " else:\n", + " set_syslog(redfish_obj, options.syslog_server)\n", + " redfish_obj.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "750b6ae8", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f91c6419", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/bios/BIOS_ChangeSettings.ipynb b/example_jupyter_notebooks/bios/BIOS_ChangeSettings.ipynb new file mode 100644 index 0000000..2d7d55f --- /dev/null +++ b/example_jupyter_notebooks/bios/BIOS_ChangeSettings.ipynb @@ -0,0 +1,285 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25002fd3", + "metadata": {}, + "source": [ + "

      Change BIOS Settings

      " + ] + }, + { + "cell_type": "markdown", + "id": "6a14567a", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to change BIOS settings. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b0a99221", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb04ead1", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "8505c876", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our change bios settings function overview, in the end this will be able to change the bios settings.

      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
      \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an http GET request is made and response is stored in systems_response.\n", + " Then we set the systems_members_uri.\n", + "
      \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", + "
      \n", + "\n", + "5. Then if bios password is present, then we will update the bios password. Finally we will send patch request from redfish object using bios_setting_uri. \n", + "\n", + " Ultimately if the operation was successfull without any errors then we will get the Success. If not we get the occured error.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "243405a4", + "metadata": {}, + "outputs": [], + "source": [ + "def change_bios_setting(_redfishobj, bios_property, property_value, bios_password):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " \n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " \n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if bios_uri:\n", + " #BIOS settings URI is needed\n", + " \n", + " bios_settings_uri = bios_data.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " body = {'Attributes': {bios_property: property_value}}\n", + " \n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " resp = _redfishobj.patch(bios_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " #uncomment if you would like to see the full list of attributes\n", + " #print(\"\\n\\nShowing BIOS attributes after changes:\\n\\n\")\n", + " #bios_data = _redfishobj.get(bios_uri)\n", + " #print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "2c62673d", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.


      \n", + " Please enter iLO url, username, password, bios.attribute, attribute_value and bios password
      \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "1f44368d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14547cd7", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " BIOS_PASSWORD = getpass.getpass(\"Enter bios password: \")\n", + " \n", + " #provide the attribute name and the associated attribute value. Note: some, values may\n", + " #be containers (arrays or dictionaries) so keep this in mind.\n", + " \n", + " ATTRIBUTE = input(\"Enter bios property you wish to change (Example: AdminName): \")\n", + " ATTRIBUTE_VAL = input(\"Enter Value of the property to change (Example: Luigi): \")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_bios_setting(REDFISHOBJ, ATTRIBUTE, ATTRIBUTE_VAL, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "91b6f3c6", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library: LINK
      \n", + " 2.HPE ilorest-api explorer: LINK
      \n", + " 3.REST API: LINK
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ba53975e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/bios/BIOS_RevertToDefault.ipynb b/example_jupyter_notebooks/bios/BIOS_RevertToDefault.ipynb new file mode 100644 index 0000000..d2ec941 --- /dev/null +++ b/example_jupyter_notebooks/bios/BIOS_RevertToDefault.ipynb @@ -0,0 +1,331 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ad9eed9d", + "metadata": {}, + "source": [ + "

      Reverting the BIOS to it's default values

      " + ] + }, + { + "cell_type": "markdown", + "id": "9bdc5c94", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b6adafee", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2c1c9a1c", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_5976/2509830492.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "# Import the required libraries\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "# Import the helper function\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "397110c8", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our reset bios to default function overview, in the end this will set the bios settings to default.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the bios_revert_default function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", + "
      \n", + "\n", + "3. In the system members response object with different odata_id we get a bios uri .\n", + " Then again an HTTP GET request is made and response is stored in bios_response.\n", + " Then we set the resret_action_uri.\n", + "
      \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios settings of the user through redfish object and then then set the path to post the action we will perform\n", + "
      \n", + "\n", + "5. Then we set the bios settings to default using the action type as Bios.ResetBios and say set it to default\n", + "\n", + " Ultimately if the operation was successfull without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91157e79", + "metadata": {}, + "outputs": [], + "source": [ + "def bios_revert_default(_redfishobj):\n", + " # Initialize the BIOS reset action URI (Uniform Resource Identifier)\n", + " bios_reset_action_uri = None\n", + " \n", + " # Get the resource directory to find the relevant URI\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " # If resource directory is not available or not to be used, find the relevant URI\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " # Get the systems URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " \n", + " # Get the systems members URI\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " \n", + " # Get the BIOS URI\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " \n", + " # Get the BIOS reset action URI\n", + " bios_reset_action_uri = bios_response.obj['Actions']['#Bios.ResetBios']['target']\n", + " else:\n", + " # Use resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_reset_action_uri = bios_data.obj['Actions']['#Bios.ResetBios']['target']\n", + " break\n", + " \n", + " # Define the body for the POST request\n", + " body = {'Action': 'Bios.ResetBios', 'ResetType': 'default'}\n", + " \n", + " # Send the POST request\n", + " resp = _redfishobj.post(bios_reset_action_uri, body)\n", + " \n", + " # Check the response status\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b26b9819", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f9886e56", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "fbdb430d", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: ncs\n", + "Enter Login account: bsdk\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_5976/2691500454.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mSYSTEM_URL\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter System URL: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mLOGIN_ACCOUNT\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter Login account: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mLOGIN_PASSWORD\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetpass\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter your password: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;31m# flag to force disable resource directory. Resource directory and associated operations are\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36mgetpass\u001b[1;34m(self, prompt, stream)\u001b[0m\n\u001b[0;32m 986\u001b[0m \u001b[0mstacklevel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 987\u001b[0m )\n\u001b[1;32m--> 988\u001b[1;33m return self._input_request(\n\u001b[0m\u001b[0;32m 989\u001b[0m \u001b[0mprompt\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 990\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"shell\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[1;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[0;32m 1049\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1050\u001b[0m \u001b[1;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1051\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Interrupted by user\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1052\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1053\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Invalid Message:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: Interrupted by user" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " # Call the function to revert BIOS to default values\n", + " bios_revert_default(REDFISHOBJ)\n", + "\n", + " # Logout from the Redfish client\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "2f8583d9", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library: LINK
      \n", + " 2.HPE ilorest-api explorer: LINK
      \n", + " 3.REST API: LINK
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0f8133c1", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f31a351", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/bios/get_base_registry.ipynb b/example_jupyter_notebooks/bios/get_base_registry.ipynb new file mode 100644 index 0000000..2f93530 --- /dev/null +++ b/example_jupyter_notebooks/bios/get_base_registry.ipynb @@ -0,0 +1,175 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b6a26458", + "metadata": {}, + "source": [ + "
      \n", + "Hello User!
      \n", + "Welcome to python-iLOrest-library
      \n", + "This script can be used to retrieve the base registry information from an HPE iLO (Integrated Lights Out) server.
      \n", + "To perform this you need to have python-ilorest-library installed in your machine.
      \n", + "And please keep your username and password handy!\n", + "
      \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "1dc8cc16", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " First, we need to \"import\" certain files that provide us the functionality to get the base registry.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "from redfish import LegacyRestClient\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "1087550c", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + " Below is the get_base_registry function. The get_base_registry function serves the purpose of retrieving the base registry information from an HPE iLO server using the HPE iLO REST API.
      \n", + " It performs the following steps to accomplish this:

      \n", + "1. The get_base_registry function sends a GET request to the /rest/v1/Registries endpoint of the HPE iLO server to retrieve the registry data.\n", + "

      \n", + "2. It iterates through the response entries, checking for the \"Id\" field or extracting the schema name.\n", + "

      \n", + "3. For each entry, it makes additional GET requests to the specified URIs to retrieve the registry information.\n", + "

      \n", + "4. If successful, it displays a message and stores the registry messages in a dictionary. The function returns the dictionary containing the registry messages.\n", + "

      \n", + "In summary, the get_base_registry function retrieves the base registry information by making requests to specific URIs, extracting relevant data, and storing it for further analysis and management.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def get_base_registry(restobj):\n", + " response = restobj.get(\"/rest/v1/Registries\")\n", + " messages = {}\n", + "\n", + " identifier = None\n", + "\n", + " for entry in response.dict[\"Items\"]:\n", + " if \"Id\" in entry:\n", + " identifier = entry[\"Id\"]\n", + " else:\n", + " identifier = entry[\"Schema\"].split(\".\")[0]\n", + "\n", + " if identifier not in [\"Base\", \"iLO\"]:\n", + " continue\n", + "\n", + " for location in entry[\"Location\"]:\n", + " reg_resp = restobj.get(location[\"Uri\"][\"extref\"])\n", + "\n", + " if reg_resp.status == 200:\n", + " sys.stdout.write(\"\\tFound \" + identifier + \" at \" + \\\n", + " location[\"Uri\"][\"extref\"] + \"\\n\")\n", + " messages[identifier] = reg_resp.dict[\"Messages\"]\n", + " else:\n", + " sys.stdout.write(\"\\t\" + identifier + \" not found at \"\\\n", + " + location[\"Uri\"][\"extref\"] + \"\\n\")\n", + "\n", + " return messages" + ] + }, + { + "cell_type": "markdown", + "id": "167d47fe", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + "The following code establishes a connection to an HPE iLO server using the HPE iLO REST API. It sets up the necessary parameters for either local or remote server connection, creates a REST client object, logs into the iLO server, executes an example function to retrieve registry information, and logs out from the server. This code showcases how to interact with the iLO server programmatically, demonstrating the usage of the HPE iLO REST API for server management tasks.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Create a REST object\n", + " REST_OBJ = LegacyRestClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " REST_OBJ.login()\n", + " sys.stdout.write(\"\\nEXAMPLE 2: Find and return registry \" + \"\\n\")\n", + " get_base_registry(REST_OBJ)\n", + " REST_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/bios/get_bios_settings.ipynb b/example_jupyter_notebooks/bios/get_bios_settings.ipynb new file mode 100644 index 0000000..6102d64 --- /dev/null +++ b/example_jupyter_notebooks/bios/get_bios_settings.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# GETTING BIOS SETTINGS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is the example to getting bios(basic input/output system) settings about HPE iLO system.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " In the beginning, we are having some import statements that are actually providing us with the required modules and libraries\n", + "for proper execution of our code.
      " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of retrieving bios settings from iLO servers.\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + " Below is the get_bios_settings function, after everything is done this function will give details about bios settings of system.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the get_bios_setting function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In case the resource directory was disabled we are using systems making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
        \n", + "
      • The information about bios settings is present inside a particular json object of iLO rest api.
      • We just need to navigate to that directory so as to obtain info about bios settings.
      • For that purpose simply we are making series of get requests.
      • \n", + " We make a final get operation by at the location bios_uri and save the response inside bios_data.\n", + "
      \n", + "
      \n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
      \n", + "\n", + "Ultimately, if bios_data variable is not null we print out information about bios settings. \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "def get_bios_setting(_redfishobj):\n", + "\n", + " bios_uri = None\n", + " bios_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " break\n", + "\n", + " if bios_data:\n", + " print(\"\\n\\nShowing bios attributes before changes:\\n\\n\")\n", + " print(json.dumps(bios_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to get_bios_settings function to obtain information about bios settings of system.
      • \n", + "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 10.0.2.15\n", + "Enter Username: Administrator\n", + "Enter password: 12iso*help\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 13\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 12\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 13\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 14\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 15\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 17\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 16\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 17\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 18\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 19\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_bios_setting(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/example_jupyter_notebooks/boot/Change_Boot_Order.ipynb b/example_jupyter_notebooks/boot/Change_Boot_Order.ipynb new file mode 100644 index 0000000..63881cd --- /dev/null +++ b/example_jupyter_notebooks/boot/Change_Boot_Order.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8359fe6", + "metadata": {}, + "source": [ + "

      Change Boot Order

      " + ] + }, + { + "cell_type": "markdown", + "id": "8cb46c69", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "6557d8e3", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9dc3d6d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "7753861c", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our change boot order function overview, in the end this will change the boot order by one position.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. This function initializes bios_boot_uri and bios_boot_response variables to None.\n", + "
      \n", + " \n", + "2. Call get_resource_directory() function by passing the \"_redfishobj\" as parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If resource directory is available, find the relevant URI from the resource directory.\n", + "
      \n", + "\n", + "3. Then we navigate through the hirerachy to find bios_boot_uri. If bios_boot_uri is not None, retrieve the BIOS boot settings using get() method. Then Retrieve the URI for BIOS boot settings from the response.\n", + "\n", + "
      \n", + "\n", + "4. If bios_password is provided, update the BIOS password with it.\n", + "
      \n", + "\n", + "5. Print the current boot order. Rotate the first boot device to the end of the boot order. Update the boot order using the patch() method with the new boot order.\n", + "
      \n", + "\n", + "6. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the updated BIOS boot settings.\n", + " \n", + "
      \n", + "\n", + "7. If bios_boot_uri is None, print an error message.\n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9740789", + "metadata": {}, + "outputs": [], + "source": [ + "def change_boot_order(_redfishobj, bios_password):\n", + "\n", + " bios_boot_uri = None\n", + " bios_boot_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " bios_boot_uri = bios_response.obj.Oem.Hpe.Links.Boot['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeServerBootSettings.' in instance['@odata.type']:\n", + " bios_boot_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if bios_boot_uri:\n", + " bios_boot_response = _redfishobj.get(bios_boot_uri)\n", + " #Bios boot settings URI is needed\n", + " bios_boot_settings_uri = bios_boot_response.obj['@Redfish.Settings']['SettingsObject']['@odata.id']\n", + " #update BIOS password\n", + " if bios_password:\n", + " _redfishobj.bios_password = bios_password\n", + " sys.stdout.write(\"Rotating the first boot device to the end of the boot order.\\n\")\n", + " sys.stdout.write('Current Order:\\n')\n", + " boot_order = bios_boot_response.obj['DefaultBootOrder']\n", + " for indx, boot_device in enumerate(boot_order):\n", + " sys.stdout.write('Pos ' + str(indx) + ' : ' + boot_device + '\\n')\n", + " device = boot_order.pop(0)\n", + " sys.stdout.write(\"Rotating device: \\'%s\\' to the end of the boot order.\\n\" % device)\n", + " boot_order.append(device)\n", + "\n", + " body = {'DefaultBootOrder': boot_order}\n", + " resp = _redfishobj.patch(bios_boot_settings_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! Your system may need to be restarted.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " else:\n", + " sys.stderr.write(\"Unable to find Boot Order URI.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "17889355", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the boot order.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call change_boot_order function with our redfish object and BIOS Password as parameters
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "73d96a09", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7cba1616", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " BIOS_PASSWORD = None\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_boot_order(REDFISHOBJ, BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2f00caf4", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library: LINK
      \n", + " 2.HPE ilorest-api explorer: LINK
      \n", + " 3.REST API: LINK
      \n", + " 4.Changing Boot Setting Documentation: LINK
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d6810680", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/boot/Change_Temp_Boot_Order.ipynb b/example_jupyter_notebooks/boot/Change_Temp_Boot_Order.ipynb new file mode 100644 index 0000000..f494564 --- /dev/null +++ b/example_jupyter_notebooks/boot/Change_Temp_Boot_Order.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a9b0b4a", + "metadata": {}, + "source": [ + "

      Change Temporary Boot Order

      " + ] + }, + { + "cell_type": "markdown", + "id": "e04e1b75", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to temporarily change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f33ca630", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0058d42d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "d69021c8", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our change temporary boot order function overview, in the end this will set the boot order temporarily to the device stored in \"boottarget\" variable.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + " \n", + "2. This function first calls get_resource_directory() function by passing the \"_redfishobj\" as parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If resource directory is available, find the relevant URI from the resource directory.\n", + "
      \n", + "\n", + "3. Then we navigate through the hirerachy to find systems_members_uri where we can set the temporary boot target. If systems_members_uri is not None, then set the attribute 'BootSourceOverrideTarget' to 'boottarget' varible.\n", + "\n", + "
      \n", + "\n", + "6. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the updated boot override target.\n", + " \n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aaba46fd", + "metadata": {}, + "outputs": [], + "source": [ + "def change_temporary_boot_order(_redfishobj, boottarget):\n", + "\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response:\n", + " print(\"\\n\\nShowing BIOS attributes before changes:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict.get('Boot'), indent=4, sort_keys=True))\n", + " body = {'Boot': {'BootSourceOverrideTarget': boottarget}}\n", + " resp = _redfishobj.patch(systems_members_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " if systems_members_response:\n", + " print(\"\\n\\nShowing boot override target:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict.get('Boot'), indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "2405f770", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the temporary boot order.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of _REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "4. When asked to enter Temporary Boot Device, enter desired temporary boot device (Example: Hdd)
      \n", + " \n", + "
      \n", + " \n", + "5. Then we call change_temporary_boot_order function with our redfish object and chosen temporary boot device as parameters
      \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "4d5f0843", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b43b7a95", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # string to represent the selected temporary boot device\n", + " TEMP_DEVICE = input(\"Enter temporary boot device: \")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " change_temporary_boot_order(REDFISHOBJ, TEMP_DEVICE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "9784ce2a", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library: LINK
      \n", + " 2.HPE ilorest-api explorer: LINK
      \n", + " 3.REST API: LINK
      \n", + " 4.Changing Boot Setting Documentation: LINK
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e50e59c", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/eskm/reset_ESKM_eventlog.ipynb b/example_jupyter_notebooks/eskm/reset_ESKM_eventlog.ipynb new file mode 100644 index 0000000..1ac340b --- /dev/null +++ b/example_jupyter_notebooks/eskm/reset_ESKM_eventlog.ipynb @@ -0,0 +1,378 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d4d890e", + "metadata": { + "tags": [] + }, + "source": [ + "# Reset_ESKM_eventlog" + ] + }, + { + "cell_type": "markdown", + "id": "62aaa233", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to resetting the ESKM event log (ESKM stand for Enterprise Secure Key Manager)
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "fbfec992", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • RedfishClient
    • \n", + "
    • ServerDownOrUnreachableError
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ee51abfe", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Collecting redfish\n", + " Downloading redfish-3.1.9-py3-none-any.whl (40 kB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.5/40.5 KB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting jsonpatch\n", + " Downloading jsonpatch-1.32-py2.py3-none-any.whl (12 kB)\n", + "Requirement already satisfied: jsonpointer in /home/tanveer/.local/lib/python3.10/site-packages (from redfish) (2.3)\n", + "Collecting requests-toolbelt\n", + " Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB)\n", + "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 KB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: requests in /usr/lib/python3/dist-packages (from redfish) (2.25.1)\n", + "Collecting jsonpath-rw\n", + " Downloading jsonpath-rw-1.4.0.tar.gz (13 kB)\n", + " Preparing metadata (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25hCollecting requests-unixsocket\n", + " Downloading requests_unixsocket-0.3.0-py2.py3-none-any.whl (11 kB)\n", + "Requirement already satisfied: decorator in /home/tanveer/.local/lib/python3.10/site-packages (from jsonpath-rw->redfish) (5.1.1)\n", + "Requirement already satisfied: ply in /usr/lib/python3/dist-packages (from jsonpath-rw->redfish) (3.11)\n", + "Requirement already satisfied: six in /usr/lib/python3/dist-packages (from jsonpath-rw->redfish) (1.16.0)\n", + "Building wheels for collected packages: jsonpath-rw\n", + " Building wheel for jsonpath-rw (setup.py) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for jsonpath-rw: filename=jsonpath_rw-1.4.0-py3-none-any.whl size=15149 sha256=adb33a2925919ff914e1e8d37078e269f133f5a20afb9ba6d09a5f3a2cb743b7\n", + " Stored in directory: /home/tanveer/.cache/pip/wheels/e3/76/6f/c25be6a9e6cc9985b96e8c95997d46790242c6426ef68e754c\n", + "Successfully built jsonpath-rw\n", + "Installing collected packages: requests-unixsocket, requests-toolbelt, jsonpath-rw, jsonpatch, redfish\n", + "Successfully installed jsonpatch-1.32 jsonpath-rw-1.4.0 redfish-3.1.9 requests-toolbelt-1.0.0 requests-unixsocket-0.3.0\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install redfish" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9688b9d5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Collecting redfish-client\n", + " Downloading redfish_client-0.3.9-py2.py3-none-any.whl (13 kB)\n", + "Requirement already satisfied: requests>=2.16 in /usr/lib/python3/dist-packages (from redfish-client) (2.25.1)\n", + "Installing collected packages: redfish-client\n", + "Successfully installed redfish-client-0.3.9\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install redfish-client" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9b53ecf2", + "metadata": {}, + "outputs": [ + { + "ename": "ImportError", + "evalue": "cannot import name 'RedfishClient' from 'redfish' (/home/tanveer/.local/lib/python3.10/site-packages/redfish/__init__.py)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01msys\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mjson\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mredfish\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RedfishClient\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mredfish\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mrest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mv1\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ServerDownOrUnreachableError\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mget_resource_directory\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m get_resource_directory\n", + "\u001b[0;31mImportError\u001b[0m: cannot import name 'RedfishClient' from 'redfish' (/home/tanveer/.local/lib/python3.10/site-packages/redfish/__init__.py)" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b8c9efd9", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      2.

      Below is the overview of reset_ESKM_eventlog function. In this function we are providing secure management of cryptographic keys for various purposes for example encryption and authentication.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present for secure key manager.\n", + "\n", + "1. In the function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "\n", + "
      \n", + "\n", + "2. If the resource directory is enabled or we want to force it's non-use then navigate to the directory where managers members data is present. \n", + " Utilising the HPE (Hewlett Packard Enterprise) OEM Redfish implementation to retrieve the URI for the ESKM (Enterprise Security Key Manager) service.\n", + " By making a Redfish API call to reset the event log of the HPE Enterprise Secure Key Manager (ESKM) security service of an HPE server. It first tries to obtain the URI for the ESKM service using the HPE-specific resource directory, but if that is not available or disabled, it falls back to navigating the Redfish API object model to find the necessary URIs for the relevant managers and security service.\n", + " Once the URI for the ESKM service is obtained, a POST request is sent to the ClearESKMLog action using the post() method of the Redfish API object, with an empty dictionary in the body of the request.\n", + " \n", + "
      \n", + "\n", + "3. Else It iterates through a list of resource instances and checks if the instance type contains #HpeESKM in it. If found, it sets the URI of that resource instance as the ESKM URI and breaks out of the loop. \n", + " \n", + " \n", + "
      \n", + " \n", + "4. If above function retrive the URI for the ESKM service from the HPE-specific Links object then we retrieves the URI for a specific action to clear the ESKM log on an HPE server's Security Service ESKM resource, using the Redfish API. It then sets the action to be executed on the server in the request body.\n", + " \n", + "
      \n", + " \n", + " If the response of this POST request was 400 it means there was some error from server-side while doing the same operation and we inform the user about the error by It attempts to extract and pretty-print the extended error message information, but if this fails, it writes an error message to the standard error stream indicating that it was unable to access the iLO Extended Message Info.\n", + "
      \n", + " Else there can also be an error which we aren't aware of, in that case we print out the response status code alongwith erro message .
      \n", + " Ultimately, if everything went properly we print out the response object along with success message.\n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "93003c6b", + "metadata": {}, + "outputs": [], + "source": [ + "def reset_ESKM_eventlog(_redfishobj):\n", + "\n", + " body = dict()\n", + " security_service_eskm_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " security_service_eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " security_service_eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if security_service_eskm_uri:\n", + " security_service_eskm_uri = _redfishobj.get(security_service_uri).obj.Links\\\n", + " ['ESKM']['@odata.id']\n", + " security_service_eskm_resp = _redfishobj.get(security_service_eskm_uri)\n", + " security_service_eskm_clearlog_uri = security_service_eskm_resp.obj['Actions']\\\n", + " ['#HpeESKM.ClearESKMLog']['target']\n", + " body[\"Action\"] = \"HpeESKM.ClearESKMLog\"\n", + " #We pass the URI and the dictionary as a POST command (part of the redfish object)\n", + " resp = _redfishobj.post(security_service_eskm_clearlog_uri, body)\n", + " #If iLO responds with something outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5a583e0e", + "metadata": {}, + "source": [ + "
      \n", + "

      3.

      This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient object is being created mainly to log into the system with valid credentials.\n", + " \n", + "
      \n", + "\n", + "3. We try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "4. Then we call reset_ESKM_eventlogfunction with our redfish object and the function does the reset the ESKM_eventlog.\n", + " \n", + "
      \n", + " \n", + "\n", + "5. Lastly, REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "85745d7d", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " reset_ESKM_eventlog(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "69132144", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "ea6fce6f", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer.ipynb b/example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer.ipynb new file mode 100644 index 0000000..cf366b6 --- /dev/null +++ b/example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer.ipynb @@ -0,0 +1,207 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "67d9df4f", + "metadata": {}, + "source": [ + "
      \n", + "Hello User!
      \n", + "Welcome to python-iLOrest-library
      \n", + "This script can be used to manage and configure the ESKM key server for HPE iLO systems.
      \n", + "To perform this you need to have python-ilorest-library installed in your machine.
      \n", + "And please keep your username and password handy!\n", + "
      \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "7350e15b", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " First, we are importing certain files that enable us to manage and configure the ESKM key server.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "26b4fe53", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + "

      Below is the set_ESKM_PrimaryKeyServer function. The function takes a Redfish client object, the primary key server address, and the primary key server port as input. It uses the Redfish API to configure the primary ESKM(Enterprise Secure Key Manager) key server on the iLO system.

      \n", + "
      It achieves this by the following steps:
      \n", + "\n", + "1. It first retrieves the relevant URI for the ESKM service by either using the resource directory or by navigating through the Redfish API endpoints.
      \n", + "The function then constructs a request body with the primary key server address and port.\n", + "2. It sends a POST request to the ESKM URI with the request body to update the primary key server configuration.
      \n", + "3. If the response is successful, it displays the updated configuration in JSON format.\n", + "If there are any errors or exceptions, it provides appropriate error messages or status codes.
      \n", + "4. Finally, it logs out from the iLO server.\n", + "

      \n", + "The set_ESKM_PrimaryKeyServer function enables the configuration of the primary ESKM key server for HPE iLO systems. It retrieves the relevant URI, sets the primary key server address and port, and updates the configuration via a POST request. It provides feedback on the success or failure of the operation and allows for proper error handling.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ESKM_PrimaryKeyServer(_redfishobj, primary_key_server_address, primary_key_server_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + "\n", + " body[\"PrimaryKeyServerAddress\"] = primary_key_server_address\n", + " body[\"PrimaryKeyServerPort\"] = int(primary_key_server_port)\n", + "\n", + " resp = _redfishobj.post(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "601ab339", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + " \n", + "The code below establishes a connection with an iLO server using the specified system URL, login account, and password. It then sets the primary ESKM key server address and port. The script utilizes the Redfish protocol to communicate with the server and performs the necessary operations to configure the key server. Finally, it logs out from the iLO server.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " PRIMARY_KEY_SERVER_ADDRESS = \"192.168.1.1\"\n", + " PRIMARY_KEY_SERVER_PORT = \"9000\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ESKM_PrimaryKeyServer(REDFISHOBJ, PRIMARY_KEY_SERVER_ADDRESS, PRIMARY_KEY_SERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/eskm/set_ESKM_username_pass.ipynb b/example_jupyter_notebooks/eskm/set_ESKM_username_pass.ipynb new file mode 100644 index 0000000..bc533d9 --- /dev/null +++ b/example_jupyter_notebooks/eskm/set_ESKM_username_pass.ipynb @@ -0,0 +1,213 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "54face1f", + "metadata": {}, + "source": [ + "
      \n", + "Hello User!
      \n", + "Welcome to python-iLOrest-library
      \n", + "This script demonstrates how to set the ESKM (Enterprise Secure Key Manager) username, password, and other related configurations for HPE iLO systems.
      \n", + "To perform this you need to have python-ilorest-library installed in your machine.
      \n", + "And please keep your username and password handy!\n", + "
      \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "7350e15b", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " First, we are importing certain files that enable us to manage and configure the ESKM key server.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e2d3008", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "6234f26f", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + "

      The code below defines a function called ESKM_username_pass that is responsible for configuring the ESKM (Enterprise Secure Key Manager) settings on an HPE iLO system using the Redfish API. The function takes several parameters, including the ESKM username, password, account group, primary key server address, and primary key server port.

      \n", + "
      The following steps explain this function:
      \n", + "\n", + "1. Get the resource directory to find the URI for the ESKM service.\n", + "2. If the resource directory is not available or disabled, manually search for the relevant URI by navigating through the API hierarchy.\n", + "3. If the URI for the ESKM service is found, create a dictionary object with the login name, password, account group, ESKM local CA certificate name, primary key server address, and primary key server port.\n", + "4. Use the HTTP PATCH method to update the ESKM service configuration with the dictionary object.\n", + "5. Check the response status code to determine if the update was successful or if an error occurred. If there was an error, print the error message or status code. If the update was successful, print the response body.\n", + "

      \n", + "The ESKM_username_pass function is used to configure the ESKM settings on an HPE iLO system. It retrieves the ESKM URI, populates the configuration data, sends a PATCH request to update the settings, and handles the response accordingly. Upon successful update, it prints a success message along with the response details.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38d43c16", + "metadata": {}, + "outputs": [], + "source": [ + "def ESKM_username_pass(_redfishobj, eskm_username, eskm_password, eskm_accountgroup, \\\n", + " eskm_primarykeyserver_addr, eskm_primarykeyserver_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " body[\"KeyManagerConfig\"] = dict()\n", + " body[\"KeyManagerConfig\"][\"LoginName\"] = eskm_username\n", + " body[\"KeyManagerConfig\"][\"Password\"] = eskm_password\n", + " body[\"KeyManagerConfig\"][\"AccountGroup\"] = eskm_accountgroup\n", + " body[\"KeyManagerConfig\"][\"ESKMLocalCACertificateName\"] = \"\"\n", + " body[\"PrimaryKeyServerAddress\"] = eskm_primarykeyserver_addr\n", + " body[\"PrimaryKeyServerPort\"] = eskm_primarykeyserver_port\n", + " resp = _redfishobj.patch(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "601ab339", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + " \n", + "The code below establishes a connection with an iLO server using the specified system URL, login account, and password. It then sets the primary ESKM key server address and port. The script utilizes the Redfish protocol to communicate with the server and performs the necessary operations to configure the key server. Finally, it logs out from the iLO server.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40aabbdc", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " ESKM_USERNAME = \"admin\"\n", + " ESKM_PASSWORD = \"password\"\n", + " ESKM_ACCOUNTGROUP = \"group\"\n", + " ESKM_PRIMARYKEYSERVER_ADDR = \"192.168.1.10\"\n", + " ESKM_PRIMARYKEYSERVER_PORT = 5927\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \\\n", + " ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ilo_license/set_license_key.ipynb b/example_jupyter_notebooks/ilo_license/set_license_key.ipynb new file mode 100644 index 0000000..7fc2ed0 --- /dev/null +++ b/example_jupyter_notebooks/ilo_license/set_license_key.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d91ced6", + "metadata": {}, + "source": [ + "# Setting license key " + ] + }, + { + "cell_type": "markdown", + "id": "11b0fe9d", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting license key.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "6cbd5f7c", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0fa1574", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "7daccb24", + "metadata": {}, + "source": [ + "

      2. This is our set_license_key function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the set_license_key function we are taking two parameters i.e. _redfishobj and ilo_key. In the set_license_key function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about license key is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the license service about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The license service information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeiLOLicense type is present in @odata.type attribute then we will store information about license key in ilo_lic_uri and break out of iteration.\n", + "
      \n", + "5. If ilo_lic_uri is not null after making above operations, we can perform the required actions to set license key. \n", + "
        \n", + "
      • The function sends a GET request to the iLO license service to retrieve the current license data. If the ConfirmationRequest field exists, it is printed to the console; otherwise, the LicenseKey field is printed.
      • \n", + "
      • The function sends a POST request to the iLO license service with the new license key provided in the ilo_key argument.
      • \n", + "
      • The job of post request here is to set the license key at the provided location and send a response whether the job was done properly or not.
      • \n", + "
      • If the response status is 400, the function attempts to print the extended error message provided by iLO. If the status is not 200 or 201, the function prints an error message to the console.
      • \n", + "
      • If the response status is 200, the function prints a success message to the console along with the response JSON.
      • \n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bacca62e", + "metadata": {}, + "outputs": [], + "source": [ + "def set_license_key(_redfishobj, ilo_key):\n", + "\n", + " ilo_lic_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " ilo_lic_uri = managers_members_response.obj.Oem.Hpe.Links['LicenseService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOLicense.' in instance['@odata.type']:\n", + " ilo_lic_uri = instance['@odata.id']\n", + "\n", + " if ilo_lic_uri:\n", + " ilo_license_collection = _redfishobj.get(ilo_lic_uri)\n", + " ilo_license_member_uri = next(iter(ilo_license_collection.obj['Members']))['@odata.id']\n", + " try:\n", + " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['ConfirmationRequest']\\\n", + " ['EON']\n", + " except KeyError:\n", + " sys.stdout.write(\"This machine will not show the full License Key.\\n\")\n", + " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['LicenseKey']\n", + "\n", + " sys.stdout.write(\"Current iLO License Data:\\n\")\n", + " print(json.dumps(ilo_license_data, indent=4, sort_keys=True))\n", + " resp = _redfishobj.post(ilo_lic_uri, {'LicenseKey' : ilo_key})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " sys.stderr.write(\"Check the validity of your license key...\\n\")\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \" \\\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "abfa5bd8", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to set_license_key function to set license key of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38798e69", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # Must be a valid iLO License Key\n", + " ILO_LICENSE_KEY = \"XXXX-XXXX-XXXX-XXXX-XXXXX\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_license_key(REDFISHOBJ, ILO_LICENSE_KEY)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "7d4c55f5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b3be89a3", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/index.ipynb b/example_jupyter_notebooks/index.ipynb new file mode 100644 index 0000000..2f001ea --- /dev/null +++ b/example_jupyter_notebooks/index.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "18ad6013", + "metadata": {}, + "source": [ + "\"HPE" + ] + }, + { + "cell_type": "markdown", + "id": "20da06d1", + "metadata": {}, + "source": [ + "

      Scripts related to BIOS

      " + ] + }, + { + "cell_type": "markdown", + "id": "fa8b0fad", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Change BIOS SettingsUpdate BIOS Settings for iLO serverPATCHBIOS_ChangeSettings
      BIOS DefaultUpdate BIOS to default settingPOSTBIOS_RevertToDefault
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "81721043", + "metadata": {}, + "source": [ + "

      Scripts related to Users

      " + ] + }, + { + "cell_type": "markdown", + "id": "cf10b943", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Add User AccountAdd new user accountPATCHAdd user account
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "5e16cdec", + "metadata": {}, + "source": [ + "

      Scripts related to Booting

      " + ] + }, + { + "cell_type": "markdown", + "id": "616fef86", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Change Boot OrderChange iLOs boot ordertPATCHChange_Boot_Order
      Change Temporary Boot OrderChange iLOs temporary boot ordertPATCHChange_Temp_Boot_Order
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cdb7878", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/nic_network/get_ilo_ip.ipynb b/example_jupyter_notebooks/nic_network/get_ilo_ip.ipynb new file mode 100644 index 0000000..c765281 --- /dev/null +++ b/example_jupyter_notebooks/nic_network/get_ilo_ip.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "27676c26", + "metadata": {}, + "source": [ + "
      \n", + "Hello User!
      \n", + "Welcome to python-iLOrest-library

      \n", + "This script demonstrates how to retrieve the IP address of an HPE iLO (Integrated Lights-Out) server locally.
      It uses the HPE iLO REST API to interact with the server and obtain the IP address information. The script establishes a connection to the iLO server, retrieves the resource directory, identifies the manager path, and retrieves the Ethernet NIC information. It then extracts the IPv4 address from the NIC information and displays it. Overall, this code focuses on obtaining the iLO IP address using the HPE iLO REST API for local server management purposes.\n", + "

      \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "8ad60173", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " First, we need to \"import\" certain files that provide us the functionality to retrieve the IP address of our HPE iLO server.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "from redfish import LegacyRestClient\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "bf3194e3", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + " Below is the get_ilo_ip function. \n", + "The get_ilo_ip function retrieves the IP address of an HPE iLO (Integrated Lights-Out) server.
      Here's a breakdown of its functionality:
      \n", + "\n", + "The function starts by obtaining the resource directory from the provided restobj, which represents the REST object.

      \n", + "It then iterates over the resource instances in the directory to find the manager path that corresponds to the iLO server.

      \n", + "Once the manager path is obtained, a GET request is made to retrieve the manager information.\n", + "The function then retrieves the Ethernet NIC information by following the link provided in the manager response.

      \n", + "It iterates over the Ethernet NIC items and checks if the IPv4 address is not \"0.0.0.0\". If a valid IPv4 address is found, it is written to the standard output.

      \n", + "In summary, the get_ilo_ip function utilizes the HPE iLO REST API to locate and retrieve the IP address of an iLO server. It provides a convenient way to programmatically obtain the server's network information.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ilo_ip(restobj):\n", + " resource_instances = get_resource_directory(restobj)\n", + " if resource_instances:\n", + " #Get URI from resource directory\n", + " for instance in resource_instances:\n", + " if \"Manager.\" in instance.Type:\n", + " manager_path = instance.href\n", + " break\n", + "\n", + " response = restobj.get(manager_path)\n", + " ethernet_rsp = restobj.get(response.dict[\"links\"][\"EthernetNICs\"][\"href\"])\n", + " for item in ethernet_rsp.dict[\"Items\"]:\n", + " if not item[\"IPv4Addresses\"][0][\"Address\"] == \"0.0.0.0\":\n", + " sys.stdout.write(\"\\t\" + item[\"IPv4Addresses\"][0][\"Address\"] + \"\\n\")\n", + " sys.stdout.write(\"%s\" % response)" + ] + }, + { + "cell_type": "markdown", + "id": "c3318f0a", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + "The following code establishes a connection to an HPE iLO server using the HPE iLO REST API. It sets up the necessary parameters for either local or remote server connection, creates a REST client object, logs into the iLO server, executes an example function to retrieve registry information, and logs out from the server.

      \n", + "This code demonstrates a simple implementation to retrieve the IP address of an HPE iLO server locally. It initializes the necessary variables, creates a REST client object, logs in to the server, retrieves and prints the IP address, and finally logs out. This example showcases the usage of the HPE iLO REST API for basic server interaction." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " SYSTEM_URL = None\n", + " LOGIN_ACCOUNT = None\n", + " LOGIN_PASSWORD = None\n", + "\n", + " #Create a REST object\n", + " REST_OBJ = LegacyRestClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " REST_OBJ.login()\n", + " sys.stdout.write(\"\\nEXAMPLE 52: Get iLO IP locally\\n\")\n", + " get_ilo_ip(REST_OBJ)\n", + " REST_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/nic_network/get_ilo_nic.ipynb b/example_jupyter_notebooks/nic_network/get_ilo_nic.ipynb new file mode 100644 index 0000000..d177abd --- /dev/null +++ b/example_jupyter_notebooks/nic_network/get_ilo_nic.ipynb @@ -0,0 +1,164 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "41a1448b", + "metadata": {}, + "source": [ + "
      \n", + "Hello User!
      \n", + "Welcome to python-iLOrest-library
      \n", + "This script provides an example implementation that allows you to retrieve the network interface card (NIC) configuration of your HPE iLO server.
      \n", + "To perform this you need to have python-ilorest-library installed in your machine.
      \n", + "And please keep your username and password handy!\n", + "
      \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "25c830bd", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " First, we are importing certain files that provide us the functionality to get the nic configuration of the server.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c3c3347f", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import LegacyRestClient\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "64642b12", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + " Below is the get_ilo_nic function. The get_ilo_nic function is responsible for retrieving the network interface card (NIC) configuration of an HPE iLO server. It takes a REST object and a parameter indicating whether to retrieve active or inactive NICs as input. Here's a brief overview of the function's steps:
      \n", + "
        The function first obtains the resource directory of the iLO server using the provided REST object. This directory contains information about the server's available resources, including the NICs.
      \n", + "
        It then searches for the NIC-related information within the resource directory by iterating through the instances and identifying the ones related to the server's manager.\n", + "Using the obtained NIC information, the function retrieves the NIC configuration data from the server.
      \n", + "
        Depending on the value of the get_active parameter, the function filters the retrieved NICs to either active or inactive ones.
      \n", + "
        Finally, the function outputs the relevant NIC information, including the NIC's self URL and its JSON representation.
      \n", + "

      In summary, the get_ilo_nic function allows you to fetch and categorize the NIC configuration of an HPE iLO server based on its active or inactive status. This information can be useful for monitoring and managing your server's network settings.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5dff7bad", + "metadata": {}, + "outputs": [], + "source": [ + "def get_ilo_nic(restobj, get_active):\n", + " resource_instances = get_resource_directory(restobj)\n", + " if resource_instances:\n", + " #Get URI from resource directory\n", + " for instance in resource_instances:\n", + " if \"Manager.\" in instance.Type:\n", + " manager_path = instance.href\n", + " break\n", + "\n", + " tmp = restobj.get(manager_path)\n", + " response = restobj.get(tmp.dict[\"links\"][\"EthernetNICs\"][\"href\"])\n", + "\n", + " for nic in response.dict[\"Items\"]:\n", + " if get_active and nic[\"Status\"][\"State\"] == \"Enabled\":\n", + " sys.stdout.write(\"Active\\t\" + nic[\"links\"][\"self\"][\"href\"] + \\\n", + " \": \" + json.dumps(nic) + \"\\n\")\n", + " elif get_active == False and nic[\"Status\"][\"State\"] == \"Disabled\":\n", + " sys.stdout.write(\"InActive\\t\" + nic[\"links\"][\"self\"][\"href\"] + \\\n", + " \": \" + json.dumps(nic) + \"\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "5531c99f", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + " \n", + "This script establishes a connection to an HPE iLO server using the provided URL, login account, and password. It then logs in to the server and retrieves the NIC configuration. The script specifically fetches active NICs and displays their information. Finally, it logs out from the server.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2cbc2d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Create a REST object\n", + " REST_OBJ = LegacyRestClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " REST_OBJ.login()\n", + " sys.stdout.write(\"\\nEXAMPLE 20: Get iLO's NIC configuration\\n\")\n", + " get_ilo_nic(REST_OBJ, True)\n", + " REST_OBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/nic_network/set_ethernet_management.ipynb b/example_jupyter_notebooks/nic_network/set_ethernet_management.ipynb new file mode 100644 index 0000000..618ff4d --- /dev/null +++ b/example_jupyter_notebooks/nic_network/set_ethernet_management.ipynb @@ -0,0 +1,288 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "22c6d15e", + "metadata": {}, + "source": [ + "
      \n", + "Hello User!
      \n", + "Welcome to python-iLOrest-library
      \n", + "The objective of this script is to demonstrate how to set the static IP configuration for the Manager ethernet interface of an HPE iLO system using the Redfish API.
      \n", + "To perform this you need to have python-ilorest-library installed in your machine.
      \n", + "And please keep your username and password handy!\n", + "
      \n", + "Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0b53f42d", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + " First, we are importing certain files that can help us to manage the ethernet interface of our server.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e2d3008", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "c32f009a", + "metadata": {}, + "source": [ + "
      \n", + "
      2.

      \n", + "

      The following code defines the set_ilo_static_ipv4 function. This function is used to set the static IPv4 configuration for the Manager ethernet interface in an iLO (Integrated Lights-Out) server.


      \n", + "\n", + "1. Retrieve the resource directory to find the URI for the ethernet interfaces or manually search for the relevant URI if the resource directory is disabled.\n", + "2. Retrieve the current configuration of the ethernet interfaces, including DHCPv4 settings, IPv4 addresses, and static name servers, and display them.\n", + "3. Iterate through each ethernet interface and prompt the user to choose which interface to modify.\n", + "4. Disable the UseDNSServers and UseGateway options if they are enabled in the DHCPv4 settings.\n", + "5. Update the IPv4Addresses and StaticNameServers with the provided values in the function parameters, or create a new body with the DNS servers if StaticNameServers are not available.\n", + "6. Send a PATCH request to update the ethernet interface configuration with the new settings.\n", + "Call the ilo_response function to handle the response and display any error messages or the updated configuration.\n", + "7. Exit the loop after processing the first ethernet interface.

      \n", + "Overall, the function retrieves the current ethernet interface configuration, allows the user to choose which interface to modify, and updates the configuration with the provided IPv4 and DNS settings.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38d43c16", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ilo_static_ipv4(_redfishobj, ipv4_dict, dns_dict):\n", + "\n", + " ethernet_data = {}\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " for interface in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Management Inteface \\'%s\\'\\n\" % ethernet_data\\\n", + " [interface].get('Id'))\n", + "\n", + " sys.stdout.write(\"\\'DHCPv4\\':\\n\")\n", + " if ethernet_data[interface].get('DHCPv4'):\n", + " print(json.dumps(ethernet_data[interface].get('DHCPv4'), indent=4, sort_keys=True))\n", + " else:\n", + " print(json.dumps(ethernet_data[interface]['Oem']['Hpe'].get('DHCPv4'), indent=4, \\\n", + " sort_keys=True))\n", + " sys.stdout.write(\"\\'IPv4\\':\\n\")\n", + " if ethernet_data[interface].get('IPv4StaticAddresses'):\n", + " print(json.dumps(ethernet_data[interface].get('IPv4Addresses'), indent=4, \\\n", + " sort_keys=True))\n", + " sys.stdout.write(\"\\'StaticNameServers\\':\\n\")\n", + " if ethernet_data[interface].get('StaticNameServers'):\n", + " print(json.dumps(ethernet_data[interface].get('StaticNameServers'), indent=4, \\\n", + " sort_keys=True))\n", + "\n", + " for ethernet in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Interface: %s\\n\" % ethernet)\n", + " ans = input(\"Would you like to modify this interface? (y/n)\\n\")\n", + " if \"n\" in ans:\n", + " continue\n", + " if 'DHCPv4' in ethernet_data[ethernet]:\n", + " if ethernet_data[ethernet]['DHCPv4'].get('UseDNSServers'):\n", + " resp = _redfishobj.patch(ethernet, {\"DHCPv4\": {\"UseDNSServers\": False}})\n", + " ilo_response(_redfishobj, resp)\n", + " if ethernet_data[ethernet]['DHCPv4'].get('UseGateway'):\n", + " resp = _redfishobj.pathc(ethernet, {\"DHCPv4\": {\"UseGateway\": False}})\n", + " ilo_response(_redfishobj, resp)\n", + " if 'IPv4StaticAddresses' in ethernet_data[ethernet]:\n", + " body.update({\"IPv4Addresses\": [ipv4_dict]})\n", + " if 'StaticNameServers' in ethernet_data[ethernet]:\n", + " body.update({\"StaticNameServers\" : [dns_dict.get('PrimaryDNS'), \\\n", + " dns_dict.get('SecondaryDNS')]})\n", + " else:\n", + " body.update({\"Oem\": {\"Hpe\": {\"IPv4\": {\"DNSServers\": [dns_dict.get('PrimaryDNS'), \\\n", + " dns_dict.get('SecondaryDNS')]}}}})\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " ilo_response(_redfishobj, resp)\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "c9017ca5", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + "

      The following code defines the ilo_response function. This function is used to handle the response from an iLO (Integrated Lights-Out) server after sending a PATCH request to update the configuration.


      \n", + "1. Check if the response status is 400. If it is, try to access the extended error message from the response object and print it in a formatted JSON representation.\n", + "2. If an exception occurs while accessing the extended error message, print a generic error message indicating that the extended message info cannot be accessed.\n", + "3. If the response status is not 400 (indicating an error), write a stderr message indicating the HTTP response status.\n", + "4. If the response status is 200 (indicating success), print a success message suggesting to reset iLO for the settings to take effect.\n", + "5. Print the response dictionary in a formatted JSON representation.\n", + "

      \n", + "Overall, the function retrieves the current ethernet interface configuration, allows the user to choose which interface to modify, and updates the configuration with the provided IPv4 and DNS settings.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7aa4cac1", + "metadata": {}, + "outputs": [], + "source": [ + "def ilo_response(_redfishobj, resp):\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! Suggest to reset iLO for settings to take effect.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "c1dc3e7f", + "metadata": {}, + "source": [ + "
      \n", + "
      4.

      \n", + " \n", + "Next is the main function. The code establishes a connection with a target server using Redfish, a standardized API for server management. It sets the URL, login credentials, and defines dictionaries for IPv4 and DNS settings. It creates a Redfish client object and attempts to log in using the provided credentials. If successful, it calls the set_ilo_static_ipv4 function to configure the IPv4 and DNS settings for a specific Ethernet interface on the server. The function retrieves the necessary information, displays the current settings, and prompts the user to choose an interface for modification. If selected, it updates the DHCPv4 and IPv4 static address settings based on the provided dictionaries and sends the changes to the server. Finally, the code logs out of the Redfish session.\n", + "

      \n", + "In summary, the code establishes a connection with a server, configures network settings using Redfish, and performs the necessary operations to modify the IPv4 and DNS settings for a specific Ethernet interface on the server.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40aabbdc", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #IPv4 settings for Address, Gateway and SubnetMask as well as DNS.\n", + " IPV4_DICT = {'Address':'16.83.61.123', \\\n", + " 'Gateway':'16.83.60.1', \\\n", + " 'SubnetMask':'255.255.252.0' \\\n", + " }\n", + " DNS_DICT = {'PrimaryDNS':'16.110.135.52', \\\n", + " 'SecondaryDNS':'16.110.135.51' \\\n", + " }\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ilo_static_ipv4(REDFISHOBJ, IPV4_DICT, DNS_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "2370b35d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ntp_timezone/set_ilo_ntp_servers.ipynb b/example_jupyter_notebooks/ntp_timezone/set_ilo_ntp_servers.ipynb new file mode 100644 index 0000000..59c3e3a --- /dev/null +++ b/example_jupyter_notebooks/ntp_timezone/set_ilo_ntp_servers.ipynb @@ -0,0 +1,278 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "57e65617", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting NTP Servers for HPE iLO Systems" + ] + }, + { + "cell_type": "markdown", + "id": "826e692d", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to set the ilo NTP server!
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy, we'll be needing it in a while!\n", + "
      \n", + " Follow the guide below to execute without any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "5bf83867", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library tp set up the ilo NTP server!
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "from reset_ilo import reset_ilo\n", + "from enable_ntp_servers import enable_ntp" + ] + }, + { + "cell_type": "markdown", + "id": "87dd8456", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "
      2.

      \n", + "

      The script begins by defining the necessary dependencies and helper functions. The set_ilo_ntp_servers function is responsible for updating the NTP server settings for the iLO system.

      \n", + "
      Steps involved are:
      \n", + "\n", + "\n", + "1. The function set_ilo_ntp_servers sets the NTP (Network Time Protocol) servers for an HPE iLO system. It first retrieves the URI for the date and time service using the get_resource_directory function. If the resource directory is disabled or not available, it finds the URI by traversing the managers' hierarchy.\n", + "\n", + "2. Once the URI is obtained, the function sends a GET request to retrieve the current NTP server settings. If the StaticNTPServers property is present, it sends a PATCH request to update the NTP server list with the provided ntp_server_list.\n", + "\n", + "3. If any error occurs during the process, the function handles it accordingly. If the response status is 400, it attempts to access the iLO extended error information and prints it. If the response status is not 200 or 400, it prints an error message.\n", + "\n", + "4. If the NTP server update is successful, it prints a success message and the updated NTP server information.\n", + "\n", + "

      \n", + "In summary, the function retrieves the URI for the date and time service, updates the NTP server settings, and handles any errors that may occur during the process.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ilo_ntp_servers(_redfishobj, ntp_server_list):\n", + "\n", + " date_time_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " date_time_uri = managers_members_response.obj.Oem.Hpe.Links['DateTimeService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLODateTime.' in instance['@odata.type']:\n", + " date_time_uri = instance['@odata.id']\n", + "\n", + " if date_time_uri:\n", + " data = _redfishobj.get(date_time_uri)\n", + " if data.dict.get('StaticNTPServers'):\n", + " resp = _redfishobj.patch(date_time_uri, {'StaticNTPServers': ntp_server_list})\n", + " else:\n", + " raise Exception(\"\\'StaticNTPServers\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " ntp_data = _redfishobj.get(date_time_uri).dict.get('StaticNTPServers')\n", + " print(\"Printing updated NTP Servers:\\n\")\n", + " print(json.dumps(ntp_data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5a12f202", + "metadata": {}, + "source": [ + "
      \n", + "
      3.

      \n", + " The following code defines the give_client function, which creates a client object and performs the login operation through the following steps:
      \n", + "1. The function give_client creates a Redfish client object by instantiating the RedfishClient class. It provides the base URL, username, and password for the Redfish service as parameters.\n", + "\n", + "2. The function attempts to log in to the Redfish service using the created client object. It sends the login request with the provided credentials.\n", + "\n", + "3. If the login is successful, the function returns the instantiated Redfish client object. If there is an error connecting to the server or if the server does not support Redfish, an error message is printed, and the program exits.\n", + "

      \n", + "In summary, the give_client function creates a Redfish client object, performs the login process, and returns the client object if the login is successful.
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a963c789", + "metadata": {}, + "outputs": [], + "source": [ + "def give_client():\n", + " try:\n", + " # Create a Redfish client object\n", + " rf_obj = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " rf_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " return rf_obj" + ] + }, + { + "cell_type": "markdown", + "id": "1d393dbe", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "
      4.

      \n", + " This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "

      \n", + " The main section of the script sets the system URL, login account, and password. It creates a Redfish client object, logs in to the iLO system, enables NTP servers for the primary iLO management interface, resets the iLO, and waits for 60 seconds. Afterward, it logs out, creates a new Redfish client object, and calls the set_ilo_ntp_servers function to configure the NTP servers using the specified list. Finally, it logs out again.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " # logfile path and filename\n", + " LOGFILE = input(\"Enter log file path and file name: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_ahs_data(REDFISHOBJ, LOGFILE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " LOGFILE = data.ahs
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "10a528a3", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ntp_timezone/set_ilo_timezone.ipynb b/example_jupyter_notebooks/ntp_timezone/set_ilo_timezone.ipynb new file mode 100644 index 0000000..f4fa3b7 --- /dev/null +++ b/example_jupyter_notebooks/ntp_timezone/set_ilo_timezone.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e9c3d898", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting the timezone for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "10884361", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is a script that demonstrates how to set the timezone for HPE iLO (Integrated Lights-Out) systems using the Redfish API.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy, we'll be needing it in a while!\n", + "
      \n", + " Follow the guide below to execute without any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "2ef56c73", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "
      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library tp set up the ilo NTP server!
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c329cde9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "6a1ae9ce", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "
      2.

      \n", + "

      The function set_timezone is defined below. It provides a convenient way to set the timezone for an HPE iLO system using the Redfish API, utilizing the resource directory or direct URI retrieval methods to locate the relevant DateTime service and perform the timezone update.

      \n", + "
      Here's a summary of the function:
      \n", + "\n", + "1. Resource Directory Retrieval: The function retrieves the resource directory information using the _redfishobj Redfish client object. If the resource directory is not available or the DISABLE_RESOURCE_DIR flag is set, it retrieves the URI for the DateTime service from the server's Managers and Members resources.\n", + "\n", + "2. Finding the Relevant URI: If the resource directory is available, the function searches for the relevant URI for the DateTime service within the resource instances. It looks for an instance with the '#HpeiLODateTime.' substring in its @odata.type.\n", + "\n", + "3. Updating the Timezone: After obtaining the DateTime service URI, the function sends a GET request to retrieve the current data for the service. If the retrieved data contains the 'TimeZone' property, it constructs a JSON payload to update the timezone to the specified value. A PATCH request is then sent to the DateTime service URI with the timezone payload to modify the timezone.\n", + "\n", + "4. Handling Responses: The function handles different response scenarios. If the response status code is 400, indicating a client-side error, it attempts to print the extended error information and the available timezone list. For response status codes other than 200 or 201, indicating an HTTP error, an appropriate error message is printed. If the response status is 200, indicating a successful update, the function prints a success message along with the updated timezone information.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f3786dd7", + "metadata": {}, + "outputs": [], + "source": [ + "def set_timezone(_redfishobj, timezone):\n", + "\n", + " date_time_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " date_time_uri = managers_members_response.obj.Oem.Hpe.Links['DateTimeService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLODateTime.' in instance['@odata.type']:\n", + " date_time_uri = instance['@odata.id']\n", + "\n", + " if date_time_uri:\n", + " data = _redfishobj.get(date_time_uri)\n", + " if data.dict.get('TimeZone'):\n", + " _data = {'TimeZone': {\"Name\": timezone}}\n", + " resp = _redfishobj.patch(date_time_uri, _data)\n", + " else:\n", + " raise Exception(\"\\'TimeZone\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " print(json.dumps(data.obj.get('TimeZoneList'), indent=4, sort_keys=True))\n", + " sys.stderr.write(\"Check the TimeZone value...\\n\")\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " ntp_data = _redfishobj.get(date_time_uri).dict.get('TimeZone')\n", + " print(\"Printing updated NTP Servers:\\n\")\n", + " print(json.dumps(ntp_data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "5b943b2e", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "
      3.

      \n", + " This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "

      \n", + " The main section of the script proceeds to create a Redfish client object using the specified system URL, login account, and password. This client object allows communication with the remote system via Redfish APIs. After successfully creating the client object, it logs in to the system to establish an authenticated session.\n", + "

      \n", + "If any server connectivity issues occur or the server does not support RedFish, an error message is displayed, and the script exits. Otherwise, the set_timezone function is called, passing the Redfish client object and the desired timezone value as parameters. This function handles the task of setting the timezone on the system using the Redfish API.\n", + "
      \n", + "Upon completion, the script logs out from the system, terminating the authenticated session.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3f7743a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #timezone property (review the list of timezones ('TimeZoneList') within the DateTime URI.\n", + " TIMEZONE = \"US/Central\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_timezone(REDFISHOBJ, TIMEZONE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "0cb9dca1", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " LOGFILE = data.ahs
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0e4573cc", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/server_manager/computer_details.ipynb b/example_jupyter_notebooks/server_manager/computer_details.ipynb new file mode 100644 index 0000000..5051b63 --- /dev/null +++ b/example_jupyter_notebooks/server_manager/computer_details.ipynb @@ -0,0 +1,230 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a38bafdc", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering the computer system details" + ] + }, + { + "cell_type": "markdown", + "id": "cfe2e2b6", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      Here is an example to get_computer_details!!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b3fec1a9", + "metadata": {}, + "source": [ + "
      \n", + "

      1. We are importing all the necessary modules from the ilorest library!


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab7125e9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "8d23d990", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is the function to get the computer details requested.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the computer_details function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about computer is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the computer data of iLO system.\n", + "
      \n", + "\n", + "3. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if computerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.\n", + " \n", + "
      \n", + " \n", + "5. Finally print the Computer Details through systems_members_response.\n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1b4d0494", + "metadata": {}, + "outputs": [], + "source": [ + "def computer_details(_redfishobj):\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " print(\"\\n\\nPrinting computer system details:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0de7de8", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " Enter iLO url, Username, Password
      \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, but if Server is not avaialbe we get an error saying \"server unreachable\".
      \n", + "
      \n", + "5. Then we call computer_details with our redfish object.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f538059", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " computer_details(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "bd337e8f", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f7fd2c36", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb b/example_jupyter_notebooks/server_manager/reboot_server.ipynb similarity index 100% rename from examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server (1).ipynb rename to example_jupyter_notebooks/server_manager/reboot_server.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb b/example_jupyter_notebooks/server_manager/reset_server.ipynb similarity index 100% rename from examples/Jupyter_notebooks/HPECTY/Tanveer/reset_serve.ipynb rename to example_jupyter_notebooks/server_manager/reset_server.ipynb diff --git a/example_jupyter_notebooks/server_manager/set_server_asset_tag.ipynb b/example_jupyter_notebooks/server_manager/set_server_asset_tag.ipynb new file mode 100644 index 0000000..002f766 --- /dev/null +++ b/example_jupyter_notebooks/server_manager/set_server_asset_tag.ipynb @@ -0,0 +1,248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c3169c50", + "metadata": {}, + "source": [ + "# Setting server asset tag" + ] + }, + { + "cell_type": "markdown", + "id": "70635f68", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting server asset tag.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f176e2a7", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbe979de", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "616c5812", + "metadata": {}, + "source": [ + "

      3. This is our set_server_asset_tag function overview.

      \n", + "
      \n", + "1. The set_server_asset_tag function sets the server asset tag on an iLO device. The function takes two parameters: _redfishobj and tag. \n", + "
        \n", + "
      • _redfishobj is a Redfish client object that represents the connection to the server
      • \n", + "
      • tag is a string that represents the asset tag to be set for the server.
      • \n", + "

      \n", + "2. In the set_server_asset_tag function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.

      \n", + "3. In the ILO rest api the information about server asset tag is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the server asset tag of iLO system.

      \n", + "4. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "

      \n", + "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #ComputerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.

      \n", + "6.The function then calls the patch() method to update the system's AssetTag property with the new tag provided as input to the function.

      \n", + "7. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", + "8. If the patch() operation is successful, the updated asset tag is printed to the console. The function then waits for 10 seconds before retrieving and displaying the updated asset tag.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4e166b2", + "metadata": {}, + "outputs": [], + "source": [ + "def set_server_asset_tag(_redfishobj, tag):\n", + "\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response and systems_members_uri and tag:\n", + " print(\"Current Asset Tag: \\'%s\\'\\n\" % systems_members_response.dict.get(\"AssetTag\"))\n", + "\n", + " resp = _redfishobj.patch(systems_members_uri, {\"AssetTag\" : tag})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", + " sys.stdout.write(\"\\nUpdated Asset Tag: \\'%s\\'\\n\" % _redfishobj.\\\n", + " get(systems_members_uri).dict.get(\"AssetTag\"))" + ] + }, + { + "cell_type": "markdown", + "id": "ef4f1fb5", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to set_server_asset_tag to set server asset tag of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "606190a9", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #asset tag property in computer systems\n", + " ASSET_TAG = \"Asset01\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_server_asset_tag(REDFISHOBJ, ASSET_TAG)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "bf946980", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "63db964c", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/server_manager/set_uid_light.ipynb b/example_jupyter_notebooks/server_manager/set_uid_light.ipynb new file mode 100644 index 0000000..b98d251 --- /dev/null +++ b/example_jupyter_notebooks/server_manager/set_uid_light.ipynb @@ -0,0 +1,270 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8ce5d6a0", + "metadata": {}, + "source": [ + "# Setting the UID light\n" + ] + }, + { + "cell_type": "markdown", + "id": "5b76e816", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting UID light
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set uid light. This code is written in Python and uses the redfish library to perform the required operations
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0581e350", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "62892493", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25868/3349352274.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "1eb087ac", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our set_uid_light to function overview, in the end this will set uid light.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "1. This is a function that uses the Redfish API to toggle the UID (Universal Identification) LED on a computer system.\n", + " The function takes a Redfish connection object _redfishobj as its only argument.

      \n", + "2. In the set_uid_light function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "

      \n", + "3. In the iLO rest api the information about UID light is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the UID light settings of iLO system.\n", + "

      \n", + "4. In the system members response object with different odata_id we get a system uri . Then again an http GET request is made and response is stored in system_response. Then we set the system_members_uri.

      \n", + "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources and if #ComputerSystem attribute is present in @odata.type attribute then we'll set system_members_uri and get system_members_response settings of the user through redfish object.

      \n", + "6.It sets the body[\"IndicatorLED\"] key to Lit if the current value of the IndicatorLED property is Off, or to \"Off\" otherwise.

      \n", + "7. It sends an HTTP PATCH request to the obtained URI with the body payload to update the IndicatorLED property.

      \n", + "8. If the response status code is not 200 (OK) or 201 (Created), it prints an error message and exits.

      \n", + "9. If the response status code is 200 or 201, it waits for 10 seconds to allow the firmware to update the LED status, and then sends a GET request to the same URI to obtain the updated resource representation of the computer system.

      \n", + "10. It prints the updated value of the IndicatorLED property.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07276165", + "metadata": {}, + "outputs": [], + "source": [ + "def set_uid_light(_redfishobj):\n", + "\n", + " body = dict()\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response and systems_members_uri:\n", + " print(\"Current Indicator LED Status: \\'%s\\'\\n\" % systems_members_response.dict.\\\n", + " get(\"IndicatorLED\"))\n", + " if \"Off\" in systems_members_response.dict.get(\"IndicatorLED\"):\n", + " print(\"Will illuminate indicator LED.\\n\")\n", + " body[\"IndicatorLED\"] = \"Lit\"\n", + " else:\n", + " print(\"Will extinguish indicator LED.\\n\")\n", + " body[\"IndicatorLED\"] = \"Off\"\n", + "\n", + " resp = _redfishobj.patch(systems_members_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", + " sys.stdout.write(\"\\nUpdated Indicator LED Status: \\'%s\\'\\n\" % _redfishobj.\\\n", + " get(systems_members_uri).dict['IndicatorLED'])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "70d73b57", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. The rest opertions are handled by Redfish object which is created by Redfish Client
      \n", + "
      \n", + " \n", + "2. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of Redfish Client class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call set_uid_light with our redfish object to set UID light.
      \n", + "
      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea7ed17c", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_uid_light(REDFISHOBJ)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "3e4a9804", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "377dc76a", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/snmp/configure_snmp.ipynb b/example_jupyter_notebooks/snmp/configure_snmp.ipynb new file mode 100644 index 0000000..d8cbe37 --- /dev/null +++ b/example_jupyter_notebooks/snmp/configure_snmp.ipynb @@ -0,0 +1,282 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "979defcc", + "metadata": {}, + "source": [ + "# Configuring SNMP for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of configuring SNMP for HPE iLO systems.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ccd0447f", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_4196/1287542820.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory \n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alerts):\n", + "\n", + " snmp_service_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to configure_snmp function to obtain snmp related information of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "faa032c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 172.1,14\n", + "Enter Username: hhello\n", + "Enter password: 1245\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[1;31m# Create a Redfish client object\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 27\u001b[1;33m REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n\u001b[0m\u001b[0;32m 28\u001b[0m password=LOGIN_PASSWORD)\n", + "\u001b[1;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;31m# Login with the Redfish client\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 31\u001b[1;33m \u001b[1;32mexcept\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mexcp\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 32\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"ERROR: server not reachable or does not support RedFish.\\n\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 33\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " ALERTS_ENABLED = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_ENABLED, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/snmp/configure_snmp_trap_source.ipynb b/example_jupyter_notebooks/snmp/configure_snmp_trap_source.ipynb new file mode 100644 index 0000000..f7941cf --- /dev/null +++ b/example_jupyter_notebooks/snmp/configure_snmp_trap_source.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0a6c95aa", + "metadata": {}, + "source": [ + "# Configuring SNMP trap source for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "594a0e06", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      This is an example of configuring SNMP trap source for HPE iLO systems.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "25be0e98", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f16a98ad", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25528/1522814575.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "8c2b4d45", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp service related information.

      \n", + " \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the snmp service information.\n", + "\n", + " \n", + "\n", + " \n", + "1. In the ILO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "2. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if power snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b53e8e73", + "metadata": {}, + "outputs": [], + "source": [ + " def configure_snmp(_redfishobj):\n", + "\n", + " snmp_service_uri = None\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " # print(managers_members_response.obj['Oem']['Hpe']['Links'])\n", + " # exit(0)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['SNMPService']['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " # resp = _redfishobj.get(snmp_service_uri)\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " # exit(0)\n", + " # TrapSourceHostname : Manager or System\n", + " body = {\"TrapSourceHostname\": \"System\"}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b852d783", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to configure_snmp function to obtain snmp related info of system.
      • \n", + "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9cf5c73", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "610979dd", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " if len(sys.argv) <= 3:\n", + " sys.stderr.write(\"ERROR: We need 3 arguments. \\nUsage: change-snmp.py \"\n", + " \"ILOIPADDR ILOUSER ILOPASSWORD \\n\")\n", + " sys.exit()\n", + "\n", + " SYSTEM_URL = \"https://\" + sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " try:\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT,\n", + " password=LOGIN_PASSWORD)\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "80f7da07", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "00b5c8a5", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/snmp/set_snmp_alert.ipynb b/example_jupyter_notebooks/snmp/set_snmp_alert.ipynb new file mode 100644 index 0000000..5dbdafa --- /dev/null +++ b/example_jupyter_notebooks/snmp/set_snmp_alert.ipynb @@ -0,0 +1,315 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "80ca2bf5", + "metadata": {}, + "source": [ + "# Setting SNMP alert destination" + ] + }, + { + "cell_type": "markdown", + "id": "647c7374", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting SNMP alert destination.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "ce2b4b70", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6a53c06", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "cfd0ef73", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "269747d5", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alertdestinations, DISABLE_RESOURCE_DIR):\n", + " snmp_service_uri = None\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " #body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " body = {\"AlertDestinations\": snmp_alertdestinations}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "ca33ee48", + "metadata": {}, + "source": [ + "

      3. This is our set_snmp_alert_destination function overview.

      \n", + "
      \n", + "1. The set_snmp_alert_destination function sets the SNMP alert destinations on an iLO device. The function takes three parameters: _redfishobj, snmp_service_uri, and alert_destination_list. \n", + "
        \n", + "
      • _redfishobj is the Redfish client object.
      • \n", + "
      • snmp_service_uri is the URI for the SNMP service on the iLO device.
      • \n", + "
      • alert_destination_list is a list of dictionaries containing the SNMP alert destinations to set.
      • \n", + "

      \n", + "2. The function gets the current SNMP service data using _redfishobj.get() and checks if the AlertDestinations property is available/modifyable.

      \n", + "3. If the property is available/modifyable, the function sends a PATCH request with the updated alert destinations using _redfishobj.patch().

      \n", + "4. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", + "5. If the patch operation is successful, the function prints the response and gets the updated SNMP alert destination data using _redfishobj.get().

      \n", + "6. The updated SNMP alert destination data is printed to the console using json.dumps() and print().

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c91c0fb8", + "metadata": {}, + "outputs": [], + "source": [ + "def set_snmp_alert_destination(_redfishobj, snmp_service_uri, alert_destination_list):\n", + " data = _redfishobj.get(snmp_service_uri)\n", + " if data.dict.get(\"AlertDestinations\"):\n", + " resp = _redfishobj.patch(snmp_service_uri, {'AlertDestinations': alert_destination_list})\n", + " else:\n", + " raise Exception(\"\\'AlertDestinations\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nPatch operation successful!\\n\\nResponse:\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " snmp_service_response = _redfishobj.get(snmp_service_uri).dict.get('AlertDestinations')\n", + " print(\"\\n\\nPrinting updated SNMP alert destination:\\n\")\n", + " print(json.dumps(snmp_service_response, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "9fdd0d40", + "metadata": {}, + "source": [ + "

      4. This is Main function overview.


      \n", + "The Main function \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • It checks the generation of iLO by calling the get_gen function and prints the iLO generation.\n", + "
      • If the iLO generation is 5, it calls the configure_snmp function to configure the SNMP service with the read communities and alerts destination, and disable resource directory flag.
      • \n", + "
      • If the iLO generation is not 5, it calls the set_snmp_alert_destination function to set the SNMP alert destination with the alert destination list for iLO4.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27378983", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " #SYSTEM_URL = \"https://15.146.46.45\"\n", + " #LOGIN_ACCOUNT = \"admin\"\n", + " #LOGIN_PASSWORD = \"admin123\"\n", + "\n", + " SYSTEM_URL = sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " #ALERTS_ENABLED = True\n", + " #Alert Destination\n", + " ALERTS_DESTINATION = [\"1.1.1.1\",\"2.2.2.2\"]\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " snmp_service_uri = \"/redfish/v1/Managers/1/SNMPService/\"\n", + "\n", + " # Number of max alert destination supported on iLO4 and iLO5 is different\n", + " alert_destination_list = [\"ILOCN771702NJ\", \"15.146.46.55\" , \"15.146.46.58\"]\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " (ilogen,_) = get_gen(REDFISHOBJ)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_DESTINATION, DISABLE_RESOURCE_DIR)\n", + " else:\n", + " set_snmp_alert_destination(REDFISHOBJ, snmp_service_uri, alert_destination_list)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "5a2f6ba5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "28ec396f", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/users_and_sessions/account_remove.ipynb b/example_jupyter_notebooks/users_and_sessions/account_remove.ipynb new file mode 100644 index 0000000..7907409 --- /dev/null +++ b/example_jupyter_notebooks/users_and_sessions/account_remove.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Remove iLO User Account" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is the example to a particular user account on HPE iLO system.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "
      1.
      \n", + "
      \n", + "
      In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + " for proper execution of our code.
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\"\"\"\n", + "An example of removing a user account from the HPE iLO systems\n", + "\"\"\"\n", + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "
      2.
      \n", + "
      \n", + " Below is the remove_ilo_user_account function, after sucessful execution of this function we will be able to delete the information of any user account that is present on the HPE iLO system.\n", + " \n", + "
      \n", + "Let me give you a walk through of it!\n", + "
      \n", + " \n", + "For removal of any general account from the system we will first have to search for the accounts that we wan't to delete based on any attribute or property that uniquely identifies the account. Upon finding that account we can just make http delete request and we are done!\n", + " \n", + "1. In the remove_ilo_user_account function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In case the resource directory was disabled we are navigating to the actual location where the all the member account information is stored by using DELETErequest.\n", + " \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources to obtain the account_collection_uri.\n", + "
      \n", + "4.
        \n", + "
      • Now we are having the location at which all the member accounts are present.
      • Simply we just find out what user account matches the account that has to be deleted based on username of the accounts.
      • If we do not find the required account after completion of iteration we print out a message that required acccount was not found on the server side.
      • \n", + "
      • After this we simply make a DELETE request to delete that particular account and save the response obtained in resp variable.
      If the http status code returned was 200, then we simply print a message that delete operation was success.
      \n", + " Else if the status code returned was anything else we print out the status code with an error message to get idea about what went wrong.\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def remove_ilo_user_account(_redfishobj, username_to_delete):\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " break\n", + "\n", + " #find the account to delete\n", + " account_uri_to_delete = None\n", + " #collection of account URIs located at the account_collection_uri endpoint using the HTTP GET method\n", + " account_uris = _redfishobj.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " # retrieving the account object located at the URI specified by account_uri['@odata.id'] using \n", + " #the HTTP GET method\n", + " account = _redfishobj.get(account_uri['@odata.id'])\n", + " #checking whether username is matching with the username_to_delete\n", + " if account.dict['UserName'] == username_to_delete:\n", + " account_uri_to_delete = account_uri['@odata.id']\n", + " break\n", + " #deleting a resource located at the account_uri_to_delete endpoint \n", + " if not account_uri_to_delete:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + " #deleting account found in the account_uri_to_delete\n", + " resp = _redfishobj.delete(account_uri_to_delete)\n", + " #checking the status for post request\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "
      3.
      \n", + "
      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • The ACCOUNT_TO_DELETE contains the username of the account that we need to delete. We are passing the same as an argument while making a call to remove_ilo_user_account function.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to remove_ilo_user_account function .
      • \n", + "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + " \n", + " \n", + " # The username of the account to remove\n", + " ACCOUNT_TO_DELETE = \"joker\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " #calling function \n", + " remove_ilo_user_account(REDFISHOBJ, ACCOUNT_TO_DELETE)\n", + "\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/example_jupyter_notebooks/users_and_sessions/modify_user_account.ipynb b/example_jupyter_notebooks/users_and_sessions/modify_user_account.ipynb new file mode 100644 index 0000000..f16ab22 --- /dev/null +++ b/example_jupyter_notebooks/users_and_sessions/modify_user_account.ipynb @@ -0,0 +1,326 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "22cbd656", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "#modify_user_account" + ] + }, + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is a example modify_user_account.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccd0447f", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

      2.

      This is our modify_ilo_user_account function overview, in the end this will help you to modify the account.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings..\n", + "\n", + "1. In the modify_user_account function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. Retrieves the account service URI, sends a GET request to the account service, and obtains the account collection URI. If a role_id is provided, it creates a request body with the modified RoleId parameter.\n", + "
      \n", + " \n", + "3. Else Iterate over resource instances to find the account collection URI. Modify privileges and/or login name if specified for an HPE server.\n", + "
      \n", + " \n", + "4. If new User name is there then modified the new user name and password in the body.\n", + " Iterate over account URIs to find the one with a matching username. If found, modify the account using a PATCH request to the identified URI.\n", + "
      \n", + " \n", + "5.Handling the error after inserting the iso image in slot \n", + "If status code is 400 the code attempts to retrieve and print extended error message .\n", + "If status code is 200 OK then it will print error meassage and status code.\n", + "Else the modification is success then code print result in JSON format.\n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "def modify_ilo_user_account(_redfishobj, username_to_modify, new_loginname, new_username, \\\n", + " new_password, role_id, privilege_dict):\n", + "\n", + " account_collection_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " #modify role id\n", + " if role_id:\n", + " body = {\"RoleId\": role_id}\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " if privilege_dict:\n", + " #HPE server, so modify privileges\n", + " body = {\"Oem\": {\"Hpe\": {\"Privileges\": {}}}}\n", + " for priv in privilege_dict:\n", + " body[\"Oem\"][\"Hpe\"][\"Privileges\"][priv] = privilege_dict[priv]\n", + " if new_loginname:\n", + " #modify login name\n", + " body[\"Oem\"][\"Hpe\"][\"LoginName\"] = new_loginname\n", + "\n", + " if new_username:\n", + " body[\"UserName\"] = new_username\n", + " if new_password:\n", + " body[\"Password\"] = new_password\n", + "\n", + " #find the account to modify\n", + " account_uri_to_modify = None\n", + " account_uris = REDFISHOBJ.get(account_collection_uri)\n", + " for account_uri in account_uris.dict['Members']:\n", + " account = REDFISHOBJ.get(account_uri['@odata.id'])\n", + " if account.dict['UserName'] == username_to_modify:\n", + " account_uri_to_modify = account_uri['@odata.id']\n", + " break\n", + "\n", + " if not account_uri_to_modify:\n", + " sys.stderr.write(\"Cannot find account to modify\")\n", + " return\n", + "\n", + " #modify the account by sending patch request\n", + " resp = REDFISHOBJ.patch(account_uri_to_modify, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER BASED WHERE YOU ARE RUUNIG THE SERVER
      \n", + "
        \n", + "
      • The variables USERNAME_TO_MODIFY, NEW_LOGINNAME, NEW_USERNAME, NEW_PASSWORD, and ROLE_ID have been assigned with the specified values.
      • \n", + "
      • PRIVILEGE_DICT represents a dictionary where each key corresponds to a specific privilege and the corresponding value indicates whether that privilege is enabled or disabled.
      • \n", + "
      • Using the redfish object we are trying to establish the connection with the server.After establish the connection we try to login .If the server is unreachable we noftify the user with error message.
      • \n", + "
      • If login is successful then we are calling the function with proper parameter.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "faa032c5", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 43\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 42\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 43\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 44\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 45\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 47\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 46\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 47\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 48\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 49\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #username of the account to modify\n", + " USERNAME_TO_MODIFY = \"bruce_wayne\"\n", + "\n", + " #account login name to change the account to\n", + " NEW_LOGINNAME = \"joker\"\n", + "\n", + " #account user name to change the account to\n", + " NEW_USERNAME = \"joker\"\n", + "\n", + " #account password to change the account to\n", + " NEW_PASSWORD = \"joker123\"\n", + "\n", + " #role to change account to\n", + " ROLE_ID = \"ReadOnly\" #Administrator, ReadOnly or Operator are available\n", + "\n", + " #update HPE account privileges\n", + " PRIVILEGE_DICT = {\"iLOConfigPriv\": False, \"VirtualMediaPriv\": False, \"RemoteConsolePriv\": True,\\\n", + " \"UserConfigPriv\": False, \"VirtualPowerAndResetPriv\": False, \\\n", + " \"SystemRecoveryConfigPriv\": False, \"LoginPriv\": True, \\\n", + " \"HostStorageConfigPriv\": False, \"HostNICConfigPriv\": False, \\\n", + " \"HostBIOSConfigPriv\": False}\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " modify_ilo_user_account(REDFISHOBJ, USERNAME_TO_MODIFY, NEW_LOGINNAME, NEW_USERNAME, \\\n", + " NEW_PASSWORD, ROLE_ID, PRIVILEGE_DICT)\n", + "\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/virtual_media/mount_virtual_media_iso.ipynb b/example_jupyter_notebooks/virtual_media/mount_virtual_media_iso.ipynb new file mode 100644 index 0000000..cfa0710 --- /dev/null +++ b/example_jupyter_notebooks/virtual_media/mount_virtual_media_iso.ipynb @@ -0,0 +1,322 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "266e8885", + "metadata": { + "tags": [] + }, + "source": [ + "# Mount_virtual-media_iso" + ] + }, + { + "cell_type": "markdown", + "id": "358b08b4", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to mount_virtual_media_iso
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "578dfc4d", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c82681e9", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'get_resource_directory'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_35788/1390777471.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'get_resource_directory'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "84274de2", + "metadata": {}, + "source": [ + "
      \n", + "

      2.

      This is our mount_virtual-media_iso function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present.
      \n", + "\n", + "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. Retrieving information on the server's management interfaces using the Redfish API client, including members and their properties and retrieving URI for virtual media using Redfish API client.\n", + "
      \n", + "\n", + "3. Else Using the Redfish API client and the Resource Directory, iterating through resource instances, and obtaining the URI for the virtual media collection.\n", + "
      \n", + "4. If virtual_media_uri is not None then If a slot matches, the program fetches the URI for adding media into that slot and then sends a POST request to the supplied URL to insert the ISO image. Additionally, the code sends a PATCH request to set the option if a parameter is provided for the server to restart from the virtual media.\n", + "
      \n", + "\n", + "5. Handling the error after inserting the iso image in slot \n", + " If status code is 400 the code attempts to retrieve and print extended error message .\n", + " If status code is 200 OK then it will print error meassage and status code.\n", + " Else the insertion is success then code print result in JSON format.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc680e58", + "metadata": {}, + "outputs": [], + "source": [ + "def mount_virtual_media_iso(_redfishobj, iso_url, media_type, boot_on_next_server_reset):\n", + " #Initializing variables for virtual media API responses.\n", + " virtual_media_uri = None\n", + " virtual_media_response = []\n", + "#Retrieving resource directory instances using Redfish API client.\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", + " virtual_media_uri = instance['@odata.id']\n", + "\n", + " if virtual_media_uri:\n", + " #retriving information Virtual media using redfish object and specified parameter\n", + " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", + " #iterates through each virtual media to find proper slot\n", + " for virtual_media_slot in virtual_media_response.obj['Members']:\n", + " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", + " if media_type in data.dict['MediaTypes']:\n", + " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.InsertMedia']['target']\n", + " post_body = {\"Image\": iso_url}\n", + "\n", + " if iso_url:\n", + " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", + " if boot_on_next_server_reset is not None:\n", + " patch_body = {}\n", + " patch_body[\"Oem\"] = {\"Hpe\": {\"BootOnNextServerReset\": \\\n", + " boot_on_next_server_reset}}\n", + " boot_resp = _redfishobj.patch(data.obj['@odata.id'], patch_body)\n", + " if not boot_resp.status == 200:\n", + " sys.stderr.write(\"Failure setting BootOnNextServerReset\")\n", + " #handling error after inserting iso image in slot \n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "567eb3f8", + "metadata": {}, + "source": [ + "
      \n", + "

      3.

      This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + "
      \n", + "1. If server is runnig in locally then url,login_account,Login-password will be None.\n", + " Else then we need to enter the proper credential.\n", + "
      \n", + "
      \n", + " \n", + "2. media_url will provide access and mount the iso image in server side and we initial media_type to CD.
      \n", + "
      \n", + "\n", + "3. Utilising the Redfish API to create a Redfish client object with the provided login information and log in to the server.
      \n", + "
      \n", + "\n", + "4. resolving the exception that is thrown when the server cannot be reached or does not implement the Redfish API, printing a message of error to standard error output, and terminating the program
      \n", + "
      \n", + "5. Using the Redfish API client object and the given arguments to mount a virtual media ISO image on a server.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7c01d222", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: 120.1.114.51\n", + "Enter Name: tann\n", + "Enter password: none\n", + "Enter bios password: noen\n", + "Enter bios property you wish to change: yes\n", + "Enter Value of the property to change: none\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 17\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 16\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 17\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 19\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 21\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 20\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 21\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 22\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 23\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + " # used to access and mount iso image on server side\n", + " MEDIA_URL = \"http:///media.iso\"\n", + "\n", + " #specify the type of content the media represents\n", + " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", + " #specify if the server should attempt to boot this media on system restart\n", + " BOOT_ON_NEXT_SERVER_RESET = True\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " mount_virtual_media_iso(REDFISHOBJ, MEDIA_URL, MEDIA_TYPE, BOOT_ON_NEXT_SERVER_RESET)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "9d0181a9", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "9e9f0846", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server.ipynb new file mode 100644 index 0000000..1dfae9f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/reboot_server.ipynb @@ -0,0 +1,236 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# REBOOTING A SERVER" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is the example to perform rebooting of a server.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "
      \n", + "

      1

      \n", + "In the beginning, we are having some import statements that are actually providing us with the required modules and libraries.\n", + "for proper execution of our code.
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "

      2

      \n", + "In below cell is the reboot_server function.\n", + "Current cell is the overview of it, utimately at the end this will reboot the server and provide the response for the same.\n", + "
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. In the reboot server function we are first using system_members_response variable to obtain information about the path at which server related information is stored by using couple of get requests.\n", + "
      \n", + "2. If the resource directory was accessible then we simply search for '#ComputerSystem' key (as this is the place comprising of server related information inside the instance['odata.type'] dictionary and finally making a get request to that location.\n", + "
      \n", + " \n", + "3. If we obtain systems_response successfully then a ressettype list is created specifying the parameters that how we want to restart.\n", + " \n", + "\n", + "4. Later both the parameters are passed into a new dictionary named body and post request is created to make changes on the server side.\n", + " A successful HTTP post request will set the values at server end so that a server gets rebooted.\n", + " \n", + "\n", + "5. Lastly, we also save response status inside resp variable and check what is the status code returned to confirm whether the post request was success or not. If success then response by server is printed and if not then error message is printed.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def reboot_server(_redfishobj):\n", + "\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj.get_resource_directory)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_uri = instance['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " #code check for determines whether a systems_response object is present, finds the URI for resetting a computer \n", + " #system, builds a request body describing the reset action and type, then sends a POST request with the provided \n", + " #reset type to restart the system.\n", + " if systems_response:\n", + " system_reboot_uri = systems_response.obj['Actions']['#ComputerSystem.Reset']['target']\n", + " body = dict()\n", + " resettype = ['ForceRestart','GracefulRestart']\n", + " body['Action'] = 'ComputerSystem.Reset'\n", + " for reset in resettype:\n", + " if reset.lower() == \"forcerestart\":\n", + " body['ResetType'] = \"ForceRestart\"\n", + " resp = _redfishobj.post(system_reboot_uri, body)\n", + " elif reset.lower() == \"gracefulrestart\":\n", + " body['ResetType'] = \"GracefulRestart\"\n", + " resp = _redfishobj.post(system_reboot_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "

      3

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + " \n", + "
      • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to reboot_server function to perform rebooting of server.
      • \n", + "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " #login credentials\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " #function call\n", + " reboot_server(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_server.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_server.ipynb new file mode 100644 index 0000000..9356919 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/reset_server.ipynb @@ -0,0 +1,304 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Reset_server" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to reseting the server!!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Declared a global variable i.e; DISABLE_RESOURCE_DIR.
      \n", + "Below we are importing all the necessary modules from the ilorest library!.
      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • RedfishClient
    • \n", + "
    • ServerDownOrUnreachableError
    • \n", + "
    • get_resource_directory
    • \n", + "
    • get_gen
    • \n", + " \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import argparse\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
      \n", + "

      This is our resetting_server function overview, in the end this function the server get restarted.

      \n", + "

      Let me give you a walk through of it!

      \n", + " 1.If either of no resource instance or DISABLE_RESOURCE_DIR flag is set then it retrieve the URI for systems from the root object, get the response for the systems URI using the Redfish API object, retrieve the URI for the members from the systems response object, and then get the response for the members URI using the Redfish API object.\n", + "
      \n", + "
      \n", + " 2.Else i.e;iterates through the resource instances, checking if the @odata.type value contains ComputerSystem. If found, it assigns the @odata.id value to managers_members_uri and retrieves the response using the Redfish API object.\n", + "
      \n", + "
      \n", + " 3.This code gets the URI for the computer system reset action, builds a dictionary with an action value and reset type, iterates through reset types, then posts the body to the URI for each reset type using the Redfish API object if managers_members_response exists.\n", + "
      \n", + "
      \n", + " 4.Next is to check the status of the response received from the previous POST request sent using the Redfish client object _redfishobj.\n", + "
      \n", + " 1.If the status is 400, it attempts to print the extended error message associated with the response.\n", + "
      \n", + " 2.If the response status is not 400 and not 200, an error message is printed to the standard error stream.\n", + "
      \n", + " 3.If the response status is 200, it indicates that the reset operation was successful. The code then prints a success message and prints the JSON response received from the server in a formatted way.\n", + "
      \n", + "
      \n", + " 5. Again function call reset_server_gen9(_redfishobj) uses the Redfish API object to retrieve the response for the managers URI, the response object to retrieve the URI for the computer system reset action, etc. The action value and reset type are created in a dictionary,and the reset type is changed to ForceRestart after printing the URI.\n", + "
      \n", + " Again the POST request sent by using RedFish client object is again checked.\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def reset_server(_redfishobj):\n", + " \n", + " managers_members_response = None\n", + " #Assigns resource directory to variable using Redfish API object\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " #checking if no resource instance or DISABLE_RESOURCE_DIR flag is set \n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if \"ComputerSystem.\" in instance['@odata.type']:\n", + " managers_members_uri = instance['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " \n", + " if managers_members_response:\n", + " path = managers_members_response.obj[\"Actions\"][\"#ComputerSystem.Reset\"][\"target\"]\n", + " body = dict()\n", + " resettype = ['ForceRestart','GracefulRestart']\n", + " body[\"Action\"] = \"ComputerSystem.Reset\"\n", + " for reset in resettype:\n", + " if reset.lower() == \"forcerestart\":\n", + " body['ResetType'] = \"ForceRestart\"\n", + " resp = _redfishobj.post(path, body)\n", + " elif reset.lower() == \"gracefulrestart\":\n", + " body['ResetType'] = \"GracefulRestart\"\n", + " resp = _redfishobj.post(path, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " \n", + "#creates a dictionary containing an action value and reset type, then posts the dictionary to the \n", + "#computer system reset action URI to reset a server using the Redfish API.\n", + "def reset_server_gen9(_redfishobj):\n", + " \n", + " managers_uri = \"/redfish/v1/Systems/1/\"\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " system_path = managers_response.obj[\"Actions\"][\"#ComputerSystem.Reset\"][\"target\"]\n", + " print(system_path)\n", + " body = dict()\n", + " body[\"Action\"] = \"Reset\"\n", + " body[\"ResetType\"] = \"ForceRestart\"\n", + "\n", + " resp = _redfishobj.post(system_path, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message \"\\\n", + " \"Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
      \n", + "

      3.

      The Main function:

      \n", + "
        \n", + "
      • After initilize the parser and adds argument such as the iLO IP address, username, and password as three command-line options to the parser. Each argument has a corresponding default value and help text.
      • \n", + "
      • In try section of code ;utilising the supplied iLO IP address, login, and password, to create a Redfish client object. If the login is successful, the get_gen function is used to check the server generation, and based on the generation number, the proper reset method is selected. The reset_server function is called if the server is a Gen5 server; otherwise, the reset_server_gen9 function is called. An error message is printed to the console and the script terminates if the server cannot be reached or does not support Redfish.
      • \n", + "
      • REDFISHOBJ.logout() will take care of logging you out of the ilo.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'argparse' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;18m__name__\u001b[39m \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__main__\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# Initialize parser \u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m parser \u001b[38;5;241m=\u001b[39m \u001b[43margparse\u001b[49m\u001b[38;5;241m.\u001b[39mArgumentParser(description \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mScript to upload and flash NVMe FW\u001b[39m\u001b[38;5;124m\"\u001b[39m) \n\u001b[1;32m 5\u001b[0m parser\u001b[38;5;241m.\u001b[39madd_argument(\n\u001b[1;32m 6\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-i\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m 7\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m--ilo\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 10\u001b[0m help\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miLO IP of the server\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 11\u001b[0m default\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m 12\u001b[0m parser\u001b[38;5;241m.\u001b[39madd_argument(\n\u001b[1;32m 13\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-u\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m 14\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m--user\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 17\u001b[0m help\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miLO username to login\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 18\u001b[0m default\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m)\n", + "\u001b[0;31mNameError\u001b[0m: name 'argparse' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # Initialize parser \n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\") \n", + "\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + " #stroing namespace object in options\n", + " options = parser.parse_args()\n", + " #getting namespaceobject ilo_ip address\n", + " system_url = \"https://\" + options.ilo_ip\n", + " #printing the url obtain by ip\n", + " print (system_url)\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " \n", + " (ilogen,_) = get_gen(redfish_obj)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " reset_server(redfish_obj)\n", + " else:\n", + " reset_server_gen9(redfish_obj)\n", + " redfish_obj.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From bfb081758f5cb2eb6235e3ae24c7ce4398c20e54 Mon Sep 17 00:00:00 2001 From: Rajeevalochana Kallur Date: Fri, 12 May 2023 16:44:22 +0530 Subject: [PATCH 035/159] more --- .../eskm/set_ESKM_PrimaryKeyServer (2).ipynb | 296 +++++++++++++ .../eskm/set_ESKM_username_password.ipynb | 289 +++++++++++++ .../flash_firmware_by_uefi.ipynb | 398 ++++++++++++++++++ .../nic_network/find_ilo_mac_address.ipynb | 228 ++++++++++ .../nic_network/set_active_ilo_nic.ipynb | 295 +++++++++++++ .../ntp_timezone/enabling_ntp_server.ipynb | 309 ++++++++++++++ .../enable_secure_boot.ipynb | 0 .../security_certificate/generate_csr.ipynb | 279 ++++++++++++ .../users_and_sessions/sessions.ipynb | 252 +++++++++++ .../eject_virtual_media_iso.ipynb | 263 ++++++++++++ .../B VENKAT RAHUL/enable_secure_boot.ipynb | 250 +++++++++++ 11 files changed, 2859 insertions(+) create mode 100644 example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer (2).ipynb create mode 100644 example_jupyter_notebooks/eskm/set_ESKM_username_password.ipynb create mode 100644 example_jupyter_notebooks/fw_info_and_flash/flash_firmware_by_uefi.ipynb create mode 100644 example_jupyter_notebooks/nic_network/find_ilo_mac_address.ipynb create mode 100644 example_jupyter_notebooks/nic_network/set_active_ilo_nic.ipynb create mode 100644 example_jupyter_notebooks/ntp_timezone/enabling_ntp_server.ipynb rename examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb => example_jupyter_notebooks/security_certificate/enable_secure_boot.ipynb (100%) create mode 100644 example_jupyter_notebooks/security_certificate/generate_csr.ipynb create mode 100644 example_jupyter_notebooks/users_and_sessions/sessions.ipynb create mode 100644 example_jupyter_notebooks/virtual_media/eject_virtual_media_iso.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb diff --git a/example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer (2).ipynb b/example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer (2).ipynb new file mode 100644 index 0000000..7c760bb --- /dev/null +++ b/example_jupyter_notebooks/eskm/set_ESKM_PrimaryKeyServer (2).ipynb @@ -0,0 +1,296 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Set_ESKM_PrimaryKeyServer

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of set_ESKM_PrimaryKeyServer
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about set_ESKM_PrimaryKeyServer function

      \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "1. This function sets the primary key server for the HPE ESKM service.
      \n", + "
      \n", + " \n", + "2. It takes three arguments: _redfishobj (an object representing the Redfish service), primary_key_server_address (a string representing the IP address or hostname of the primary key server), and primary_key_server_port (an integer representing the port number of the primary key server).
      \n", + "
      \n", + "\n", + "3. It uses the get_resource_directory function to find the relevant ESKM URI, which is used to make a POST request to set the primary key server.
      \n", + "
      \n", + "\n", + "4. If the POST request is successful (returns an HTTP status code of 200), the function prints a success message and the JSON response from the server.
      \n", + "
      \n", + "5. If the POST request is unsuccessful, the function prints an error message and, if available, the extended error information from the server response.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ESKM_PrimaryKeyServer(_redfishobj, primary_key_server_address, primary_key_server_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + "\n", + " body[\"PrimaryKeyServerAddress\"] = primary_key_server_address\n", + " body[\"PrimaryKeyServerPort\"] = int(primary_key_server_port)\n", + "\n", + " resp = _redfishobj.post(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      3.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      4.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " PRIMARY_KEY_SERVER_ADDRESS = \"192.168.1.1\"\n", + " PRIMARY_KEY_SERVER_PORT = \"9000\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ESKM_PrimaryKeyServer(REDFISHOBJ, PRIMARY_KEY_SERVER_ADDRESS, PRIMARY_KEY_SERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/eskm/set_ESKM_username_password.ipynb b/example_jupyter_notebooks/eskm/set_ESKM_username_password.ipynb new file mode 100644 index 0000000..f38c417 --- /dev/null +++ b/example_jupyter_notebooks/eskm/set_ESKM_username_password.ipynb @@ -0,0 +1,289 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Setting the ESKM username and password for HPE iLO systems

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of setting the ESKM username and password for HPE iLO systems
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about ESKM_username_pass function

      \n", + " \n", + "1. The function sets up an Electronic Software Key Manager (ESKM) on an iLO (Integrated Lights Out) server using the Redfish API.
      \n", + "
      \n", + " \n", + "2. It takes several input parameters including ESKM username, password, account group, primary key server address, and primary key server port.
      \n", + "
      \n", + "\n", + "3. It first attempts to locate the URI for the ESKM resource either by using the Redfish Resource Directory or by manually navigating through the Redfish API.br>\n", + "
      \n", + "\n", + "4. If the ESKM URI is found, the function constructs a JSON payload containing the ESKM configuration information and primary key server details and sends it as a PATCH request to the ESKM resource.
      \n", + "
      \n", + "5. If the PATCH request is successful (i.e., returns an HTTP status code of 200), the function prints out a success message along with the response payload, otherwise it prints out an error message.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def ESKM_username_pass(_redfishobj, eskm_username, eskm_password, eskm_accountgroup, \\\n", + " eskm_primarykeyserver_addr, eskm_primarykeyserver_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " body[\"KeyManagerConfig\"] = dict()\n", + " body[\"KeyManagerConfig\"][\"LoginName\"] = eskm_username\n", + " body[\"KeyManagerConfig\"][\"Password\"] = eskm_password\n", + " body[\"KeyManagerConfig\"][\"AccountGroup\"] = eskm_accountgroup\n", + " body[\"KeyManagerConfig\"][\"ESKMLocalCACertificateName\"] = \"\"\n", + " body[\"PrimaryKeyServerAddress\"] = eskm_primarykeyserver_addr\n", + " body[\"PrimaryKeyServerPort\"] = eskm_primarykeyserver_port\n", + " resp = _redfishobj.patch(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      3.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      4.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " ESKM_USERNAME = \"admin\"\n", + " ESKM_PASSWORD = \"password\"\n", + " ESKM_ACCOUNTGROUP = \"group\"\n", + " ESKM_PRIMARYKEYSERVER_ADDR = \"192.168.1.10\"\n", + " ESKM_PRIMARYKEYSERVER_PORT = 5927\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \\\n", + " ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/fw_info_and_flash/flash_firmware_by_uefi.ipynb b/example_jupyter_notebooks/fw_info_and_flash/flash_firmware_by_uefi.ipynb new file mode 100644 index 0000000..e951cf7 --- /dev/null +++ b/example_jupyter_notebooks/fw_info_and_flash/flash_firmware_by_uefi.ipynb @@ -0,0 +1,398 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Uploading Firmware to the iLO Repository For Flashing

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of uploading firmware to the iLO Repository for flashings
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "import argparse\n", + "from random import randint\n", + "\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "import logging\n", + "from redfish import redfish_logger\n", + "\n", + "from ilorest_util import get_resource_directory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "102138e9", + "metadata": {}, + "outputs": [], + "source": [ + "LOGGERFILE = \"RedfishApiExamples.log\"\n", + "LOGGERFORMAT = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n", + "LOGGER = redfish_logger(LOGGERFILE, LOGGERFORMAT, logging.DEBUG)" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about upload_firmware function

      \n", + " \n", + "1. The function upload_firmware takes in parameters such as _redfishobj, firmware_loc, comp_type, update_repo, and update_target..
      \n", + "
      \n", + " \n", + "2. It uploads firmware to a specified location using the Redfish API and HTTP POST request.
      \n", + "
      \n", + "\n", + "3. The function first obtains the UpdateService URI and HttpPushUri using the _redfishobj and then reads the firmware file as binary data.
      \n", + "
      \n", + "\n", + "4. It creates a payload containing the session key, JSON data, and the firmware file in multipart-form data format..
      \n", + "
      \n", + "5. Finally, the function sends the payload as an HTTP POST request to the specified path and returns an appropriate response based on the HTTP status code.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, comp_type, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " print (update_service_uri)\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + " print (path)\n", + "\n", + " body = []\n", + "\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " #ImageLocation = \"c:\\\\test\"\n", + " #filename = \"I41_2.40_08_10_2020.fwpkg\"\n", + " #ImagePath = os.path.join(ImageLocation, filename)\n", + " #file_name = os.path.basename(firmware_loc)\n", + " #print (ImagePath)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(file_tuple)\n", + " #print (body)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " print ('Begin upload....please wait...')\n", + " # We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2b320019", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is about create task function

      \n", + " \n", + "1. The function create_task takes in parameters such as _redfishobj, firmware_loc, and tpm_flag.
      \n", + "
      \n", + " \n", + "2. It creates a new task for applying firmware updates using the Redfish API and HTTP POST request.
      \n", + "
      \n", + "\n", + "3. The function first obtains the session key and creates the necessary header dictionary for the HTTP request.It then checks if there are any current tasks in the task queue before creating a new task with a random ID and the given firmware file name.
      \n", + "
      \n", + "\n", + "4. The task is created using the update_task dictionary and sent as an HTTP POST request to the specified path.
      \n", + "
      \n", + "5. Finally, the function returns an appropriate response based on the HTTP status code.\n", + "
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09f2bc6b", + "metadata": {}, + "outputs": [], + "source": [ + "def create_task(_redfishobj, firmware_loc, tpm_flag=True):\n", + "\n", + " session_key = _redfishobj.session_key\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " updatable_by = ['Uefi']\n", + " task_path = '/redfish/v1/UpdateService/UpdateTaskQueue/'\n", + " file_name = os.path.basename(firmware_loc)\n", + "\n", + " task_resp = _redfishobj.get(task_path)\n", + " if not task_resp.obj[\"Members@odata.count\"]:\n", + " print (\"No current tasks, proceed to create new task\")\n", + "\n", + "\n", + " update_task = {'Name': 'Update-%s-%s' % (str(randint(0, 1000000)), \\\n", + " file_name), 'Command': 'ApplyUpdate',\\\n", + " 'Filename': file_name, 'UpdatableBy': updatable_by, 'TPMOverride': tpm_flag}\n", + "\n", + " resp = _redfishobj.post(task_path, update_task, headers=header)\n", + " #print (resp)\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to create update task queue...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Task Queue Creation complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "bcac4f85", + "metadata": {}, + "source": [ + "
      \n", + "

      4.

      \n", + " The Main function:
      PLEASE PROVIDE THE FOLLOWING CREDENTIALS HERE TO PROCEED FURTHER

      \n", + "
        \n", + "
      • The path to the firmware file to upload (-c/--component)
      • \n", + "
      • The iLO IP of the server (-i/--ilo)
      • \n", + "
      • The iLO username to login (-u/--user)
      • \n", + "
      • The iLO password to log in (-p/--password)
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-c',\n", + " '--component',\n", + " dest='comp_path',\n", + " action=\"store\",\n", + " required=True,\n", + " help=\"The path to the firmware file to upload\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-s',\n", + " '--session_key',\n", + " dest='session_key',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"Http session key for the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # Upload the firmware file to the iLO Repository\n", + " update_repo_flag = True\n", + " # Update the system with the firmware file\n", + " update_target_flag = False\n", + "\n", + " comp_type = 'C'\n", + " tpm_flag = True\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + " #system_url = \"https://\" + \"15.146.46.49\"\n", + " #session_id = \"515b196969f7d879886ee4a2da4ccba8\"\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " if options.session_key:\n", + " redfish_obj = RedfishClient(base_url=system_url, session_key= options.session_key)\n", + " else:\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(redfish_obj, options.comp_path, comp_type, update_repo_flag, update_target_flag)\n", + " if comp_type == 'C':\n", + " create_task(redfish_obj, options.comp_path, tpm_flag)\n", + "\n", + " redfish_obj.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/nic_network/find_ilo_mac_address.ipynb b/example_jupyter_notebooks/nic_network/find_ilo_mac_address.ipynb new file mode 100644 index 0000000..cfd4a78 --- /dev/null +++ b/example_jupyter_notebooks/nic_network/find_ilo_mac_address.ipynb @@ -0,0 +1,228 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "# Finding iLo Mac address" + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to find_ilo_mac_address!!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
      \n", + "

      This is our find_ilo_mac_address function overview, in the end this will give us about finding ilo mac address related information.

      \n", + "

      Let me give you a walk through of it!

      \n", + "
        \n", + "
      1. For the identification of a device, its mac address is very much required. If you have the Systems Management Homepage installed, you can find out by clicking \"Management Processor\" and then check the Physical Address field.
      2. \n", + "
      3. If we don't have a resource directory, information about the ethernet data is stored inside the managers json object. Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.
      4. \n", + "
      5. Ethernet interface gives the response for that member about the ilo mac address
      6. \n", + "
      7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the ethernet interface is present in @odata.type attribute then we will store information about ethernet interface in ethernet_data dictionary and break out of iteration.
      8. \n", + "
      9. Finally, we get iLo Network Manager Interface and iLO Mac Address as output.
      10. \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def find_ilo_mac_address(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " for iface in ethernet_data:\n", + " sys.stdout.write(\"iLO Network Manager Interface: \\'%s\\'\\n\" % ethernet_data[iface]['Id'])\n", + " sys.stdout.write(\"\\tiLO Mac Address: \\'%s\\'\\n\" % ethernet_data[iface].get('MACAddress'))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
      \n", + "

      3.

      The Main function:
      PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + "
        \n", + "
      • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
      • \n", + "
      • If server is down or Unreachable we get \"server not reachable\" message!
      • \n", + "
      • and Once everything is done you are automatically logged out with .logout() 😁.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " find_ilo_mac_address(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/nic_network/set_active_ilo_nic.ipynb b/example_jupyter_notebooks/nic_network/set_active_ilo_nic.ipynb new file mode 100644 index 0000000..e0299c5 --- /dev/null +++ b/example_jupyter_notebooks/nic_network/set_active_ilo_nic.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Setting the active Manager NIC

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of setting the active Manager NIC
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about set_active_ilo_nic function

      \n", + " \n", + "\n", + "1. This function is used to enable/disable Ethernet interfaces on an iLO (Integrated Lights Out) management interface.
      \n", + "
      \n", + " \n", + "2. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
      \n", + "
      \n", + "\n", + "3. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
      \n", + "
      \n", + "\n", + "4. If the PATCH request is successful (HTTP status 200), the function prints a success message and the response body, which contains information about the updated Ethernet interface.
      \n", + "
      \n", + "5. Finally, the function reminds the user that they need to reset iLO for the change to take effect.
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def set_active_ilo_nic(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " for interface in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Management Inteface \\'%s\\'\\n\" % ethernet_data\\\n", + " [interface].get('Id'))\n", + " sys.stdout.write(\"\\t\\'Interface Enabled\\': %s\\n\" % ethernet_data[interface].\\\n", + " get('InterfaceEnabled'))\n", + "\n", + " for ethernet in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Interface: %s\\n\" % ethernet)\n", + " ans = input(\"Would you like to enable/disable this interface? (enable/disable)\\n\")\n", + " if \"en\" in ans:\n", + " body = {\"InterfaceEnabled\": True}\n", + " else:\n", + " body = {\"InterfaceEnabled\": False}\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! You will need to reset iLO for this change to take effect.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_active_ilo_nic(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "316c3f0e", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/ntp_timezone/enabling_ntp_server.ipynb b/example_jupyter_notebooks/ntp_timezone/enabling_ntp_server.ipynb new file mode 100644 index 0000000..656cc07 --- /dev/null +++ b/example_jupyter_notebooks/ntp_timezone/enabling_ntp_server.ipynb @@ -0,0 +1,309 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# ENABLING NTP SERVER " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is the example to enable ntp servers .
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "

      2

      \n", + "Below function describes the process how to enable NTP servers for HPE ilo systems. NTP or Network Time Protocol is an internet protocol used to synchronize with computer clokc time sources in a network. \n", + "Current cell is the explains the processes performed inside the below function.\n", + "
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. Initially, to obtain NTP server related information for HPE ilo systems a series of HTTP GET requests are being made so as to navigate to that path inside the iLO rest api where required information is stored.\n", + "After completion of these get requests we will be having the relevant uri in manager_ethernet_interfaces_members.\n", + "
      \n", + "2. Else if resource directory is enabled we can just use the resource directory to and then again navigate through the api to find relevant uri.\n", + "
      \n", + " \n", + "3. Whatever changes need to be made to enable the NTP server are being enclosed inside the dictionary named as body. Next up for all the instances of ethernet in ethernet_data we simply make a HTTP PATCH request by passing the ethernet instance and body dictionary with the PATCH request. \n", + " \n", + "\n", + "4. Following the patch request, the response returned by server is being saved inside resp variable and later if the server returns proper response it means there is no error else error is returned with error information. A reference for json.dumps\n", + "function as it is used multiple times - click here.\n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def enable_ntp(_redfishobj, ntp_servers, DISABLE_RESOURCE_DIR):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " print(json.dumps(ethernet_data, indent=4, sort_keys=True))\n", + "\n", + " body = {\"Oem\": {\"Hpe\": {\"DHCPv4\": {\"UseNTPServers\": ntp_servers}, \\\n", + " \"DHCPv6\": {\"UseNTPServers\": ntp_servers}}}}\n", + " for ethernet in ethernet_data:\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " _data = _redfishobj.get(ethernet).dict\n", + " sys.stdout.write(\"\\nShowing \\'%s\\' interface after changes:\\n\" % ethernet)\n", + " print(json.dumps(_data, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + "

      3

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + " \n", + "
      • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to enable_ntp function by passing parameters such as redfishclient object and enable flag to perform required operation.
      • \n", + "
      • After getting required information Redfish.logout() closes the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'ilorest'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mgetpass\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m redfish_client\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mredfish_object\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RedfishClient\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mexceptions\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ServerDownOrUnreachableError\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'ilorest'" + ] + } + ], + "source": [ + "import getpass\n", + "from ilorest import redfish_client\n", + "from ilorest.redfish_object import RedfishClient\n", + "from ilorest.exceptions import ServerDownOrUnreachableError\n", + "\n", + "def main():\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n", + "if __name__ == \"__main__\":\n", + " main()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb b/example_jupyter_notebooks/security_certificate/enable_secure_boot.ipynb similarity index 100% rename from examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb rename to example_jupyter_notebooks/security_certificate/enable_secure_boot.ipynb diff --git a/example_jupyter_notebooks/security_certificate/generate_csr.ipynb b/example_jupyter_notebooks/security_certificate/generate_csr.ipynb new file mode 100644 index 0000000..83a9be5 --- /dev/null +++ b/example_jupyter_notebooks/security_certificate/generate_csr.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "042acf39", + "metadata": { + "tags": [] + }, + "source": [ + "# Generating a certificate signing request for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "7b34599c", + "metadata": {}, + "source": [ + "
      \n", + "Hello there.!
      Welcome to python-iLOrest-library
      Here is an example to generate_csr!!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "e7338dfb", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c9837f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "034daf66", + "metadata": {}, + "source": [ + "
      \n", + "

      2.

      This is our generate csr function overview, in the end we will be able to make a certificate signing request.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the generate_csr function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about Http certificates is stored inside the managers json object.\n", + " And now through managers_response variable, we are making a http GET operation to and trying to obtain the certificates of signing of iLO system.\n", + "
      \n", + "\n", + "3. In the system managers members response object with different odata_id we get a security service uri .\n", + " Then again an http GET request is made and response is stored in security_service_response.\n", + " Then we will make a http_cert_response by using csr_uri through security_service_response and then using http_cert_response we will get generate_csr_uri.\n", + "
      \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeHttpsCert attribute is present in @odata.type attribute then we'll set csr_uri and get generate csr uri of the target.\n", + "
      \n", + "\n", + "5. If generate_csr_uri exists, then we will define the body and send a post request through redfish object. After generating the csr, we can obtain the csr_response using get method for csr_uri. csr_response contains CertificateSigningRequest. \n", + "\n", + "
      \n", + "6. If you get the result, then it is successful. if you don't get the result, then there is an error.\n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "644bd708", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_csr(_redfishobj, csr_file, csr_properties):\n", + "\n", + " csr_uri = None\n", + " generate_csr_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " csr_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", + " https_cert_response = _redfishobj.get(csr_uri)\n", + " generate_csr_uri = https_cert_response.obj['Actions']['#HpeHttpsCert.GenerateCSR']\\\n", + " ['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeHttpsCert.' in instance['@odata.type']:\n", + " csr_uri = instance['@odata.id']\n", + " generate_csr_uri = _redfishobj.get(csr_uri).obj['Actions']\\\n", + " ['#HpeHttpsCert.GenerateCSR']['target']\n", + " break\n", + "\n", + " if generate_csr_uri:\n", + " body = dict()\n", + " body[\"Action\"] = \"HpeHttpsCert.GenerateCSR\"\n", + " body[\"City\"] = csr_properties[\"City\"]\n", + " body[\"CommonName\"] = csr_properties[\"CommonName\"]\n", + " body[\"Country\"] = csr_properties[\"Country\"]\n", + " body[\"OrgName\"] = csr_properties[\"OrgName\"]\n", + " body[\"OrgUnit\"] = csr_properties[\"OrgUnit\"]\n", + " body[\"State\"] = csr_properties[\"State\"]\n", + " resp = _redfishobj.post(generate_csr_uri, body)\n", + " if resp.status in [200, 201]:\n", + " sys.stdout.write(\"Generating CSR, this may take a few minutes\\n\")\n", + " sys.stdout.write(\"Sleeping for 5 minutes...\\n\")\n", + " time.sleep(600)\n", + " csr_resp = _redfishobj.get(csr_uri).dict['CertificateSigningRequest']\n", + " with open(csr_file, 'wb') as csroutput:\n", + " csroutput.write(csr_resp)\n", + " sys.stdout.write(\"CSR Data saved to file: '%s'\\n\" % csr_file)\n", + " else:\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", + " #info error message to see what went wrong\n", + " if resp.status not in [200, 201]:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2da11ba0", + "metadata": {}, + "source": [ + "
      \n", + "

      3.

      This is Main function overview.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + " Enter your ilo url,Username,Password here.
      \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call generate_csr with our redfish object.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46b3e899", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = input(\"Enter password: \")\n", + "\n", + " #CSR Dictionary, each value should be updated to reflect the desired CSR\n", + " CSR_DICT = {\"City\" : input(\"Enter city:\"), \"CommonName\": input(\"Enter name:\"), \"Country\": input(\"Enter country :\"), \\\n", + " \"OrgName\": input(\"Enter organization :\"), \"OrgUnit\": input(\"Enter unit :\"), \"State\": input(\"Enter state:\")}\n", + "\n", + " #After CSR is generated, a file will be created and the CSR will be downloaded\n", + " CSR_FILE = \"csr.txt\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " generate_csr(REDFISHOBJ, CSR_FILE, CSR_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "06934cbc", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "12c33902", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/users_and_sessions/sessions.ipynb b/example_jupyter_notebooks/users_and_sessions/sessions.ipynb new file mode 100644 index 0000000..fc1f0bb --- /dev/null +++ b/example_jupyter_notebooks/users_and_sessions/sessions.ipynb @@ -0,0 +1,252 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Manually Managing Sessions With Redfish

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of manually managing sessions with Redfish
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from six.moves import urllib\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is about sessions function

      \n", + " \n", + "1. This function creates a new session with an iLO server using provided login credentials..
      \n", + "
      \n", + " \n", + "2. The function sends a POST request to the /redfish/v1/Sessions endpoint to create the session..
      \n", + "
      \n", + "\n", + "3. If the session is created successfully (response code 201), the function prints the session URI and X-Auth Token key..
      \n", + "
      \n", + "\n", + "4. The function also sends a DELETE request to the session URI to terminate the session.
      \n", + "
      \n", + "5. If the session creation fails, the function prints an error message and tries to access the iLO Extended Message Info for more details..
      \n", + " \n", + "\n", + "\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def sessions(_redfishobj, login_account, login_password):\n", + "\n", + " new_session = {\"UserName\": login_account, \"Password\": login_password}\n", + " response = _redfishobj.post('/redfish/v1/Sessions', new_session)\n", + "\n", + " if response.status == 201:\n", + " print(\"Success!\\n\")\n", + " session_uri = response.getheader(\"location\")\n", + " session_uri = urllib.parse.urlparse(session_uri)\n", + " sys.stdout.write(\"\\tSession \" + session_uri.path + \" created.\\n\")\n", + " x_auth_token = response.getheader(\"x-auth-token\")\n", + " sys.stdout.write(\"\\tThis is the session X-Auth Token key \" + x_auth_token + \".\\n\")\n", + " print(json.dumps(response.dict, indent=4, sort_keys=True))\n", + "\n", + " # Delete the created session\n", + " sys.stdout.write(\"\\tTerminating this session.\\n\")\n", + " sessresp = _redfishobj.delete(session_uri.path)\n", + " print(json.dumps(sessresp.dict, indent=4, sort_keys=True))\n", + " else:\n", + " sys.stderr.write(\"ERROR: failed to create a session.\\n\")\n", + " try:\n", + " print(json.dumps(sessresp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended\"\n", + " \" Message Info...\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " sessions(REDFISHOBJ, LOGIN_ACCOUNT, LOGIN_PASSWORD)#calling sessions function" + ] + }, + { + "cell_type": "markdown", + "id": "316c3f0e", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/virtual_media/eject_virtual_media_iso.ipynb b/example_jupyter_notebooks/virtual_media/eject_virtual_media_iso.ipynb new file mode 100644 index 0000000..9556027 --- /dev/null +++ b/example_jupyter_notebooks/virtual_media/eject_virtual_media_iso.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "45dd47a5", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of mounting virtual media for HPE iLO systems
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "23eeb2bf", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92ec68a2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "10a8e977", + "metadata": {}, + "source": [ + "

      2.

      This is our mount_virtual_media_iso function overview, in the end this will give us with virtual media related information.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the virtual media information.\n", + "\n", + "1. In the mount_virtual_media_iso function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about virtual media is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The virtual media information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if virtual media is present in @odata.type attribute then we will store information about virtual media in virtual_media_uri and break out of iteration.\n", + "
      \n", + "\n", + "Ultimately if virtual_media_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f034ef9c", + "metadata": {}, + "outputs": [], + "source": [ + "def mount_virtual_media_iso(_redfishobj, media_type,):\n", + "\n", + " virtual_media_uri = None\n", + " virtual_media_response = []\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", + " virtual_media_uri = instance['@odata.id']\n", + "\n", + " if virtual_media_uri:\n", + " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", + " for virtual_media_slot in virtual_media_response.obj['Members']:\n", + " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", + " if media_type in data.dict['MediaTypes']:\n", + " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.EjectMedia']['target']\n", + " post_body = {\"Action\": \"HpeiLOVirtualMedia.EjectVirtualMedia\"}\n", + " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "268b5a18", + "metadata": {}, + "source": [ + "

      3.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab494baf", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 25\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 26\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 27\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 31\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 30\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 31\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 32\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 33\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " \n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #specify the type of content the media represents\n", + " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + "\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " mount_virtual_media_iso(REDFISHOBJ, MEDIA_TYPE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "90621a8a", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a839daaa", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + " \n", + "
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb new file mode 100644 index 0000000..3bcdf99 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b44c9aad", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of enabling secure boot
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "74ee46a2", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below
      \n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3b9ca27", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "d0e073c6", + "metadata": {}, + "source": [ + "

      2.

      This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", + "\n", + "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", + " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", + "
      \n", + "\n", + "3. In the systems response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in systems_members_response.\n", + " The secure boot information is ultimately present in the systems_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", + "
      \n", + "\n", + "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d60549e", + "metadata": {}, + "outputs": [], + "source": [ + "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", + "\n", + " secure_boot_uri = None\n", + " secure_boot_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#SecureBoot.' in instance['@odata.type']:\n", + " secure_boot_uri = instance['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + "\n", + " if secure_boot_data:\n", + " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if secure_boot_uri:\n", + " body = {'SecureBootEnable': secure_boot_enable}\n", + " resp = _redfishobj.patch(secure_boot_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b227f8f6", + "metadata": {}, + "source": [ + "
      \n", + "

      The Main function:

      \n", + "

      Please enter your login credentials here to proceed further:

      \n", + "
        \n", + "
      • Once your credentials are entered, a Redfish object is created with the help of the RedfishClient class, and a session is created to log you in to the server.
      • \n", + "
      • If the server is down or unreachable, we get a \"server not reachable\" message.
      • \n", + "
      • If not, we make a call to the enable_secure_boot function to obtain secure boot-related information of the system.
      • \n", + "
      • After getting the required information, Redfish.logout() closes the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8028b4ff", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Properties:\n", + " #secure boot enable property\n", + " SECURE_BOOT_ENABLE = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "28cb201c", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cf8a164b", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 97888a5fcadd0fee338caedda287bb7c6c804a32 Mon Sep 17 00:00:00 2001 From: Rajeevalochana Kallur Date: Fri, 12 May 2023 16:45:25 +0530 Subject: [PATCH 036/159] Create test.txt --- example_jupyter_notebooks/smartarray_storage/test.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 example_jupyter_notebooks/smartarray_storage/test.txt diff --git a/example_jupyter_notebooks/smartarray_storage/test.txt b/example_jupyter_notebooks/smartarray_storage/test.txt new file mode 100644 index 0000000..e69de29 From a00157e8902f76d072fc65137f1ade7cb93455c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 May 2023 16:47:31 +0530 Subject: [PATCH 037/159] added 4 more scripts --- .../.ipynb_checkpoints/index-checkpoint.ipynb | 81 ++- .../Test_ESKM_Connection-checkpoint.ipynb | 272 ++++++++++ .../Bhuvan/ESKM/Test_ESKM_Connection.ipynb | 272 ++++++++++ .../Update_iLO_Firmware-checkpoint.ipynb | 279 ++++++++++ ...epository_with_COMPSIG.py-checkpoint.ipynb | 293 ++++++++++ ...irmware_to_iLO_repository-checkpoint.ipynb | 283 ++++++++++ .../Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb | 279 ++++++++++ ...mware_iLO_Repository_with_COMPSIG.py.ipynb | 293 ++++++++++ .../Upload_firmware_to_iLO_repository.ipynb | 283 ++++++++++ .../Bhuvan/USERS/Add_user_account.ipynb | 504 ++++++++++++++++++ .../HPECTY/Bhuvan/index.ipynb | 81 ++- 11 files changed, 2918 insertions(+), 2 deletions(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb index 2f001ea..8fb312c 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb @@ -119,10 +119,89 @@ "\n" ] }, + { + "cell_type": "markdown", + "id": "2a39acd4", + "metadata": {}, + "source": [ + "

      Scripts related to Firmware

      " + ] + }, + { + "cell_type": "markdown", + "id": "a7f7d0e2", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Upload Firmware to iLO repositoryScript for uploading firmware to the iLO Repository for flashingUpload_Firmware_to_iLO_repo
      Upload Firmware with associated COMPSIG file to iLO repositoryScript for uploading a firmware component with a size less than\n", + "32 GB, and associated Component Signature (compsig) signature file to the iLO RepositoryUpload_Firmware_iLO_Repo_with_COMPSIG
      Update FirmwareScript for updating Firmware via HTTP URLUpdate_iLO_Firmware
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "a224da35", + "metadata": {}, + "source": [ + "

      Scripts related to ESKM (Enterprise Secure Key Manager)

      " + ] + }, + { + "cell_type": "markdown", + "id": "b44242b9", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Test ESKM ConnectionScript for testing connection to the ESKM system for HPE iLO systemsTest_ESKM_Connection
      \n" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "0cdb7878", + "id": "7e5e8be8", "metadata": {}, "outputs": [], "source": [] diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb new file mode 100644 index 0000000..94f9df5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb @@ -0,0 +1,272 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "17caee10", + "metadata": {}, + "source": [ + "

      Test ESKM Connection

      " + ] + }, + { + "cell_type": "markdown", + "id": "8ca92dce", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contain script for testing connection to the ESKM (Enterprise Secure Key Manager) system for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "d5c69ec2", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "149adcfa", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "c74f9b37", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our test_ESKM_connection function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The test_ESKM_connection_ilo_firmware function takes one parameter - _redfishobj.\n", + "
      \n", + " \n", + "2. Initialize the eskm_uri and body variables to None and an empty dictionary, respectively.\n", + "
      \n", + "\n", + "3. Call the get_resource_directory() function by passing _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or disabled, find the relevant URI by navigating through the server's API.\n", + "
      \n", + "\n", + "4. If the resource directory is available, find the relevant URI from the resource directory.\n", + "
      \n", + "\n", + "5. Check if eskm_uri has been set. If eskm_uri is not None, retrieve the URI for the ESKM service.\n", + "
      \n", + "\n", + "6. If the ESKM URI is available, retrieve the URI for testing the ESKM connection from the response.\n", + "
      \n", + "\n", + "7. Set the Action field of the body dictionary to \"HpeESKM.TestESKMConnections\".\n", + "
      \n", + " \n", + "8. Call the post() method of the _redfishobj object with the ESKM test connection URI and the body dictionary as parameters.\n", + "
      \n", + " \n", + "9. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the JSON-formatted response.\n", + "
      \n", + " \n", + " \n", + "10. If eskm_uri is None, print an error message.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96ac0e95", + "metadata": {}, + "outputs": [], + "source": [ + "def test_ESKM_connection(_redfishobj):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + "\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " eskm_test_conn_uri = _redfishobj.get(eskm_uri).obj['Actions']['#HpeESKM.TestESKMConnections']['target']\n", + " body[\"Action\"] = \"HpeESKM.TestESKMConnections\"\n", + " resp = _redfishobj.post(eskm_test_conn_uri, body)\n", + " #If iLO responds with something outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "beb17e66", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to test connection to ESKM Systems.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "5. Then we call test_ESKM_connection with our redfish object as parameter.

      \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "571dd05d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09b2811e", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " test_ESKM_connection(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "d0cdf874", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbc4710b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb new file mode 100644 index 0000000..94f9df5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb @@ -0,0 +1,272 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "17caee10", + "metadata": {}, + "source": [ + "

      Test ESKM Connection

      " + ] + }, + { + "cell_type": "markdown", + "id": "8ca92dce", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contain script for testing connection to the ESKM (Enterprise Secure Key Manager) system for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "d5c69ec2", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "149adcfa", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "c74f9b37", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our test_ESKM_connection function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The test_ESKM_connection_ilo_firmware function takes one parameter - _redfishobj.\n", + "
      \n", + " \n", + "2. Initialize the eskm_uri and body variables to None and an empty dictionary, respectively.\n", + "
      \n", + "\n", + "3. Call the get_resource_directory() function by passing _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or disabled, find the relevant URI by navigating through the server's API.\n", + "
      \n", + "\n", + "4. If the resource directory is available, find the relevant URI from the resource directory.\n", + "
      \n", + "\n", + "5. Check if eskm_uri has been set. If eskm_uri is not None, retrieve the URI for the ESKM service.\n", + "
      \n", + "\n", + "6. If the ESKM URI is available, retrieve the URI for testing the ESKM connection from the response.\n", + "
      \n", + "\n", + "7. Set the Action field of the body dictionary to \"HpeESKM.TestESKMConnections\".\n", + "
      \n", + " \n", + "8. Call the post() method of the _redfishobj object with the ESKM test connection URI and the body dictionary as parameters.\n", + "
      \n", + " \n", + "9. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the JSON-formatted response.\n", + "
      \n", + " \n", + " \n", + "10. If eskm_uri is None, print an error message.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96ac0e95", + "metadata": {}, + "outputs": [], + "source": [ + "def test_ESKM_connection(_redfishobj):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + "\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " eskm_test_conn_uri = _redfishobj.get(eskm_uri).obj['Actions']['#HpeESKM.TestESKMConnections']['target']\n", + " body[\"Action\"] = \"HpeESKM.TestESKMConnections\"\n", + " resp = _redfishobj.post(eskm_test_conn_uri, body)\n", + " #If iLO responds with something outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "beb17e66", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to test connection to ESKM Systems.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "5. Then we call test_ESKM_connection with our redfish object as parameter.

      \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "571dd05d", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09b2811e", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " test_ESKM_connection(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "d0cdf874", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbc4710b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb new file mode 100644 index 0000000..bda8be1 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb9e0a5e", + "metadata": {}, + "source": [ + "

      Update Firmware via HTTP URL

      " + ] + }, + { + "cell_type": "markdown", + "id": "1a50e99e", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contain script for updating Firmware via HTTP URL. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3af51f99", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c723fbdf", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_14568/1390777471.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b42060d7", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our update_ilo_firmware function overview, in the end this will update the iLO Firmware.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The update_ilo_firmware function takes three parameters - _redfishobj representing the connection to the server, fw_url representing the firmware update URL, and tpm_flag representing the TPM override flag.\n", + "
      \n", + " \n", + "2.The function initializes the body and update_service_uri variables to None.\n", + "
      \n", + "\n", + "3. The get_resource_directory() function is called by passing the _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, the relevant URI is found by navigating through the server's API. If the resource directory is available, the relevant URI is found from the resource directory.\n", + "
      \n", + "\n", + "4. If update_service_uri and fw_url are not None, the update_uri is retrieved from the server using the get() method and by accessing the Actions attribute.\n", + "
      \n", + "\n", + "5. The body dictionary is updated with the fw_url and tpm_flag if tpm_flag is provided.\n", + "
      \n", + "\n", + "6. The post() method is called on the update_uri with the body dictionary as a parameter. The response is stored in the resp variable.\n", + "
      \n", + "\n", + "\n", + "7. If the HTTP response status code is 400, the iLO extended info error message is printed. If the HTTP response status code is not 200 or 201, an error message is printed. If the HTTP response status code is 200 or 201, a success message is printed along.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59bfcc8a", + "metadata": {}, + "outputs": [], + "source": [ + "def update_ilo_firmware(_redfishobj, fw_url, tpm_flag):\n", + "\n", + " body = dict()\n", + " update_service_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if update_service_uri and fw_url:\n", + " update_uri = _redfishobj.get(update_service_uri).obj['Actions']['#UpdateService.SimpleUpdate']['target']\n", + " body[\"ImageURI\"] = fw_url\n", + " if tpm_flag:\n", + " body[\"TPMOverrideFlag\"] = tpm_flag\n", + " resp = _redfishobj.post(update_uri, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "9bb9670c", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to update the firmware.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call update_ilo_firmware with our redfish object, FIRMWARE_URL and Trusted Platform Module (TPM) Flag as parameters.
      \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + " \n", + "7. When prompted for Firmware URL, enter the firmware file path. Example: \"http://\">

      \n", + " \n", + "8. If a TPM module (Trusted Platform Module / Cryptographic Co-processor) is installed/present onboard then be sure to include this by changing TPM_FLAG variable to True. By default this variable is set to False.
      \n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "82f44947", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98301396", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # firmware file path and filename\n", + " FIRMWARE_URL = input(\"Enter Firmware URL\")\n", + " \n", + " # If a TPM module (Trusted Platform Module/ Cryptographic Co-processor) is installed/present\n", + " # onboard then be sure to include this.\n", + " \n", + " TPM_FLAG = False\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " update_ilo_firmware(REDFISHOBJ, FIRMWARE_URL, TPM_FLAG)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "cce9c778", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44500ca7", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb new file mode 100644 index 0000000..053e56d --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb @@ -0,0 +1,293 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7fdda07e", + "metadata": {}, + "source": [ + "

      Upload Firmware component and associated Component Signature (.comsig) file to iLO repository

      " + ] + }, + { + "cell_type": "markdown", + "id": "d7574d95", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains script for uploading a firmware component with a size less than\n", + "32 GB, and associated compsig signature file to the iLO Repository.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b1692ebb", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a03dc92", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "ce6577f5", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our upload_firmware function overview, in the end this will upload firmware component along with compsig to the iLO Repository.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. This function takes four parameters: _redfishobj which is the Redfish client object, firmware_loc which is the path to the firmware image file, compsig_loc which is the path to the firmware image signature file, update_repo which is a boolean flag to specify whether to update the firmware repository or not, and update_target which is a boolean flag to specify whether to update the target device or not.\n", + "
      \n", + " \n", + "2. Call get_resource_directory() function by passing the _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If the resource directory is available, find the relevant URI from the resource directory.\n", + "
      \n", + "\n", + "3. Then the function retrieves the update service URI from the response of the previous step.\n", + "
      \n", + "\n", + "4. The function reads the firmware and signature files and prepares the data in the required format to upload the firmware using the HttpPushUri. The function builds a list of tuples that contain the session key, json data, firmware file, and firmware signature file.\n", + "
      \n", + "\n", + "5. The function creates a header dictionary containing the session key.\n", + "
      \n", + "\n", + "6. The function passes the list of payload to the _redfishobj.post() method with the HttpPushUri as the path to upload the firmware and signature files.\n", + "
      \n", + "\n", + "\n", + "7. If the HTTP response status code is 400, print an error message indicating that the firmware upload failed with the HTTP response message. If the HTTP response status code is neither 200 nor 201, print an error message indicating that an HTTP response with the status code was returned. If the HTTP response status code is 200 or 201, print a success message indicating that the firmware upload is complete.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53612a22", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, compsig_loc, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + "\n", + " body = []\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " filename = os.path.basename(firmware_loc)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " compsigname = os.path.basename(compsig_loc)\n", + " with open(compsig_loc, 'rb') as cle:\n", + " compsigoutput = cle.read()\n", + "\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + " compsig_tuple = ('compsig', (compsigname, compsigoutput, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(compsig_tuple)\n", + " body.append(file_tuple)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " #We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware... Error: '%s'\\n\" % str(resp))\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "85b41e74", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload new firmware to iLO repository for flashing.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call upload_firmware with our redfish object, FIRMWARE_PATH, COMPSIG_PATH, UPDATE_REPO (set as True) and UPDATE_TARGET (set as False) as parameters.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + " \n", + "7. When prompted for entering Firmware companent path, enter the entire path containing the firmware component.. Example: \"/path/to/cpxxxxxx.exe\"
      The path to the firmware component file to upload. .rpm and .zip component are also valid.

      \n", + " \n", + "8. When prompted for entering compsig path, enter the entire path containing the Component Signature (compsig) file having .compsig extension.. Example: \"/path/to//cpxxxxxx.compsig\"

      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "6ee4ac0a", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17305248", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # The path to the firmware component file to upload.\n", + " # .rpm and .zip component are also valid.\n", + " #\n", + " \n", + " FIRMWARE_PATH = input(\"Enter firmware path \")\n", + " COMPSIG_PATH = input(\"Enter compsig path \")\n", + " # Upload the firmware file to the iLO Repository\n", + " UPDATE_REPO = True\n", + " # Update the system with the firmware file\n", + " UPDATE_TARGET = False\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(REDFISHOBJ, FIRMWARE_PATH, COMPSIG_PATH, UPDATE_REPO, UPDATE_TARGET)\n", + "\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "cacde035", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a6bfbe3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb new file mode 100644 index 0000000..53fc8e1 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb9e0a5e", + "metadata": {}, + "source": [ + "

      Upload Firmware to iLO repository for flashing

      " + ] + }, + { + "cell_type": "markdown", + "id": "1ab478ee", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains script for uploading Firmware to iLO repository for flashing. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "183ac248", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7bede674", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "5b72b845", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our upload_firmware function overview, in the end this will upload firmware to the iLO Repository for flashing.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload the firmware.
      \n", + "\n", + "1. The function takes three parameters as input: _redfishobj, firmware_loc, update_repo, and update_target.\n", + "
      \n", + " \n", + "2. It calls the get_resource_directory() function by passing the _redfishobj parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, it finds the relevant URI by navigating through the server's API.\n", + "
      \n", + "\n", + "3. If the resource directory is available, it obtains all account instances from the resource directory and then retrieves the URI for the Update Service.\n", + "
      \n", + "\n", + "4. The function then sends an HTTP GET request to the obtained URI to retrieve the HttpPushUri path.\n", + "
      \n", + "\n", + "5. It then reads the firmware file using the open() method and stores its contents in the output variable.\n", + "
      \n", + "\n", + "6. The function builds the payload for the multipart-form data using session key, parameters, and firmware file tuples.\n", + "
      \n", + "\n", + "\n", + "7. It then creates a header dictionary containing the session key and passes the whole payload to the post() method.\n", + "
      \n", + " \n", + "\n", + "8. If the HTTP response status code is not 200 or 201, it prints an error message. If the HTTP response status code is 400, it prints a \"Failed to upload firmware...\" error message. If the HTTP response status code is 200 or 201, it prints a success message.\n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "beb01150", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + "\n", + " body = []\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " filename = os.path.basename(firmware_loc)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(file_tuple)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " #We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "4041fb30", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload new firmware to iLO repository for flashing.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call upload_firmware with our redfish object, FIRMWARE_PATH, UPDATE_REPO (set as True) and UPDATE_TARGET (set as False) as parameters.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + " \n", + "7. When prompted enter the entire path containing the new firmware (.fwpkg). Example: \"C:\\\\Users\\\\oconnogr\\\\git\\\\python-restful-interface-tool\\\\src\\\\ilo5_230_p31.fwpkg\"\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "dbfb1f99", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d3ff3bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # The path to the firmware file to upload\n", + " FIRMWARE_PATH = input(\"Enter entire path containing the Firmware (.fwpkg)\")\n", + " # Upload the firmware file to the iLO Repository\n", + " UPDATE_REPO = True\n", + " # Update the system with the firmware file\n", + " UPDATE_TARGET = False\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(REDFISHOBJ, FIRMWARE_PATH, UPDATE_REPO, UPDATE_TARGET)\n", + "\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "d6d44e9b", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f430b10", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb new file mode 100644 index 0000000..bda8be1 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb9e0a5e", + "metadata": {}, + "source": [ + "

      Update Firmware via HTTP URL

      " + ] + }, + { + "cell_type": "markdown", + "id": "1a50e99e", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contain script for updating Firmware via HTTP URL. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3af51f99", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "c723fbdf", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_14568/1390777471.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b42060d7", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our update_ilo_firmware function overview, in the end this will update the iLO Firmware.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The update_ilo_firmware function takes three parameters - _redfishobj representing the connection to the server, fw_url representing the firmware update URL, and tpm_flag representing the TPM override flag.\n", + "
      \n", + " \n", + "2.The function initializes the body and update_service_uri variables to None.\n", + "
      \n", + "\n", + "3. The get_resource_directory() function is called by passing the _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, the relevant URI is found by navigating through the server's API. If the resource directory is available, the relevant URI is found from the resource directory.\n", + "
      \n", + "\n", + "4. If update_service_uri and fw_url are not None, the update_uri is retrieved from the server using the get() method and by accessing the Actions attribute.\n", + "
      \n", + "\n", + "5. The body dictionary is updated with the fw_url and tpm_flag if tpm_flag is provided.\n", + "
      \n", + "\n", + "6. The post() method is called on the update_uri with the body dictionary as a parameter. The response is stored in the resp variable.\n", + "
      \n", + "\n", + "\n", + "7. If the HTTP response status code is 400, the iLO extended info error message is printed. If the HTTP response status code is not 200 or 201, an error message is printed. If the HTTP response status code is 200 or 201, a success message is printed along.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59bfcc8a", + "metadata": {}, + "outputs": [], + "source": [ + "def update_ilo_firmware(_redfishobj, fw_url, tpm_flag):\n", + "\n", + " body = dict()\n", + " update_service_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if update_service_uri and fw_url:\n", + " update_uri = _redfishobj.get(update_service_uri).obj['Actions']['#UpdateService.SimpleUpdate']['target']\n", + " body[\"ImageURI\"] = fw_url\n", + " if tpm_flag:\n", + " body[\"TPMOverrideFlag\"] = tpm_flag\n", + " resp = _redfishobj.post(update_uri, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "9bb9670c", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to update the firmware.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call update_ilo_firmware with our redfish object, FIRMWARE_URL and Trusted Platform Module (TPM) Flag as parameters.
      \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + " \n", + "7. When prompted for Firmware URL, enter the firmware file path. Example: \"http://\">

      \n", + " \n", + "8. If a TPM module (Trusted Platform Module / Cryptographic Co-processor) is installed/present onboard then be sure to include this by changing TPM_FLAG variable to True. By default this variable is set to False.
      \n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "82f44947", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98301396", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # firmware file path and filename\n", + " FIRMWARE_URL = input(\"Enter Firmware URL\")\n", + " \n", + " # If a TPM module (Trusted Platform Module/ Cryptographic Co-processor) is installed/present\n", + " # onboard then be sure to include this.\n", + " \n", + " TPM_FLAG = False\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " update_ilo_firmware(REDFISHOBJ, FIRMWARE_URL, TPM_FLAG)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "cce9c778", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44500ca7", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb new file mode 100644 index 0000000..053e56d --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb @@ -0,0 +1,293 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7fdda07e", + "metadata": {}, + "source": [ + "

      Upload Firmware component and associated Component Signature (.comsig) file to iLO repository

      " + ] + }, + { + "cell_type": "markdown", + "id": "d7574d95", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains script for uploading a firmware component with a size less than\n", + "32 GB, and associated compsig signature file to the iLO Repository.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b1692ebb", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0a03dc92", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "ce6577f5", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our upload_firmware function overview, in the end this will upload firmware component along with compsig to the iLO Repository.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. This function takes four parameters: _redfishobj which is the Redfish client object, firmware_loc which is the path to the firmware image file, compsig_loc which is the path to the firmware image signature file, update_repo which is a boolean flag to specify whether to update the firmware repository or not, and update_target which is a boolean flag to specify whether to update the target device or not.\n", + "
      \n", + " \n", + "2. Call get_resource_directory() function by passing the _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, find the relevant URI by navigating through the server's API. If the resource directory is available, find the relevant URI from the resource directory.\n", + "
      \n", + "\n", + "3. Then the function retrieves the update service URI from the response of the previous step.\n", + "
      \n", + "\n", + "4. The function reads the firmware and signature files and prepares the data in the required format to upload the firmware using the HttpPushUri. The function builds a list of tuples that contain the session key, json data, firmware file, and firmware signature file.\n", + "
      \n", + "\n", + "5. The function creates a header dictionary containing the session key.\n", + "
      \n", + "\n", + "6. The function passes the list of payload to the _redfishobj.post() method with the HttpPushUri as the path to upload the firmware and signature files.\n", + "
      \n", + "\n", + "\n", + "7. If the HTTP response status code is 400, print an error message indicating that the firmware upload failed with the HTTP response message. If the HTTP response status code is neither 200 nor 201, print an error message indicating that an HTTP response with the status code was returned. If the HTTP response status code is 200 or 201, print a success message indicating that the firmware upload is complete.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53612a22", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, compsig_loc, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + "\n", + " body = []\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " filename = os.path.basename(firmware_loc)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " compsigname = os.path.basename(compsig_loc)\n", + " with open(compsig_loc, 'rb') as cle:\n", + " compsigoutput = cle.read()\n", + "\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + " compsig_tuple = ('compsig', (compsigname, compsigoutput, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(compsig_tuple)\n", + " body.append(file_tuple)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " #We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware... Error: '%s'\\n\" % str(resp))\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "85b41e74", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload new firmware to iLO repository for flashing.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call upload_firmware with our redfish object, FIRMWARE_PATH, COMPSIG_PATH, UPDATE_REPO (set as True) and UPDATE_TARGET (set as False) as parameters.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + " \n", + "7. When prompted for entering Firmware companent path, enter the entire path containing the firmware component.. Example: \"/path/to/cpxxxxxx.exe\"
      The path to the firmware component file to upload. .rpm and .zip component are also valid.

      \n", + " \n", + "8. When prompted for entering compsig path, enter the entire path containing the Component Signature (compsig) file having .compsig extension.. Example: \"/path/to//cpxxxxxx.compsig\"

      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "6ee4ac0a", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17305248", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # The path to the firmware component file to upload.\n", + " # .rpm and .zip component are also valid.\n", + " #\n", + " \n", + " FIRMWARE_PATH = input(\"Enter firmware path \")\n", + " COMPSIG_PATH = input(\"Enter compsig path \")\n", + " # Upload the firmware file to the iLO Repository\n", + " UPDATE_REPO = True\n", + " # Update the system with the firmware file\n", + " UPDATE_TARGET = False\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(REDFISHOBJ, FIRMWARE_PATH, COMPSIG_PATH, UPDATE_REPO, UPDATE_TARGET)\n", + "\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "cacde035", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a6bfbe3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb new file mode 100644 index 0000000..358d0cc --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb9e0a5e", + "metadata": {}, + "source": [ + "

      Upload Firmware to iLO repository for flashing

      " + ] + }, + { + "cell_type": "markdown", + "id": "1ab478ee", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contain script for uploading Firmware to iLO repository for flashing. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "183ac248", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7bede674", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "5b72b845", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our upload_firmware function overview, in the end this will upload firmware to the iLO Repository for flashing.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload the firmware.
      \n", + "\n", + "1. The function takes these parameters as input: _redfishobj, firmware_loc, update_repo, and update_target.\n", + "
      \n", + " \n", + "2. It calls the get_resource_directory() function by passing the _redfishobj parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, it finds the relevant URI by navigating through the server's API.\n", + "
      \n", + "\n", + "3. If the resource directory is available, it obtains all account instances from the resource directory and then retrieves the URI for the Update Service.\n", + "
      \n", + "\n", + "4. The function then sends an HTTP GET request to the obtained URI to retrieve the HttpPushUri path.\n", + "
      \n", + "\n", + "5. It then reads the firmware file using the open() method and stores its contents in the output variable.\n", + "
      \n", + "\n", + "6. The function builds the payload for the multipart-form data using session key, parameters, and firmware file tuples.\n", + "
      \n", + "\n", + "\n", + "7. It then creates a header dictionary containing the session key and passes the whole payload to the post() method.\n", + "
      \n", + " \n", + "\n", + "8. If the HTTP response status code is not 200 or 201, it prints an error message. If the HTTP response status code is 400, it prints a \"Failed to upload firmware...\" error message. If the HTTP response status code is 200 or 201, it prints a success message.\n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "beb01150", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + "\n", + " body = []\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " filename = os.path.basename(firmware_loc)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(file_tuple)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " #We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "4041fb30", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload new firmware to iLO repository for flashing.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call upload_firmware with our redfish object, FIRMWARE_PATH, UPDATE_REPO (set as True) and UPDATE_TARGET (set as False) as parameters.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

      \n", + " \n", + "7. When prompted, enter the entire path containing the new firmware (.fwpkg). Example: \"C:\\\\Users\\\\oconnogr\\\\git\\\\python-restful-interface-tool\\\\src\\\\ilo5_230_p31.fwpkg\"\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "dbfb1f99", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d3ff3bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " # The path to the firmware file to upload\n", + " FIRMWARE_PATH = input(\"Enter entire path containing the Firmware (.fwpkg)\")\n", + " # Upload the firmware file to the iLO Repository\n", + " UPDATE_REPO = True\n", + " # Update the system with the firmware file\n", + " UPDATE_TARGET = False\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(REDFISHOBJ, FIRMWARE_PATH, UPDATE_REPO, UPDATE_TARGET)\n", + "\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "d6d44e9b", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f430b10", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb new file mode 100644 index 0000000..e93595e --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb @@ -0,0 +1,504 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

      Add new user account by iLO privileges or redfish standard roles

      " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will help you to add new user account by iLO privileges or redfish standard roles. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy.
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen\n", + "\n", + "#to take password inputs securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "613446a1", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our add_ilo_user_account function overview, in the end this will add new iLO user account. This function will be called only if the generation of iLO is not 4.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to add new iLO user account.
      \n", + "\n", + "1. This function takes in six parameters: _redfishobj, new_loginname, new_username, new_password, role_id, and privilege_dict.\n", + "
      \n", + " \n", + "2. The function first calls the get_resource_directory() function by passing _redfishobj as the parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, it finds the relevant URI by navigating through the server's API.\n", + "
      \n", + "\n", + "3. If the resource directory is available, the function obtains all the account instances from the resource directory and sets the account_collection_uri. If it's an HPE server, it sets the body dictionary with the privileges passed in privilege_dict parameter.\n", + "
      \n", + "\n", + "4. The function then fills the body dictionary with the necessary details like new_username, new_password, and RoleId/Oem depending on the type of server.\n", + "
      \n", + "\n", + "5. The function then sends a POST command by passing the account_collection_uri and body dictionary as the parameters to create a new user account.\n", + "
      \n", + "\n", + "6. If the iLO server responds with an HTTP status code outside of 200 or 201, the function prints an error message. If the HTTP response status code is 400, it prints the iLO extended info error message. If the HTTP response status code is 200 or 201, it prints a success message and the newly created user account details in JSON format.\n", + " \n", + "
      \n", + "\n", + "7. If bios_boot_uri is None, print an error message.\n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea197a20", + "metadata": {}, + "outputs": [], + "source": [ + "def add_ilo_user_account(_redfishobj, new_loginname, new_username, new_password, role_id, privilege_dict):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " #Add via role id\n", + " body = {\"RoleId\": role_id}\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " body = {\"Oem\": {\"Hpe\": {\"Privileges\": {}}}}\n", + " #HPE server, so add via privileges\n", + " for priv in privilege_dict:\n", + " body[\"Oem\"][\"Hpe\"][\"Privileges\"][priv] = privilege_dict[priv]\n", + " #Add login name\n", + " body[\"Oem\"][\"Hpe\"][\"LoginName\"] = new_loginname\n", + "\n", + " #Fill in the rest of the payload\n", + " body[\"UserName\"] = new_username\n", + " body[\"Password\"] = new_password\n", + "\n", + " #We pass the URI and the dictionary as a POST command (part of the redfish object)\n", + " resp = _redfishobj.post(account_collection_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "94f279a6", + "metadata": {}, + "source": [ + "
      \n", + "

      This function adds a new iLO user account in the HPE Gen9 server or having iLO generation 4 servers.


      \n", + " \n", + " \n", + "1. The function takes _redfishobj, new_loginname, new_username, and new_password as input parameters..\n", + "
      \n", + " \n", + "2. The account collection URI for the HPE Gen9 server is initialized as /redfish/v1/AccountService/Accounts/.\n", + "
      \n", + "\n", + "3. The privilege dictionary for the HPE Gen9 server is constructed in the body variable. The privileges are specified for the iLO user account to be added. The login name is also added.\n", + "
      \n", + "\n", + "4. The username and password for the iLO user account to be added are added to the body dictionary.\n", + "
      \n", + "\n", + "5. The POST command is passed to _redfishobj to add the iLO user account using the account_collection_uri and body dictionary.\n", + "
      \n", + "\n", + "6. If the HTTP response status code is 200 or 201, the newly created user account details are printed using json.dumps().\n", + " \n", + "
      \n", + "\n", + "7. If the HTTP response status code is not 200 or 201, an error message is printed using sys.stderr.write().\n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc44c03c", + "metadata": {}, + "outputs": [], + "source": [ + "def add_ilo_user_account_gen9(_redfishobj, new_loginname, new_username, new_password):\n", + "\n", + " account_collection_uri = \"/redfish/v1/AccountService/Accounts/\"\n", + " #Add via gen9 priv dic\n", + " body = {'Oem': {'Hp': {'Privileges': {\"LoginPriv\": True, \"RemoteConsolePriv\": True,\n", + " \"UserConfigPriv\": True, \"VirtualMediaPriv\": True, \"VirtualPowerAndResetPriv\": True,\n", + " \"iLOConfigPriv\": True}, 'LoginName': new_loginname}},'UserName': new_username, 'Password': new_password}\n", + " #We pass the URI and the dictionary as a POST command (part of the redfish object)\n", + " resp = _redfishobj.post(account_collection_uri, body)\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to add new user.\n", + " \n", + "\n", + " 1. The follwoing Main function prompts to take SYSTEM_URL, LOGIN_ACCOUNT, LOGIN_PASSWORD, ACCOUNT_LOGIN_NAME, ACCOUNT_USER_NAME, ACCOUNT_PASSWORD, ROLE_ID and PRIVILAGES as inputs.
      \n", + "
      \n", + " \n", + " \n", + " 2. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + " 3. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object. If users want to use create RedfishClient using \"certificate\" for authentication (which is optional), they can do so by uncommenting the lines ca_cert_data, ca_cert_data, ca_cert_data,ca_cert_data and providing their values.
      \n", + "
      \n", + " \n", + " 4. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + " \n", + " 5. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " 6. Then we call add_ilo_user_account or add_ilo_user_account_gen9 based on the generation of iLO by pssing appropriate as parameters to those functions.
      \n", + " \n", + " \n", + " 7. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally, use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
      \n", + "
      Instructions
      \n", + "
        \n", + "
      • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
      • \n", + "
      • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
      • \n", + "
      • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
      • \n", + "
      • For more clarification on the above points please visit iLO Users Documentation
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "39d4c0f0", + "metadata": {}, + "source": [ + "
      \n", + "
      Roles and Privileges
      \n", + "

      iLO uses a set of privileges assigned to each user account to grant and restrict access to features. iLO 6’s privileges are:


      \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      RedfishiLO Web Interface (GUI)
      LoginPrivLogin
      RemoteConsolePrivRemote Console
      VirtualPowerAndResetPrivVirtual Power and Reset
      VirtualMediaPrivVirtual Media
      HostBIOSConfigPrivHost BIOS
      iLOConfigPrivConfigure iLO Settings
      UserConfigPrivAdminister User Accounts
      HostNICConfigPrivHost NIC
      HostStorageConfigPrivHost Storage
      SystemRecoveryConfigPrivRecovery Set
      \n", + "\n", + "
      Roles
      \n", + "

      You can use RoleId to create users with specific starting privileges.
      \n", + "On a GET of the local user account, RoleId is synthesized based upon the enabled privileges. iLO 6 does not store a separate RoleId value. For this reason, modifications to raw privileges may or may not result in a changed RoleId based upon iLO’s mapping.
      \n", + "If the PATCH includes both RoleID and individual privileges, the privileges corresponding to the RoleId are assigned to the local user account first, and then the explicit privileges are assigned.

      \n", + "\n", + "
      Privileges granted on Local Account Creation by RoleId
      \n", + "
      \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      RoleIdPrivileges
      AdministratorHostBIOSConfigPriv, HostNICConfigPriv, HostStorageConfigPriv, LoginPriv, RemoteConsolePriv, UserConfigPriv, VirtualMediaPriv, VirtualPowerAndResetPriv, iLOConfigPriv
      OperatorHostBIOSConfigPriv, HostNICConfigPriv, HostStorageConfigPriv, LoginPriv, RemoteConsolePriv, VirtualMediaPriv, VirtualPowerAndResetPriv
      ReadOnlyLoginPriv
      \n", + "\n", + "\n", + "
      RoleId shown on an existing Local User Account by Privilege
      \n", + "

      The RoleId reported is the smallest superset of assigned privileges.

      \n", + "
      \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      PrivilegesRoleId
      LoginPriv onlyReadOnly
      iLOConfigPriv or UserConfigPriv or SystemRecoveryConfigPriv and anything elseAdministrator
      any other combinationOperator
      \n", + "\n", + " \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b99181a4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter System URL: f\n", + "Enter Login account: f\n", + "Enter your password: ········\n", + "Enter Account Login Name: f\n", + "Enter Account User Name: f\n", + "Enter Account password: ········\n", + "Enter ROLE_ID: f\n", + "For the below privilages enter 'True' if that privilages needs to be set for the user else enter 'False'\n", + "Truef\n", + "Truef\n", + "Truef\n", + "Truef\n" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " #account login name (iLO GUI actually considers this to be 'UserName', but\n", + " #this is the redfish standard username)\n", + " ACCOUNT_LOGIN_NAME = input(\"Enter Account Login Name: \")\n", + "\n", + " #account user name (iLO GUI actually considers this to be 'LoginName', but\n", + " #this is the redfish login)\n", + " ACCOUNT_USER_NAME = input(\"Enter Account User Name: \")\n", + "\n", + " #account password\n", + " ACCOUNT_PASSWORD = getpass.getpass(\"Enter Account password: \")\n", + "\n", + " #A predefined role for the user, (The redfish standard method for accounts).\n", + " #This is a translated to a pre-configured arrangement of privileges on HPE servers\n", + " ROLE_ID = input(\"Enter ROLE_ID: \") #Administrator, ReadOnly or Operator are available\n", + "\n", + " #Dictionary of modifiable privileges for HPE servers (modify this if you wish to directly set\n", + " #an account with specific privileges\n", + " \n", + " PRIVILEGE_DICT = {\"iLOConfigPriv\": True, \"VirtualMediaPriv\": True, \"RemoteConsolePriv\": True, \"UserConfigPriv\": True, \"VirtualPowerAndResetPriv\": True, \\\n", + " \"SystemRecoveryConfigPriv\": True, \"LoginPriv\": True, \"HostStorageConfigPriv\": True, \"HostNICConfigPriv\": True,\n", + " \"HostBIOSConfigPriv\": True}\n", + " \n", + " print(\"For the below privilages enter 'True' if that privilages needs to be set for the user else enter 'False'\")\n", + " \n", + " for key in PRIVILEGE_DICT.keys():\n", + " PRIVILEGE_DICT[key] = input(f\"{key}\")\n", + " \n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + "# ca_cert_data = {}\n", + "# ca_cert_data[\"cert_file\"] = \"c:\\\\test\\\\ppcacuser.crt\"\n", + "# ca_cert_data[\"key_file\"] = \"c:\\\\test\\\\ppcacuserpriv.key\"\n", + "# ca_cert_data[\"key_password\"] = \"password\"\n", + " LOGIN_ACCOUNT = None\n", + " LOGIN_PASSWORD = None\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD, ca_cert_data=ca_cert_data)\n", + " #REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, ca_cert_data=ca_cert_data)\n", + " # Login with the Redfish client\n", + " if ca_cert_data is None:\n", + " REDFISHOBJ.login()\n", + " else:\n", + " REDFISHOBJ.login(auth='certificate')\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + "\n", + " #if account_collection_uri and accounts:\n", + " #add specified account\n", + " (ilogen,_) = get_gen(REDFISHOBJ)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) !=4:\n", + " add_ilo_user_account(REDFISHOBJ,ACCOUNT_LOGIN_NAME,ACCOUNT_USER_NAME,ACCOUNT_PASSWORD,ROLE_ID,PRIVILEGE_DICT)\n", + " else:\n", + " add_ilo_user_account_gen9(REDFISHOBJ,ACCOUNT_LOGIN_NAME,ACCOUNT_USER_NAME,ACCOUNT_PASSWORD)\n", + " \n", + " REDFISHOBJ.logout()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb index 2f001ea..8fb312c 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb @@ -119,10 +119,89 @@ "\n" ] }, + { + "cell_type": "markdown", + "id": "2a39acd4", + "metadata": {}, + "source": [ + "

      Scripts related to Firmware

      " + ] + }, + { + "cell_type": "markdown", + "id": "a7f7d0e2", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Upload Firmware to iLO repositoryScript for uploading firmware to the iLO Repository for flashingUpload_Firmware_to_iLO_repo
      Upload Firmware with associated COMPSIG file to iLO repositoryScript for uploading a firmware component with a size less than\n", + "32 GB, and associated Component Signature (compsig) signature file to the iLO RepositoryUpload_Firmware_iLO_Repo_with_COMPSIG
      Update FirmwareScript for updating Firmware via HTTP URLUpdate_iLO_Firmware
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "a224da35", + "metadata": {}, + "source": [ + "

      Scripts related to ESKM (Enterprise Secure Key Manager)

      " + ] + }, + { + "cell_type": "markdown", + "id": "b44242b9", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Test ESKM ConnectionScript for testing connection to the ESKM system for HPE iLO systemsTest_ESKM_Connection
      \n" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "0cdb7878", + "id": "7e5e8be8", "metadata": {}, "outputs": [], "source": [] From 4cd16a8aa163a5dbd77aa698aadc141bcf26f2dd Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Tue, 16 May 2023 00:22:41 +0530 Subject: [PATCH 038/159] Delete examples/Jupyter_notebooks/HPECTY/Dharitri directory --- .../HPECTY/Dharitri/AHS/clear_ahs_data.ipynb | 254 -------------- .../Dharitri/COMPUTER/computer_details.ipynb | 230 ------------- .../COMPUTER/set_server_asset_tag.ipynb | 248 -------------- .../Dharitri/COMPUTER/set_uid_light.ipynb | 270 --------------- .../Dharitri/LicenseKey/set_license_key.ipynb | 262 --------------- .../HPECTY/Dharitri/SNMP/configure_snmp.ipynb | 282 ---------------- .../SNMP/configure_snmp_trap_source.ipynb | 246 -------------- .../HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb | 315 ------------------ .../Dharitri/Syslog/set_syslogserver.ipynb | 283 ---------------- .../Dharitri/iLO/clear_ilo_iel_iml_log.ipynb | 246 -------------- .../HPECTY/Dharitri/index.ipynb | 255 -------------- 11 files changed, 2891 deletions(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb deleted file mode 100644 index 8d3ee2f..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/AHS/clear_ahs_data.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e2d7d850", - "metadata": { - "tags": [] - }, - "source": [ - "# Clearing AHS data for HPE iLO systems" - ] - }, - { - "cell_type": "markdown", - "id": "88f096f8", - "metadata": {}, - "source": [ - "
      \n", - "Welcome to python-iLOrest-library
      Here is an example to Clearing AHS(Active Health System) data!!!
      \n", - " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", - " To perform this u need to have python-ilorest-library installed in your machine.
      \n", - " Please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "d1525f25", - "metadata": { - "tags": [] - }, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ce9142d", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory\n", - "import getpass" - ] - }, - { - "cell_type": "markdown", - "id": "b9615aea", - "metadata": {}, - "source": [ - "
      \n", - "

      2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


      \n", - " \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", - "\n", - "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
      \n", - " \n", - "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", - "
      \n", - "\n", - "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", - " Then we set the active_health_system_clear_log_uri.\n", - "
      \n", - "\n", - "4. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", - "
      \n", - "\n", - "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", - "\n", - " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "16042277", - "metadata": {}, - "outputs": [], - "source": [ - "def clear_ahs_data(_redfishobj):\n", - "\n", - " active_health_system_clear_log_uri = None\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", - " ['ActiveHealthSystem']['@odata.id']\n", - " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", - " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", - " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", - " active_health_system_uri = instance['@odata.id']\n", - " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", - " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", - " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", - " break\n", - "\n", - " if active_health_system_clear_log_uri:\n", - " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", - " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", - "\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", - " sort_keys=True))\n", - " except Exception:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" - ] - }, - { - "cell_type": "markdown", - "id": "6e7543eb", - "metadata": {}, - "source": [ - "
      \n", - "

      3. This is Main function overview.

      \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", - "\n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", - "
      \n", - " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", - "
      \n", - "\n", - "3. Once you enter everything a redfish object is created with the help of RedfishClient class.
      \n", - "
      \n", - "\n", - "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", - "
      \n", - "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
      \n", - "
      \n", - "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "270f99bf", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", - " \n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " clear_ahs_data(REDFISHOBJ)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "1557bfee", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally : use the following values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " \"https://10.0.0.100\"
      \n", - " \"https://ilo.hostname\"\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "e685a623", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb deleted file mode 100644 index 5051b63..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/computer_details.ipynb +++ /dev/null @@ -1,230 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a38bafdc", - "metadata": { - "tags": [] - }, - "source": [ - "# Gathering the computer system details" - ] - }, - { - "cell_type": "markdown", - "id": "cfe2e2b6", - "metadata": {}, - "source": [ - "
      \n", - " Welcome to python-iLOrest-library
      Here is an example to get_computer_details!!!
      As you are here let's get it done easily.
      \n", - " To perform this u need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "b3fec1a9", - "metadata": {}, - "source": [ - "
      \n", - "

      1. We are importing all the necessary modules from the ilorest library!


      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - "
    • get_resource_directory
    • \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "ab7125e9", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory\n", - "import getpass" - ] - }, - { - "cell_type": "markdown", - "id": "8d23d990", - "metadata": {}, - "source": [ - "
      \n", - "

      2. This is the function to get the computer details requested.


      \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", - "\n", - "1. In the computer_details function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
      \n", - " \n", - "2. In the ILO rest api the information about computer is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the computer data of iLO system.\n", - "
      \n", - "\n", - "3. In the system members response object with different odata_id we get a system uri .\n", - " Then again an http GET request is made and response is stored in system_response.\n", - " Then we set the system_members_uri.\n", - "
      \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if computerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.\n", - " \n", - "
      \n", - " \n", - "5. Finally print the Computer Details through systems_members_response.\n", - "
      \n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "1b4d0494", - "metadata": {}, - "outputs": [], - "source": [ - "def computer_details(_redfishobj):\n", - " systems_members_uri = None\n", - " systems_members_response = None\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", - " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", - " systems_response = _redfishobj.get(systems_uri)\n", - " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - " else:\n", - " for instance in resource_instances:\n", - " #Use Resource directory to find the relevant URI\n", - " if '#ComputerSystem.' in instance['@odata.type']:\n", - " systems_members_uri = instance['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - "\n", - " print(\"\\n\\nPrinting computer system details:\\n\\n\")\n", - " print(json.dumps(systems_members_response.dict, indent=4, sort_keys=True))\n" - ] - }, - { - "cell_type": "markdown", - "id": "e0de7de8", - "metadata": {}, - "source": [ - "
      \n", - "

      3. This is Main function overview.

      \n", - "
      \n", - " Enter iLO url, Username, Password
      \n", - "\n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", - "
      \n", - " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", - "
      \n", - "\n", - "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", - "
      \n", - "\n", - "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, but if Server is not avaialbe we get an error saying \"server unreachable\".
      \n", - "
      \n", - "5. Then we call computer_details with our redfish object.
      \n", - " \n", - "\n", - "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f538059", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", - " \n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " computer_details(REDFISHOBJ)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "bd337e8f", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally : use the following values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " \"https://10.0.0.100\"
      \n", - " \"https://ilo.hostname\"\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "f7fd2c36", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb deleted file mode 100644 index 002f766..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_server_asset_tag.ipynb +++ /dev/null @@ -1,248 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "c3169c50", - "metadata": {}, - "source": [ - "# Setting server asset tag" - ] - }, - { - "cell_type": "markdown", - "id": "70635f68", - "metadata": {}, - "source": [ - "
      \n", - " Welcome to python-iLOrest-library
      This is an example of setting server asset tag.
      As you are here let's get it done easily.
      \n", - " To perform this you need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "f176e2a7", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbe979de", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "import time\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "616c5812", - "metadata": {}, - "source": [ - "

      3. This is our set_server_asset_tag function overview.

      \n", - "
      \n", - "1. The set_server_asset_tag function sets the server asset tag on an iLO device. The function takes two parameters: _redfishobj and tag. \n", - "
        \n", - "
      • _redfishobj is a Redfish client object that represents the connection to the server
      • \n", - "
      • tag is a string that represents the asset tag to be set for the server.
      • \n", - "

      \n", - "2. In the set_server_asset_tag function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.

      \n", - "3. In the ILO rest api the information about server asset tag is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the server asset tag of iLO system.

      \n", - "4. In the system members response object with different odata_id we get a system uri .\n", - " Then again an http GET request is made and response is stored in system_response.\n", - " Then we set the system_members_uri.\n", - "

      \n", - "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if #ComputerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.

      \n", - "6.The function then calls the patch() method to update the system's AssetTag property with the new tag provided as input to the function.

      \n", - "7. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", - "8. If the patch() operation is successful, the updated asset tag is printed to the console. The function then waits for 10 seconds before retrieving and displaying the updated asset tag.

      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4e166b2", - "metadata": {}, - "outputs": [], - "source": [ - "def set_server_asset_tag(_redfishobj, tag):\n", - "\n", - " systems_members_uri = None\n", - " systems_members_response = None\n", - "\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", - " systems_response = _redfishobj.get(systems_uri)\n", - " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#ComputerSystem.' in instance['@odata.type']:\n", - " systems_members_uri = instance['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - "\n", - " if systems_members_response and systems_members_uri and tag:\n", - " print(\"Current Asset Tag: \\'%s\\'\\n\" % systems_members_response.dict.get(\"AssetTag\"))\n", - "\n", - " resp = _redfishobj.patch(systems_members_uri, {\"AssetTag\" : tag})\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", - " sys.stdout.write(\"\\nUpdated Asset Tag: \\'%s\\'\\n\" % _redfishobj.\\\n", - " get(systems_members_uri).dict.get(\"AssetTag\"))" - ] - }, - { - "cell_type": "markdown", - "id": "ef4f1fb5", - "metadata": {}, - "source": [ - "

      3. This is Main function overview.


      \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", - "
        \n", - "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", - "
      • If server is down or unreachable we get server not reachable message.
      • \n", - "
      • If not then we make a call to set_server_asset_tag to set server asset tag of system.
      • \n", - "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", - "
      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "606190a9", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " #asset tag property in computer systems\n", - " ASSET_TAG = \"Asset01\"\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = True\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " set_server_asset_tag(REDFISHOBJ, ASSET_TAG)\n", - " REDFISHOBJ.logout()\n" - ] - }, - { - "cell_type": "markdown", - "id": "bf946980", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally use the following commented values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " https://10.0.0.100
      \n", - " https://ilo.hostname\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "63db964c", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb deleted file mode 100644 index b98d251..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/COMPUTER/set_uid_light.ipynb +++ /dev/null @@ -1,270 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8ce5d6a0", - "metadata": {}, - "source": [ - "# Setting the UID light\n" - ] - }, - { - "cell_type": "markdown", - "id": "5b76e816", - "metadata": {}, - "source": [ - "
      \n", - "Welcome to python-iLOrest-library
      Here is an example to Setting UID light
      \n", - " This Jupyter Notebook will contains a example code to demonstrate how to set uid light. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", - " To perform this you need to have python-ilorest-library installed in your machine.
      \n", - " Please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "0581e350", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "62892493", - "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'redfish'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25868/3349352274.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" - ] - } - ], - "source": [ - "import sys\n", - "import json\n", - "import time\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "1eb087ac", - "metadata": {}, - "source": [ - "
      \n", - "

      2. This is our set_uid_light to function overview, in the end this will set uid light.


      \n", - " \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", - "1. This is a function that uses the Redfish API to toggle the UID (Universal Identification) LED on a computer system.\n", - " The function takes a Redfish connection object _redfishobj as its only argument.

      \n", - "2. In the set_uid_light function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "

      \n", - "3. In the iLO rest api the information about UID light is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the UID light settings of iLO system.\n", - "

      \n", - "4. In the system members response object with different odata_id we get a system uri . Then again an http GET request is made and response is stored in system_response. Then we set the system_members_uri.

      \n", - "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources and if #ComputerSystem attribute is present in @odata.type attribute then we'll set system_members_uri and get system_members_response settings of the user through redfish object.

      \n", - "6.It sets the body[\"IndicatorLED\"] key to Lit if the current value of the IndicatorLED property is Off, or to \"Off\" otherwise.

      \n", - "7. It sends an HTTP PATCH request to the obtained URI with the body payload to update the IndicatorLED property.

      \n", - "8. If the response status code is not 200 (OK) or 201 (Created), it prints an error message and exits.

      \n", - "9. If the response status code is 200 or 201, it waits for 10 seconds to allow the firmware to update the LED status, and then sends a GET request to the same URI to obtain the updated resource representation of the computer system.

      \n", - "10. It prints the updated value of the IndicatorLED property.

      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "07276165", - "metadata": {}, - "outputs": [], - "source": [ - "def set_uid_light(_redfishobj):\n", - "\n", - " body = dict()\n", - " systems_members_uri = None\n", - " systems_members_response = None\n", - "\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", - " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", - " systems_response = _redfishobj.get(systems_uri)\n", - " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#ComputerSystem.' in instance['@odata.type']:\n", - " systems_members_uri = instance['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - "\n", - " if systems_members_response and systems_members_uri:\n", - " print(\"Current Indicator LED Status: \\'%s\\'\\n\" % systems_members_response.dict.\\\n", - " get(\"IndicatorLED\"))\n", - " if \"Off\" in systems_members_response.dict.get(\"IndicatorLED\"):\n", - " print(\"Will illuminate indicator LED.\\n\")\n", - " body[\"IndicatorLED\"] = \"Lit\"\n", - " else:\n", - " print(\"Will extinguish indicator LED.\\n\")\n", - " body[\"IndicatorLED\"] = \"Off\"\n", - "\n", - " resp = _redfishobj.patch(systems_members_uri, body)\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", - " sys.stdout.write(\"\\nUpdated Indicator LED Status: \\'%s\\'\\n\" % _redfishobj.\\\n", - " get(systems_members_uri).dict['IndicatorLED'])\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "70d73b57", - "metadata": {}, - "source": [ - "
      \n", - "

      3. This is Main function overview.

      \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", - "\n", - "1. The rest opertions are handled by Redfish object which is created by Redfish Client
      \n", - "
      \n", - " \n", - "2. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", - "
      \n", - "\n", - "3. Once you enter everything a redfish object is created with the help of Redfish Client class.
      \n", - "
      \n", - "\n", - "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", - "
      \n", - "5. Then we call set_uid_light with our redfish object to set UID light.
      \n", - "
      \n", - "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea7ed17c", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = True\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " set_uid_light(REDFISHOBJ)\n", - " REDFISHOBJ.logout()\n" - ] - }, - { - "cell_type": "markdown", - "id": "3e4a9804", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally : use the following values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " \"https://10.0.0.100\"
      \n", - " \"https://ilo.hostname\"\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "377dc76a", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb deleted file mode 100644 index 7fc2ed0..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/LicenseKey/set_license_key.ipynb +++ /dev/null @@ -1,262 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "7d91ced6", - "metadata": {}, - "source": [ - "# Setting license key " - ] - }, - { - "cell_type": "markdown", - "id": "11b0fe9d", - "metadata": {}, - "source": [ - "
      \n", - " Welcome to python-iLOrest-library
      This is an example of setting license key.
      As you are here let's get it done easily.
      \n", - " To perform this you need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "6cbd5f7c", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f0fa1574", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "7daccb24", - "metadata": {}, - "source": [ - "

      2. This is our set_license_key function overview.

      \n", - "
      \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", - "\n", - "1. In the set_license_key function we are taking two parameters i.e. _redfishobj and ilo_key. In the set_license_key function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
      \n", - " \n", - "2. In the iLO rest api the information about license key is stored inside the managers json object.\n", - " Through managers_response variable we are making a http GET operation to and trying to obtain the license service about iLO system.\n", - "
      \n", - "\n", - "3. In the managers response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in managers_members_response.\n", - " The license service information is ultimately present in the managers_members_response.\n", - "
      \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if HpeiLOLicense type is present in @odata.type attribute then we will store information about license key in ilo_lic_uri and break out of iteration.\n", - "
      \n", - "5. If ilo_lic_uri is not null after making above operations, we can perform the required actions to set license key. \n", - "
        \n", - "
      • The function sends a GET request to the iLO license service to retrieve the current license data. If the ConfirmationRequest field exists, it is printed to the console; otherwise, the LicenseKey field is printed.
      • \n", - "
      • The function sends a POST request to the iLO license service with the new license key provided in the ilo_key argument.
      • \n", - "
      • The job of post request here is to set the license key at the provided location and send a response whether the job was done properly or not.
      • \n", - "
      • If the response status is 400, the function attempts to print the extended error message provided by iLO. If the status is not 200 or 201, the function prints an error message to the console.
      • \n", - "
      • If the response status is 200, the function prints a success message to the console along with the response JSON.
      • \n", - "
      \n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bacca62e", - "metadata": {}, - "outputs": [], - "source": [ - "def set_license_key(_redfishobj, ilo_key):\n", - "\n", - " ilo_lic_uri = None\n", - "\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " ilo_lic_uri = managers_members_response.obj.Oem.Hpe.Links['LicenseService']['@odata.id']\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#HpeiLOLicense.' in instance['@odata.type']:\n", - " ilo_lic_uri = instance['@odata.id']\n", - "\n", - " if ilo_lic_uri:\n", - " ilo_license_collection = _redfishobj.get(ilo_lic_uri)\n", - " ilo_license_member_uri = next(iter(ilo_license_collection.obj['Members']))['@odata.id']\n", - " try:\n", - " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['ConfirmationRequest']\\\n", - " ['EON']\n", - " except KeyError:\n", - " sys.stdout.write(\"This machine will not show the full License Key.\\n\")\n", - " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['LicenseKey']\n", - "\n", - " sys.stdout.write(\"Current iLO License Data:\\n\")\n", - " print(json.dumps(ilo_license_data, indent=4, sort_keys=True))\n", - " resp = _redfishobj.post(ilo_lic_uri, {'LicenseKey' : ilo_key})\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " sys.stderr.write(\"Check the validity of your license key...\\n\")\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO \" \\\n", - " \"Extended Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" - ] - }, - { - "cell_type": "markdown", - "id": "abfa5bd8", - "metadata": {}, - "source": [ - "

      3. This is Main function overview.


      \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", - "
        \n", - "
      • Once your credentials are entered a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", - "
      • If server is down or unreachable we get server not reachable message.
      • \n", - "
      • If not then we make a call to set_license_key function to set license key of system.
      • \n", - "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", - "
      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "38798e69", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " # Must be a valid iLO License Key\n", - " ILO_LICENSE_KEY = \"XXXX-XXXX-XXXX-XXXX-XXXXX\"\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = True\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " set_license_key(REDFISHOBJ, ILO_LICENSE_KEY)\n", - " REDFISHOBJ.logout()\n" - ] - }, - { - "cell_type": "markdown", - "id": "7d4c55f5", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally use the following commented values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " https://10.0.0.100
      \n", - " https://ilo.hostname\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "b3be89a3", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb deleted file mode 100644 index d8cbe37..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp.ipynb +++ /dev/null @@ -1,282 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "979defcc", - "metadata": {}, - "source": [ - "# Configuring SNMP for HPE iLO systems" - ] - }, - { - "cell_type": "markdown", - "id": "a127fdb8", - "metadata": {}, - "source": [ - "
      \n", - " Welcome to python-iLOrest-library
      This is an example of configuring SNMP for HPE iLO systems.
      As you are here let's get it done easily.
      \n", - " To perform this u need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "0cf44a38", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "ccd0447f", - "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'redfish'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_4196/1287542820.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" - ] - } - ], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory \n", - "import getpass" - ] - }, - { - "cell_type": "markdown", - "id": "c988b347", - "metadata": {}, - "source": [ - "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", - "
      \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", - "\n", - "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
      \n", - " \n", - "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", - " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", - "
      \n", - "\n", - "3. In the managers response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in managers_members_response.\n", - " The snmp configuration information is ultimately present in the managers_members_response.\n", - "
      \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", - "
      \n", - "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3804eab", - "metadata": {}, - "outputs": [], - "source": [ - "def configure_snmp(_redfishobj, read_communities, snmp_alerts):\n", - "\n", - " snmp_service_uri = None\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", - " else:\n", - " for instance in resource_instances:\n", - " #Use Resource directory to find the relevant URI\n", - " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", - " snmp_service_uri = instance['@odata.id']\n", - "\n", - " if snmp_service_uri:\n", - " body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", - " resp = _redfishobj.patch(snmp_service_uri, body)\n", - "\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "6e047370", - "metadata": {}, - "source": [ - "

      3. This is Main function overview.


      \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", - "
        \n", - "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", - "
      • If server is down or unreachable we get server not reachable message.
      • \n", - "
      • If not then we make a call to configure_snmp function to obtain snmp related information of system.
      • \n", - "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", - "
      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "faa032c5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter iLO IP address: 172.1,14\n", - "Enter Username: hhello\n", - "Enter password: 1245\n" - ] - }, - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[1;31m# Create a Redfish client object\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 27\u001b[1;33m REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n\u001b[0m\u001b[0;32m 28\u001b[0m password=LOGIN_PASSWORD)\n", - "\u001b[1;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;31m# Login with the Redfish client\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 31\u001b[1;33m \u001b[1;32mexcept\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mexcp\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 32\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"ERROR: server not reachable or does not support RedFish.\\n\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 33\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " #Properties:\n", - " #read communities array\n", - " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", - " #alerts_enabled primitive (boolean)\n", - " ALERTS_ENABLED = True\n", - " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_ENABLED, DISABLE_RESOURCE_DIR)\n", - " REDFISHOBJ.logout()\n", - " \n" - ] - }, - { - "cell_type": "markdown", - "id": "337fd6f7", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally use the following commented values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " https://10.0.0.100
      \n", - " https://ilo.hostname\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "a45c7e01", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb deleted file mode 100644 index f7941cf..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/configure_snmp_trap_source.ipynb +++ /dev/null @@ -1,246 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0a6c95aa", - "metadata": {}, - "source": [ - "# Configuring SNMP trap source for HPE iLO systems" - ] - }, - { - "cell_type": "markdown", - "id": "594a0e06", - "metadata": {}, - "source": [ - "
      \n", - "Welcome to python-iLOrest-library
      This is an example of configuring SNMP trap source for HPE iLO systems.
      As you are here let's get it done easily.
      \n", - " To perform this u need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "25be0e98", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "f16a98ad", - "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'redfish'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25528/1522814575.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" - ] - } - ], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory\n" - ] - }, - { - "cell_type": "markdown", - "id": "8c2b4d45", - "metadata": {}, - "source": [ - "

      2. This is our configure_snmp function overview, in the end this will give us with snmp service related information.

      \n", - " \n", - "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the snmp service information.\n", - "\n", - " \n", - "\n", - " \n", - "1. In the ILO rest api the information about snmp is stored inside the managers json object.\n", - " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", - "
      \n", - "\n", - "2. In the managers response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in managers_members_response.\n", - " The snmp configuration information is ultimately present in the managers_members_response.\n", - "
      \n", - "\n", - "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if power snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", - "
      \n", - "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b53e8e73", - "metadata": {}, - "outputs": [], - "source": [ - " def configure_snmp(_redfishobj):\n", - "\n", - " snmp_service_uri = None\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " # print(managers_members_response.obj['Oem']['Hpe']['Links'])\n", - " # exit(0)\n", - " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['SNMPService']['@odata.id']\n", - "\n", - " if snmp_service_uri:\n", - " # resp = _redfishobj.get(snmp_service_uri)\n", - " # print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " # exit(0)\n", - " # TrapSourceHostname : Manager or System\n", - " body = {\"TrapSourceHostname\": \"System\"}\n", - " resp = _redfishobj.patch(snmp_service_uri, body)\n", - "\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " # print(json.dumps(resp.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "b852d783", - "metadata": {}, - "source": [ - "

      3. This is Main function overview.


      \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", - "
        \n", - "
      • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", - "
      • If server is down or unreachable we get server not reachable message.
      • \n", - "
      • If not then we make a call to configure_snmp function to obtain snmp related info of system.
      • \n", - "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", - "
      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d9cf5c73", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "610979dd", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - "\n", - " if len(sys.argv) <= 3:\n", - " sys.stderr.write(\"ERROR: We need 3 arguments. \\nUsage: change-snmp.py \"\n", - " \"ILOIPADDR ILOUSER ILOPASSWORD \\n\")\n", - " sys.exit()\n", - "\n", - " SYSTEM_URL = \"https://\" + sys.argv[1]\n", - " LOGIN_ACCOUNT = sys.argv[2]\n", - " LOGIN_PASSWORD = sys.argv[3]\n", - "\n", - " try:\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT,\n", - " password=LOGIN_PASSWORD)\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " configure_snmp(REDFISHOBJ)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "80f7da07", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally use the following commented values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " https://10.0.0.100
      \n", - " https://ilo.hostname\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "00b5c8a5", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb deleted file mode 100644 index 5dbdafa..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/SNMP/set_snmp_alert.ipynb +++ /dev/null @@ -1,315 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "80ca2bf5", - "metadata": {}, - "source": [ - "# Setting SNMP alert destination" - ] - }, - { - "cell_type": "markdown", - "id": "647c7374", - "metadata": {}, - "source": [ - "
      \n", - " Welcome to python-iLOrest-library
      This is an example of setting SNMP alert destination.
      As you are here let's get it done easily.
      \n", - " To perform this you need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "ce2b4b70", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6a53c06", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from ilorest_util import get_resource_directory\n", - "from ilorest_util import get_gen" - ] - }, - { - "cell_type": "markdown", - "id": "cfd0ef73", - "metadata": {}, - "source": [ - "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", - "
      \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", - "\n", - "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
      \n", - " \n", - "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", - " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", - "
      \n", - "\n", - "3. In the managers response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in managers_members_response.\n", - " The snmp configuration information is ultimately present in the managers_members_response.\n", - "
      \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", - "
      \n", - "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "269747d5", - "metadata": {}, - "outputs": [], - "source": [ - "def configure_snmp(_redfishobj, read_communities, snmp_alertdestinations, DISABLE_RESOURCE_DIR):\n", - " snmp_service_uri = None\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", - " else:\n", - " for instance in resource_instances:\n", - " #Use Resource directory to find the relevant URI\n", - " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", - " snmp_service_uri = instance['@odata.id']\n", - "\n", - " if snmp_service_uri:\n", - " #body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", - " body = {\"AlertDestinations\": snmp_alertdestinations}\n", - " resp = _redfishobj.patch(snmp_service_uri, body)\n", - "\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "ca33ee48", - "metadata": {}, - "source": [ - "

      3. This is our set_snmp_alert_destination function overview.

      \n", - "
      \n", - "1. The set_snmp_alert_destination function sets the SNMP alert destinations on an iLO device. The function takes three parameters: _redfishobj, snmp_service_uri, and alert_destination_list. \n", - "
        \n", - "
      • _redfishobj is the Redfish client object.
      • \n", - "
      • snmp_service_uri is the URI for the SNMP service on the iLO device.
      • \n", - "
      • alert_destination_list is a list of dictionaries containing the SNMP alert destinations to set.
      • \n", - "

      \n", - "2. The function gets the current SNMP service data using _redfishobj.get() and checks if the AlertDestinations property is available/modifyable.

      \n", - "3. If the property is available/modifyable, the function sends a PATCH request with the updated alert destinations using _redfishobj.patch().

      \n", - "4. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", - "5. If the patch operation is successful, the function prints the response and gets the updated SNMP alert destination data using _redfishobj.get().

      \n", - "6. The updated SNMP alert destination data is printed to the console using json.dumps() and print().

      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c91c0fb8", - "metadata": {}, - "outputs": [], - "source": [ - "def set_snmp_alert_destination(_redfishobj, snmp_service_uri, alert_destination_list):\n", - " data = _redfishobj.get(snmp_service_uri)\n", - " if data.dict.get(\"AlertDestinations\"):\n", - " resp = _redfishobj.patch(snmp_service_uri, {'AlertDestinations': alert_destination_list})\n", - " else:\n", - " raise Exception(\"\\'AlertDestinations\\' property is not available/modifyable.\\n\")\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"\\nPatch operation successful!\\n\\nResponse:\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " snmp_service_response = _redfishobj.get(snmp_service_uri).dict.get('AlertDestinations')\n", - " print(\"\\n\\nPrinting updated SNMP alert destination:\\n\")\n", - " print(json.dumps(snmp_service_response, indent=4, sort_keys=True))\n" - ] - }, - { - "cell_type": "markdown", - "id": "9fdd0d40", - "metadata": {}, - "source": [ - "

      4. This is Main function overview.


      \n", - "The Main function \n", - "
        \n", - "
      • Once your credentials that are enter everything a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", - "
      • If server is down or unreachable we get server not reachable message.
      • \n", - "
      • It checks the generation of iLO by calling the get_gen function and prints the iLO generation.\n", - "
      • If the iLO generation is 5, it calls the configure_snmp function to configure the SNMP service with the read communities and alerts destination, and disable resource directory flag.
      • \n", - "
      • If the iLO generation is not 5, it calls the set_snmp_alert_destination function to set the SNMP alert destination with the alert destination list for iLO4.
      • \n", - "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", - "
      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "27378983", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " #SYSTEM_URL = \"https://15.146.46.45\"\n", - " #LOGIN_ACCOUNT = \"admin\"\n", - " #LOGIN_PASSWORD = \"admin123\"\n", - "\n", - " SYSTEM_URL = sys.argv[1]\n", - " LOGIN_ACCOUNT = sys.argv[2]\n", - " LOGIN_PASSWORD = sys.argv[3]\n", - "\n", - " #Properties:\n", - " #read communities array\n", - " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", - " #alerts_enabled primitive (boolean)\n", - " #ALERTS_ENABLED = True\n", - " #Alert Destination\n", - " ALERTS_DESTINATION = [\"1.1.1.1\",\"2.2.2.2\"]\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - " snmp_service_uri = \"/redfish/v1/Managers/1/SNMPService/\"\n", - "\n", - " # Number of max alert destination supported on iLO4 and iLO5 is different\n", - " alert_destination_list = [\"ILOCN771702NJ\", \"15.146.46.55\" , \"15.146.46.58\"]\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - " (ilogen,_) = get_gen(REDFISHOBJ)\n", - " print (\"Generation is \", ilogen)\n", - " if int(ilogen) == 5:\n", - " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_DESTINATION, DISABLE_RESOURCE_DIR)\n", - " else:\n", - " set_snmp_alert_destination(REDFISHOBJ, snmp_service_uri, alert_destination_list)\n", - " REDFISHOBJ.logout()\n" - ] - }, - { - "cell_type": "markdown", - "id": "5a2f6ba5", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally use the following commented values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " https://10.0.0.100
      \n", - " https://ilo.hostname\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "28ec396f", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb deleted file mode 100644 index 14a772b..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/Syslog/set_syslogserver.ipynb +++ /dev/null @@ -1,283 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "b92b79fb", - "metadata": {}, - "source": [ - "# Setting remote syslog server" - ] - }, - { - "cell_type": "markdown", - "id": "2ed959e3", - "metadata": {}, - "source": [ - "
      \n", - "Welcome to python-iLOrest-library
      Here is an example to Setting remote syslog server
      \n", - " This Jupyter Notebook will contains a example code to demonstrate how to set remote syslog server. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", - " To perform this you need to have python-ilorest-library installed in your machine.
      \n", - " Please keep your username and password handy!\n", - "
      \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "3a91bf91", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - "
    • ilorest_util
    • \n", - "
    • argparse
    • \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b6eed1f2", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "import argparse\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "global DISABLE_RESOURCE_DIR\n", - "from ilorest_util import get_resource_directory\n", - "from ilorest_util import get_gen" - ] - }, - { - "cell_type": "markdown", - "id": "6393e74d", - "metadata": {}, - "source": [ - "
      \n", - "

      2. This is our set_syslog function overview


      \n", - " This function sets the remote syslog server and enables remote syslog on an iLO system.

      \n", - "1. It takes two parameters:\n", - "
        \n", - "
      • _redfishobj: an object representing the connection to the iLO device through the Redfish API.
      • \n", - "
      • syslog_server: a string representing the IP address or hostname of the remote syslog server.

      \n", - "2. The function first retrieves the model information of the system, which is used to determine the Oem (Original equipment manufacturer) name, as the endpoint structure and payload might differ based on the manufacturer. It determines the model of the server by sending a GET request to the /redfish/v1/Systems/1/ URI and extracting the Model attribute from the response.

      \n", - "3. It checks if the model contains \"Gen9\" or \"Gen8\". If either of them is present, it sets the \"hp\" variable to \"Hp\". Otherwise, it sets it to \"Hpe\".

      \n", - "4. It then constructs the URI for the syslog configuration resource and sends a PATCH request with the request body to set the remote syslog server and enable remote syslog.

      \n", - " 5. Finally, it calls the ilo_response, passing the _redfishobj and resp (response) as arguments. This function handles response from the server.

      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2971240e", - "metadata": {}, - "outputs": [], - "source": [ - "def set_syslog(_redfishobj, syslog_server):\n", - "\n", - " model_uri = \"/redfish/v1/Systems/1/\"\n", - " model = _redfishobj.get(model_uri).obj['Model']\n", - " print (model)\n", - " if \"Gen9\" in model or 'Gen8' in model:\n", - " hp = \"Hp\"\n", - " else:\n", - " hp = \"Hpe\"\n", - "\n", - " syslog_uri = \"/redfish/v1/Managers/1/NetworkService/\"\n", - "\n", - " body = {\"Oem\": {hp: {\"RemoteSyslogServer\": syslog_server, \"RemoteSyslogEnabled\": True}}}\n", - " resp = _redfishobj.patch(syslog_uri, body)\n", - " ilo_response(_redfishobj, resp)" - ] - }, - { - "cell_type": "markdown", - "id": "1fdc6d56", - "metadata": {}, - "source": [ - "
      \n", - "

      3. This is ilo_response function overview


      \n", - " The ilo_response function is responsible for handling the response from the iLO server.

      \n", - "1. It takes two parameters: _redfishobj (Redfish client object) and resp (response object).

      \n", - "2. It checks the status code of the response. If it is equal to 400, it indicates a client error.

      \n", - "3. It tries to extract and print the extended error information from the response using the key error ['@Message.ExtendedInfo'].\n", - "If there is an exception while accessing the extended error information, it writes an error message to the standard error stream.

      \n", - "4. If the status code is not 400 but is not equal to 200 either, it indicates an HTTP response error.\n", - "It writes an error message to the standard error stream, indicating the HTTP response status.

      \n", - "5. If the status code is 200, it indicates a successful response.\n", - "It prints the message \"Success\" to indicate the operation was successful.
      \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2db998f", - "metadata": {}, - "outputs": [], - "source": [ - "def ilo_response(_redfishobj, resp):\n", - "\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success\")" - ] - }, - { - "cell_type": "markdown", - "id": "d95a2d40", - "metadata": {}, - "source": [ - "
      \n", - "

      4. This is Main function overview.

      \n", - "1. An argument parser is initialized to parse the command-line arguments passed to the script. The parser expects arguments such as iLO url, username, password, and syslog server IP.

      \n", - "2.The rest opertions are handled by Redfish object which is created by Redfish Client

      \n", - "3. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object. Once you enter everything a redfish object is created with the help of Redfish Client class.

      \n", - "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"

      \n", - "5. The get_gen function is called to retrieve the iLO generation number of the server.\n", - " Depending on the iLO generation number, the set_syslog function is called with the Redfish client object and the syslog server IP address.

      \n", - "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3681c0d2", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # Initialize parser\n", - " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", - "\n", - " parser.add_argument(\n", - " '-i',\n", - " '--ilo',\n", - " dest='ilo_ip',\n", - " action=\"store\",\n", - " help=\"iLO IP of the server\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-u',\n", - " '--user',\n", - " dest='ilo_user',\n", - " action=\"store\",\n", - " help=\"iLO username to login\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-p',\n", - " '--password',\n", - " dest='ilo_pass',\n", - " action=\"store\",\n", - " help=\"iLO password to log in.\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-s',\n", - " '--syslog_server',\n", - " dest='syslog_server',\n", - " action=\"store\",\n", - " required=True,\n", - " help=\"iLO password to log in.\",\n", - " default=None)\n", - "\n", - " options = parser.parse_args()\n", - "\n", - " system_url = \"https://\" + options.ilo_ip\n", - " print (system_url)\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = True\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", - " # Login with the Redfish client\n", - " redfish_obj.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " (ilogen,_) = get_gen(redfish_obj)\n", - " print (\"Generation is \", ilogen)\n", - " if int(ilogen) == 5:\n", - " set_syslog(redfish_obj, options.syslog_server)\n", - " else:\n", - " set_syslog(redfish_obj, options.syslog_server)\n", - " redfish_obj.logout()\n" - ] - }, - { - "cell_type": "markdown", - "id": "750b6ae8", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally : use the following values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " \"https://10.0.0.100\"
      \n", - " \"https://ilo.hostname\"\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "f91c6419", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb deleted file mode 100644 index 19de2bd..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/iLO/clear_ilo_iel_iml_log.ipynb +++ /dev/null @@ -1,246 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "89dc5655", - "metadata": { - "tags": [] - }, - "source": [ - "# CLEAR iLO LOGS" - ] - }, - { - "cell_type": "markdown", - "id": "898cbb84", - "metadata": {}, - "source": [ - "
      \n", - "Welcome to python-iLOrest-library
      Here is an example to for clearing out the iLO event log and management log at server side!
      As you are here let's get it done easily.
      \n", - " To perform this you need to have python-ilorest-library installed in your machine.
      \n", - " And please keep your username and password handy!\n", - " \n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "98f3c2dd", - "metadata": {}, - "source": [ - "
      \n", - "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", - "
    • sys \n", - "
    • \n", - "
    • json
    • \n", - "
    • redfish
    • \n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "935d8f7c", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "import getpass\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "from get_resource_directory import get_resource_directory\n", - "import getpass" - ] - }, - { - "cell_type": "markdown", - "id": "ef3013ef", - "metadata": {}, - "source": [ - "
      \n", - "

      2. This cell gives overview about of the function used to clear event logs such as IML and IEL logs.


      \n", - "The IML provides a record of historical events that have occurred on the server and the IEL is the iLO event log provides record of significant events detected by iLO.\n", - " \n", - "1. When the resource directory is disabled then we simply navigate through the API for obtaining the relevant uri.\n", - " The series of HTTP get requests aims to extracts log_services_response so as to get the path of the directory for which IEL and IML logs need to be cleared.\n", - "
      \n", - "2. Else if the resource directory enabled then rather we can simply extract the uri by #LogService.attribute inside the instance['odatatype'] dictionary and again make a HTTP get request to obtain the required uri.\n", - "
      \n", - "3. After obtaining the uri we just need to make changes on the same location using a post request so as to clear IEL and IML logs successfully. For this body dictionary contains the attribute to be changed and IEL/IML are searched in the path of clear_log_services_uri and the respective changes are made by redfishobj.post(path,body).\n", - "
      \n", - " \n", - "4. Later we also check for the response returned by the server side. If the response is anything outside of status code with 200 then error message gets rendered on the webpage else the success message is printed out with the response dictionary returned by the server.\n", - "\n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "a7abae2a", - "metadata": {}, - "outputs": [], - "source": [ - "def clear_ilo_event_log(_redfishobj, clear_IML_IEL):\n", - "\n", - " clear_log_services_uri = []\n", - "\n", - " resource_instances = redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", - " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", - " systems_response = _redfishobj.get(systems_uri)\n", - " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - " log_services_uri = systems_members_response.obj['LogServices']['@odata.id']\n", - " log_services_response = _redfishobj.get(log_services_uri)\n", - " log_services_uris = log_services_response.obj['Members']\n", - " for log_services_uri in log_services_uris:\n", - " log_services_response = _redfishobj.get(log_services_uri['@odata.id'])\n", - " clear_log_services_uri.append(log_services_response.obj['Actions']\\\n", - " ['#LogService.ClearLog']['target'])\n", - " else:\n", - " for instance in resource_instances:\n", - " #Use Resource directory to find the relevant URI\n", - " if '#LogService.' in instance['@odata.type']:\n", - " log_service_uri = instance['@odata.id']\n", - " clear_log_services_uri.append(_redfishobj.get(log_service_uri).dict['Actions']\\\n", - " ['#LogService.ClearLog']['target'])\n", - "\n", - " if clear_log_services_uri:\n", - " body = {\"Action\": \"LogService.ClearLog\"}\n", - " for path in clear_log_services_uri:\n", - " if (\"IEL\" in clear_IML_IEL and \"IEL\" in path) or (\"IML\" in clear_IML_IEL and \\\n", - " \"IML\" in path):\n", - " if \"IEL\" in path:\n", - " sys.stdout.write(\"Clearing IEL log.\\n\")\n", - " else:\n", - " sys.stdout.write(\"Clearing IML log.\\n\")\n", - " resp = _redfishobj.post(path, body)\n", - " else:\n", - " continue\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", - " \"Extended Message Info...\\n\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "331b8289", - "metadata": {}, - "source": [ - "
      \n", - "

      3. The Main function


      \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", - " \n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", - "
      \n", - " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", - "
      \n", - "\n", - "3. Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.

      \n", - "4. If server is down or Unreachable we get server not reachable message!

      \n", - "5. Else if no error is encountered a function call is made i.e. clear_ilo_event_log(REDFISHOBJ, CLEAR_IEL_IML)that is responsible for handling clearing all the IEL and IML logs at the server side.

      \n", - "6. Lastly, REDFISHOBJ.logout logs us out of the system and ends the session.\n", - " \n", - "
      " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4143942b", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " \n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - " CLEAR_IML_IEL = \"IML\" # provide either the string IML or IEL\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " clear_ilo_event_log(REDFISHOBJ, CLEAR_IML_IEL)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "f120e784", - "metadata": {}, - "source": [ - "
      \n", - " When running on the server locally : use the following values
      \n", - " SYSTEM_URL = None
      \n", - " LOGIN_ACCOUNT = None
      \n", - " LOGIN_PASSWORD = None
      \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", - " SYSTEM_URL acceptable examples:
      \n", - " \"https://10.0.0.100\"
      \n", - " \"https://ilo.hostname\"\n", - "
      " - ] - }, - { - "cell_type": "markdown", - "id": "f702c0ae", - "metadata": {}, - "source": [ - "
      In case you need help 🔗 links to relevant resources :\n", - "
      \n", - " 1.Python-ilorest-library:LINK
      \n", - " 2.Hpe ilorest-api explorer:LINK
      \n", - " 3.Rest api: LINK
      \n", - " \n", - "
      " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb deleted file mode 100644 index 161b91f..0000000 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb +++ /dev/null @@ -1,255 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "18ad6013", - "metadata": {}, - "source": [ - "\"HPE" - ] - }, - { - "cell_type": "markdown", - "id": "20da06d1", - "metadata": {}, - "source": [ - "

      Scripts related to AHS

      " - ] - }, - { - "cell_type": "markdown", - "id": "fa8b0fad", - "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Clear AHS dataClear active health state data of iLO serverDELETEclear_ahs_data
      \n" - ] - }, - { - "cell_type": "markdown", - "id": "81721043", - "metadata": {}, - "source": [ - "

      Scripts related to Computer

      " - ] - }, - { - "cell_type": "markdown", - "id": "cf10b943", - "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Computer DetailsGet all the available computer/hosts details in iLO\tGETcomputer_details
      Set Server Asset TagSetting server asset tag\tPATCHset_server_asset_tag
      Set UID LightSetting UID LightPATCHset_uid_light
      \n" - ] - }, - { - "cell_type": "markdown", - "id": "01ee71dd", - "metadata": {}, - "source": [ - "

      Scripts related to iLO

      " - ] - }, - { - "cell_type": "markdown", - "id": "fbce5754", - "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Clear iLO IEL IML log\tClearing out the iLO event log and management log at server sideDELETEclear_ilo_iel_iml_log
      \n" - ] - }, - { - "cell_type": "markdown", - "id": "0140b004", - "metadata": {}, - "source": [ - "

      Scripts related to SNMP

      " - ] - }, - { - "cell_type": "markdown", - "id": "d60f6ff8", - "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Configure SNMPConfiguring SNMP for HPE iLO systemsPATCHconfigure_snmp
      Configure SNMP trap sourceConfiguring SNMP trap source for HPE iLO systemsPATCHconfigure_snmp_trap_source
      Set SNMP alert destinationSetting SNMP alert destination for HPE iLO systemsPATCHset_snmp_alert
      \n" - ] - }, - { - "cell_type": "markdown", - "id": "aff5c9ed", - "metadata": {}, - "source": [ - "

      Scripts related to License Key

      " - ] - }, - { - "cell_type": "markdown", - "id": "c9cfb10a", - "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Set License Key\tSetting License KeyPATCHset_license_key
      \n" - ] - }, - { - "cell_type": "markdown", - "id": "2c6d7156", - "metadata": {}, - "source": [ - "

      Scripts related to Syslog

      " - ] - }, - { - "cell_type": "markdown", - "id": "bcae99e1", - "metadata": {}, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Set remote syslog server\tSetting Remote syslog Server for an HPE iLO management processor.PATCHset_syslogserver
      \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From a18b863c41cfca95abaf0d871953013c7eb888ba Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Tue, 16 May 2023 00:24:42 +0530 Subject: [PATCH 039/159] Create index.ipynb --- examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb @@ -0,0 +1 @@ + From ba20bc78da5bf7a06a97db786ad2f0ecdecd128a Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Tue, 16 May 2023 00:26:05 +0530 Subject: [PATCH 040/159] Add files via upload --- .../ahs_syslog_iml/clear_ahs_data.ipynb | 266 +++++++++++++++ .../clear_ilo_iel_iml_log.ipynb | 246 ++++++++++++++ .../ahs_syslog_iml/set_syslogserver.ipynb | 283 ++++++++++++++++ .../HPECTY/Dharitri/bios/set_bios_iscsi.ipynb | 252 ++++++++++++++ .../Dharitri/bios/set_bios_password.ipynb | 260 +++++++++++++++ .../ilo_license/set_license_key.ipynb | 262 +++++++++++++++ .../HPECTY/Dharitri/index.ipynb | 245 +++++++++++++- .../server_manager/computer_details.ipynb | 230 +++++++++++++ .../server_manager/set_server_asset_tag.ipynb | 248 ++++++++++++++ .../server_manager/set_uid_light.ipynb | 275 +++++++++++++++ .../HPECTY/Dharitri/snmp/configure_snmp.ipynb | 282 ++++++++++++++++ .../snmp/configure_snmp_trap_source.ipynb | 246 ++++++++++++++ .../HPECTY/Dharitri/snmp/set_snmp_alert.ipynb | 315 ++++++++++++++++++ 13 files changed, 3409 insertions(+), 1 deletion(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ahs_data.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/set_syslogserver.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_iscsi.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_password.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/ilo_license/set_license_key.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/computer_details.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_server_asset_tag.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_uid_light.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp_trap_source.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/set_snmp_alert.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ahs_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ahs_data.ipynb new file mode 100644 index 0000000..8b32730 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ahs_data.ipynb @@ -0,0 +1,266 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d7d850", + "metadata": { + "tags": [] + }, + "source": [ + "# Clearing AHS data for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "88f096f8", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Clearing AHS(Active Health System) data!!!
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "d1525f25", + "metadata": { + "tags": [] + }, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "8ce9142d", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_21748/2847628525.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b9615aea", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the clear_ahs_data function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "
      \n", + "\n", + "3. In the Managers member's response object with different odata_id we get a bios uri . Then again an http GET request is made and response is stored in active_health_system_response.\n", + " Then we set the active_health_system_clear_log_uri.\n", + "
      \n", + "\n", + "4. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", + "
      \n", + "\n", + "5. We will post the active_health_system_clear_log_uri and the body to the Redfish Client through Redfish Object\n", + "\n", + " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16042277", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ahs_data(_redfishobj):\n", + "\n", + " active_health_system_clear_log_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " active_health_system_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['ActiveHealthSystem']['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response.obj['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOActiveHealthSystem.' in instance['@odata.type']:\n", + " active_health_system_uri = instance['@odata.id']\n", + " active_health_system_response = _redfishobj.get(active_health_system_uri)\n", + " active_health_system_clear_log_uri = active_health_system_response['Actions']\\\n", + " ['#HpeiLOActiveHealthSystem.ClearLog']['target']\n", + " break\n", + "\n", + " if active_health_system_clear_log_uri:\n", + " body = {\"Action\": \"HpeiLOActiveHealthSystem.ClearLog\"}\n", + " resp = _redfishobj.redfish_client.post(active_health_system_clear_log_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "6e7543eb", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. The rest opertions are handled by Redfish object which is created by Redfish Client
      \n", + "
      \n", + " \n", + "2. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of Redfish Client class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call clear_ahs_data with our redfish object and rest the settings to default.
      \n", + "
      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270f99bf", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ahs_data(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "1557bfee", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "e685a623", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb new file mode 100644 index 0000000..19de2bd --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "89dc5655", + "metadata": { + "tags": [] + }, + "source": [ + "# CLEAR iLO LOGS" + ] + }, + { + "cell_type": "markdown", + "id": "898cbb84", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to for clearing out the iLO event log and management log at server side!
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "98f3c2dd", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "935d8f7c", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import getpass\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "ef3013ef", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This cell gives overview about of the function used to clear event logs such as IML and IEL logs.


      \n", + "The IML provides a record of historical events that have occurred on the server and the IEL is the iLO event log provides record of significant events detected by iLO.\n", + " \n", + "1. When the resource directory is disabled then we simply navigate through the API for obtaining the relevant uri.\n", + " The series of HTTP get requests aims to extracts log_services_response so as to get the path of the directory for which IEL and IML logs need to be cleared.\n", + "
      \n", + "2. Else if the resource directory enabled then rather we can simply extract the uri by #LogService.attribute inside the instance['odatatype'] dictionary and again make a HTTP get request to obtain the required uri.\n", + "
      \n", + "3. After obtaining the uri we just need to make changes on the same location using a post request so as to clear IEL and IML logs successfully. For this body dictionary contains the attribute to be changed and IEL/IML are searched in the path of clear_log_services_uri and the respective changes are made by redfishobj.post(path,body).\n", + "
      \n", + " \n", + "4. Later we also check for the response returned by the server side. If the response is anything outside of status code with 200 then error message gets rendered on the webpage else the success message is printed out with the response dictionary returned by the server.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a7abae2a", + "metadata": {}, + "outputs": [], + "source": [ + "def clear_ilo_event_log(_redfishobj, clear_IML_IEL):\n", + "\n", + " clear_log_services_uri = []\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " log_services_uri = systems_members_response.obj['LogServices']['@odata.id']\n", + " log_services_response = _redfishobj.get(log_services_uri)\n", + " log_services_uris = log_services_response.obj['Members']\n", + " for log_services_uri in log_services_uris:\n", + " log_services_response = _redfishobj.get(log_services_uri['@odata.id'])\n", + " clear_log_services_uri.append(log_services_response.obj['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#LogService.' in instance['@odata.type']:\n", + " log_service_uri = instance['@odata.id']\n", + " clear_log_services_uri.append(_redfishobj.get(log_service_uri).dict['Actions']\\\n", + " ['#LogService.ClearLog']['target'])\n", + "\n", + " if clear_log_services_uri:\n", + " body = {\"Action\": \"LogService.ClearLog\"}\n", + " for path in clear_log_services_uri:\n", + " if (\"IEL\" in clear_IML_IEL and \"IEL\" in path) or (\"IML\" in clear_IML_IEL and \\\n", + " \"IML\" in path):\n", + " if \"IEL\" in path:\n", + " sys.stdout.write(\"Clearing IEL log.\\n\")\n", + " else:\n", + " sys.stdout.write(\"Clearing IML log.\\n\")\n", + " resp = _redfishobj.post(path, body)\n", + " else:\n", + " continue\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "331b8289", + "metadata": {}, + "source": [ + "
      \n", + "

      3. The Main function


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + " \n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.

      \n", + "4. If server is down or Unreachable we get server not reachable message!

      \n", + "5. Else if no error is encountered a function call is made i.e. clear_ilo_event_log(REDFISHOBJ, CLEAR_IEL_IML)that is responsible for handling clearing all the IEL and IML logs at the server side.

      \n", + "6. Lastly, REDFISHOBJ.logout logs us out of the system and ends the session.\n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4143942b", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " CLEAR_IML_IEL = \"IML\" # provide either the string IML or IEL\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " clear_ilo_event_log(REDFISHOBJ, CLEAR_IML_IEL)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "f120e784", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f702c0ae", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/set_syslogserver.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/set_syslogserver.ipynb new file mode 100644 index 0000000..14a772b --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/ahs_syslog_iml/set_syslogserver.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b92b79fb", + "metadata": {}, + "source": [ + "# Setting remote syslog server" + ] + }, + { + "cell_type": "markdown", + "id": "2ed959e3", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting remote syslog server
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set remote syslog server. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "3a91bf91", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • ilorest_util
    • \n", + "
    • argparse
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6eed1f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import argparse\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "global DISABLE_RESOURCE_DIR\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "6393e74d", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our set_syslog function overview


      \n", + " This function sets the remote syslog server and enables remote syslog on an iLO system.

      \n", + "1. It takes two parameters:\n", + "
        \n", + "
      • _redfishobj: an object representing the connection to the iLO device through the Redfish API.
      • \n", + "
      • syslog_server: a string representing the IP address or hostname of the remote syslog server.

      \n", + "2. The function first retrieves the model information of the system, which is used to determine the Oem (Original equipment manufacturer) name, as the endpoint structure and payload might differ based on the manufacturer. It determines the model of the server by sending a GET request to the /redfish/v1/Systems/1/ URI and extracting the Model attribute from the response.

      \n", + "3. It checks if the model contains \"Gen9\" or \"Gen8\". If either of them is present, it sets the \"hp\" variable to \"Hp\". Otherwise, it sets it to \"Hpe\".

      \n", + "4. It then constructs the URI for the syslog configuration resource and sends a PATCH request with the request body to set the remote syslog server and enable remote syslog.

      \n", + " 5. Finally, it calls the ilo_response, passing the _redfishobj and resp (response) as arguments. This function handles response from the server.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2971240e", + "metadata": {}, + "outputs": [], + "source": [ + "def set_syslog(_redfishobj, syslog_server):\n", + "\n", + " model_uri = \"/redfish/v1/Systems/1/\"\n", + " model = _redfishobj.get(model_uri).obj['Model']\n", + " print (model)\n", + " if \"Gen9\" in model or 'Gen8' in model:\n", + " hp = \"Hp\"\n", + " else:\n", + " hp = \"Hpe\"\n", + "\n", + " syslog_uri = \"/redfish/v1/Managers/1/NetworkService/\"\n", + "\n", + " body = {\"Oem\": {hp: {\"RemoteSyslogServer\": syslog_server, \"RemoteSyslogEnabled\": True}}}\n", + " resp = _redfishobj.patch(syslog_uri, body)\n", + " ilo_response(_redfishobj, resp)" + ] + }, + { + "cell_type": "markdown", + "id": "1fdc6d56", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is ilo_response function overview


      \n", + " The ilo_response function is responsible for handling the response from the iLO server.

      \n", + "1. It takes two parameters: _redfishobj (Redfish client object) and resp (response object).

      \n", + "2. It checks the status code of the response. If it is equal to 400, it indicates a client error.

      \n", + "3. It tries to extract and print the extended error information from the response using the key error ['@Message.ExtendedInfo'].\n", + "If there is an exception while accessing the extended error information, it writes an error message to the standard error stream.

      \n", + "4. If the status code is not 400 but is not equal to 200 either, it indicates an HTTP response error.\n", + "It writes an error message to the standard error stream, indicating the HTTP response status.

      \n", + "5. If the status code is 200, it indicates a successful response.\n", + "It prints the message \"Success\" to indicate the operation was successful.
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2db998f", + "metadata": {}, + "outputs": [], + "source": [ + "def ilo_response(_redfishobj, resp):\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success\")" + ] + }, + { + "cell_type": "markdown", + "id": "d95a2d40", + "metadata": {}, + "source": [ + "
      \n", + "

      4. This is Main function overview.

      \n", + "1. An argument parser is initialized to parse the command-line arguments passed to the script. The parser expects arguments such as iLO url, username, password, and syslog server IP.

      \n", + "2.The rest opertions are handled by Redfish object which is created by Redfish Client

      \n", + "3. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object. Once you enter everything a redfish object is created with the help of Redfish Client class.

      \n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"

      \n", + "5. The get_gen function is called to retrieve the iLO generation number of the server.\n", + " Depending on the iLO generation number, the set_syslog function is called with the Redfish client object and the syslog server IP address.

      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3681c0d2", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-s',\n", + " '--syslog_server',\n", + " dest='syslog_server',\n", + " action=\"store\",\n", + " required=True,\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " (ilogen,_) = get_gen(redfish_obj)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " set_syslog(redfish_obj, options.syslog_server)\n", + " else:\n", + " set_syslog(redfish_obj, options.syslog_server)\n", + " redfish_obj.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "750b6ae8", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f91c6419", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_iscsi.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_iscsi.ipynb new file mode 100644 index 0000000..6e8dec5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_iscsi.ipynb @@ -0,0 +1,252 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a036d81b", + "metadata": {}, + "source": [ + "# Setting an ISCSI boot instance for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "0ffb0a82", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      Here is an example to set an ISCSI boot instance for HPE iLO systems.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " Also do run each succesive cell of code \n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc60fabf", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b0ad498", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d2c00edc", + "metadata": {}, + "source": [ + "
      \n", + "

      2. Below is a set_bios_iscsi that sets the ISCSI boot instance for HPE iLO systems.


      \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. The function takes two parameters: _redfishobj (a Redfish client object) and iscsi_properties (a dictionary containing the iSCSI properties to be set).

      \n", + "2. It calls the get_resource_directory function to obtain the resource directory from the Redfish service. If DISABLE_RESOURCE_DIR is set to True or the resource directory is empty, the code retrieves the necessary URIs manually.

      \n", + "3. If the resource directory is disabled or not available, the code fetches the systems URI and retrieves the BIOS URI from the response. The code retrieves the iSCSI URI from the BIOS response and fetches the iSCSI data.

      \n", + "4. If the resource directory is enabled and available, the code iterates over the instances in the resource directory and searches for the iSCSI instance based on its type.

      \n", + "5. If the iSCSI data is found, the code loops over the iSCSI sources and checks if the iSCSIBootInstance property matches the current index. If a match is found, the code updates the iSCSI properties for that instance.

      \n", + "6. The code sends a PATCH request to the iSCSI URI with the updated iSCSI sources data.

      \n", + "7. If the response status is 400, indicating an error, the code attempts to print the error message. If the response status is not 200 or 201, an error message is printed.

      \n", + "8. If the response status is 200, the code indicates success and suggests that a system reboot will be required to apply the changes. It also prints the response details.

      \n", + "\n", + "The loop is broken after processing the desired iSCSI instance.\n", + "
      \n", + " \n", + "
      \n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6bfe14a", + "metadata": {}, + "outputs": [], + "source": [ + "def set_bios_iscsi(_redfishobj, iscsi_properties):\n", + "\n", + " iscsi_uri = None\n", + " iscsi_data = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " iscsi_uri = bios_response.obj.Oem.Hpe.Links['iScsi']['@odata.id']\n", + " iscsi_data = _redfishobj.get(iscsi_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiSCSISoftwareInitiator.' in instance['@odata.type']:\n", + " iscsi_uri = instance['@odata.id']\n", + " iscsi_data = _redfishobj.get(iscsi_uri)\n", + "\n", + " if iscsi_data:\n", + " for indx, inst in enumerate(iscsi_data.obj['iSCSISources']):\n", + " if iscsi_properties['iSCSIBootInstance'] == indx:\n", + " iscsi_data.dict['iSCSISources'][indx].update(iscsi_properties)\n", + " resp = _redfishobj.patch(iscsi_uri, {'iSCSISources' : iscsi_data.dict['iSCSISources']})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the\n", + " #iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], \\\n", + " indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " print(json.dumps(resp.ori, indent=4, sort_keys=True))\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \" \\\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! A system reboot will be required to complete the change.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "55289e4d", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + "
        \n", + "
      • Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
      • \n", + "
      • We are passing the required information to change the password of iLO user account i.e. base_url, username, password
      • \n", + "
      • If server is down or Unreachable we get server not reachable message.
      • \n", + "
      • The set_bios_iscsi function is called, passing the RedfishClient object (REDFISHOBJ) and the iSCSI properties dictionary (ISCSI_PROPERTIES).
      • \n", + "\n", + "
      • After setting the iSCSI properties, the logout method of the RedfishClient object is called to end the session with the server.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11b07dec", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #iscsi properties\n", + " ISCSI_PROPERTIES = {\"iSCSIBootInstance\": 2, \\\n", + " \"iSCSITargetName\": \"Target\", \\\n", + " \"iSCSIAttemptName\": \"Empty\", \\\n", + " \"iSCSIConnectRetry\": 5}\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_bios_iscsi(REDFISHOBJ, ISCSI_PROPERTIES)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "9b5acb64", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "1c7d1d0b", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_password.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_password.ipynb new file mode 100644 index 0000000..db9e133 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/bios/set_bios_password.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d357d38b", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting Bios Password" + ] + }, + { + "cell_type": "markdown", + "id": "fce7e904", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      Here is an example to change bios password for HPE iLO system!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " Also do run each succesive cell of code \n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a89aa82f", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e96dc046", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_18168/2847628525.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "828be423", + "metadata": {}, + "source": [ + "
      \n", + "

      2. Below is the set_bios_password function, through which we can change the password of bios system.


      \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the set_bios_setting function we are taking three parameters i.e. Redfish object, new_password and exisiting password as bios_password. Also resource_instances variable is being obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. If the resource directory was disabled we are making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
        \n", + "
      • The information about bios settings is present inside a particular json object of iLO rest api.
      • We just need to navigate to that directory so as to obtain info about bios settings and later make changes to the existing password.
      • For that purpose simply we are making series of get requests.
      • \n", + "
      • After navigating through iLO rest api we actually save the http address of location where bios settings are present inside bios_uri
      • \n", + "
      \n", + "
      \n", + " \n", + "\n", + "3. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
      \n", + "4. If bios_uri is not null after making above operations, we can perform the required actions to change the bios password.
        \n", + "
      • Following up we make get request and obtain the URL of the location where we are actually going to make the changes.
      • Ultimately, we make a post request by passing the bios_change_pass_uri and body dictionary that contains the changes made to the password.
      • \n", + "
      • The job of post request here is to update the password at the provided location and send a response whether the job was done properly or not.
      • \n", + " \n", + " If the reponse status code was anything other than 200 or 201 then we can print out the response status code and error message.
        \n", + " Else we print out success message with the response obtained after making post request.\n", + "
        \n", + " \n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ee515d74", + "metadata": {}, + "outputs": [], + "source": [ + "def set_bios_password(_redfishobj, new_password, bios_password):\n", + "\n", + " bios_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if bios_uri:\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_change_pass_uri = bios_data.obj['Actions']['#Bios.ChangePassword']['target']\n", + " body = dict()\n", + " body[\"PasswordName\"] = \"Administrator\"\n", + " body[\"OldPassword\"] = bios_password\n", + " body[\"NewPassword\"] = new_password\n", + " resp = _redfishobj.post(bios_change_pass_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "1b93c0d7", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + "
        \n", + "
      • Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
      • \n", + "
      • We are passing the required information to change the password of iLO user account i.e. base_url, username, password
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • Once everything is done you are automatically logged out.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38b9fd3a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD =getpass.getpass(\"Enter password: \")\n", + "\n", + " #new BIOS password\n", + " NEW_BIOS_PASSWORD = \"password\"\n", + " #old BIOS password\n", + " OLD_BIOS_PASSWORD = \"password\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_bios_password(REDFISHOBJ, NEW_BIOS_PASSWORD, OLD_BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "34f69788", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "71f23513", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/ilo_license/set_license_key.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/ilo_license/set_license_key.ipynb new file mode 100644 index 0000000..7fc2ed0 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/ilo_license/set_license_key.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7d91ced6", + "metadata": {}, + "source": [ + "# Setting license key " + ] + }, + { + "cell_type": "markdown", + "id": "11b0fe9d", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting license key.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "6cbd5f7c", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0fa1574", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "7daccb24", + "metadata": {}, + "source": [ + "

      2. This is our set_license_key function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the set_license_key function we are taking two parameters i.e. _redfishobj and ilo_key. In the set_license_key function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about license key is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the license service about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The license service information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeiLOLicense type is present in @odata.type attribute then we will store information about license key in ilo_lic_uri and break out of iteration.\n", + "
      \n", + "5. If ilo_lic_uri is not null after making above operations, we can perform the required actions to set license key. \n", + "
        \n", + "
      • The function sends a GET request to the iLO license service to retrieve the current license data. If the ConfirmationRequest field exists, it is printed to the console; otherwise, the LicenseKey field is printed.
      • \n", + "
      • The function sends a POST request to the iLO license service with the new license key provided in the ilo_key argument.
      • \n", + "
      • The job of post request here is to set the license key at the provided location and send a response whether the job was done properly or not.
      • \n", + "
      • If the response status is 400, the function attempts to print the extended error message provided by iLO. If the status is not 200 or 201, the function prints an error message to the console.
      • \n", + "
      • If the response status is 200, the function prints a success message to the console along with the response JSON.
      • \n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bacca62e", + "metadata": {}, + "outputs": [], + "source": [ + "def set_license_key(_redfishobj, ilo_key):\n", + "\n", + " ilo_lic_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " ilo_lic_uri = managers_members_response.obj.Oem.Hpe.Links['LicenseService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiLOLicense.' in instance['@odata.type']:\n", + " ilo_lic_uri = instance['@odata.id']\n", + "\n", + " if ilo_lic_uri:\n", + " ilo_license_collection = _redfishobj.get(ilo_lic_uri)\n", + " ilo_license_member_uri = next(iter(ilo_license_collection.obj['Members']))['@odata.id']\n", + " try:\n", + " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['ConfirmationRequest']\\\n", + " ['EON']\n", + " except KeyError:\n", + " sys.stdout.write(\"This machine will not show the full License Key.\\n\")\n", + " ilo_license_data = _redfishobj.get(ilo_license_member_uri).obj['LicenseKey']\n", + "\n", + " sys.stdout.write(\"Current iLO License Data:\\n\")\n", + " print(json.dumps(ilo_license_data, indent=4, sort_keys=True))\n", + " resp = _redfishobj.post(ilo_lic_uri, {'LicenseKey' : ilo_key})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " sys.stderr.write(\"Check the validity of your license key...\\n\")\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \" \\\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "abfa5bd8", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to set_license_key function to set license key of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38798e69", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # Must be a valid iLO License Key\n", + " ILO_LICENSE_KEY = \"XXXX-XXXX-XXXX-XXXX-XXXXX\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_license_key(REDFISHOBJ, ILO_LICENSE_KEY)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "7d4c55f5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b3be89a3", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb index 8b13789..006b159 100644 --- a/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/index.ipynb @@ -1 +1,244 @@ - +{ + "cells": [ + { + "cell_type": "markdown", + "id": "18ad6013", + "metadata": {}, + "source": [ + "\"HPE" + ] + }, + { + "cell_type": "markdown", + "id": "20da06d1", + "metadata": {}, + "source": [ + "

      Scripts related to ahs_syslog_iml

      " + ] + }, + { + "cell_type": "markdown", + "id": "fa8b0fad", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Clear AHS dataClear active health state data of iLO serverDELETEclear_ahs_data
      Set remote syslog server\tSetting Remote syslog Server for an HPE iLO management processor.PATCHset_syslogserver
      Clear iLO IEL IML log\tClearing out the iLO event log and management log at server sideDELETEclear_ilo_iel_iml_log
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "81721043", + "metadata": {}, + "source": [ + "

      Scripts related to server_manager

      " + ] + }, + { + "cell_type": "markdown", + "id": "cf10b943", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Computer DetailsGet all the available computer/hosts details in iLO\tGETcomputer_details
      Set Server Asset TagSetting server asset tag\tPATCHset_server_asset_tag
      Set UID LightSetting UID LightPATCHset_uid_light
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "01ee71dd", + "metadata": {}, + "source": [ + "

      Scripts related to BIOS

      " + ] + }, + { + "cell_type": "markdown", + "id": "fbce5754", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Set bios passwordChange bios password for HPE iLO systemPATCHset_bios_password
      Set bios ISCSISetting an ISCSI boot instance for HPE iLO systemsPATCHset_bios_iscsi
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "0140b004", + "metadata": {}, + "source": [ + "

      Scripts related to SNMP

      " + ] + }, + { + "cell_type": "markdown", + "id": "d60f6ff8", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Configure SNMPConfiguring SNMP for HPE iLO systemsPATCHconfigure_snmp
      Configure SNMP trap sourceConfiguring SNMP trap source for HPE iLO systemsPATCHconfigure_snmp_trap_source
      Set SNMP alert destinationSetting SNMP alert destination for HPE iLO systemsPATCHset_snmp_alert
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "aff5c9ed", + "metadata": {}, + "source": [ + "

      Scripts related to ilo_license

      " + ] + }, + { + "cell_type": "markdown", + "id": "c9cfb10a", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Set License Key\tSetting License KeyPATCHset_license_key
      \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/computer_details.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/computer_details.ipynb new file mode 100644 index 0000000..5051b63 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/computer_details.ipynb @@ -0,0 +1,230 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a38bafdc", + "metadata": { + "tags": [] + }, + "source": [ + "# Gathering the computer system details" + ] + }, + { + "cell_type": "markdown", + "id": "cfe2e2b6", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      Here is an example to get_computer_details!!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b3fec1a9", + "metadata": {}, + "source": [ + "
      \n", + "

      1. We are importing all the necessary modules from the ilorest library!


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • get_resource_directory
    • \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab7125e9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "8d23d990", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is the function to get the computer details requested.


      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. In the computer_details function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about computer is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the computer data of iLO system.\n", + "
      \n", + "\n", + "3. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if computerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.\n", + " \n", + "
      \n", + " \n", + "5. Finally print the Computer Details through systems_members_response.\n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1b4d0494", + "metadata": {}, + "outputs": [], + "source": [ + "def computer_details(_redfishobj):\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " print(\"\\n\\nPrinting computer system details:\\n\\n\")\n", + " print(json.dumps(systems_members_response.dict, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0de7de8", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " Enter iLO url, Username, Password
      \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, but if Server is not avaialbe we get an error saying \"server unreachable\".
      \n", + "
      \n", + "5. Then we call computer_details with our redfish object.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the iLO.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f538059", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " \n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " computer_details(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "bd337e8f", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f7fd2c36", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_server_asset_tag.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_server_asset_tag.ipynb new file mode 100644 index 0000000..002f766 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_server_asset_tag.ipynb @@ -0,0 +1,248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c3169c50", + "metadata": {}, + "source": [ + "# Setting server asset tag" + ] + }, + { + "cell_type": "markdown", + "id": "70635f68", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting server asset tag.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "f176e2a7", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbe979de", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "616c5812", + "metadata": {}, + "source": [ + "

      3. This is our set_server_asset_tag function overview.

      \n", + "
      \n", + "1. The set_server_asset_tag function sets the server asset tag on an iLO device. The function takes two parameters: _redfishobj and tag. \n", + "
        \n", + "
      • _redfishobj is a Redfish client object that represents the connection to the server
      • \n", + "
      • tag is a string that represents the asset tag to be set for the server.
      • \n", + "

      \n", + "2. In the set_server_asset_tag function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.

      \n", + "3. In the ILO rest api the information about server asset tag is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the server asset tag of iLO system.

      \n", + "4. In the system members response object with different odata_id we get a system uri .\n", + " Then again an http GET request is made and response is stored in system_response.\n", + " Then we set the system_members_uri.\n", + "

      \n", + "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #ComputerSystem attribute is present in @odata.type attribute then we'll set systems_members_uri and get systems_members_response of the user through redfish object.

      \n", + "6.The function then calls the patch() method to update the system's AssetTag property with the new tag provided as input to the function.

      \n", + "7. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", + "8. If the patch() operation is successful, the updated asset tag is printed to the console. The function then waits for 10 seconds before retrieving and displaying the updated asset tag.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4e166b2", + "metadata": {}, + "outputs": [], + "source": [ + "def set_server_asset_tag(_redfishobj, tag):\n", + "\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response and systems_members_uri and tag:\n", + " print(\"Current Asset Tag: \\'%s\\'\\n\" % systems_members_response.dict.get(\"AssetTag\"))\n", + "\n", + " resp = _redfishobj.patch(systems_members_uri, {\"AssetTag\" : tag})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", + " sys.stdout.write(\"\\nUpdated Asset Tag: \\'%s\\'\\n\" % _redfishobj.\\\n", + " get(systems_members_uri).dict.get(\"AssetTag\"))" + ] + }, + { + "cell_type": "markdown", + "id": "ef4f1fb5", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to set_server_asset_tag to set server asset tag of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "606190a9", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #asset tag property in computer systems\n", + " ASSET_TAG = \"Asset01\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_server_asset_tag(REDFISHOBJ, ASSET_TAG)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "bf946980", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "63db964c", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_uid_light.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_uid_light.ipynb new file mode 100644 index 0000000..52df6b8 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/server_manager/set_uid_light.ipynb @@ -0,0 +1,275 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8ce5d6a0", + "metadata": {}, + "source": [ + "# Setting the UID light\n" + ] + }, + { + "cell_type": "markdown", + "id": "5b76e816", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting UID light
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set uid light. This code is written in Python and uses the redfish library to perform the required operations
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0581e350", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "62892493", + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (Temp/ipykernel_9848/2405422628.py, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m File \u001b[1;32m\"C:\\Users\\Win10\\AppData\\Local\\Temp/ipykernel_9848/2405422628.py\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m
      \u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      Here is an example to Setting UID light
      \n", + " This Jupyter Notebook will contains a example code to demonstrate how to set uid light. This code is written in Python and uses the redfish library to perform the required operations

      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " Please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      import sys\n", + "import json\n", + "import time\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "1eb087ac", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our set_uid_light to function overview, in the end this will set uid light.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "1. This is a function that uses the Redfish API to toggle the UID (Universal Identification) LED on a computer system.\n", + " The function takes a Redfish connection object _redfishobj as its only argument.

      \n", + "2. In the set_uid_light function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "

      \n", + "3. In the iLO rest api the information about UID light is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation to and trying to obtain the UID light settings of iLO system.\n", + "

      \n", + "4. In the system members response object with different odata_id we get a system uri . Then again an http GET request is made and response is stored in system_response. Then we set the system_members_uri.

      \n", + "5. Else if resource directory is enabled then we will simply iterate through all instances inside resources and if #ComputerSystem attribute is present in @odata.type attribute then we'll set system_members_uri and get system_members_response settings of the user through redfish object.

      \n", + "6.It sets the body[\"IndicatorLED\"] key to Lit if the current value of the IndicatorLED property is Off, or to \"Off\" otherwise.

      \n", + "7. It sends an HTTP PATCH request to the obtained URI with the body payload to update the IndicatorLED property.

      \n", + "8. If the response status code is not 200 (OK) or 201 (Created), it prints an error message and exits.

      \n", + "9. If the response status code is 200 or 201, it waits for 10 seconds to allow the firmware to update the LED status, and then sends a GET request to the same URI to obtain the updated resource representation of the computer system.

      \n", + "10. It prints the updated value of the IndicatorLED property.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07276165", + "metadata": {}, + "outputs": [], + "source": [ + "def set_uid_light(_redfishobj):\n", + "\n", + " body = dict()\n", + " systems_members_uri = None\n", + " systems_members_response = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#ComputerSystem.' in instance['@odata.type']:\n", + " systems_members_uri = instance['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + "\n", + " if systems_members_response and systems_members_uri:\n", + " print(\"Current Indicator LED Status: \\'%s\\'\\n\" % systems_members_response.dict.\\\n", + " get(\"IndicatorLED\"))\n", + " if \"Off\" in systems_members_response.dict.get(\"IndicatorLED\"):\n", + " print(\"Will illuminate indicator LED.\\n\")\n", + " body[\"IndicatorLED\"] = \"Lit\"\n", + " else:\n", + " print(\"Will extinguish indicator LED.\\n\")\n", + " body[\"IndicatorLED\"] = \"Off\"\n", + "\n", + " resp = _redfishobj.patch(systems_members_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " time.sleep(10) #going to wait 10 seconds before obtaining the LED indicator state\n", + " sys.stdout.write(\"\\nUpdated Indicator LED Status: \\'%s\\'\\n\" % _redfishobj.\\\n", + " get(systems_members_uri).dict['IndicatorLED'])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "70d73b57", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
      \n", + "\n", + "1. The rest opertions are handled by Redfish object which is created by Redfish Client
      \n", + "
      \n", + " \n", + "2. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish object is created with the help of Redfish Client class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call set_uid_light with our redfish object to set UID light.
      \n", + "
      \n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea7ed17c", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_uid_light(REDFISHOBJ)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "3e4a9804", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "377dc76a", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp.ipynb new file mode 100644 index 0000000..d8cbe37 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp.ipynb @@ -0,0 +1,282 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "979defcc", + "metadata": {}, + "source": [ + "# Configuring SNMP for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "a127fdb8", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of configuring SNMP for HPE iLO systems.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "0cf44a38", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ccd0447f", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_4196/1287542820.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory \n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "c988b347", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3804eab", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alerts):\n", + "\n", + " snmp_service_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "6e047370", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials are entered a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to configure_snmp function to obtain snmp related information of system.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "faa032c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: 172.1,14\n", + "Enter Username: hhello\n", + "Enter password: 1245\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[1;31m# Create a Redfish client object\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 27\u001b[1;33m REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n\u001b[0m\u001b[0;32m 28\u001b[0m password=LOGIN_PASSWORD)\n", + "\u001b[1;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_37744/4234067056.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[1;31m# Login with the Redfish client\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[0mREDFISHOBJ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlogin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 31\u001b[1;33m \u001b[1;32mexcept\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mexcp\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 32\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"ERROR: server not reachable or does not support RedFish.\\n\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 33\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address, account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " ALERTS_ENABLED = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_ENABLED, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "id": "337fd6f7", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a45c7e01", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp_trap_source.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp_trap_source.ipynb new file mode 100644 index 0000000..f7941cf --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/configure_snmp_trap_source.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0a6c95aa", + "metadata": {}, + "source": [ + "# Configuring SNMP trap source for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "594a0e06", + "metadata": {}, + "source": [ + "
      \n", + "Welcome to python-iLOrest-library
      This is an example of configuring SNMP trap source for HPE iLO systems.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "25be0e98", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f16a98ad", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_25528/1522814575.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "8c2b4d45", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp service related information.

      \n", + " \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the snmp service information.\n", + "\n", + " \n", + "\n", + " \n", + "1. In the ILO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "2. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "3. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if power snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b53e8e73", + "metadata": {}, + "outputs": [], + "source": [ + " def configure_snmp(_redfishobj):\n", + "\n", + " snmp_service_uri = None\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " # print(managers_members_response.obj['Oem']['Hpe']['Links'])\n", + " # exit(0)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['SNMPService']['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " # resp = _redfishobj.get(snmp_service_uri)\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " # exit(0)\n", + " # TrapSourceHostname : Manager or System\n", + " body = {\"TrapSourceHostname\": \"System\"}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4,\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " # print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b852d783", + "metadata": {}, + "source": [ + "

      3. This is Main function overview.


      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
      \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • If not then we make a call to configure_snmp function to obtain snmp related info of system.
      • \n", + "
      • After getting required information Redfish.logout()closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9cf5c73", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "610979dd", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " if len(sys.argv) <= 3:\n", + " sys.stderr.write(\"ERROR: We need 3 arguments. \\nUsage: change-snmp.py \"\n", + " \"ILOIPADDR ILOUSER ILOPASSWORD \\n\")\n", + " sys.exit()\n", + "\n", + " SYSTEM_URL = \"https://\" + sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " try:\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT,\n", + " password=LOGIN_PASSWORD)\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " configure_snmp(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "80f7da07", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "00b5c8a5", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/set_snmp_alert.ipynb b/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/set_snmp_alert.ipynb new file mode 100644 index 0000000..3af4e93 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Dharitri/snmp/set_snmp_alert.ipynb @@ -0,0 +1,315 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "80ca2bf5", + "metadata": {}, + "source": [ + "# Setting SNMP alert destination" + ] + }, + { + "cell_type": "markdown", + "id": "647c7374", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      This is an example of setting SNMP alert destination.
      As you are here let's get it done easily.
      \n", + " To perform this you need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "ce2b4b70", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.

      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6a53c06", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "cfd0ef73", + "metadata": {}, + "source": [ + "

      2. This is our configure_snmp function overview, in the end this will give us with snmp configure related information.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "\n", + "1. In the configure_snmp function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the iLO rest api the information about snmp is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the snmp about iLO system.\n", + "
      \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The snmp configuration information is ultimately present in the managers_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if snmp is present in @odata.type attribute then we will store information about snmp in snmp_service_uri and break out of iteration.\n", + "
      \n", + "Ultimately if snmp_service_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "269747d5", + "metadata": {}, + "outputs": [], + "source": [ + "def configure_snmp(_redfishobj, read_communities, snmp_alertdestinations, DISABLE_RESOURCE_DIR):\n", + " snmp_service_uri = None\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " snmp_service_uri = managers_members_response.obj.Oem.Hpe.Links['Snmp']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeiLOSnmpService.' in instance['@odata.type']:\n", + " snmp_service_uri = instance['@odata.id']\n", + "\n", + " if snmp_service_uri:\n", + " #body = {\"AlertsEnabled\": snmp_alerts, \"ReadCommunities\": read_communities}\n", + " body = {\"AlertDestinations\": snmp_alertdestinations}\n", + " resp = _redfishobj.patch(snmp_service_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "ca33ee48", + "metadata": {}, + "source": [ + "

      3. This is our set_snmp_alert_destination function overview.

      \n", + "
      \n", + "1. The set_snmp_alert_destination function sets the SNMP alert destinations on an iLO device. The function takes three parameters: _redfishobj, snmp_service_uri, and alert_destination_list. \n", + "
        \n", + "
      • _redfishobj is the Redfish client object.
      • \n", + "
      • snmp_service_uri is the URI for the SNMP service on the iLO device.
      • \n", + "
      • alert_destination_list is a list of dictionaries containing the SNMP alert destinations to set.
      • \n", + "

      \n", + "2. The function gets the current SNMP service data using _redfishobj.get() and checks if the AlertDestinations property is available/modifyable.

      \n", + "3. If the property is available/modifyable, the function sends a PATCH request with the updated alert destinations using _redfishobj.patch().

      \n", + "4. If the iLO device responds with a status code outside of 200 or 201, the function attempts to access the iLO extended message info to see what went wrong.

      \n", + "5. If the patch operation is successful, the function prints the response and gets the updated SNMP alert destination data using _redfishobj.get().

      \n", + "6. The updated SNMP alert destination data is printed to the console using json.dumps() and print().

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c91c0fb8", + "metadata": {}, + "outputs": [], + "source": [ + "def set_snmp_alert_destination(_redfishobj, snmp_service_uri, alert_destination_list):\n", + " data = _redfishobj.get(snmp_service_uri)\n", + " if data.dict.get(\"AlertDestinations\"):\n", + " resp = _redfishobj.patch(snmp_service_uri, {'AlertDestinations': alert_destination_list})\n", + " else:\n", + " raise Exception(\"\\'AlertDestinations\\' property is not available/modifyable.\\n\")\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nPatch operation successful!\\n\\nResponse:\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " snmp_service_response = _redfishobj.get(snmp_service_uri).dict.get('AlertDestinations')\n", + " print(\"\\n\\nPrinting updated SNMP alert destination:\\n\")\n", + " print(json.dumps(snmp_service_response, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "9fdd0d40", + "metadata": {}, + "source": [ + "

      4. This is Main function overview.


      \n", + "The Main function \n", + "
        \n", + "
      • Once your credentials that are enter everything a redfish object is created using the input system URL, login account, and login password with the help of RedfishClient class and a session is created and now you will be logged in to the server.
      • \n", + "
      • If server is down or unreachable we get server not reachable message.
      • \n", + "
      • It checks the generation of iLO by calling the get_gen function and prints the iLO generation.\n", + "
      • If the iLO generation is 5, it calls the configure_snmp function to configure the SNMP service with the read communities and alerts destination, and disable resource directory flag.
      • \n", + "
      • If the iLO generation is not 5, it calls the set_snmp_alert_destination function to set the SNMP alert destination with the alert destination list for iLO4.
      • \n", + "
      • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27378983", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " #SYSTEM_URL = \"https://15.146.46.45\"\n", + " #LOGIN_ACCOUNT = \"admin\"\n", + " #LOGIN_PASSWORD = \"admin123\"\n", + "\n", + " SYSTEM_URL = sys.argv[1]\n", + " LOGIN_ACCOUNT = sys.argv[2]\n", + " LOGIN_PASSWORD = sys.argv[3]\n", + "\n", + " #Properties:\n", + " #read communities array\n", + " READ_COMMUNITIES = [\"public\", \"\", \"\"]\n", + " #alerts_enabled primitive (boolean)\n", + " #ALERTS_ENABLED = True\n", + " #Alert Destination\n", + " ALERTS_DESTINATION = [\"1.1.1.1\",\"2.2.2.2\"]\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + " snmp_service_uri = \"/redfish/v1/Managers/1/SNMPService/\"\n", + "\n", + " # Number of max alert destination supported on iLO4 and iLO5 is different\n", + " alert_destination_list = [\"ILOCN771702NJ\", \"15.146.46.55\" , \"15.146.46.58\"]\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " (ilogen,_) = get_gen(REDFISHOBJ)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " configure_snmp(REDFISHOBJ, READ_COMMUNITIES, ALERTS_DESTINATION, DISABLE_RESOURCE_DIR)\n", + " else:\n", + " set_snmp_alert_destination(REDFISHOBJ, snmp_service_uri, alert_destination_list)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "5a2f6ba5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "28ec396f", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 0957feef851efba9d61f7b35690e8e91021f25ba Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Tue, 16 May 2023 00:28:27 +0530 Subject: [PATCH 041/159] Add files via upload --- .../bios/set_bios_iscsi.ipynb | 252 +++++++++++++++++ .../bios/set_bios_password.ipynb | 260 ++++++++++++++++++ 2 files changed, 512 insertions(+) create mode 100644 example_jupyter_notebooks/bios/set_bios_iscsi.ipynb create mode 100644 example_jupyter_notebooks/bios/set_bios_password.ipynb diff --git a/example_jupyter_notebooks/bios/set_bios_iscsi.ipynb b/example_jupyter_notebooks/bios/set_bios_iscsi.ipynb new file mode 100644 index 0000000..6e8dec5 --- /dev/null +++ b/example_jupyter_notebooks/bios/set_bios_iscsi.ipynb @@ -0,0 +1,252 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a036d81b", + "metadata": {}, + "source": [ + "# Setting an ISCSI boot instance for HPE iLO systems" + ] + }, + { + "cell_type": "markdown", + "id": "0ffb0a82", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      Here is an example to set an ISCSI boot instance for HPE iLO systems.
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " Also do run each succesive cell of code \n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cc60fabf", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b0ad498", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n" + ] + }, + { + "cell_type": "markdown", + "id": "d2c00edc", + "metadata": {}, + "source": [ + "
      \n", + "

      2. Below is a set_bios_iscsi that sets the ISCSI boot instance for HPE iLO systems.


      \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. The function takes two parameters: _redfishobj (a Redfish client object) and iscsi_properties (a dictionary containing the iSCSI properties to be set).

      \n", + "2. It calls the get_resource_directory function to obtain the resource directory from the Redfish service. If DISABLE_RESOURCE_DIR is set to True or the resource directory is empty, the code retrieves the necessary URIs manually.

      \n", + "3. If the resource directory is disabled or not available, the code fetches the systems URI and retrieves the BIOS URI from the response. The code retrieves the iSCSI URI from the BIOS response and fetches the iSCSI data.

      \n", + "4. If the resource directory is enabled and available, the code iterates over the instances in the resource directory and searches for the iSCSI instance based on its type.

      \n", + "5. If the iSCSI data is found, the code loops over the iSCSI sources and checks if the iSCSIBootInstance property matches the current index. If a match is found, the code updates the iSCSI properties for that instance.

      \n", + "6. The code sends a PATCH request to the iSCSI URI with the updated iSCSI sources data.

      \n", + "7. If the response status is 400, indicating an error, the code attempts to print the error message. If the response status is not 200 or 201, an error message is printed.

      \n", + "8. If the response status is 200, the code indicates success and suggests that a system reboot will be required to apply the changes. It also prints the response details.

      \n", + "\n", + "The loop is broken after processing the desired iSCSI instance.\n", + "
      \n", + " \n", + "
      \n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6bfe14a", + "metadata": {}, + "outputs": [], + "source": [ + "def set_bios_iscsi(_redfishobj, iscsi_properties):\n", + "\n", + " iscsi_uri = None\n", + " iscsi_data = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " bios_response = _redfishobj.get(bios_uri)\n", + " iscsi_uri = bios_response.obj.Oem.Hpe.Links['iScsi']['@odata.id']\n", + " iscsi_data = _redfishobj.get(iscsi_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeiSCSISoftwareInitiator.' in instance['@odata.type']:\n", + " iscsi_uri = instance['@odata.id']\n", + " iscsi_data = _redfishobj.get(iscsi_uri)\n", + "\n", + " if iscsi_data:\n", + " for indx, inst in enumerate(iscsi_data.obj['iSCSISources']):\n", + " if iscsi_properties['iSCSIBootInstance'] == indx:\n", + " iscsi_data.dict['iSCSISources'][indx].update(iscsi_properties)\n", + " resp = _redfishobj.patch(iscsi_uri, {'iSCSISources' : iscsi_data.dict['iSCSISources']})\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the\n", + " #iLO extended info error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], \\\n", + " indent=4, sort_keys=True))\n", + " except Exception as excp:\n", + " print(json.dumps(resp.ori, indent=4, sort_keys=True))\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \" \\\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! A system reboot will be required to complete the change.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "55289e4d", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + "
        \n", + "
      • Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
      • \n", + "
      • We are passing the required information to change the password of iLO user account i.e. base_url, username, password
      • \n", + "
      • If server is down or Unreachable we get server not reachable message.
      • \n", + "
      • The set_bios_iscsi function is called, passing the RedfishClient object (REDFISHOBJ) and the iSCSI properties dictionary (ISCSI_PROPERTIES).
      • \n", + "\n", + "
      • After setting the iSCSI properties, the logout method of the RedfishClient object is called to end the session with the server.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11b07dec", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #iscsi properties\n", + " ISCSI_PROPERTIES = {\"iSCSIBootInstance\": 2, \\\n", + " \"iSCSITargetName\": \"Target\", \\\n", + " \"iSCSIAttemptName\": \"Empty\", \\\n", + " \"iSCSIConnectRetry\": 5}\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_bios_iscsi(REDFISHOBJ, ISCSI_PROPERTIES)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "9b5acb64", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "1c7d1d0b", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/example_jupyter_notebooks/bios/set_bios_password.ipynb b/example_jupyter_notebooks/bios/set_bios_password.ipynb new file mode 100644 index 0000000..db9e133 --- /dev/null +++ b/example_jupyter_notebooks/bios/set_bios_password.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d357d38b", + "metadata": { + "tags": [] + }, + "source": [ + "# Setting Bios Password" + ] + }, + { + "cell_type": "markdown", + "id": "fce7e904", + "metadata": {}, + "source": [ + "
      \n", + " Welcome to python-iLOrest-library
      Here is an example to change bios password for HPE iLO system!!
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + " Also do run each succesive cell of code \n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a89aa82f", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary modules from the ilorest library.


      \n", + "
    • sys \n", + "
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e96dc046", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_18168/2847628525.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from get_resource_directory import get_resource_directory\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "828be423", + "metadata": {}, + "source": [ + "
      \n", + "

      2. Below is the set_bios_password function, through which we can change the password of bios system.


      \n", + " There is a hierarchy involved in iLO Rest Api and everything is in form of JSON objects i.e. name-value pairs. So we are simply following the hierarchy to navigate to required information.\n", + "\n", + "1. In the set_bios_setting function we are taking three parameters i.e. Redfish object, new_password and exisiting password as bios_password. Also resource_instances variable is being obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. If the resource directory was disabled we are making a series of http GET. requests to the server so as to obtain info about bios settings.\n", + "
        \n", + "
      • The information about bios settings is present inside a particular json object of iLO rest api.
      • We just need to navigate to that directory so as to obtain info about bios settings and later make changes to the existing password.
      • For that purpose simply we are making series of get requests.
      • \n", + "
      • After navigating through iLO rest api we actually save the http address of location where bios settings are present inside bios_uri
      • \n", + "
      \n", + "
      \n", + " \n", + "\n", + "3. Else if the resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if #bios attribute is present in @odata.type attribute then we'll store information about bios settings of the system inside of bios_data variable and break out of iteration.\n", + "
      \n", + "4. If bios_uri is not null after making above operations, we can perform the required actions to change the bios password.
        \n", + "
      • Following up we make get request and obtain the URL of the location where we are actually going to make the changes.
      • Ultimately, we make a post request by passing the bios_change_pass_uri and body dictionary that contains the changes made to the password.
      • \n", + "
      • The job of post request here is to update the password at the provided location and send a response whether the job was done properly or not.
      • \n", + " \n", + " If the reponse status code was anything other than 200 or 201 then we can print out the response status code and error message.
        \n", + " Else we print out success message with the response obtained after making post request.\n", + "
        \n", + " \n", + "
      \n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ee515d74", + "metadata": {}, + "outputs": [], + "source": [ + "def set_bios_password(_redfishobj, new_password, bios_password):\n", + "\n", + " bios_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " bios_uri = systems_members_response.obj['Bios']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#Bios.' in instance['@odata.type']:\n", + " bios_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if bios_uri:\n", + " bios_data = _redfishobj.get(bios_uri)\n", + " bios_change_pass_uri = bios_data.obj['Actions']['#Bios.ChangePassword']['target']\n", + " body = dict()\n", + " body[\"PasswordName\"] = \"Administrator\"\n", + " body[\"OldPassword\"] = bios_password\n", + " body[\"NewPassword\"] = new_password\n", + " resp = _redfishobj.post(bios_change_pass_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "1b93c0d7", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
      \n", + "
        \n", + "
      • Once you enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
      • \n", + "
      • We are passing the required information to change the password of iLO user account i.e. base_url, username, password
      • \n", + "
      • If server is down or Unreachable we get server not reachable message!
      • \n", + "
      • Once everything is done you are automatically logged out.
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38b9fd3a", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD =getpass.getpass(\"Enter password: \")\n", + "\n", + " #new BIOS password\n", + " NEW_BIOS_PASSWORD = \"password\"\n", + " #old BIOS password\n", + " OLD_BIOS_PASSWORD = \"password\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_bios_password(REDFISHOBJ, NEW_BIOS_PASSWORD, OLD_BIOS_PASSWORD)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "34f69788", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally : use the following values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "71f23513", + "metadata": {}, + "source": [ + "
      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 0a3e473b13335cd5c690414dcc888d1b3a54816f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 May 2023 02:57:43 +0530 Subject: [PATCH 042/159] added all 12 scripts --- .../.ipynb_checkpoints/index-checkpoint.ipynb | 74 ++++- .../Bhuvan/BIOS/BIOS_RevertToDefault.ipynb | 6 +- ...ftware_Firmware_Inventory-checkpoint.ipynb | 295 ++++++++++++++++++ .../Software_Firmware_Inventory.ipynb | 295 ++++++++++++++++++ .../Expand_data-checkpoint.ipynb | 223 +++++++++++++ .../Bhuvan/MISCELLANEOUS/Expand_data.ipynb | 223 +++++++++++++ .../Get_Powermetrics_Average-checkpoint.ipynb | 267 ++++++++++++++++ .../POWER/Get_Powermetrics_Average.ipynb | 267 ++++++++++++++++ .../HPECTY/Bhuvan/index.ipynb | 74 ++++- python-ilorest-library | 1 + 10 files changed, 1720 insertions(+), 5 deletions(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb create mode 160000 python-ilorest-library diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb index 8fb312c..6bb46a5 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/.ipynb_checkpoints/index-checkpoint.ipynb @@ -161,6 +161,12 @@ " \n", " Update_iLO_Firmware\n", " \n", + " \n", + " View Firmware Inventory\n", + " Script for viewing the firmware inventory on HPE iLO systems\n", + " \n", + " Software_Firmware_Inventory\n", + " \n", " \n", "\n" ] @@ -198,10 +204,76 @@ "\n" ] }, + { + "cell_type": "markdown", + "id": "a0d4cfe3", + "metadata": {}, + "source": [ + "

      Scripts related to Power

      " + ] + }, + { + "cell_type": "markdown", + "id": "e8055b18", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Get Power Metrics AverageScript for gathering the power metrics average on HPE iLO systemsGet_Powermetrics_Average
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "bcbac905", + "metadata": {}, + "source": [ + "

      Miscellaneous Scripts

      " + ] + }, + { + "cell_type": "markdown", + "id": "610e17bf", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Example Data ResopnsesExample Script for expanding data responsesExpand_data
      \n" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "7e5e8be8", + "id": "347cbdcf", "metadata": {}, "outputs": [], "source": [] diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb index d2ec941..6175c59 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb @@ -275,9 +275,9 @@ "
      \n", " In case you need help 🔗 links to relevant resources :\n", "
      \n", - " 1.Python-ilorest-library: LINK
      \n", - " 2.HPE ilorest-api explorer: LINK
      \n", - " 3.REST API: LINK
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", " \n", "
      " ] diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb new file mode 100644 index 0000000..f9ea666 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "90595900", + "metadata": {}, + "source": [ + "

      Script for viewing the firmware inventory on HPE iLO systems

      " + ] + }, + { + "cell_type": "markdown", + "id": "887d7741", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to view firmware inventory on HPE iLO Systems. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "830d2b30", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a88487d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "827bf8e1", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our get_inventory_uri function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. This function initializes the update_service_uri and inventory_uri variables to None.

      \n", + " \n", + "2. Call the get_resource_directory() function by passing _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or disabled, find the relevant URI by navigating through the server's API.

      \n", + "\n", + "3. If the resource directory is available, find the relevant URI from the resource directory.

      \n", + "\n", + "4. Check if update_service_uri has been set. If update_service_uri is not None, retrieve the URI for the update service.

      \n", + "\n", + "5. Retrieve the update service response using the get() method on _redfishobj. If the provided selection contains the word \"software\" (case insensitive), set the inventory_uri to the URI of the software inventory obtained from the update service response.

      \n", + "\n", + "6. If the provided selection contains the word \"firmware\" (case insensitive), set the inventory_uri to the URI of the firmware inventory obtained from the update service response.

      \n", + " \n", + "7. If an invalid selection is provided, raise an exception with an error message.

      \n", + " \n", + "8. Print the inventory URI.

      \n", + " \n", + "9. Call the get_inventory() function, passing _redfishobj and inventory_uri as parameters.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a11214ba", + "metadata": {}, + "outputs": [], + "source": [ + "def get_inventory_uri(_redfishobj, select):\n", + "\n", + " update_service_uri = None\n", + " inventory_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " if update_service_uri:\n", + " update_service_resp = _redfishobj.get(update_service_uri)\n", + " if \"software\" in select.lower():\n", + " inventory_uri = update_service_resp.obj['SoftwareInventory']['@odata.id']\n", + " elif \"firmware\" in select.lower():\n", + " inventory_uri = update_service_resp.obj['FirmwareInventory']['@odata.id']\n", + " else:\n", + " raise Exception(\"Invalid selection provided: Please select 'software' or 'firmware' to obtain the relevant invetory data.\")\n", + " sys.stdout.write(\"Printing data in invetory: %s\\n\" % inventory_uri)\n", + " get_inventory(_redfishobj, inventory_uri)" + ] + }, + { + "cell_type": "markdown", + "id": "c329bc0f", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is our get_inventory function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. This function retrieves the list of members from the provided inventory_uri using the get() method on _redfishobj.

      \n", + " \n", + "2. If there are no members in the inventory, print a message indicating that the inventory is empty.

      \n", + "\n", + "3. Iterate over each inventory item in the list of members.

      \n", + "\n", + "4. Retrieve the details of each inventory item using the get() method on _redfishobj with the item's URI.

      \n", + "\n", + "5. Print the name and description of the inventory item.

      \n", + "\n", + "6. Print the JSON-formatted contents of the inventory item.

      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ea93329", + "metadata": {}, + "outputs": [], + "source": [ + "def get_inventory(_redfishobj, inventory_uri):\n", + "\n", + " _members = _redfishobj.get(inventory_uri).obj['Members']\n", + " if not _members:\n", + " sys.stderr.write(\"\\tInventory empty.\\n\")\n", + " else:\n", + " for inventory_item in _members:\n", + " _resp = _redfishobj.get(inventory_item['@odata.id'])\n", + " sys.stdout.write(\"Printing contents of inventory item, \\'%s\\':\\'%s\\'\\n\" % (_resp.dict.get('Name'), _resp.dict.get('Description')))\n", + " print(json.dumps(_resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "3c50b324", + "metadata": {}, + "source": [ + "
      \n", + "

      4. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "5. SELECT variable is by default set to 'firmware'. But one can choose either 'software' or 'firmware' for inventory selection.

      \n", + " \n", + "6. Then we call get_inventory_uri with our redfish object and SELECT variable.
      \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "91f1a8a5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ccf0065", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " \n", + " SELECT = \"firmware\" #provide either 'software' or 'firmware' for inventory selection\n", + " \n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_inventory_uri(REDFISHOBJ, SELECT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "eb99bfc3", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00c564f3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb new file mode 100644 index 0000000..f9ea666 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "90595900", + "metadata": {}, + "source": [ + "

      Script for viewing the firmware inventory on HPE iLO systems

      " + ] + }, + { + "cell_type": "markdown", + "id": "887d7741", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to view firmware inventory on HPE iLO Systems. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "830d2b30", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a88487d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "827bf8e1", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our get_inventory_uri function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. This function initializes the update_service_uri and inventory_uri variables to None.

      \n", + " \n", + "2. Call the get_resource_directory() function by passing _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or disabled, find the relevant URI by navigating through the server's API.

      \n", + "\n", + "3. If the resource directory is available, find the relevant URI from the resource directory.

      \n", + "\n", + "4. Check if update_service_uri has been set. If update_service_uri is not None, retrieve the URI for the update service.

      \n", + "\n", + "5. Retrieve the update service response using the get() method on _redfishobj. If the provided selection contains the word \"software\" (case insensitive), set the inventory_uri to the URI of the software inventory obtained from the update service response.

      \n", + "\n", + "6. If the provided selection contains the word \"firmware\" (case insensitive), set the inventory_uri to the URI of the firmware inventory obtained from the update service response.

      \n", + " \n", + "7. If an invalid selection is provided, raise an exception with an error message.

      \n", + " \n", + "8. Print the inventory URI.

      \n", + " \n", + "9. Call the get_inventory() function, passing _redfishobj and inventory_uri as parameters.

      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a11214ba", + "metadata": {}, + "outputs": [], + "source": [ + "def get_inventory_uri(_redfishobj, select):\n", + "\n", + " update_service_uri = None\n", + " inventory_uri = None\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " if update_service_uri:\n", + " update_service_resp = _redfishobj.get(update_service_uri)\n", + " if \"software\" in select.lower():\n", + " inventory_uri = update_service_resp.obj['SoftwareInventory']['@odata.id']\n", + " elif \"firmware\" in select.lower():\n", + " inventory_uri = update_service_resp.obj['FirmwareInventory']['@odata.id']\n", + " else:\n", + " raise Exception(\"Invalid selection provided: Please select 'software' or 'firmware' to obtain the relevant invetory data.\")\n", + " sys.stdout.write(\"Printing data in invetory: %s\\n\" % inventory_uri)\n", + " get_inventory(_redfishobj, inventory_uri)" + ] + }, + { + "cell_type": "markdown", + "id": "c329bc0f", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is our get_inventory function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. This function retrieves the list of members from the provided inventory_uri using the get() method on _redfishobj.

      \n", + " \n", + "2. If there are no members in the inventory, print a message indicating that the inventory is empty.

      \n", + "\n", + "3. Iterate over each inventory item in the list of members.

      \n", + "\n", + "4. Retrieve the details of each inventory item using the get() method on _redfishobj with the item's URI.

      \n", + "\n", + "5. Print the name and description of the inventory item.

      \n", + "\n", + "6. Print the JSON-formatted contents of the inventory item.

      \n", + " \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ea93329", + "metadata": {}, + "outputs": [], + "source": [ + "def get_inventory(_redfishobj, inventory_uri):\n", + "\n", + " _members = _redfishobj.get(inventory_uri).obj['Members']\n", + " if not _members:\n", + " sys.stderr.write(\"\\tInventory empty.\\n\")\n", + " else:\n", + " for inventory_item in _members:\n", + " _resp = _redfishobj.get(inventory_item['@odata.id'])\n", + " sys.stdout.write(\"Printing contents of inventory item, \\'%s\\':\\'%s\\'\\n\" % (_resp.dict.get('Name'), _resp.dict.get('Description')))\n", + " print(json.dumps(_resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "3c50b324", + "metadata": {}, + "source": [ + "
      \n", + "

      4. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "5. SELECT variable is by default set to 'firmware'. But one can choose either 'software' or 'firmware' for inventory selection.

      \n", + " \n", + "6. Then we call get_inventory_uri with our redfish object and SELECT variable.
      \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "91f1a8a5", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ccf0065", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " \n", + " SELECT = \"firmware\" #provide either 'software' or 'firmware' for inventory selection\n", + " \n", + " DISABLE_RESOURCE_DIR = True\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_inventory_uri(REDFISHOBJ, SELECT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "eb99bfc3", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00c564f3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb new file mode 100644 index 0000000..d82c82a --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb @@ -0,0 +1,223 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b6480262", + "metadata": {}, + "source": [ + "

      Example of expanding data responses

      " + ] + }, + { + "cell_type": "markdown", + "id": "051ce734", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to expand a data response. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "58eab40d", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfa6671a", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "c5f4583b", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our expand_data function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The expand_data function takes two parameters: _redfishobj and expand_url, with a default value of \"/redfish/v1/\" for expand_url.

      \n", + " \n", + "2. It sends a GET request to the _redfishobj (Redfish object) using the provided expand_url to retrieve the response.

      \n", + "\n", + "3. Another GET request is sent to the _redfishobj with the expand_url appended with ?$expand=.. This request is used to retrieve an expanded response.

      \n", + "\n", + "4. The function then prints the standard response to the standard output stream.

      \n", + "\n", + "5. The standard response, represented as a dictionary, is printed.

      \n", + "\n", + "6. Next, the function prints the expanded response to the standard output stream.

      \n", + " \n", + "7. The expanded response, represented as a dictionary, is printed.
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "509e8725", + "metadata": {}, + "outputs": [], + "source": [ + "def expand_data(_redfishobj, expand_url=\"/redfish/v1/\"):\n", + "\n", + " response = _redfishobj.get(expand_url)\n", + " exp_response = _redfishobj.get(expand_url+'?$expand=.')\n", + " sys.stdout.write('Standard response:\\n')\n", + " sys.stdout.write('\\t'+str(response.dict)+'\\n')\n", + " sys.stdout.write('Expanded response:\\n')\n", + " sys.stdout.write('\\t'+str(exp_response.dict)+'\\n')" + ] + }, + { + "cell_type": "markdown", + "id": "523f5bda", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to get the power metrics average.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "5. When prompted for URL, enter the URL that you want to be expanded. Example: /redfish/v1/systems/

      \n", + " \n", + "6. Then we call expand_data with our redfish object and EXPAND_URL.
      \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b80bdfed", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eabae678", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " #url to be expanded\n", + " EXPAND_URL = input(\"Enter the URL that is to be expanded (Ex: /redfish/v1/systems/)\")\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " expand_data(REDFISHOBJ, EXPAND_URL)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "76b99be7", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d2bbf56", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb new file mode 100644 index 0000000..d82c82a --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb @@ -0,0 +1,223 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b6480262", + "metadata": {}, + "source": [ + "

      Example of expanding data responses

      " + ] + }, + { + "cell_type": "markdown", + "id": "051ce734", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to expand a data response. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "58eab40d", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfa6671a", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "c5f4583b", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our expand_data function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The expand_data function takes two parameters: _redfishobj and expand_url, with a default value of \"/redfish/v1/\" for expand_url.

      \n", + " \n", + "2. It sends a GET request to the _redfishobj (Redfish object) using the provided expand_url to retrieve the response.

      \n", + "\n", + "3. Another GET request is sent to the _redfishobj with the expand_url appended with ?$expand=.. This request is used to retrieve an expanded response.

      \n", + "\n", + "4. The function then prints the standard response to the standard output stream.

      \n", + "\n", + "5. The standard response, represented as a dictionary, is printed.

      \n", + "\n", + "6. Next, the function prints the expanded response to the standard output stream.

      \n", + " \n", + "7. The expanded response, represented as a dictionary, is printed.
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "509e8725", + "metadata": {}, + "outputs": [], + "source": [ + "def expand_data(_redfishobj, expand_url=\"/redfish/v1/\"):\n", + "\n", + " response = _redfishobj.get(expand_url)\n", + " exp_response = _redfishobj.get(expand_url+'?$expand=.')\n", + " sys.stdout.write('Standard response:\\n')\n", + " sys.stdout.write('\\t'+str(response.dict)+'\\n')\n", + " sys.stdout.write('Expanded response:\\n')\n", + " sys.stdout.write('\\t'+str(exp_response.dict)+'\\n')" + ] + }, + { + "cell_type": "markdown", + "id": "523f5bda", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to get the power metrics average.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + " \n", + "5. When prompted for URL, enter the URL that you want to be expanded. Example: /redfish/v1/systems/

      \n", + " \n", + "6. Then we call expand_data with our redfish object and EXPAND_URL.
      \n", + " \n", + "\n", + "7. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "b80bdfed", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eabae678", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " #url to be expanded\n", + " EXPAND_URL = input(\"Enter the URL that is to be expanded (Ex: /redfish/v1/systems/)\")\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " expand_data(REDFISHOBJ, EXPAND_URL)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "markdown", + "id": "76b99be7", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d2bbf56", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb new file mode 100644 index 0000000..b26edc4 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb @@ -0,0 +1,267 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "029d388f", + "metadata": {}, + "source": [ + "

      Gathering the power metrics average on HPE iLO systems

      " + ] + }, + { + "cell_type": "markdown", + "id": "e04b1c54", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to gather power metrics average. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "41203a2d", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "dc837b94", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_25992/2798673744.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "db36318d", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our get_powermetrics_average function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The function get_powermetrics_average takes _redfishobj as a parameter, which represents the Redfish object used to interact with the server.\n", + "
      \n", + " \n", + "2. It initializes the variable power_metrics_uri to None.\n", + "
      \n", + "\n", + "3. The function attempts to retrieve the resource directory using the _redfishobj.get_resource_directory() method. If the resource directory is disabled or not available, it follows an alternative approach to find the relevant URI.\n", + "
      \n", + "\n", + "4. If the resource directory is disabled or not available, it retrieves the chassis URI from the root object using _redfishobj.root.obj['Chassis']['@odata.id'] and makes a GET request to obtain the chassis response.\n", + "
      \n", + "\n", + "5. Within the chassis members response, it retrieves the URI for power metrics under the HPE OEM namespace using chassis_members_response.obj.Oem.Hpe['Power']['@odata.id']. This URI represents the power metrics data.\n", + "
      \n", + "\n", + "6. If the resource directory is available, the function iterates through the resource instances obtained from the resource directory.\n", + "
      \n", + " \n", + "7. It checks if the @odata.type of the instance contains '#Power.', indicating that it represents power metrics. If found, it sets the power_metrics_uri variable to the @odata.id of the instance and breaks the loop.\n", + "
      \n", + " \n", + "8. If the power_metrics_uri is not None, it makes a GET request to retrieve the power metrics data using _redfishobj.get(power_metrics_uri).obj.Oem.Hpe.\n", + "
      \n", + " \n", + " \n", + "9. The function then prints the power data, represented as a JSON object.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b5104a8", + "metadata": {}, + "outputs": [], + "source": [ + "def get_powermetrics_average(_redfishobj):\n", + "\n", + " power_metrics_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " chassis_uri = _redfishobj.root.obj['Chassis']['@odata.id']\n", + " chassis_response = _redfishobj.get(chassis_uri)\n", + " chassis_members_uri = next(iter(chassis_response.obj['Members']))['@odata.id']\n", + " chassis_members_response = _redfishobj.get(chassis_members_uri)\n", + " power_metrics_uri = chassis_members_response.obj.Oem.Hpe['Power']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#Power.' in instance['@odata.type']:\n", + " power_metrics_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if power_metrics_uri:\n", + " power_metrics_data = _redfishobj.get(power_metrics_uri).obj.Oem.Hpe\n", + " print(\"\\n\\nPower Data:\\n\\n\")\n", + " print(json.dumps(power_metrics_data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "d38fc2fb", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to get the power metrics average.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call get_powermetrics_average with our redfish object.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a4d2be84", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1399a2d5", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_powermetrics_average(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "dcb75619", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "045e852d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb new file mode 100644 index 0000000..b26edc4 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb @@ -0,0 +1,267 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "029d388f", + "metadata": {}, + "source": [ + "

      Gathering the power metrics average on HPE iLO systems

      " + ] + }, + { + "cell_type": "markdown", + "id": "e04b1c54", + "metadata": {}, + "source": [ + "
      \n", + "
        \n", + "
      • This Jupyter Notebook will contains a example code to demonstrate how to gather power metrics average. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", + "
      • As you are here let's get it done easily.
      • \n", + "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • Please keep your username and password handy
      • \n", + "
      • Do execute each successive cell once to avoid any errors!
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "41203a2d", + "metadata": {}, + "source": [ + "
      \n", + "

      1. Below we are importing all the necessary python libraries

      \n", + "
        \n", + "
      • sys
      • \n", + "
      • json
      • \n", + "
      • redfish
      • \n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "dc837b94", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_25992/2798673744.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "db36318d", + "metadata": {}, + "source": [ + "
      \n", + "

      2. This is our get_powermetrics_average function overview.


      \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to do this.
      \n", + "\n", + "1. The function get_powermetrics_average takes _redfishobj as a parameter, which represents the Redfish object used to interact with the server.\n", + "
      \n", + " \n", + "2. It initializes the variable power_metrics_uri to None.\n", + "
      \n", + "\n", + "3. The function attempts to retrieve the resource directory using the _redfishobj.get_resource_directory() method. If the resource directory is disabled or not available, it follows an alternative approach to find the relevant URI.\n", + "
      \n", + "\n", + "4. If the resource directory is disabled or not available, it retrieves the chassis URI from the root object using _redfishobj.root.obj['Chassis']['@odata.id'] and makes a GET request to obtain the chassis response.\n", + "
      \n", + "\n", + "5. Within the chassis members response, it retrieves the URI for power metrics under the HPE OEM namespace using chassis_members_response.obj.Oem.Hpe['Power']['@odata.id']. This URI represents the power metrics data.\n", + "
      \n", + "\n", + "6. If the resource directory is available, the function iterates through the resource instances obtained from the resource directory.\n", + "
      \n", + " \n", + "7. It checks if the @odata.type of the instance contains '#Power.', indicating that it represents power metrics. If found, it sets the power_metrics_uri variable to the @odata.id of the instance and breaks the loop.\n", + "
      \n", + " \n", + "8. If the power_metrics_uri is not None, it makes a GET request to retrieve the power metrics data using _redfishobj.get(power_metrics_uri).obj.Oem.Hpe.\n", + "
      \n", + " \n", + " \n", + "9. The function then prints the power data, represented as a JSON object.\n", + "
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b5104a8", + "metadata": {}, + "outputs": [], + "source": [ + "def get_powermetrics_average(_redfishobj):\n", + "\n", + " power_metrics_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " chassis_uri = _redfishobj.root.obj['Chassis']['@odata.id']\n", + " chassis_response = _redfishobj.get(chassis_uri)\n", + " chassis_members_uri = next(iter(chassis_response.obj['Members']))['@odata.id']\n", + " chassis_members_response = _redfishobj.get(chassis_members_uri)\n", + " power_metrics_uri = chassis_members_response.obj.Oem.Hpe['Power']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#Power.' in instance['@odata.type']:\n", + " power_metrics_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if power_metrics_uri:\n", + " power_metrics_data = _redfishobj.get(power_metrics_uri).obj.Oem.Hpe\n", + " print(\"\\n\\nPower Data:\\n\\n\")\n", + " print(json.dumps(power_metrics_data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "d38fc2fb", + "metadata": {}, + "source": [ + "
      \n", + "

      3. This is Main function overview.

      \n", + "
      \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to get the power metrics average.\n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
      \n", + "
      \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
      \n", + "
      \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
      \n", + "
      \n", + "\n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
      \n", + "
      \n", + "5. Then we call get_powermetrics_average with our redfish object.
      \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "a4d2be84", + "metadata": {}, + "source": [ + "
      \n", + " When running on the server locally,use the following values:
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " \"https://10.0.0.100\"
      \n", + " \"https://ilo.hostname\"\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1399a2d5", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_powermetrics_average(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "dcb75619", + "metadata": {}, + "source": [ + "
      \n", + " In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1. Python-ilorest-library: LINK
      \n", + " 2. HPE ilorest-api explorer: LINK
      \n", + " 3. REST API: LINK
      \n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "045e852d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb index 8fb312c..6bb46a5 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/index.ipynb @@ -161,6 +161,12 @@ " \n", " Update_iLO_Firmware\n", " \n", + " \n", + " View Firmware Inventory\n", + " Script for viewing the firmware inventory on HPE iLO systems\n", + " \n", + " Software_Firmware_Inventory\n", + " \n", " \n", "\n" ] @@ -198,10 +204,76 @@ "\n" ] }, + { + "cell_type": "markdown", + "id": "a0d4cfe3", + "metadata": {}, + "source": [ + "

      Scripts related to Power

      " + ] + }, + { + "cell_type": "markdown", + "id": "e8055b18", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Get Power Metrics AverageScript for gathering the power metrics average on HPE iLO systemsGet_Powermetrics_Average
      \n" + ] + }, + { + "cell_type": "markdown", + "id": "bcbac905", + "metadata": {}, + "source": [ + "

      Miscellaneous Scripts

      " + ] + }, + { + "cell_type": "markdown", + "id": "610e17bf", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
      OPERATIONDESCRIPTIONMETHODLOCATION
      Example Data ResopnsesExample Script for expanding data responsesExpand_data
      \n" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "7e5e8be8", + "id": "347cbdcf", "metadata": {}, "outputs": [], "source": [] diff --git a/python-ilorest-library b/python-ilorest-library new file mode 160000 index 0000000..97888a5 --- /dev/null +++ b/python-ilorest-library @@ -0,0 +1 @@ +Subproject commit 97888a5fcadd0fee338caedda287bb7c6c804a32 From 1b59aa46324c55798d27b6d602b752132f34dc6d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 May 2023 22:44:19 +0530 Subject: [PATCH 043/159] bhuvan - made corrections --- .../enable_secure_boot-checkpoint.ipynb | 250 ++++++++++++ .../B VENKAT RAHUL/enable_secure_boot.ipynb | 2 +- .../BIOS_ChangeSettings-checkpoint.ipynb | 27 +- .../BIOS_RevertToDefault-checkpoint.ipynb | 19 +- .../Bhuvan/BIOS/BIOS_ChangeSettings.ipynb | 27 +- .../Bhuvan/BIOS/BIOS_RevertToDefault.ipynb | 19 +- .../Change_Boot_Order-checkpoint.ipynb | 15 +- .../Change_Temp_Boot_Order-checkpoint.ipynb | 15 +- .../Bhuvan/BOOT/Change_Boot_Order.ipynb | 15 +- .../Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb | 15 +- .../Test_ESKM_Connection-checkpoint.ipynb | 14 +- .../Bhuvan/ESKM/Test_ESKM_Connection.ipynb | 14 +- ...ftware_Firmware_Inventory-checkpoint.ipynb | 13 +- .../Update_iLO_Firmware-checkpoint.ipynb | 13 +- ...epository_with_COMPSIG.py-checkpoint.ipynb | 12 +- ...irmware_to_iLO_repository-checkpoint.ipynb | 19 +- .../Software_Firmware_Inventory.ipynb | 13 +- .../Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb | 13 +- ...mware_iLO_Repository_with_COMPSIG.py.ipynb | 12 +- .../Upload_firmware_to_iLO_repository.ipynb | 13 +- .../Expand_data-checkpoint.ipynb | 26 +- .../Bhuvan/MISCELLANEOUS/Expand_data.ipynb | 26 +- .../Get_Powermetrics_Average-checkpoint.ipynb | 13 +- .../POWER/Get_Powermetrics_Average.ipynb | 13 +- .../Add_user_account-checkpoint.ipynb | 355 +++++++++++++++--- .../Bhuvan/USERS/Add_user_account.ipynb | 61 ++- 26 files changed, 803 insertions(+), 231 deletions(-) create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb new file mode 100644 index 0000000..a49f015 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b44c9aad", + "metadata": {}, + "source": [ + "
      \n", + "Hello User.!
      Welcome to python-iLOrest-library
      This is an example of enabling secure boot
      As you are here let's get it done easily.
      \n", + " To perform this u need to have python-ilorest-library installed in your machine.
      \n", + " And please keep your username and password handy!\n", + "
      \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "74ee46a2", + "metadata": {}, + "source": [ + "
      \n", + "

      1.

      \n", + " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below
      \n", + " \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3b9ca27", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "d0e073c6", + "metadata": {}, + "source": [ + "

      2.

      This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.
      \n", + " Let me give you a walk through of it!\n", + "
      \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", + "\n", + "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
      \n", + " \n", + "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", + " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", + "
      \n", + "\n", + "3. In the systems response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in systems_members_response.\n", + " The secure boot information is ultimately present in the systems_members_response.\n", + "
      \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", + "
      \n", + "\n", + "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
      " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d60549e", + "metadata": {}, + "outputs": [], + "source": [ + "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", + "\n", + " secure_boot_uri = None\n", + " secure_boot_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#SecureBoot.' in instance['@odata.type']:\n", + " secure_boot_uri = instance['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + "\n", + " if secure_boot_data:\n", + " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if secure_boot_uri:\n", + " body = {'SecureBootEnable': secure_boot_enable}\n", + " resp = _redfishobj.patch(secure_boot_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b227f8f6", + "metadata": {}, + "source": [ + "
      \n", + "

      The Main function:

      \n", + "

      Please enter your login credentials here to proceed further:

      \n", + "
        \n", + "
      • Once your credentials are entered, a Redfish object is created with the help of the RedfishClient class, and a session is created to log you in to the server.
      • \n", + "
      • If the server is down or unreachable, we get a \"server not reachable\" message.
      • \n", + "
      • If not, we make a call to the enable_secure_boot function to obtain secure boot-related information of the system.
      • \n", + "
      • After getting the required information, Redfish.logout() closes the particular session and logs us out of the system.
      • \n", + "
      \n", + "
      \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8028b4ff", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = \"https://10.0.0.100\"\n", + " LOGIN_ACCOUNT = \"admin\"\n", + " LOGIN_PASSWORD = \"password\"\n", + "\n", + " #Properties:\n", + " #secure boot enable property\n", + " SECURE_BOOT_ENABLE = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "28cb201c", + "metadata": {}, + "source": [ + "

      4.

      \n", + " When running on the server locally use the following commented values
      \n", + " SYSTEM_URL = None
      \n", + " LOGIN_ACCOUNT = None
      \n", + " LOGIN_PASSWORD = None
      \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
      \n", + " SYSTEM_URL acceptable examples:
      \n", + " https://10.0.0.100
      \n", + " https://ilo.hostname\n", + "
      " + ] + }, + { + "cell_type": "markdown", + "id": "cf8a164b", + "metadata": {}, + "source": [ + "

      5.

      In case you need help 🔗 links to relevant resources :\n", + "
      \n", + " 1.Python-ilorest-library:LINK
      \n", + " 2.Hpe ilorest-api explorer:LINK
      \n", + " 3.Rest api: LINK
      \n", + " \n", + "
      " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb index 3bcdf99..a49f015 100644 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb @@ -242,7 +242,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.9.7" } }, "nbformat": 4, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb index 2d7d55f..17e2513 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_ChangeSettings-checkpoint.ipynb @@ -17,7 +17,7 @@ "
        \n", "
      • This Jupyter Notebook will contains a example code to demonstrate how to change BIOS settings. This code is written in Python and uses the redfish library to perform the required operations.

      • \n", "
      • As you are here let's get it done easily.
      • \n", - "
      • To perform this u need to have python-ilorest-library installed in your machine.
      • \n", + "
      • To perform this you need to have python-ilorest-library installed in your machine.
      • \n", "
      • Please keep your username and password handy
      • \n", "
      • Do execute each successive cell once to avoid any errors!
      • \n", "
      \n", @@ -35,6 +35,7 @@ "
    • sys
    • \n", "
    • json
    • \n", "
    • redfish
    • \n", + "
    • getpass - to take password as inputs securely
    • \n", "
    \n", "
    " ] @@ -69,16 +70,16 @@ "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", "
    \n", " \n", - "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation trying to obtain the bios settings of iLO system.\n", "
    \n", "\n", - "3. In the system members response object with different odata_id we get a bios uri .\n", + "3. In the system members response object with different odata_id we get a BIOS URI .\n", " Then again an http GET request is made and response is stored in systems_response.\n", " Then we set the systems_members_uri.\n", "
    \n", "\n", - "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + "4. Else i.e., resource directory is enabled then we will simply iterate through all instances inside resources \n", " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", "
    \n", "\n", @@ -161,18 +162,18 @@ "source": [ "
    \n", "

    3. This is Main function overview.


    \n", - " Please enter iLO url, username, password, bios.attribute, attribute_value and bios password
    \n", + " Please enter iLO url, username, password, bios attribute, attribute_value and bios password when asked.
    \n", "\n", "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", "
    \n", " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "2. RedfishClient class takes 3 parameters iLO URL, Username, Password and returns a redfish object.
    \n", "
    \n", "\n", "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", "
    \n", "\n", - "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", "
    \n", "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
    \n", " \n", @@ -243,12 +244,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb index d2ec941..041c819 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/.ipynb_checkpoints/BIOS_RevertToDefault-checkpoint.ipynb @@ -15,9 +15,9 @@ "source": [ "
    \n", "
      \n", - "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to it's default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  223. sys
  224. \n", "
  225. json
  226. \n", "
  227. redfish
  228. \n", + "
  229. getpass - to take password as inputs securely
  230. \n", " \n", "
    " ] @@ -86,7 +87,7 @@ "
    \n", " \n", "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", - " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", + " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", "
    \n", "\n", "3. In the system members response object with different odata_id we get a bios uri .\n", @@ -177,7 +178,7 @@ "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", "
    \n", " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "2. RedfishClient class takes 3 parameters iLO URL, Username, Password and returns a redfish object.
    \n", "
    \n", "\n", "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", @@ -273,12 +274,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb index 2d7d55f..17e2513 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_ChangeSettings.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to change BIOS settings. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  231. sys
  232. \n", "
  233. json
  234. \n", "
  235. redfish
  236. \n", + "
  237. getpass - to take password as inputs securely
  238. \n", " \n", "
    " ] @@ -69,16 +70,16 @@ "1. In the change_bios_settings function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", "
    \n", " \n", - "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", - " And now through system_response variable, we are making a http GET operation to and trying to obtain the bios settings of iLO system.\n", + "2. In the iLO rest api the information about bios is stored inside the systems json object.\n", + " And now through system_response variable, we are making a http GET operation trying to obtain the bios settings of iLO system.\n", "
    \n", "\n", - "3. In the system members response object with different odata_id we get a bios uri .\n", + "3. In the system members response object with different odata_id we get a BIOS URI .\n", " Then again an http GET request is made and response is stored in systems_response.\n", " Then we set the systems_members_uri.\n", "
    \n", "\n", - "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + "4. Else i.e., resource directory is enabled then we will simply iterate through all instances inside resources \n", " and if bios attribute is present in @odata.type attribute then we'll set bios_uri and get bios data of the user through redfish object. Now we will get the bios_settings_uri through bios_data object.\n", "
    \n", "\n", @@ -161,18 +162,18 @@ "source": [ "
    \n", "

    3. This is Main function overview.


    \n", - " Please enter iLO url, username, password, bios.attribute, attribute_value and bios password
    \n", + " Please enter iLO url, username, password, bios attribute, attribute_value and bios password when asked.
    \n", "\n", "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", "
    \n", " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "2. RedfishClient class takes 3 parameters iLO URL, Username, Password and returns a redfish object.
    \n", "
    \n", "\n", "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", "
    \n", "\n", - "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", "
    \n", "5. Then we call change_bios_settings with our redfish object and the attribute we need and change and the value along with the bios password.
    \n", " \n", @@ -243,12 +244,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb index 6175c59..041c819 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BIOS/BIOS_RevertToDefault.ipynb @@ -15,9 +15,9 @@ "source": [ "
    \n", "
      \n", - "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how to revert BIOS to it's default values. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  239. sys
  240. \n", "
  241. json
  242. \n", "
  243. redfish
  244. \n", + "
  245. getpass - to take password as inputs securely
  246. \n", " \n", "
    " ] @@ -86,7 +87,7 @@ "
    \n", " \n", "2. In the ILO rest api the information about bios is stored inside the systems json object.\n", - " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", + " And now through system_response variable, we are making a HTTP GET operation and trying to obtain the bios settings of iLO system.\n", "
    \n", "\n", "3. In the system members response object with different odata_id we get a bios uri .\n", @@ -177,7 +178,7 @@ "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", "
    \n", " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "2. RedfishClient class takes 3 parameters iLO URL, Username, Password and returns a redfish object.
    \n", "
    \n", "\n", "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", @@ -273,12 +274,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb index 63881cd..2289ea2 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Boot_Order-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  247. sys
  248. \n", "
  249. json
  250. \n", "
  251. redfish
  252. \n", + "
  253. getpass - to take password as inputs securely
  254. \n", " \n", "
    " ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -240,13 +240,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " 4.Changing Boot Setting Documentation: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb index f494564..b4158bf 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/.ipynb_checkpoints/Change_Temp_Boot_Order-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to temporarily change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  255. sys
  256. \n", "
  257. json
  258. \n", "
  259. redfish
  260. \n", + "
  261. getpass - to take password as inputs securely
  262. \n", " \n", "
    " ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -217,13 +217,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " 4.Changing Boot Setting Documentation: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb index 63881cd..2289ea2 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Boot_Order.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  263. sys
  264. \n", "
  265. json
  266. \n", "
  267. redfish
  268. \n", + "
  269. getpass - to take password as inputs securely
  270. \n", " \n", "
    " ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -240,13 +240,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " 4.Changing Boot Setting Documentation: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb index f494564..b4158bf 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/BOOT/Change_Temp_Boot_Order.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to temporarily change boot order for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  271. sys
  272. \n", "
  273. json
  274. \n", "
  275. redfish
  276. \n", + "
  277. getpass - to take password as inputs securely
  278. \n", " \n", "
    " ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -217,13 +217,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1.Python-ilorest-library: LINK
    \n", - " 2.HPE ilorest-api explorer: LINK
    \n", - " 3.REST API: LINK
    \n", - " 4.Changing Boot Setting Documentation: LINK
    \n", - " \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb index 94f9df5..0af3935 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/.ipynb_checkpoints/Test_ESKM_Connection-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contain script for testing connection to the ESKM (Enterprise Secure Key Manager) system for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  279. sys
  280. \n", "
  281. json
  282. \n", "
  283. redfish
  284. \n", + "
  285. getpass - to take password as inputs securely
  286. \n", " \n", "" ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -92,7 +92,6 @@ "
    \n", " \n", "9. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the JSON-formatted response.\n", - "
    \n", " \n", " \n", "10. If eskm_uri is None, print an error message.\n", @@ -231,11 +230,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb index 94f9df5..0af3935 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/ESKM/Test_ESKM_Connection.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contain script for testing connection to the ESKM (Enterprise Secure Key Manager) system for HPE iLO systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  287. sys
  288. \n", "
  289. json
  290. \n", "
  291. redfish
  292. \n", + "
  293. getpass - to take password as inputs securely
  294. \n", " \n", "" ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -92,7 +92,6 @@ "
    \n", " \n", "9. If the HTTP response status code is not 200 or 201, print an error message. If the HTTP response status code is 400, print the iLO extended info error message. If the HTTP response status code is 200 or 201, print a success message and the JSON-formatted response.\n", - "
    \n", " \n", " \n", "10. If eskm_uri is None, print an error message.\n", @@ -231,11 +230,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb index f9ea666..b7bb521 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Software_Firmware_Inventory-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to view firmware inventory on HPE iLO Systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  295. sys
  296. \n", "
  297. json
  298. \n", "
  299. redfish
  300. \n", + "
  301. getpass - to take password as inputs securely
  302. \n", " \n", "" ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -254,11 +254,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb index bda8be1..5dcb77d 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Update_iLO_Firmware-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contain script for updating Firmware via HTTP URL. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -82,7 +82,7 @@ "1. The update_ilo_firmware function takes three parameters - _redfishobj representing the connection to the server, fw_url representing the firmware update URL, and tpm_flag representing the TPM override flag.\n", "
    \n", " \n", - "2.The function initializes the body and update_service_uri variables to None.\n", + "2. The function initializes the body and update_service_uri variables to None.\n", "
    \n", "\n", "3. The get_resource_directory() function is called by passing the _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, the relevant URI is found by navigating through the server's API. If the resource directory is available, the relevant URI is found from the resource directory.\n", @@ -238,11 +238,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb index 053e56d..58da752 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_Firmware_iLO_Repository_with_COMPSIG.py-checkpoint.ipynb @@ -18,7 +18,7 @@ "
  303. This Jupyter Notebook will contains script for uploading a firmware component with a size less than\n", "32 GB, and associated compsig signature file to the iLO Repository.

  304. \n", "
  305. As you are here let's get it done easily.
  306. \n", - "
  307. To perform this u need to have python-ilorest-library installed in your machine.
  308. \n", + "
  309. To perform this you need to have python-ilorest-library installed in your machine.
  310. \n", "
  311. Please keep your username and password handy
  312. \n", "
  313. Do execute each successive cell once to avoid any errors!
  314. \n", " \n", @@ -36,6 +36,7 @@ "
  315. sys
  316. \n", "
  317. json
  318. \n", "
  319. redfish
  320. \n", + "
  321. getpass - to take password as inputs securely
  322. \n", " \n", "" ] @@ -252,11 +253,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb index 53fc8e1..ad6d508 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/.ipynb_checkpoints/Upload_firmware_to_iLO_repository-checkpoint.ipynb @@ -15,9 +15,9 @@ "source": [ "
    \n", "
      \n", - "
    • This Jupyter Notebook will contains script for uploading Firmware to iLO repository for flashing. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • This Jupyter Notebook will contain script for uploading Firmware to iLO repository for flashing. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  323. sys
  324. \n", "
  325. json
  326. \n", "
  327. redfish
  328. \n", + "
  329. getpass - to take password as inputs securely
  330. \n", " \n", "
    " ] @@ -54,7 +55,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -67,7 +67,7 @@ "

    2. This is our upload_firmware function overview, in the end this will upload firmware to the iLO Repository for flashing.


    \n", " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to upload the firmware.
    \n", "\n", - "1. The function takes three parameters as input: _redfishobj, firmware_loc, update_repo, and update_target.\n", + "1. The function takes these parameters as input: _redfishobj, firmware_loc, update_repo, and update_target.\n", "
    \n", " \n", "2. It calls the get_resource_directory() function by passing the _redfishobj parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, it finds the relevant URI by navigating through the server's API.\n", @@ -176,7 +176,7 @@ "\n", "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.

    \n", " \n", - "7. When prompted enter the entire path containing the new firmware (.fwpkg). Example: \"C:\\\\Users\\\\oconnogr\\\\git\\\\python-restful-interface-tool\\\\src\\\\ilo5_230_p31.fwpkg\"\n", + "7. When prompted, enter the entire path containing the new firmware (.fwpkg). Example: \"C:\\\\Users\\\\oconnogr\\\\git\\\\python-restful-interface-tool\\\\src\\\\ilo5_230_p31.fwpkg\"\n", "\n", " " ] @@ -242,11 +242,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb index f9ea666..b7bb521 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Software_Firmware_Inventory.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to view firmware inventory on HPE iLO Systems. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  331. sys
  332. \n", "
  333. json
  334. \n", "
  335. redfish
  336. \n", + "
  337. getpass - to take password as inputs securely
  338. \n", " \n", "" ] @@ -53,7 +54,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -254,11 +254,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb index bda8be1..5dcb77d 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Update_iLO_Firmware.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contain script for updating Firmware via HTTP URL. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -82,7 +82,7 @@ "1. The update_ilo_firmware function takes three parameters - _redfishobj representing the connection to the server, fw_url representing the firmware update URL, and tpm_flag representing the TPM override flag.\n", "
    \n", " \n", - "2.The function initializes the body and update_service_uri variables to None.\n", + "2. The function initializes the body and update_service_uri variables to None.\n", "
    \n", "\n", "3. The get_resource_directory() function is called by passing the _redfishobj as a parameter to retrieve the resource directory of the server. If the resource directory is not available or it is disabled, the relevant URI is found by navigating through the server's API. If the resource directory is available, the relevant URI is found from the resource directory.\n", @@ -238,11 +238,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb index 053e56d..58da752 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_Firmware_iLO_Repository_with_COMPSIG.py.ipynb @@ -18,7 +18,7 @@ "
  339. This Jupyter Notebook will contains script for uploading a firmware component with a size less than\n", "32 GB, and associated compsig signature file to the iLO Repository.

  340. \n", "
  341. As you are here let's get it done easily.
  342. \n", - "
  343. To perform this u need to have python-ilorest-library installed in your machine.
  344. \n", + "
  345. To perform this you need to have python-ilorest-library installed in your machine.
  346. \n", "
  347. Please keep your username and password handy
  348. \n", "
  349. Do execute each successive cell once to avoid any errors!
  350. \n", " \n", @@ -36,6 +36,7 @@ "
  351. sys
  352. \n", "
  353. json
  354. \n", "
  355. redfish
  356. \n", + "
  357. getpass - to take password as inputs securely
  358. \n", " \n", "" ] @@ -252,11 +253,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb index 358d0cc..ad6d508 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/FIRMWARE/Upload_firmware_to_iLO_repository.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contain script for uploading Firmware to iLO repository for flashing. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  359. sys
  360. \n", "
  361. json
  362. \n", "
  363. redfish
  364. \n", + "
  365. getpass - to take password as inputs securely
  366. \n", " \n", "" ] @@ -54,7 +55,6 @@ "\n", "from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -242,11 +242,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb index d82c82a..6d38569 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/.ipynb_checkpoints/Expand_data-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to expand a data response. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  367. sys
  368. \n", "
  369. json
  370. \n", "
  371. redfish
  372. \n", + "
  373. getpass - to take password as inputs securely
  374. \n", " \n", "" ] @@ -51,7 +52,6 @@ "from redfish import RedfishClient\n", "from redfish.rest.v1 import ServerDownOrUnreachableError\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -152,7 +152,16 @@ "execution_count": null, "id": "eabae678", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: hye\n", + "Enter Username: ue\n" + ] + } + ], "source": [ "if __name__ == \"__main__\":\n", " \n", @@ -173,7 +182,7 @@ " sys.exit()\n", "\n", " expand_data(REDFISHOBJ, EXPAND_URL)\n", - " REDFISHOBJ.logout()\n" + " REDFISHOBJ.logout()" ] }, { @@ -182,11 +191,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb index d82c82a..6d38569 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/MISCELLANEOUS/Expand_data.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to expand a data response. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  375. sys
  376. \n", "
  377. json
  378. \n", "
  379. redfish
  380. \n", + "
  381. getpass - to take password as inputs securely
  382. \n", " \n", "" ] @@ -51,7 +52,6 @@ "from redfish import RedfishClient\n", "from redfish.rest.v1 import ServerDownOrUnreachableError\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -152,7 +152,16 @@ "execution_count": null, "id": "eabae678", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Enter iLO IP address: hye\n", + "Enter Username: ue\n" + ] + } + ], "source": [ "if __name__ == \"__main__\":\n", " \n", @@ -173,7 +182,7 @@ " sys.exit()\n", "\n", " expand_data(REDFISHOBJ, EXPAND_URL)\n", - " REDFISHOBJ.logout()\n" + " REDFISHOBJ.logout()" ] }, { @@ -182,11 +191,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb index b26edc4..073e74b 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/.ipynb_checkpoints/Get_Powermetrics_Average-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to gather power metrics average. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  383. sys
  384. \n", "
  385. json
  386. \n", "
  387. redfish
  388. \n", + "
  389. getpass - to take password as inputs securely
  390. \n", " \n", "" ] @@ -67,7 +68,6 @@ "\n", "#from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -226,11 +226,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb index b26edc4..073e74b 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/POWER/Get_Powermetrics_Average.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will contains a example code to demonstrate how to gather power metrics average. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  391. sys
  392. \n", "
  393. json
  394. \n", "
  395. redfish
  396. \n", + "
  397. getpass - to take password as inputs securely
  398. \n", " \n", "" ] @@ -67,7 +68,6 @@ "\n", "#from get_resource_directory import get_resource_directory\n", "\n", - "#This is to take passwords as input securely\n", "import getpass" ] }, @@ -226,11 +226,12 @@ "metadata": {}, "source": [ "
    \n", - " In case you need help 🔗 links to relevant resources :\n", + " In case you need help please check the follwoing links for reference:\n", "
    \n", - " 1. Python-ilorest-library: LINK
    \n", - " 2. HPE ilorest-api explorer: LINK
    \n", - " 3. REST API: LINK
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", "
    " ] }, diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb index 524a7a2..105e597 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/.ipynb_checkpoints/Add_user_account-checkpoint.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will help you to add new user account by iLO privileges or redfish standard roles. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy.
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -35,6 +35,7 @@ "
  399. sys
  400. \n", "
  401. json
  402. \n", "
  403. redfish
  404. \n", + "
  405. getpass - to take password as inputs securely
  406. \n", " \n", "" ] @@ -55,39 +56,182 @@ "from ilorest_util import get_resource_directory\n", "from ilorest_util import get_gen\n", "\n", - "#to take password inputs securely\n", "import getpass" ] }, { "cell_type": "markdown", - "id": "b41f56eb", + "id": "613446a1", "metadata": {}, "source": [ "
    \n", - "

    3. This is Main function overview.

    \n", - "
    \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.\n", + "

    2. This is our add_ilo_user_account function overview, in the end this will add new iLO user account. This function will be called only if the generation of iLO is not 4.


    \n", + " \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to add new iLO user account.
    \n", "\n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "1. This function takes in six parameters: _redfishobj, new_loginname, new_username, new_password, role_id, and privilege_dict.\n", "
    \n", " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "2. The function first calls the get_resource_directory() function by passing _redfishobj as the parameter to retrieve the resource directory of the server. If resource directory is not available or it is disabled, it finds the relevant URI by navigating through the server's API.\n", "
    \n", "\n", - "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "3. If the resource directory is available, the function obtains all the account instances from the resource directory and sets the account_collection_uri. If it's an HPE server, it sets the body dictionary with the privileges passed in privilege_dict parameter.\n", "
    \n", "\n", - "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "4. The function then fills the body dictionary with the necessary details like new_username, new_password, and RoleId/Oem depending on the type of server.\n", "
    \n", - "5. Then we call bios_revert_default with our redfish object and rest the settings to default.
    \n", + "\n", + "5. The function then sends a POST command by passing the account_collection_uri and body dictionary as the parameters to create a new user account.\n", + "
    \n", + "\n", + "6. If the iLO server responds with an HTTP status code outside of 200 or 201, the function prints an error message. If the HTTP response status code is 400, it prints the iLO extended info error message. If the HTTP response status code is 200 or 201, it prints a success message and the newly created user account details in JSON format.\n", " \n", + "
    \n", "\n", - "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "7. If bios_boot_uri is None, print an error message.\n", + " \n", "\n", "
    " ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea197a20", + "metadata": {}, + "outputs": [], + "source": [ + "def add_ilo_user_account(_redfishobj, new_loginname, new_username, new_password, role_id, privilege_dict):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually to obtain\n", + " #account info\n", + " account_service_uri = _redfishobj.root.obj['AccountService']['@odata.id']\n", + " account_service_response = _redfishobj.get(account_service_uri)\n", + " account_collection_uri = account_service_response.obj['Accounts']['@odata.id']\n", + " #Add via role id\n", + " body = {\"RoleId\": role_id}\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#ManagerAccountCollection.' in instance['@odata.type']:\n", + " account_collection_uri = instance['@odata.id']\n", + " body = {\"Oem\": {\"Hpe\": {\"Privileges\": {}}}}\n", + " #HPE server, so add via privileges\n", + " for priv in privilege_dict:\n", + " body[\"Oem\"][\"Hpe\"][\"Privileges\"][priv] = privilege_dict[priv]\n", + " #Add login name\n", + " body[\"Oem\"][\"Hpe\"][\"LoginName\"] = new_loginname\n", + "\n", + " #Fill in the rest of the payload\n", + " body[\"UserName\"] = new_username\n", + " body[\"Password\"] = new_password\n", + "\n", + " #We pass the URI and the dictionary as a POST command (part of the redfish object)\n", + " resp = _redfishobj.post(account_collection_uri, body)\n", + "\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended Message Info...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "94f279a6", + "metadata": {}, + "source": [ + "
    \n", + "

    This function adds a new iLO user account in the HPE Gen9 server or having iLO generation 4 servers.


    \n", + " \n", + " \n", + "1. The function takes _redfishobj, new_loginname, new_username, and new_password as input parameters..\n", + "
    \n", + " \n", + "2. The account collection URI for the HPE Gen9 server is initialized as /redfish/v1/AccountService/Accounts/.\n", + "
    \n", + "\n", + "3. The privilege dictionary for the HPE Gen9 server is constructed in the body variable. The privileges are specified for the iLO user account to be added. The login name is also added.\n", + "
    \n", + "\n", + "4. The username and password for the iLO user account to be added are added to the body dictionary.\n", + "
    \n", + "\n", + "5. The POST command is passed to _redfishobj to add the iLO user account using the account_collection_uri and body dictionary.\n", + "
    \n", + "\n", + "6. If the HTTP response status code is 200 or 201, the newly created user account details are printed using json.dumps().\n", + " \n", + "
    \n", + "\n", + "7. If the HTTP response status code is not 200 or 201, an error message is printed using sys.stderr.write().\n", + " \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc44c03c", + "metadata": {}, + "outputs": [], + "source": [ + "def add_ilo_user_account_gen9(_redfishobj, new_loginname, new_username, new_password):\n", + "\n", + " account_collection_uri = \"/redfish/v1/AccountService/Accounts/\"\n", + " #Add via gen9 priv dic\n", + " body = {'Oem': {'Hp': {'Privileges': {\"LoginPriv\": True, \"RemoteConsolePriv\": True,\n", + " \"UserConfigPriv\": True, \"VirtualMediaPriv\": True, \"VirtualPowerAndResetPriv\": True,\n", + " \"iLOConfigPriv\": True}, 'LoginName': new_loginname}},'UserName': new_username, 'Password': new_password}\n", + " #We pass the URI and the dictionary as a POST command (part of the redfish object)\n", + " resp = _redfishobj.post(account_collection_uri, body)\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to add new user.\n", + " \n", + "\n", + " 1. The follwoing Main function prompts to take SYSTEM_URL, LOGIN_ACCOUNT, LOGIN_PASSWORD, ACCOUNT_LOGIN_NAME, ACCOUNT_USER_NAME, ACCOUNT_PASSWORD, ROLE_ID and PRIVILAGES as inputs.
    \n", + "
    \n", + " \n", + " \n", + " 2. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + " 3. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object. If users want to use create RedfishClient using \"certificate\" for authentication (which is optional), they can do so by uncommenting the lines ca_cert_data, ca_cert_data, ca_cert_data,ca_cert_data and providing their values.
    \n", + "
    \n", + " \n", + " 4. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + " \n", + " 5. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + " 6. Then we call add_ilo_user_account or add_ilo_user_account_gen9 based on the generation of iLO by pssing appropriate as parameters to those functions.
    \n", + " \n", + " \n", + " 7. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + " \n", + "
    " + ] + }, { "cell_type": "markdown", "id": "c8cd2ffd", @@ -123,32 +267,145 @@ }, { "cell_type": "markdown", - "id": "acc45fbf", + "id": "39d4c0f0", "metadata": {}, - "source": [] + "source": [ + "
    \n", + "
    Roles and Privileges
    \n", + "

    iLO uses a set of privileges assigned to each user account to grant and restrict access to features. iLO 6’s privileges are:


    \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    RedfishiLO Web Interface (GUI)
    LoginPrivLogin
    RemoteConsolePrivRemote Console
    VirtualPowerAndResetPrivVirtual Power and Reset
    VirtualMediaPrivVirtual Media
    HostBIOSConfigPrivHost BIOS
    iLOConfigPrivConfigure iLO Settings
    UserConfigPrivAdminister User Accounts
    HostNICConfigPrivHost NIC
    HostStorageConfigPrivHost Storage
    SystemRecoveryConfigPrivRecovery Set
    \n", + "\n", + "
    Roles
    \n", + "

    You can use RoleId to create users with specific starting privileges.
    \n", + "On a GET of the local user account, RoleId is synthesized based upon the enabled privileges. iLO 6 does not store a separate RoleId value. For this reason, modifications to raw privileges may or may not result in a changed RoleId based upon iLO’s mapping.
    \n", + "If the PATCH includes both RoleID and individual privileges, the privileges corresponding to the RoleId are assigned to the local user account first, and then the explicit privileges are assigned.

    \n", + "\n", + "
    Privileges granted on Local Account Creation by RoleId
    \n", + "
    \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    RoleIdPrivileges
    AdministratorHostBIOSConfigPriv, HostNICConfigPriv, HostStorageConfigPriv, LoginPriv, RemoteConsolePriv, UserConfigPriv, VirtualMediaPriv, VirtualPowerAndResetPriv, iLOConfigPriv
    OperatorHostBIOSConfigPriv, HostNICConfigPriv, HostStorageConfigPriv, LoginPriv, RemoteConsolePriv, VirtualMediaPriv, VirtualPowerAndResetPriv
    ReadOnlyLoginPriv
    \n", + "\n", + "\n", + "
    RoleId shown on an existing Local User Account by Privilege
    \n", + "

    The RoleId reported is the smallest superset of assigned privileges.

    \n", + "
    \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    PrivilegesRoleId
    LoginPriv onlyReadOnly
    iLOConfigPriv or UserConfigPriv or SystemRecoveryConfigPriv and anything elseAdministrator
    any other combinationOperator
    \n", + "\n", + " \n", + "\n", + "
    " + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "b99181a4", - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter System URL: f\n", - "Enter Login account: f\n", - "Enter your password: ········\n", - "Enter Account Login Name: f\n", - "Enter Account User Name: f\n", - "Enter Account password: ········\n", - "Enter ROLE_ID: f\n", - "For the below privilages enter 'True' if that privilages needs to be set for the user else enter 'False'\n", - "Truef\n", - "Truef\n", - "Truef\n", - "Truef\n" + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_19108/564943029.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mSYSTEM_URL\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter System URL: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[0mLOGIN_ACCOUNT\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter Login account: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[0mLOGIN_PASSWORD\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetpass\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter your password: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[1;34m(self, prompt)\u001b[0m\n\u001b[0;32m 1004\u001b[0m \u001b[1;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1005\u001b[0m )\n\u001b[1;32m-> 1006\u001b[1;33m return self._input_request(\n\u001b[0m\u001b[0;32m 1007\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprompt\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1008\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"shell\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[1;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[0;32m 1049\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1050\u001b[0m \u001b[1;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1051\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Interrupted by user\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1052\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1053\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Invalid Message:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: Interrupted by user" ] } ], @@ -191,10 +448,10 @@ " # intended for HPE servers.\n", " DISABLE_RESOURCE_DIR = False\n", "\n", - " ca_cert_data = {}\n", - " ca_cert_data[\"cert_file\"] = \"c:\\\\test\\\\ppcacuser.crt\"\n", - " ca_cert_data[\"key_file\"] = \"c:\\\\test\\\\ppcacuserpriv.key\"\n", - " ca_cert_data[\"key_password\"] = \"password\"\n", + "# ca_cert_data = {}\n", + "# ca_cert_data[\"cert_file\"] = \"c:\\\\test\\\\ppcacuser.crt\"\n", + "# ca_cert_data[\"key_file\"] = \"c:\\\\test\\\\ppcacuserpriv.key\"\n", + "# ca_cert_data[\"key_password\"] = \"password\"\n", " LOGIN_ACCOUNT = None\n", " LOGIN_PASSWORD = None\n", "\n", @@ -211,28 +468,38 @@ " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", " sys.exit()\n", "\n", - " #obtain all account instances, by navigating set paths and keys to find the relevant URI\n", - " #(account_collection_uri, accounts, rd) = get_accounts(redfishobj, DISABLE_RESOURCE_DIR)\n", - " #print(\"\\n\\nShowing accounts before changes:\\n\\n\")\n", - " #show_accounts(redfishobj, accounts)\n", "\n", " #if account_collection_uri and accounts:\n", " #add specified account\n", " (ilogen,_) = get_gen(REDFISHOBJ)\n", " print (\"Generation is \", ilogen)\n", - " if int(ilogen) == 5:\n", + " if int(ilogen) !=4:\n", " add_ilo_user_account(REDFISHOBJ,ACCOUNT_LOGIN_NAME,ACCOUNT_USER_NAME,ACCOUNT_PASSWORD,ROLE_ID,PRIVILEGE_DICT)\n", " else:\n", " add_ilo_user_account_gen9(REDFISHOBJ,ACCOUNT_LOGIN_NAME,ACCOUNT_USER_NAME,ACCOUNT_PASSWORD)\n", + " \n", " REDFISHOBJ.logout()" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "0b490052", + "cell_type": "markdown", + "id": "acf871b9", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help please check the follwoing links for reference:\n", + "
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a6b25775", "metadata": {}, - "outputs": [], "source": [] } ], diff --git a/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb index e93595e..105e597 100644 --- a/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb +++ b/examples/Jupyter_notebooks/HPECTY/Bhuvan/USERS/Add_user_account.ipynb @@ -17,7 +17,7 @@ "
      \n", "
    • This Jupyter Notebook will help you to add new user account by iLO privileges or redfish standard roles. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", "
    • As you are here let's get it done easily.
    • \n", - "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • To perform this you need to have python-ilorest-library installed in your machine.
    • \n", "
    • Please keep your username and password handy.
    • \n", "
    • Do execute each successive cell once to avoid any errors!
    • \n", "
    \n", @@ -31,6 +31,12 @@ "source": [ "
    \n", "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    • getpass - to take password as inputs securely
    • \n", + "
    \n", "
    " ] }, @@ -50,7 +56,6 @@ "from ilorest_util import get_resource_directory\n", "from ilorest_util import get_gen\n", "\n", - "#to take password inputs securely\n", "import getpass" ] }, @@ -384,26 +389,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "b99181a4", - "metadata": {}, + "metadata": { + "scrolled": true + }, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter System URL: f\n", - "Enter Login account: f\n", - "Enter your password: ········\n", - "Enter Account Login Name: f\n", - "Enter Account User Name: f\n", - "Enter Account password: ········\n", - "Enter ROLE_ID: f\n", - "For the below privilages enter 'True' if that privilages needs to be set for the user else enter 'False'\n", - "Truef\n", - "Truef\n", - "Truef\n", - "Truef\n" + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mC:\\Users\\BHUVAN~1\\AppData\\Local\\Temp/ipykernel_19108/564943029.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mSYSTEM_URL\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter System URL: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[0mLOGIN_ACCOUNT\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter Login account: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[0mLOGIN_PASSWORD\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetpass\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetpass\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Enter your password: \"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[1;34m(self, prompt)\u001b[0m\n\u001b[0;32m 1004\u001b[0m \u001b[1;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1005\u001b[0m )\n\u001b[1;32m-> 1006\u001b[1;33m return self._input_request(\n\u001b[0m\u001b[0;32m 1007\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprompt\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1008\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"shell\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\ipykernel\\kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[1;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[0;32m 1049\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1050\u001b[0m \u001b[1;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1051\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Interrupted by user\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1052\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1053\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Invalid Message:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: Interrupted by user" ] } ], @@ -478,6 +480,27 @@ " \n", " REDFISHOBJ.logout()" ] + }, + { + "cell_type": "markdown", + "id": "acf871b9", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help please check the follwoing links for reference:\n", + "
    \n", + " 1. Python-ilorest-library: Python ilorest library
    \n", + " 2. HPE ilorest-api explorer: ilorestful api explorer
    \n", + " 3. HPE iLO Redfish Documentation: HPE iLO Redfish API Documentation
    \n", + " 4. REST API: Restful API
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "a6b25775", + "metadata": {}, + "source": [] } ], "metadata": { From 3c0400857a5124da4f96b53e19f84c14f9f70efd Mon Sep 17 00:00:00 2001 From: tanveer128 <123229272+tanveer128@users.noreply.github.com> Date: Tue, 30 May 2023 18:59:14 +0530 Subject: [PATCH 044/159] Add files via upload --- .../HPECTY/Tanveer/get_logical_drives.ipynb | 306 ++++++++++++++++++ .../Tanveer/get_resource_directory.ipynb | 234 ++++++++++++++ 2 files changed, 540 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/get_logical_drives.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/Tanveer/get_resource_directory.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/get_logical_drives.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/get_logical_drives.ipynb new file mode 100644 index 0000000..b273b94 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/get_logical_drives.ipynb @@ -0,0 +1,306 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "594a0e06", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of get_logical-drives.
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "25be0e98", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  407. sys \n", + "
  408. \n", + "
  409. json
  410. \n", + "
  411. redfish
  412. \n", + "
  413. argparse
  414. \n", + "
  415. get_resource_directory
  416. \n", + "
  417. get_gen
  418. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f16a98ad", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "import argparse\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "from ilorest_util import get_resource_directory\n", + "from ilorest_util import get_gen" + ] + }, + { + "cell_type": "markdown", + "id": "8c2b4d45", + "metadata": {}, + "source": [ + "

    2.

    This is our get_SmartArray_LogicalDrives function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present for error free execution.\n", + "
    \n", + " \n", + " \n", + "1. The variables smartstorage_response and smartarraycontrollers are initialized as an empty list and dictionary, respectively.\n", + "
    \n", + "\n", + "2. The get_resource_directory function is used in the code to try and retrieve the resource directory. The code resorts to a manual search for the pertinent URIs if the resource directory is unavailable or the DISABLE_RESOURCE_DIR flag is set to True.The code repeats the preceding code snippet's procedures to retrieve the pertinent URIs for smart storage and array controllers if the resource directory is not in use or unavailable.\n", + "
    \n", + "\n", + "3. The code searches through each instance in the resource directory for instances of the specified type if the resource directory is used. It fetches the response, which is an array of array controller members, and extracts the instance's URI. After locating the first pertinent instance, the loop ends.\n", + "The smartstorage_response is then used by the code, presuming it contains the array of array controller elements.\n", + "The code obtains specific information about each controller in smartstorage_response and stores it in the smartarraycontrollers dictionary with the controller's @odata.id as the key.\n", + "
    \n", + " \n", + "4.For the specified smart storage array controller, it prints the logical drive URIs.The code gets the logical drives URI from the controller's links, sends an HTTP GET request to get the answer, and sets the result to the logicaldrives_resp variable. \n", + "
    \n", + " \n", + "5.The LogicalDrives key in the smartarraycontrollers dictionary is used to add the logical drive members.\n", + "A message is sent to stderr if there are no logical drives.\n", + "
    \n", + " \n", + "6.The code publishes information about each logical drive in logicaldrives_resp, fetches detailed drive data with an HTTP GET request, and prints the drive data as JSON.\n", + "
    \n", + " \n", + "7. The initial values of the variables smartarraycontrollers and smartstorage_response are a dictionary and an empty \n", + "list respectively.The code configures the smartstorage_uri to point to the endpoint \n", + "/redfish/v1/Systems/1/SmartStorage/ArrayControllers/ for Gen9 servers. To obtain data about the array\n", + "controllers, use this endpoint.\n", + "
    \n", + "\n", + "8. An HTTP GET request is sent to the smartstorage_uri, and the array of array controller members is extracted \n", + "from the response to populate the smartstorage_response.The code obtains specific information about each controller \n", + "in smartstorage_response and stores it in the smartarraycontrollers dictionary with the controller\n", + "@odata.id as the key.\n", + "
    \n", + "9.The logical drive URIs for the specific smart storage array controller are printed by the code.The controller links, \n", + "specifically the LogicalDrives key under the Links object, are where the logicaldrives_uri is located.In order to \n", + "receive the logical drives response, which provides details about the logical drives connected to the controller, \n", + "the code performs an HTTP GET request to the logicaldrives_uri.\n", + "
    \n", + "10.If the number of logical drive members is zero, an error message stating that no logical \n", + "drives are accessible for this controller is sent to stderr.Otherwise, the code publishes information about each \n", + "logical drive in the logicaldrives_resp, makes an HTTP GET request to the logical drive URI ,obtains detailed drive \n", + "data, and prints the drive data as JSON.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95b318b7", + "metadata": {}, + "outputs": [], + "source": [ + "def get_SmartArray_LogicalDrives_gen9(_redfishobj):\n", + "\n", + " smartstorage_response = []\n", + " smartarraycontrollers = dict()\n", + "\n", + " smartstorage_uri = \"/redfish/v1/Systems/1/SmartStorage/ArrayControllers/\"\n", + " print (smartstorage_uri)\n", + " smartstorage_response = _redfishobj.get(smartstorage_uri).obj['Members']\n", + "\n", + " for controller in smartstorage_response:\n", + " smartarraycontrollers[controller['@odata.id']] = _redfishobj.get(controller['@odata.id']).obj\n", + " sys.stdout.write(\"Logical Drive URIs for Smart Storage Array Controller \\'%s\\' : \\n\" \\\n", + " % smartarraycontrollers[controller['@odata.id']].get('Id'))\n", + " logicaldrives_uri = smartarraycontrollers[controller['@odata.id']].Links\\\n", + " ['LogicalDrives']['@odata.id']\n", + " print (logicaldrives_uri)\n", + " logicaldrives_resp = _redfishobj.get(logicaldrives_uri)\n", + " if logicaldrives_resp.dict['Members@odata.count'] == 0:\n", + " sys.stderr.write(\"\\tLogical drives are not available for this controller.\\n\")\n", + " else:\n", + " for lds in logicaldrives_resp.dict['Members']:\n", + " sys.stdout.write(\"\\t An associated logical drive: %s\\n\" % logicaldrives_resp.dict['Name'])\n", + " drive_data = _redfishobj.get(lds['@odata.id']).dict\n", + " print(json.dumps(drive_data, indent=4, sort_keys=True))\n", + "def get_SmartArray_LogicalDrives_gen9(_redfishobj):\n", + "\n", + " smartstorage_response = []\n", + " smartarraycontrollers = dict()\n", + "\n", + " smartstorage_uri = \"/redfish/v1/Systems/1/SmartStorage/ArrayControllers/\"\n", + " print (smartstorage_uri)\n", + " smartstorage_response = _redfishobj.get(smartstorage_uri).obj['Members']\n", + "\n", + " for controller in smartstorage_response:\n", + " smartarraycontrollers[controller['@odata.id']] = _redfishobj.get(controller['@odata.id']).obj\n", + " sys.stdout.write(\"Logical Drive URIs for Smart Storage Array Controller \\'%s\\' : \\n\" \\\n", + " % smartarraycontrollers[controller['@odata.id']].get('Id'))\n", + " logicaldrives_uri = smartarraycontrollers[controller['@odata.id']].Links\\\n", + " ['LogicalDrives']['@odata.id']\n", + " print (logicaldrives_uri)\n", + " logicaldrives_resp = _redfishobj.get(logicaldrives_uri)\n", + " if logicaldrives_resp.dict['Members@odata.count'] == 0:\n", + " sys.stderr.write(\"\\tLogical drives are not available for this controller.\\n\")\n", + " else:\n", + " for lds in logicaldrives_resp.dict['Members']:\n", + " sys.stdout.write(\"\\t An associated logical drive: %s\\n\" % logicaldrives_resp.dict['Name'])\n", + " drive_data = _redfishobj.get(lds['@odata.id']).dict\n", + " print(json.dumps(drive_data, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "id": "b852d783", + "metadata": {}, + "source": [ + "

    3.

    \n", + "The Main function:
    \n", + "
      \n", + "
    • An instance of the argparse is created by the code.assigns the ArgumentParser class to the parser variable. The goal of the script is described in the description parameter.
    • \n", + "
    • Using the add_argument method of the ArgumentParser class, the code adds the following three command-line arguments:1.-i or --ilo: Specifies the iLO IP address of the server
      2.u or --user: Indicates the iLO login username. It has the dest, action, help, and default parameters, just as the -i argument.
      \n", + " 3.-p or --password: Specifies the iLO password for login.\n", + "
    • \n", + "
    • A new variable named system_url is created and given the value \"https://\" + options.ilo_ip by the code. This creates the system's URL using the supplied iLO IP address. The iLO IP address will come after the \"https://\" in the final URL.The created URL will be shown on the console once the code outputs the system_url variable.
    • \n", + "
    • The DISABLE_RESOURCE_DIR option is set to False by the code. This option is used to specify whether or not the resource directory should be disabled, along with any related procedures. It is specifically set to False in this instance, allowing the resource directory to be utilised.
    • \n", + "
    • The base_url, username, and password that were received through the command-line inputs are passed to the code, which then creates a RedfishClient object with the name redfish_obj.The specified credentials are used to log in to the server by calling the redfish_obj.login() method. A session is established with the server as a result.A ServerDownOrUnreachableError exception is thrown if the server cannot be reached or does not support Redfish, and the script is terminated after printing an error message to stderr.
    • \n", + "
    • The redfish_obj is supplied as an argument when the get_gen() function is used. The server generation data is retrieved using this function.The second value of the tuple given by get_gen() is disregarded using , and the server generation is kept in the ilogen variable.The console is printed with the server generation.
    • \n", + "
    • The get_SmartArray_LogicalDrives() function is called with the redfish_obj parameter to obtain details on the smart array logical drives if the server generation is equal to 5, indicating a Gen5 server.\n", + "The get_SmartArray_LogicalDrives_gen9() function is called with the redfish_obj parameter to obtain details about the smart array logical drives unique to Gen9 servers if the server generation is not 5, indicating a different generation.
    • \n", + "
    • Finally logout from the session can be done by using redfish_obj.logout()
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "610979dd", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + " (ilogen,_) = get_gen(redfish_obj)\n", + " print (\"Generation is \", ilogen)\n", + " if int(ilogen) == 5:\n", + " get_SmartArray_LogicalDrives(redfish_obj)\n", + " else:\n", + " get_SmartArray_LogicalDrives_gen9(redfish_obj)\n", + " redfish_obj.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "80f7da07", + "metadata": {}, + "source": [ + "

    4.

    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "00b5c8a5", + "metadata": {}, + "source": [ + "

    5.

    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/Tanveer/get_resource_directory.ipynb b/examples/Jupyter_notebooks/HPECTY/Tanveer/get_resource_directory.ipynb new file mode 100644 index 0000000..4c63595 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/Tanveer/get_resource_directory.ipynb @@ -0,0 +1,234 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a38bafdc", + "metadata": { + "tags": [] + }, + "source": [ + "# Get_Resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "cfe2e2b6", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to get_resource_directory
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "b3fec1a9", + "metadata": {}, + "source": [ + "
    \n", + "

    1.

    \n", + "Below we are importing all the necessary modules from the ilorest library!.
    \n", + "
  419. sys \n", + "
  420. \n", + "
  421. redfish
  422. \n", + "
  423. get_resource_directory
  424. \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab7125e9", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "#from get_resource_directory import get_resource_directory" + ] + }, + { + "cell_type": "markdown", + "id": "8d23d990", + "metadata": {}, + "source": [ + "
    \n", + "

    2.

    \n", + " A redfishobj parameter is required for the function get_resource_directory. The resource directory can be retrieved using this function from a Redfish API.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. It tries to use the redfishobj object to access the resource directory URI. The server's resources are gathered in the resource directory.The server is not an HPE server and an error message is displayed to stderr if the resource directory URI cannot be discovered (KeyError is thrown). Then, the function returns null.\n", + "
    \n", + " \n", + "2. If the resource directory URI is located, the code uses the redfishobj.get method to send an HTTP GET request to retrieve the resource directory.\n", + "
    \n", + "\n", + "3. A response status of 200 (OK) indicates a successful retrieval of the resource directory. The function assigns the list of resource instances to the resources variable and sends a message to stdout showing the location of the resource directory.\n", + "
    \n", + "\n", + "4. If the response status isn't 200, the resource directory is either unavailable or missing. The resources variable is empty and an error is reported to stderr.\n", + " \n", + "
    \n", + " \n", + "5. Finally the function get_resource_directory return the resources.\n", + "
    \n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1b4d0494", + "metadata": {}, + "outputs": [], + "source": [ + "def get_resource_directory(redfishobj):\n", + "\n", + " try:\n", + " resource_uri = redfishobj.root.obj.Oem.Hpe.Links.ResourceDirectory['@odata.id']\n", + " except KeyError:\n", + " sys.stderr.write(\"Resource directory is only available on HPE servers.\\n\")\n", + " return None\n", + "\n", + " response = redfishobj.get(resource_uri)\n", + " resources = []\n", + "\n", + " if response.status == 200:\n", + " sys.stdout.write(\"\\tFound resource directory at /redfish/v1/resourcedirectory\" + \"\\n\\n\")\n", + " resources = response.dict[\"Instances\"]\n", + " else:\n", + " sys.stderr.write(\"\\tResource directory missing at /redfish/v1/resourcedirectory\" + \"\\n\")\n", + "\n", + " return resources\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0de7de8", + "metadata": {}, + "source": [ + "
    \n", + "

    3.

    This is get_gen function overview.
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "\n", + "\n", + "1. The _redfishobj object, which is presumed to be a Redfish response object, is used to retrieve the root response.\n", + "The server generation's default setting is set to 5 (iLO 5).
    \n", + "
    \n", + " \n", + "2. By looking at the keys beneath the \"Oem\" key in the root response, it determines whether the OEM (Original Equipment Manufacturer) of the server is either \"Hpe\" or \"Hp.\" Gencompany is set to True if one of these keys is discovered; otherwise, it is set to False..
    \n", + "
    \n", + "\n", + "3. If gencompany is True, the variable comp is changed to Hp otherwise, it stays None.\n", + "Comp is changed to Hpe if comp is not None and the Oem key contains the subkey Hpe in the root response.
    \n", + "
    \n", + "\n", + "4. The function then accesses nested dictionaries in the root response to see if the server's manager type is present.It fetches the manager type and firmware version if the manager type is present.\n", + "It thinks the server is an iLO 4 type on a Moonshot system if the manager type ends with CM (probably \"Chassis Manager\") in which case it sets ilogen to 4 and iloversion to None.
    \n", + "
    \n", + "5. In the absence of that, it takes the management type's generation number and the firmware version number. These values are combined to create a decimal version number, which is then assigned to iloversion. Ilogen is given the extracted generation number.\n", + "
    \n", + " \n", + "\n", + "6. A tuple including the server generation (ilogen) and version (iloversion) is the function's final output.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f538059", + "metadata": {}, + "outputs": [], + "source": [ + "def get_gen(_redfishobj):\n", + "\trootresp = _redfishobj.root.obj\n", + "\t#Default iLO 5\n", + "\tilogen = 5\n", + "\tgencompany = next(iter(rootresp.get(\"Oem\", {}).keys()), None) in ('Hpe', 'Hp')\n", + "\tcomp = 'Hp' if gencompany else None\n", + "\tcomp = 'Hpe' if rootresp.get(\"Oem\", {}).get('Hpe', None) else comp\n", + "\tif comp and next(iter(rootresp.get(\"Oem\", {}).get(comp, {}).get(\"Manager\", {}))).\\\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tget('ManagerType', None):\n", + "\t\tilogen = next(iter(rootresp.get(\"Oem\", {}).get(comp, {}).get(\"Manager\", {})))\\\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.get(\"ManagerType\")\n", + "\t\tilover = next(iter(rootresp.get(\"Oem\", {}).get(comp, {}).get(\"Manager\", {}))).\\\n", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t get(\"ManagerFirmwareVersion\")\n", + "\t\tif ilogen.split(' ')[-1] == \"CM\":\n", + "\t\t\t# Assume iLO 4 types in Moonshot\n", + "\t\t\tilogen = 4\n", + "\t\t\tiloversion = None\n", + "\t\telse:\n", + "\t\t\tilogen = ilogen.split(' ')[1]\n", + "\t\t\tiloversion = float(ilogen.split(' ')[-1] + '.' + \\\n", + "\t\t\t\t\t\t\t\t\t\t\t''.join(ilover.split('.')))\n", + "\treturn (ilogen, iloversion)\n" + ] + }, + { + "cell_type": "markdown", + "id": "bd337e8f", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "f7fd2c36", + "metadata": {}, + "source": [ + "
    In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library:LINK
    \n", + " 2.Hpe ilorest-api explorer:LINK
    \n", + " 3.Rest api: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 944fc50b57130d845c667eac60d9b832852e1af2 Mon Sep 17 00:00:00 2001 From: venkatrahul2003 <104755146+venkatrahul2003@users.noreply.github.com> Date: Tue, 30 May 2023 19:24:37 +0530 Subject: [PATCH 045/159] Delete examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL directory --- .../enable_secure_boot-checkpoint.ipynb | 250 ----------- .../eject_virtual_media_iso.ipynb | 263 ------------ .../B VENKAT RAHUL/enable_secure_boot.ipynb | 250 ----------- .../B VENKAT RAHUL/enabling_ntp_server.ipynb | 309 -------------- .../B VENKAT RAHUL/find_ilo_mac_address.ipynb | 228 ---------- .../flash_firmware_by_uefi.ipynb | 398 ------------------ .../HPECTY/B VENKAT RAHUL/generate_csr.ipynb | 279 ------------ .../HPECTY/B VENKAT RAHUL/sessions.ipynb | 252 ----------- .../set_ESKM_PrimaryKeyServer.ipynb | 296 ------------- .../set_ESKM_username_password.ipynb | 289 ------------- .../B VENKAT RAHUL/set_active_ilo_nic.ipynb | 295 ------------- 11 files changed, 3109 deletions(-) delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb delete mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb deleted file mode 100644 index a49f015..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/.ipynb_checkpoints/enable_secure_boot-checkpoint.ipynb +++ /dev/null @@ -1,250 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "b44c9aad", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of enabling secure boot
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "74ee46a2", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below
    \n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3b9ca27", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "d0e073c6", - "metadata": {}, - "source": [ - "

    2.

    This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.
    \n", - " Let me give you a walk through of it!\n", - "
    \n", - "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", - "\n", - "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
    \n", - " \n", - "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", - " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", - "
    \n", - "\n", - "3. In the systems response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in systems_members_response.\n", - " The secure boot information is ultimately present in the systems_members_response.\n", - "
    \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", - "
    \n", - "\n", - "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d60549e", - "metadata": {}, - "outputs": [], - "source": [ - "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", - "\n", - " secure_boot_uri = None\n", - " secure_boot_data = None\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", - " systems_response = _redfishobj.get(systems_uri)\n", - " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", - " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#SecureBoot.' in instance['@odata.type']:\n", - " secure_boot_uri = instance['@odata.id']\n", - " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", - "\n", - " if secure_boot_data:\n", - " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", - " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", - "\n", - " if secure_boot_uri:\n", - " body = {'SecureBootEnable': secure_boot_enable}\n", - " resp = _redfishobj.patch(secure_boot_uri, body)\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"\\nSuccess!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", - " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", - " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "b227f8f6", - "metadata": {}, - "source": [ - "
    \n", - "

    The Main function:

    \n", - "

    Please enter your login credentials here to proceed further:

    \n", - "
      \n", - "
    • Once your credentials are entered, a Redfish object is created with the help of the RedfishClient class, and a session is created to log you in to the server.
    • \n", - "
    • If the server is down or unreachable, we get a \"server not reachable\" message.
    • \n", - "
    • If not, we make a call to the enable_secure_boot function to obtain secure boot-related information of the system.
    • \n", - "
    • After getting the required information, Redfish.logout() closes the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8028b4ff", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " #Properties:\n", - " #secure boot enable property\n", - " SECURE_BOOT_ENABLE = True\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "28cb201c", - "metadata": {}, - "source": [ - "

    4.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cf8a164b", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - "
    \n", - " 1.Python-ilorest-library:LINK
    \n", - " 2.Hpe ilorest-api explorer:LINK
    \n", - " 3.Rest api: LINK
    \n", - " \n", - "
    " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb deleted file mode 100644 index 9556027..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb +++ /dev/null @@ -1,263 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "45dd47a5", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of mounting virtual media for HPE iLO systems
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "23eeb2bf", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92ec68a2", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "10a8e977", - "metadata": {}, - "source": [ - "

    2.

    This is our mount_virtual_media_iso function overview, in the end this will give us with virtual media related information.
    \n", - " Let me give you a walk through of it!\n", - "
    \n", - "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the virtual media information.\n", - "\n", - "1. In the mount_virtual_media_iso function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
    \n", - " \n", - "2. In the ILO rest api the information about virtual media is stored inside the managers json object.\n", - " Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.\n", - "
    \n", - "\n", - "3. In the managers response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in managers_members_response.\n", - " The virtual media information is ultimately present in the managers_members_response.\n", - "
    \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if virtual media is present in @odata.type attribute then we will store information about virtual media in virtual_media_uri and break out of iteration.\n", - "
    \n", - "\n", - "Ultimately if virtual_media_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f034ef9c", - "metadata": {}, - "outputs": [], - "source": [ - "def mount_virtual_media_iso(_redfishobj, media_type,):\n", - "\n", - " virtual_media_uri = None\n", - " virtual_media_response = []\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", - " else:\n", - " for instance in resource_instances:\n", - " #Use Resource directory to find the relevant URI\n", - " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", - " virtual_media_uri = instance['@odata.id']\n", - "\n", - " if virtual_media_uri:\n", - " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", - " for virtual_media_slot in virtual_media_response.obj['Members']:\n", - " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", - " if media_type in data.dict['MediaTypes']:\n", - " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.EjectMedia']['target']\n", - " post_body = {\"Action\": \"HpeiLOVirtualMedia.EjectVirtualMedia\"}\n", - " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", - " \"Extended Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " break" - ] - }, - { - "cell_type": "markdown", - "id": "268b5a18", - "metadata": {}, - "source": [ - "

    3.

    \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", - "
      \n", - "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", - "
    • If server is down or Unreachable we get server not reachable message!
    • \n", - "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", - "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "ab494baf", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[1], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 25\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 26\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 27\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[1], line 31\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 30\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 31\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 32\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 33\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", - "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " \n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " #specify the type of content the media represents\n", - " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - "\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " mount_virtual_media_iso(REDFISHOBJ, MEDIA_TYPE)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "90621a8a", - "metadata": {}, - "source": [ - "

    4.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "a839daaa", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb deleted file mode 100644 index a49f015..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot.ipynb +++ /dev/null @@ -1,250 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "b44c9aad", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of enabling secure boot
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "74ee46a2", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below
    \n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3b9ca27", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "d0e073c6", - "metadata": {}, - "source": [ - "

    2.

    This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.
    \n", - " Let me give you a walk through of it!\n", - "
    \n", - "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", - "\n", - "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
    \n", - " \n", - "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", - " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", - "
    \n", - "\n", - "3. In the systems response object we are iterating on all the members with different odata_id .\n", - " Then again an http GET request is made and response is stored in systems_members_response.\n", - " The secure boot information is ultimately present in the systems_members_response.\n", - "
    \n", - "\n", - "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", - "
    \n", - "\n", - "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8d60549e", - "metadata": {}, - "outputs": [], - "source": [ - "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", - "\n", - " secure_boot_uri = None\n", - " secure_boot_data = None\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", - " systems_response = _redfishobj.get(systems_uri)\n", - " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", - " systems_members_response = _redfishobj.get(systems_members_uri)\n", - " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", - " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#SecureBoot.' in instance['@odata.type']:\n", - " secure_boot_uri = instance['@odata.id']\n", - " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", - "\n", - " if secure_boot_data:\n", - " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", - " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", - "\n", - " if secure_boot_uri:\n", - " body = {'SecureBootEnable': secure_boot_enable}\n", - " resp = _redfishobj.patch(secure_boot_uri, body)\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"\\nSuccess!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", - " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", - " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "b227f8f6", - "metadata": {}, - "source": [ - "
    \n", - "

    The Main function:

    \n", - "

    Please enter your login credentials here to proceed further:

    \n", - "
      \n", - "
    • Once your credentials are entered, a Redfish object is created with the help of the RedfishClient class, and a session is created to log you in to the server.
    • \n", - "
    • If the server is down or unreachable, we get a \"server not reachable\" message.
    • \n", - "
    • If not, we make a call to the enable_secure_boot function to obtain secure boot-related information of the system.
    • \n", - "
    • After getting the required information, Redfish.logout() closes the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8028b4ff", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " #Properties:\n", - " #secure boot enable property\n", - " SECURE_BOOT_ENABLE = True\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "28cb201c", - "metadata": {}, - "source": [ - "

    4.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cf8a164b", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - "
    \n", - " 1.Python-ilorest-library:LINK
    \n", - " 2.Hpe ilorest-api explorer:LINK
    \n", - " 3.Rest api: LINK
    \n", - " \n", - "
    " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb deleted file mode 100644 index 656cc07..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb +++ /dev/null @@ -1,309 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# ENABLING NTP SERVER " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to enable ntp servers .
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "import sys\n", - "import json\n", - "import getpass\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
    \n", - "

    2

    \n", - "Below function describes the process how to enable NTP servers for HPE ilo systems. NTP or Network Time Protocol is an internet protocol used to synchronize with computer clokc time sources in a network. \n", - "Current cell is the explains the processes performed inside the below function.\n", - "
    \n", - " Let me give you a walk through of it!\n", - "
    \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", - "\n", - "1. Initially, to obtain NTP server related information for HPE ilo systems a series of HTTP GET requests are being made so as to navigate to that path inside the iLO rest api where required information is stored.\n", - "After completion of these get requests we will be having the relevant uri in manager_ethernet_interfaces_members.\n", - "
    \n", - "2. Else if resource directory is enabled we can just use the resource directory to and then again navigate through the api to find relevant uri.\n", - "
    \n", - " \n", - "3. Whatever changes need to be made to enable the NTP server are being enclosed inside the dictionary named as body. Next up for all the instances of ethernet in ethernet_data we simply make a HTTP PATCH request by passing the ethernet instance and body dictionary with the PATCH request. \n", - " \n", - "\n", - "4. Following the patch request, the response returned by server is being saved inside resp variable and later if the server returns proper response it means there is no error else error is returned with error information. A reference for json.dumps\n", - "function as it is used multiple times - click here.\n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "def enable_ntp(_redfishobj, ntp_servers, DISABLE_RESOURCE_DIR):\n", - "\n", - " ethernet_data = {}\n", - "\n", - " resource_instances = redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", - " ['@odata.id']\n", - " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", - " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", - " obj['Members']\n", - " for _member in manager_ethernet_interfaces_members:\n", - " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", - " ethernet_data[_member['@odata.id']] = _tmp\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", - " instance['@odata.id']:\n", - " ethernet_uri = instance['@odata.id']\n", - " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", - " for _ethernet_interface in ethernet_interfaces:\n", - " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", - " get(_ethernet_interface['@odata.id']).dict\n", - " break\n", - "\n", - " if ethernet_data:\n", - " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", - " print(json.dumps(ethernet_data, indent=4, sort_keys=True))\n", - "\n", - " body = {\"Oem\": {\"Hpe\": {\"DHCPv4\": {\"UseNTPServers\": ntp_servers}, \\\n", - " \"DHCPv6\": {\"UseNTPServers\": ntp_servers}}}}\n", - " for ethernet in ethernet_data:\n", - " resp = _redfishobj.patch(ethernet, body)\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " _data = _redfishobj.get(ethernet).dict\n", - " sys.stdout.write(\"\\nShowing \\'%s\\' interface after changes:\\n\" % ethernet)\n", - " print(json.dumps(_data, indent=4, sort_keys=True))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
    \n", - "

    3

    \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", - "
      \n", - " \n", - "
    • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", - "
    • If server is down or Unreachable we get server not reachable message!
    • \n", - "
    • If not then we make a call to enable_ntp function by passing parameters such as redfishclient object and enable flag to perform required operation.
    • \n", - "
    • After getting required information Redfish.logout() closes the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " \n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # Properties\n", - " # NTP Servers Enable/Disable Flag\n", - " NTP_SERVERS = True\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", - " REDFISHOBJ.logout()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
    In case you need help 🔗 links to relevant resources :\n", - "
    \n", - " 1.Python-ilorest-library:LINK
    \n", - " 2.Hpe ilorest-api explorer:LINK
    \n", - " 3.Rest api: LINK
    \n", - " \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'ilorest'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mgetpass\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m redfish_client\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mredfish_object\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RedfishClient\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mexceptions\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ServerDownOrUnreachableError\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'ilorest'" - ] - } - ], - "source": [ - "import getpass\n", - "from ilorest import redfish_client\n", - "from ilorest.redfish_object import RedfishClient\n", - "from ilorest.exceptions import ServerDownOrUnreachableError\n", - "\n", - "def main():\n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # Properties\n", - " # NTP Servers Enable/Disable Flag\n", - " NTP_SERVERS = True\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", - " REDFISHOBJ.logout()\n", - " \n", - "if __name__ == \"__main__\":\n", - " main()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb deleted file mode 100644 index cfd4a78..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb +++ /dev/null @@ -1,228 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3dfca749-3331-47de-9d47-c705fdbfd813", - "metadata": { - "tags": [] - }, - "source": [ - "# Finding iLo Mac address" - ] - }, - { - "cell_type": "markdown", - "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", - "metadata": {}, - "source": [ - "
    \n", - "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to find_ilo_mac_address!!!
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7873d333-4738-4dfc-8cf3-8e424eafaa48", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "import getpass\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "#from get_resource_directory import get_resource_directory\n" - ] - }, - { - "cell_type": "markdown", - "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", - "metadata": {}, - "source": [ - "
    \n", - "

    This is our find_ilo_mac_address function overview, in the end this will give us about finding ilo mac address related information.

    \n", - "

    Let me give you a walk through of it!

    \n", - "
      \n", - "
    1. For the identification of a device, its mac address is very much required. If you have the Systems Management Homepage installed, you can find out by clicking \"Management Processor\" and then check the Physical Address field.
    2. \n", - "
    3. If we don't have a resource directory, information about the ethernet data is stored inside the managers json object. Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.
    4. \n", - "
    5. Ethernet interface gives the response for that member about the ilo mac address
    6. \n", - "
    7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the ethernet interface is present in @odata.type attribute then we will store information about ethernet interface in ethernet_data dictionary and break out of iteration.
    8. \n", - "
    9. Finally, we get iLo Network Manager Interface and iLO Mac Address as output.
    10. \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", - "metadata": {}, - "outputs": [], - "source": [ - "def find_ilo_mac_address(_redfishobj):\n", - "\n", - " ethernet_data = {}\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", - " ['@odata.id']\n", - " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", - " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", - " obj['Members']\n", - " for _member in manager_ethernet_interfaces_members:\n", - " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", - " ethernet_data[_member['@odata.id']] = _tmp\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", - " instance['@odata.id']:\n", - " ethernet_uri = instance['@odata.id']\n", - " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", - " for _ethernet_interface in ethernet_interfaces:\n", - " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", - " get(_ethernet_interface['@odata.id']).dict\n", - " for iface in ethernet_data:\n", - " sys.stdout.write(\"iLO Network Manager Interface: \\'%s\\'\\n\" % ethernet_data[iface]['Id'])\n", - " sys.stdout.write(\"\\tiLO Mac Address: \\'%s\\'\\n\" % ethernet_data[iface].get('MACAddress'))\n" - ] - }, - { - "cell_type": "markdown", - "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", - "metadata": {}, - "source": [ - "
    \n", - "

    3.

    The Main function:
    PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", - "
      \n", - "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", - "
    • If server is down or Unreachable we get \"server not reachable\" message!
    • \n", - "
    • and Once everything is done you are automatically logged out with .logout() 😁.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6398fb6f-5672-4075-bf73-8af549f172de", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", - " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " find_ilo_mac_address(REDFISHOBJ)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", - "metadata": {}, - "source": [ - "
    \n", - " When running on the server locally : use the following values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " \"https://10.0.0.100\"
    \n", - " \"https://ilo.hostname\"\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb deleted file mode 100644 index e951cf7..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb +++ /dev/null @@ -1,398 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f815c9a7", - "metadata": {}, - "source": [ - "

    Uploading Firmware to the iLO Repository For Flashing

    " - ] - }, - { - "cell_type": "markdown", - "id": "2a3a9755", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of uploading firmware to the iLO Repository for flashings
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cc555954", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cff3ead6", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys\n", - "import json\n", - "import argparse\n", - "from random import randint\n", - "\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "import logging\n", - "from redfish import redfish_logger\n", - "\n", - "from ilorest_util import get_resource_directory" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "102138e9", - "metadata": {}, - "outputs": [], - "source": [ - "LOGGERFILE = \"RedfishApiExamples.log\"\n", - "LOGGERFORMAT = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n", - "LOGGER = redfish_logger(LOGGERFILE, LOGGERFORMAT, logging.DEBUG)" - ] - }, - { - "cell_type": "markdown", - "id": "b41f56eb", - "metadata": {}, - "source": [ - "
    \n", - "

    2. This is about upload_firmware function

    \n", - " \n", - "1. The function upload_firmware takes in parameters such as _redfishobj, firmware_loc, comp_type, update_repo, and update_target..
    \n", - "
    \n", - " \n", - "2. It uploads firmware to a specified location using the Redfish API and HTTP POST request.
    \n", - "
    \n", - "\n", - "3. The function first obtains the UpdateService URI and HttpPushUri using the _redfishobj and then reads the firmware file as binary data.
    \n", - "
    \n", - "\n", - "4. It creates a payload containing the session key, JSON data, and the firmware file in multipart-form data format..
    \n", - "
    \n", - "5. Finally, the function sends the payload as an HTTP POST request to the specified path and returns an appropriate response based on the HTTP status code.\n", - "
    \n", - " \n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b99181a4", - "metadata": {}, - "outputs": [], - "source": [ - "def upload_firmware(_redfishobj, firmware_loc, comp_type, update_repo=True, update_target=False):\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - "\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #resource directory is not available so we will navigate through paths manually\n", - " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", - " else:\n", - " #obtain all account instances from resource directory\n", - " for instance in resource_instances:\n", - " if '#UpdateService.' in instance['@odata.type']:\n", - " update_service_uri = instance['@odata.id']\n", - "\n", - " print (update_service_uri)\n", - "\n", - " update_service_response = _redfishobj.get(update_service_uri)\n", - "\n", - " path = update_service_response.obj.HttpPushUri\n", - " print (path)\n", - "\n", - " body = []\n", - "\n", - " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", - " session_key = _redfishobj.session_key\n", - "\n", - " #ImageLocation = \"c:\\\\test\"\n", - " #filename = \"I41_2.40_08_10_2020.fwpkg\"\n", - " #ImagePath = os.path.join(ImageLocation, filename)\n", - " #file_name = os.path.basename(firmware_loc)\n", - " #print (ImagePath)\n", - " with open(firmware_loc, 'rb') as fle:\n", - " output = fle.read()\n", - "\n", - " session_tuple = ('sessionKey', session_key)\n", - " parameters_tuple = ('parameters', json.dumps(json_data))\n", - " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", - "\n", - " #Build the payload from each multipart-form data tuple\n", - " body.append(session_tuple)\n", - " body.append(parameters_tuple)\n", - " body.append(file_tuple)\n", - " #print (body)\n", - "\n", - " #Create our header dictionary\n", - " header = {'Cookie': 'sessionKey=' + session_key}\n", - "\n", - " print ('Begin upload....please wait...')\n", - " # We pass the whole list payload to post\n", - " resp = _redfishobj.post(path, body, headers=header)\n", - "\n", - " if resp.status == 400:\n", - " sys.stderr.write(\"Failed to upload firmware...\")\n", - " elif not resp.status in [200, 201]:\n", - " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Upload complete!\\n\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "2b320019", - "metadata": {}, - "source": [ - "
    \n", - "

    3. This is about create task function

    \n", - " \n", - "1. The function create_task takes in parameters such as _redfishobj, firmware_loc, and tpm_flag.
    \n", - "
    \n", - " \n", - "2. It creates a new task for applying firmware updates using the Redfish API and HTTP POST request.
    \n", - "
    \n", - "\n", - "3. The function first obtains the session key and creates the necessary header dictionary for the HTTP request.It then checks if there are any current tasks in the task queue before creating a new task with a random ID and the given firmware file name.
    \n", - "
    \n", - "\n", - "4. The task is created using the update_task dictionary and sent as an HTTP POST request to the specified path.
    \n", - "
    \n", - "5. Finally, the function returns an appropriate response based on the HTTP status code.\n", - "
    \n", - " \n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "09f2bc6b", - "metadata": {}, - "outputs": [], - "source": [ - "def create_task(_redfishobj, firmware_loc, tpm_flag=True):\n", - "\n", - " session_key = _redfishobj.session_key\n", - " #Create our header dictionary\n", - " header = {'Cookie': 'sessionKey=' + session_key}\n", - "\n", - " updatable_by = ['Uefi']\n", - " task_path = '/redfish/v1/UpdateService/UpdateTaskQueue/'\n", - " file_name = os.path.basename(firmware_loc)\n", - "\n", - " task_resp = _redfishobj.get(task_path)\n", - " if not task_resp.obj[\"Members@odata.count\"]:\n", - " print (\"No current tasks, proceed to create new task\")\n", - "\n", - "\n", - " update_task = {'Name': 'Update-%s-%s' % (str(randint(0, 1000000)), \\\n", - " file_name), 'Command': 'ApplyUpdate',\\\n", - " 'Filename': file_name, 'UpdatableBy': updatable_by, 'TPMOverride': tpm_flag}\n", - "\n", - " resp = _redfishobj.post(task_path, update_task, headers=header)\n", - " #print (resp)\n", - " if resp.status == 400:\n", - " sys.stderr.write(\"Failed to create update task queue...\")\n", - " elif not resp.status in [200, 201]:\n", - " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Task Queue Creation complete!\\n\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "bcac4f85", - "metadata": {}, - "source": [ - "
    \n", - "

    4.

    \n", - " The Main function:
    PLEASE PROVIDE THE FOLLOWING CREDENTIALS HERE TO PROCEED FURTHER

    \n", - "
      \n", - "
    • The path to the firmware file to upload (-c/--component)
    • \n", - "
    • The iLO IP of the server (-i/--ilo)
    • \n", - "
    • The iLO username to login (-u/--user)
    • \n", - "
    • The iLO password to log in (-p/--password)
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "0b490052", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", - "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - "\n", - " # Initialize parser\n", - " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", - "\n", - " parser.add_argument(\n", - " '-c',\n", - " '--component',\n", - " dest='comp_path',\n", - " action=\"store\",\n", - " required=True,\n", - " help=\"The path to the firmware file to upload\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-s',\n", - " '--session_key',\n", - " dest='session_key',\n", - " action=\"store\",\n", - " required=False,\n", - " help=\"Http session key for the server\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-i',\n", - " '--ilo',\n", - " dest='ilo_ip',\n", - " action=\"store\",\n", - " required=False,\n", - " help=\"iLO IP of the server\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-u',\n", - " '--user',\n", - " dest='ilo_user',\n", - " action=\"store\",\n", - " required=False,\n", - " help=\"iLO username to login\",\n", - " default=None)\n", - " parser.add_argument(\n", - " '-p',\n", - " '--password',\n", - " dest='ilo_pass',\n", - " action=\"store\",\n", - " required=False,\n", - " help=\"iLO password to log in.\",\n", - " default=None)\n", - "\n", - " options = parser.parse_args()\n", - "\n", - " system_url = \"https://\" + options.ilo_ip\n", - " print (system_url)\n", - "\n", - " # Upload the firmware file to the iLO Repository\n", - " update_repo_flag = True\n", - " # Update the system with the firmware file\n", - " update_target_flag = False\n", - "\n", - " comp_type = 'C'\n", - " tpm_flag = True\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = True\n", - " #system_url = \"https://\" + \"15.146.46.49\"\n", - " #session_id = \"515b196969f7d879886ee4a2da4ccba8\"\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " if options.session_key:\n", - " redfish_obj = RedfishClient(base_url=system_url, session_key= options.session_key)\n", - " else:\n", - " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", - " # Login with the Redfish client\n", - " redfish_obj.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " upload_firmware(redfish_obj, options.comp_path, comp_type, update_repo_flag, update_target_flag)\n", - " if comp_type == 'C':\n", - " create_task(redfish_obj, options.comp_path, tpm_flag)\n", - "\n", - " redfish_obj.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "acc45fbf", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "a73f3528", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb deleted file mode 100644 index 83a9be5..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb +++ /dev/null @@ -1,279 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "042acf39", - "metadata": { - "tags": [] - }, - "source": [ - "# Generating a certificate signing request for HPE iLO systems" - ] - }, - { - "cell_type": "markdown", - "id": "7b34599c", - "metadata": {}, - "source": [ - "
    \n", - "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to generate_csr!!!
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "e7338dfb", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c9837f2", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "#from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "034daf66", - "metadata": {}, - "source": [ - "
    \n", - "

    2.

    This is our generate csr function overview, in the end we will be able to make a certificate signing request.
    \n", - " Let me give you a walk through of it!\n", - "
    \n", - " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", - "\n", - "1. In the generate_csr function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", - "
    \n", - " \n", - "2. In the ILO rest api the information about Http certificates is stored inside the managers json object.\n", - " And now through managers_response variable, we are making a http GET operation to and trying to obtain the certificates of signing of iLO system.\n", - "
    \n", - "\n", - "3. In the system managers members response object with different odata_id we get a security service uri .\n", - " Then again an http GET request is made and response is stored in security_service_response.\n", - " Then we will make a http_cert_response by using csr_uri through security_service_response and then using http_cert_response we will get generate_csr_uri.\n", - "
    \n", - "\n", - "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", - " and if HpeHttpsCert attribute is present in @odata.type attribute then we'll set csr_uri and get generate csr uri of the target.\n", - "
    \n", - "\n", - "5. If generate_csr_uri exists, then we will define the body and send a post request through redfish object. After generating the csr, we can obtain the csr_response using get method for csr_uri. csr_response contains CertificateSigningRequest. \n", - "\n", - "
    \n", - "6. If you get the result, then it is successful. if you don't get the result, then there is an error.\n", - " \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "644bd708", - "metadata": {}, - "outputs": [], - "source": [ - "def generate_csr(_redfishobj, csr_file, csr_properties):\n", - "\n", - " csr_uri = None\n", - " generate_csr_uri = None\n", - "\n", - " resource_instances = _redfishobj.get_resource_directory()\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", - " ['SecurityService']['@odata.id']\n", - " security_service_response = _redfishobj.get(security_service_uri)\n", - " csr_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", - " https_cert_response = _redfishobj.get(csr_uri)\n", - " generate_csr_uri = https_cert_response.obj['Actions']['#HpeHttpsCert.GenerateCSR']\\\n", - " ['target']\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#HpeHttpsCert.' in instance['@odata.type']:\n", - " csr_uri = instance['@odata.id']\n", - " generate_csr_uri = _redfishobj.get(csr_uri).obj['Actions']\\\n", - " ['#HpeHttpsCert.GenerateCSR']['target']\n", - " break\n", - "\n", - " if generate_csr_uri:\n", - " body = dict()\n", - " body[\"Action\"] = \"HpeHttpsCert.GenerateCSR\"\n", - " body[\"City\"] = csr_properties[\"City\"]\n", - " body[\"CommonName\"] = csr_properties[\"CommonName\"]\n", - " body[\"Country\"] = csr_properties[\"Country\"]\n", - " body[\"OrgName\"] = csr_properties[\"OrgName\"]\n", - " body[\"OrgUnit\"] = csr_properties[\"OrgUnit\"]\n", - " body[\"State\"] = csr_properties[\"State\"]\n", - " resp = _redfishobj.post(generate_csr_uri, body)\n", - " if resp.status in [200, 201]:\n", - " sys.stdout.write(\"Generating CSR, this may take a few minutes\\n\")\n", - " sys.stdout.write(\"Sleeping for 5 minutes...\\n\")\n", - " time.sleep(600)\n", - " csr_resp = _redfishobj.get(csr_uri).dict['CertificateSigningRequest']\n", - " with open(csr_file, 'wb') as csroutput:\n", - " csroutput.write(csr_resp)\n", - " sys.stdout.write(\"CSR Data saved to file: '%s'\\n\" % csr_file)\n", - " else:\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", - " #info error message to see what went wrong\n", - " if resp.status not in [200, 201]:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", - " \"Extended Message Info...\\n\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "2da11ba0", - "metadata": {}, - "source": [ - "
    \n", - "

    3.

    This is Main function overview.
    \n", - " Let me give you a walk through of it!\n", - "
    \n", - " Enter your ilo url,Username,Password here.
    \n", - "\n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", - "
    \n", - " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", - "
    \n", - "\n", - "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", - "
    \n", - "\n", - "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", - "
    \n", - "5. Then we call generate_csr with our redfish object.
    \n", - " \n", - "\n", - "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "46b3e899", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " SYSTEM_URL = input(\"Enter System URL: \")\n", - " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", - " LOGIN_PASSWORD = input(\"Enter password: \")\n", - "\n", - " #CSR Dictionary, each value should be updated to reflect the desired CSR\n", - " CSR_DICT = {\"City\" : input(\"Enter city:\"), \"CommonName\": input(\"Enter name:\"), \"Country\": input(\"Enter country :\"), \\\n", - " \"OrgName\": input(\"Enter organization :\"), \"OrgUnit\": input(\"Enter unit :\"), \"State\": input(\"Enter state:\")}\n", - "\n", - " #After CSR is generated, a file will be created and the CSR will be downloaded\n", - " CSR_FILE = \"csr.txt\"\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " generate_csr(REDFISHOBJ, CSR_FILE, CSR_DICT)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "06934cbc", - "metadata": {}, - "source": [ - "
    \n", - " When running on the server locally : use the following values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " \"https://10.0.0.100\"
    \n", - " \"https://ilo.hostname\"\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "12c33902", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb deleted file mode 100644 index fc1f0bb..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb +++ /dev/null @@ -1,252 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f815c9a7", - "metadata": {}, - "source": [ - "

    Manually Managing Sessions With Redfish

    " - ] - }, - { - "cell_type": "markdown", - "id": "2a3a9755", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of manually managing sessions with Redfish
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cc555954", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cff3ead6", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from six.moves import urllib\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n" - ] - }, - { - "cell_type": "markdown", - "id": "b41f56eb", - "metadata": {}, - "source": [ - "
    \n", - "

    2. This is about sessions function

    \n", - " \n", - "1. This function creates a new session with an iLO server using provided login credentials..
    \n", - "
    \n", - " \n", - "2. The function sends a POST request to the /redfish/v1/Sessions endpoint to create the session..
    \n", - "
    \n", - "\n", - "3. If the session is created successfully (response code 201), the function prints the session URI and X-Auth Token key..
    \n", - "
    \n", - "\n", - "4. The function also sends a DELETE request to the session URI to terminate the session.
    \n", - "
    \n", - "5. If the session creation fails, the function prints an error message and tries to access the iLO Extended Message Info for more details..
    \n", - " \n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b99181a4", - "metadata": {}, - "outputs": [], - "source": [ - "def sessions(_redfishobj, login_account, login_password):\n", - "\n", - " new_session = {\"UserName\": login_account, \"Password\": login_password}\n", - " response = _redfishobj.post('/redfish/v1/Sessions', new_session)\n", - "\n", - " if response.status == 201:\n", - " print(\"Success!\\n\")\n", - " session_uri = response.getheader(\"location\")\n", - " session_uri = urllib.parse.urlparse(session_uri)\n", - " sys.stdout.write(\"\\tSession \" + session_uri.path + \" created.\\n\")\n", - " x_auth_token = response.getheader(\"x-auth-token\")\n", - " sys.stdout.write(\"\\tThis is the session X-Auth Token key \" + x_auth_token + \".\\n\")\n", - " print(json.dumps(response.dict, indent=4, sort_keys=True))\n", - "\n", - " # Delete the created session\n", - " sys.stdout.write(\"\\tTerminating this session.\\n\")\n", - " sessresp = _redfishobj.delete(session_uri.path)\n", - " print(json.dumps(sessresp.dict, indent=4, sort_keys=True))\n", - " else:\n", - " sys.stderr.write(\"ERROR: failed to create a session.\\n\")\n", - " try:\n", - " print(json.dumps(sessresp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended\"\n", - " \" Message Info...\")\n" - ] - }, - { - "cell_type": "markdown", - "id": "031a5cbe", - "metadata": {}, - "source": [ - "

    3.

    \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", - "
      \n", - "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", - "
    • If server is down or Unreachable we get server not reachable message!
    • \n", - "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", - "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "c8cd2ffd", - "metadata": {}, - "source": [ - "

    4.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "77edbde3", - "metadata": {}, - "source": [ - "
    \n", - "
    Instructions
    \n", - "
      \n", - "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", - "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", - "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", - "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "0b490052", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", - "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - " \n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " sessions(REDFISHOBJ, LOGIN_ACCOUNT, LOGIN_PASSWORD)#calling sessions function" - ] - }, - { - "cell_type": "markdown", - "id": "316c3f0e", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "markdown", - "id": "acc45fbf", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb deleted file mode 100644 index 7c760bb..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb +++ /dev/null @@ -1,296 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f815c9a7", - "metadata": {}, - "source": [ - "

    Set_ESKM_PrimaryKeyServer

    " - ] - }, - { - "cell_type": "markdown", - "id": "2a3a9755", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of set_ESKM_PrimaryKeyServer
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cc555954", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cff3ead6", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "b41f56eb", - "metadata": {}, - "source": [ - "
    \n", - "

    2. This is about set_ESKM_PrimaryKeyServer function

    \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "1. This function sets the primary key server for the HPE ESKM service.
    \n", - "
    \n", - " \n", - "2. It takes three arguments: _redfishobj (an object representing the Redfish service), primary_key_server_address (a string representing the IP address or hostname of the primary key server), and primary_key_server_port (an integer representing the port number of the primary key server).
    \n", - "
    \n", - "\n", - "3. It uses the get_resource_directory function to find the relevant ESKM URI, which is used to make a POST request to set the primary key server.
    \n", - "
    \n", - "\n", - "4. If the POST request is successful (returns an HTTP status code of 200), the function prints a success message and the JSON response from the server.
    \n", - "
    \n", - "5. If the POST request is unsuccessful, the function prints an error message and, if available, the extended error information from the server response.\n", - "
    \n", - " \n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b99181a4", - "metadata": {}, - "outputs": [], - "source": [ - "def set_ESKM_PrimaryKeyServer(_redfishobj, primary_key_server_address, primary_key_server_port):\n", - "\n", - " eskm_uri = None\n", - " body = dict()\n", - "\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", - " ['@odata.id']\n", - " security_service_response = _redfishobj.get(security_service_uri)\n", - " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#HpeESKM.' in instance['@odata.type']:\n", - " eskm_uri = instance['@odata.id']\n", - " break\n", - "\n", - " if eskm_uri:\n", - "\n", - " body[\"PrimaryKeyServerAddress\"] = primary_key_server_address\n", - " body[\"PrimaryKeyServerPort\"] = int(primary_key_server_port)\n", - "\n", - " resp = _redfishobj.post(eskm_uri, body)\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "c8cd2ffd", - "metadata": {}, - "source": [ - "

    3.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "031a5cbe", - "metadata": {}, - "source": [ - "

    4.

    \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", - "
      \n", - "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", - "
    • If server is down or Unreachable we get server not reachable message!
    • \n", - "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", - "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "77edbde3", - "metadata": {}, - "source": [ - "
    \n", - "
    Instructions
    \n", - "
      \n", - "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", - "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", - "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", - "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "0b490052", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", - "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - " # When running on the server locally use the following commented values\n", - " #SYSTEM_URL = None\n", - " #LOGIN_ACCOUNT = None\n", - " #LOGIN_PASSWORD = None\n", - "\n", - " # When running remotely connect using the secured (https://) address,\n", - " # account name, and password to send https requests\n", - " # SYSTEM_URL acceptable examples:\n", - " # \"https://10.0.0.100\"\n", - " # \"https://ilo.hostname\"\n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " PRIMARY_KEY_SERVER_ADDRESS = \"192.168.1.1\"\n", - " PRIMARY_KEY_SERVER_PORT = \"9000\"\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " set_ESKM_PrimaryKeyServer(REDFISHOBJ, PRIMARY_KEY_SERVER_ADDRESS, PRIMARY_KEY_SERVER_PORT)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "acc45fbf", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "a73f3528", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb deleted file mode 100644 index f38c417..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb +++ /dev/null @@ -1,289 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f815c9a7", - "metadata": {}, - "source": [ - "

    Setting the ESKM username and password for HPE iLO systems

    " - ] - }, - { - "cell_type": "markdown", - "id": "2a3a9755", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of setting the ESKM username and password for HPE iLO systems
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cc555954", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cff3ead6", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "b41f56eb", - "metadata": {}, - "source": [ - "
    \n", - "

    2. This is about ESKM_username_pass function

    \n", - " \n", - "1. The function sets up an Electronic Software Key Manager (ESKM) on an iLO (Integrated Lights Out) server using the Redfish API.
    \n", - "
    \n", - " \n", - "2. It takes several input parameters including ESKM username, password, account group, primary key server address, and primary key server port.
    \n", - "
    \n", - "\n", - "3. It first attempts to locate the URI for the ESKM resource either by using the Redfish Resource Directory or by manually navigating through the Redfish API.br>\n", - "
    \n", - "\n", - "4. If the ESKM URI is found, the function constructs a JSON payload containing the ESKM configuration information and primary key server details and sends it as a PATCH request to the ESKM resource.
    \n", - "
    \n", - "5. If the PATCH request is successful (i.e., returns an HTTP status code of 200), the function prints out a success message along with the response payload, otherwise it prints out an error message.\n", - "
    \n", - " \n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b99181a4", - "metadata": {}, - "outputs": [], - "source": [ - "def ESKM_username_pass(_redfishobj, eskm_username, eskm_password, eskm_accountgroup, \\\n", - " eskm_primarykeyserver_addr, eskm_primarykeyserver_port):\n", - "\n", - " eskm_uri = None\n", - " body = dict()\n", - "\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", - " ['@odata.id']\n", - " security_service_response = _redfishobj.get(security_service_uri)\n", - " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#HpeESKM.' in instance['@odata.type']:\n", - " eskm_uri = instance['@odata.id']\n", - " break\n", - "\n", - " if eskm_uri:\n", - " body[\"KeyManagerConfig\"] = dict()\n", - " body[\"KeyManagerConfig\"][\"LoginName\"] = eskm_username\n", - " body[\"KeyManagerConfig\"][\"Password\"] = eskm_password\n", - " body[\"KeyManagerConfig\"][\"AccountGroup\"] = eskm_accountgroup\n", - " body[\"KeyManagerConfig\"][\"ESKMLocalCACertificateName\"] = \"\"\n", - " body[\"PrimaryKeyServerAddress\"] = eskm_primarykeyserver_addr\n", - " body[\"PrimaryKeyServerPort\"] = eskm_primarykeyserver_port\n", - " resp = _redfishobj.patch(eskm_uri, body)\n", - " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", - " #error message to see what went wrong\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success!\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "markdown", - "id": "c8cd2ffd", - "metadata": {}, - "source": [ - "

    3.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "031a5cbe", - "metadata": {}, - "source": [ - "

    4.

    \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", - "
      \n", - "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", - "
    • If server is down or Unreachable we get server not reachable message!
    • \n", - "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", - "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "77edbde3", - "metadata": {}, - "source": [ - "
    \n", - "
    Instructions
    \n", - "
      \n", - "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", - "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", - "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", - "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "0b490052", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", - "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - " \n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " ESKM_USERNAME = \"admin\"\n", - " ESKM_PASSWORD = \"password\"\n", - " ESKM_ACCOUNTGROUP = \"group\"\n", - " ESKM_PRIMARYKEYSERVER_ADDR = \"192.168.1.10\"\n", - " ESKM_PRIMARYKEYSERVER_PORT = 5927\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", - " password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \\\n", - " ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "acc45fbf", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "id": "a73f3528", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb deleted file mode 100644 index e0299c5..0000000 --- a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb +++ /dev/null @@ -1,295 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f815c9a7", - "metadata": {}, - "source": [ - "

    Setting the active Manager NIC

    " - ] - }, - { - "cell_type": "markdown", - "id": "2a3a9755", - "metadata": {}, - "source": [ - "
    \n", - "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of setting the active Manager NIC
    As you are here let's get it done easily.
    \n", - " To perform this u need to have python-ilorest-library installed in your machine.
    \n", - " And please keep your username and password handy!\n", - "
    \n", - " Also do execute each successive cell once to avoid any errors!\n", - " \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "cc555954", - "metadata": {}, - "source": [ - "
    \n", - "

    1.

    \n", - " Below we are importing all the necessary modules from the ilorest library! To know more about the modules click below\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cff3ead6", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "import json\n", - "from redfish import RedfishClient\n", - "from redfish.rest.v1 import ServerDownOrUnreachableError\n", - "\n", - "from get_resource_directory import get_resource_directory" - ] - }, - { - "cell_type": "markdown", - "id": "b41f56eb", - "metadata": {}, - "source": [ - "
    \n", - "

    2. This is about set_active_ilo_nic function

    \n", - " \n", - "\n", - "1. This function is used to enable/disable Ethernet interfaces on an iLO (Integrated Lights Out) management interface.
    \n", - "
    \n", - " \n", - "2. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
    \n", - "
    \n", - "\n", - "3. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
    \n", - "
    \n", - "\n", - "4. If the PATCH request is successful (HTTP status 200), the function prints a success message and the response body, which contains information about the updated Ethernet interface.
    \n", - "
    \n", - "5. Finally, the function reminds the user that they need to reset iLO for the change to take effect.
    \n", - " \n", - "\n", - "\n", - "\n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b99181a4", - "metadata": {}, - "outputs": [], - "source": [ - "def set_active_ilo_nic(_redfishobj):\n", - "\n", - " ethernet_data = {}\n", - "\n", - " resource_instances = get_resource_directory(_redfishobj)\n", - " if DISABLE_RESOURCE_DIR or not resource_instances:\n", - " #if we do not have a resource directory or want to force it's non use to find the\n", - " #relevant URI\n", - " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", - " managers_response = _redfishobj.get(managers_uri)\n", - " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", - " managers_members_response = _redfishobj.get(managers_members_uri)\n", - " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", - " ['@odata.id']\n", - " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", - " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", - " obj['Members']\n", - " for _member in manager_ethernet_interfaces_members:\n", - " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", - " ethernet_data[_member['@odata.id']] = _tmp\n", - " else:\n", - " #Use Resource directory to find the relevant URI\n", - " for instance in resource_instances:\n", - " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", - " instance['@odata.id']:\n", - " ethernet_uri = instance['@odata.id']\n", - " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", - " for _ethernet_interface in ethernet_interfaces:\n", - " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", - " get(_ethernet_interface['@odata.id']).dict\n", - " break\n", - "\n", - " if ethernet_data:\n", - " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", - " for interface in ethernet_data:\n", - " sys.stdout.write(\"Ethernet Management Inteface \\'%s\\'\\n\" % ethernet_data\\\n", - " [interface].get('Id'))\n", - " sys.stdout.write(\"\\t\\'Interface Enabled\\': %s\\n\" % ethernet_data[interface].\\\n", - " get('InterfaceEnabled'))\n", - "\n", - " for ethernet in ethernet_data:\n", - " sys.stdout.write(\"Ethernet Interface: %s\\n\" % ethernet)\n", - " ans = input(\"Would you like to enable/disable this interface? (enable/disable)\\n\")\n", - " if \"en\" in ans:\n", - " body = {\"InterfaceEnabled\": True}\n", - " else:\n", - " body = {\"InterfaceEnabled\": False}\n", - " resp = _redfishobj.patch(ethernet, body)\n", - " if resp.status == 400:\n", - " try:\n", - " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", - " sort_keys=True))\n", - " except Exception as excp:\n", - " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", - " \"Message Info...\")\n", - " elif resp.status != 200:\n", - " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", - " else:\n", - " print(\"Success! You will need to reset iLO for this change to take effect.\\n\")\n", - " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", - " break\n" - ] - }, - { - "cell_type": "markdown", - "id": "031a5cbe", - "metadata": {}, - "source": [ - "

    3.

    \n", - "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", - "
      \n", - "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", - "
    • If server is down or Unreachable we get server not reachable message!
    • \n", - "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", - "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "c8cd2ffd", - "metadata": {}, - "source": [ - "

    4.

    \n", - " When running on the server locally use the following commented values
    \n", - " SYSTEM_URL = None
    \n", - " LOGIN_ACCOUNT = None
    \n", - " LOGIN_PASSWORD = None
    \n", - "\n", - " When running remotely connect using the secured (https://) address,\n", - " account name, and password to send https requests\n", - "
    \n", - " SYSTEM_URL acceptable examples:
    \n", - " https://10.0.0.100
    \n", - " https://ilo.hostname\n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "77edbde3", - "metadata": {}, - "source": [ - "
    \n", - "
    Instructions
    \n", - "
      \n", - "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", - "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", - "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", - "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", - "
    \n", - "
    " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "0b490052", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ServerDownOrUnreachableError' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", - "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" - ] - } - ], - "source": [ - "if __name__ == \"__main__\":\n", - " \n", - " SYSTEM_URL = \"https://10.0.0.100\"\n", - " LOGIN_ACCOUNT = \"admin\"\n", - " LOGIN_PASSWORD = \"password\"\n", - "\n", - " # flag to force disable resource directory. Resource directory and associated operations are\n", - " # intended for HPE servers.\n", - " DISABLE_RESOURCE_DIR = False\n", - "\n", - " try:\n", - " # Create a Redfish client object\n", - " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\password=LOGIN_PASSWORD)\n", - " # Login with the Redfish client\n", - " REDFISHOBJ.login()\n", - " except ServerDownOrUnreachableError as excp:\n", - " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", - " sys.exit()\n", - "\n", - " set_active_ilo_nic(REDFISHOBJ)\n", - " REDFISHOBJ.logout()" - ] - }, - { - "cell_type": "markdown", - "id": "316c3f0e", - "metadata": {}, - "source": [ - "

    5.

    In case you need help 🔗 links to relevant resources :\n", - " \n", - "
    \n" - ] - }, - { - "cell_type": "markdown", - "id": "acc45fbf", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From e0c9d0f6b6068437331d5165432dda3073d32e1c Mon Sep 17 00:00:00 2001 From: venkatrahul2003 <104755146+venkatrahul2003@users.noreply.github.com> Date: Tue, 30 May 2023 19:26:35 +0530 Subject: [PATCH 046/159] Add files via upload --- .../eject_virtual_media_iso.ipynb | 275 ++++++++++++ .../B VENKAT RAHUL/enable_secure_boot-.ipynb | 263 ++++++++++++ .../B VENKAT RAHUL/enabling_ntp_server.ipynb | 313 ++++++++++++++ .../B VENKAT RAHUL/find_ilo_mac_address.ipynb | 232 ++++++++++ .../flash_firmware_by_uefi.ipynb | 398 ++++++++++++++++++ .../HPECTY/B VENKAT RAHUL/generate_csr.ipynb | 283 +++++++++++++ .../get_SmartArray_EncryptionSettings.ipynb | 246 +++++++++++ .../HPECTY/B VENKAT RAHUL/get_schema.ipynb | 220 ++++++++++ .../HPECTY/B VENKAT RAHUL/sessions.ipynb | 250 +++++++++++ .../set_ESKM_PrimaryKeyServer.ipynb | 297 +++++++++++++ .../set_ESKM_username_password.ipynb | 290 +++++++++++++ .../B VENKAT RAHUL/set_active_ilo_nic.ipynb | 295 +++++++++++++ 12 files changed, 3362 insertions(+) create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_SmartArray_EncryptionSettings.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_schema.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb create mode 100644 examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb new file mode 100644 index 0000000..5c12a68 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/eject_virtual_media_iso.ipynb @@ -0,0 +1,275 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "71861904", + "metadata": {}, + "source": [ + "

    Mount Virtual Media Iso

    " + ] + }, + { + "cell_type": "markdown", + "id": "45dd47a5", + "metadata": {}, + "source": [ + "
    \n", + "
      \n", + "
    • This Jupyter Notebook will contains a example code to demonstrate how Mount virtula media iso. This code is written in Python and uses the redfish library to perform the required operations.

    • \n", + "
    • As you are here let's get it done easily.
    • \n", + "
    • To perform this u need to have python-ilorest-library installed in your machine.
    • \n", + "
    • Please keep your username and password handy
    • \n", + "
    • Do execute each successive cell once to avoid any errors!
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "23eeb2bf", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92ec68a2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "10a8e977", + "metadata": {}, + "source": [ + "
    \n", + "

    2.This is our mount_virtual_media_iso function overview, in the end this will give us with virtual media related information.


    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the virtual media information.\n", + "\n", + "1. In the mount_virtual_media_iso function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about virtual media is stored inside the managers json object.\n", + " Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.\n", + "
    \n", + "\n", + "3. In the managers response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in managers_members_response.\n", + " The virtual media information is ultimately present in the managers_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if virtual media is present in @odata.type attribute then we will store information about virtual media in virtual_media_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if virtual_media_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f034ef9c", + "metadata": {}, + "outputs": [], + "source": [ + "def mount_virtual_media_iso(_redfishobj, media_type,):\n", + "\n", + " virtual_media_uri = None\n", + " virtual_media_response = []\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " virtual_media_uri = managers_members_response.obj['VirtualMedia']['@odata.id']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#VirtualMediaCollection.' in instance['@odata.type']:\n", + " virtual_media_uri = instance['@odata.id']\n", + "\n", + " if virtual_media_uri:\n", + " virtual_media_response = _redfishobj.get(virtual_media_uri)\n", + " for virtual_media_slot in virtual_media_response.obj['Members']:\n", + " data = _redfishobj.get(virtual_media_slot['@odata.id'])\n", + " if media_type in data.dict['MediaTypes']:\n", + " virtual_media_mount_uri = data.obj['Actions']['#VirtualMedia.EjectMedia']['target']\n", + " post_body = {\"Action\": \"HpeiLOVirtualMedia.EjectVirtualMedia\"}\n", + " resp = _redfishobj.post(virtual_media_mount_uri, post_body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO\"\n", + " \"Extended Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break" + ] + }, + { + "cell_type": "markdown", + "id": "268b5a18", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "90621a8a", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ab494baf", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 25\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 26\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 27\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 31\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 30\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 31\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 32\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 33\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " \n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " #specify the type of content the media represents\n", + " MEDIA_TYPE = \"CD\" #current possible options: Floppy, USBStick, CD, DVD\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + "\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " mount_virtual_media_iso(REDFISHOBJ, MEDIA_TYPE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "a839daaa", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb new file mode 100644 index 0000000..95713c5 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enable_secure_boot-.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0e4729be", + "metadata": {}, + "source": [ + "

    Enable Secure Boot

    " + ] + }, + { + "cell_type": "markdown", + "id": "b44c9aad", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of enabling secure boot
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "74ee46a2", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3b9ca27", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "d0e073c6", + "metadata": {}, + "source": [ + "
    \n", + "

    2.This is our enable_secure_boot function overview, in the end this will give us with secure boot related information.


    \n", + " Let me give you a walk through of it!\n", + "
    \n", + "There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the secure boot information.\n", + "\n", + "1. In the enable_secure_boot function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about secureboot is stored inside the systems json object.\n", + " Through systems_response variable we are making a http GET operation to and trying to obtain the secure boot about iLO system.\n", + "
    \n", + "\n", + "3. In the systems response object we are iterating on all the members with different odata_id .\n", + " Then again an http GET request is made and response is stored in systems_members_response.\n", + " The secure boot information is ultimately present in the systems_members_response.\n", + "
    \n", + "\n", + "4. Else if resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if secure boot is present in @odata.type attribute then we will store information about secure boot in secure_boot_uri and break out of iteration.\n", + "
    \n", + "\n", + "Ultimately if secure_boot_uri was obtained without any errors then get the information at the relevant uri and print out that information .\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d60549e", + "metadata": {}, + "outputs": [], + "source": [ + "def enable_secure_boot(_redfishobj, secure_boot_enable):\n", + "\n", + " secure_boot_uri = None\n", + " secure_boot_data = None\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " secure_boot_uri = systems_members_response.obj['SecureBoot']['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#SecureBoot.' in instance['@odata.type']:\n", + " secure_boot_uri = instance['@odata.id']\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + "\n", + " if secure_boot_data:\n", + " print(\"\\n\\nShowing Secure Boot properties before changes:\\n\\n\")\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))\n", + "\n", + " if secure_boot_uri:\n", + " body = {'SecureBootEnable': secure_boot_enable}\n", + " resp = _redfishobj.patch(secure_boot_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \" \\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"\\nSuccess!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " print(\"\\n\\nShowing Secure Boot properties after changes:\\n\\n\")\n", + " secure_boot_data = _redfishobj.get(secure_boot_uri)\n", + " print(json.dumps(secure_boot_data.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "b227f8f6", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "

    Please enter your login credentials here to proceed further:

    \n", + "
      \n", + "
    • Once your credentials are entered, a Redfish object is created with the help of the RedfishClient class, and a session is created to log you in to the server.
    • \n", + "
    • If the server is down or unreachable, we get a \"server not reachable\" message.
    • \n", + "
    • If not, we make a call to the enable_secure_boot function to obtain secure boot-related information of the system.
    • \n", + "
    • After getting the required information, Redfish.logout() closes the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    \n" + ] + }, + { + "cell_type": "markdown", + "id": "28cb201c", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8028b4ff", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " #Properties:\n", + " #secure boot enable property\n", + " SECURE_BOOT_ENABLE = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_secure_boot(REDFISHOBJ, SECURE_BOOT_ENABLE)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "cf8a164b", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb new file mode 100644 index 0000000..2873a97 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/enabling_ntp_server.ipynb @@ -0,0 +1,313 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

    Enable Ntp Servers

    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is the example to enable ntp servers .
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    2.Below function describes the process how to enable NTP servers for HPE ilo systems. NTP or Network Time Protocol is an internet protocol used to synchronize with computer clokc time sources in a network. \n", + "Current cell is the explains the processes performed inside the below function.

    \n", + "
    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to obtain the power metrics information.\n", + "\n", + "1. Initially, to obtain NTP server related information for HPE ilo systems a series of HTTP GET requests are being made so as to navigate to that path inside the iLO rest api where required information is stored.\n", + "After completion of these get requests we will be having the relevant uri in manager_ethernet_interfaces_members.\n", + "
    \n", + "2. Else if resource directory is enabled we can just use the resource directory to and then again navigate through the api to find relevant uri.\n", + "
    \n", + " \n", + "3. Whatever changes need to be made to enable the NTP server are being enclosed inside the dictionary named as body. Next up for all the instances of ethernet in ethernet_data we simply make a HTTP PATCH request by passing the ethernet instance and body dictionary with the PATCH request. \n", + " \n", + "\n", + "4. Following the patch request, the response returned by server is being saved inside resp variable and later if the server returns proper response it means there is no error else error is returned with error information. A reference for json.dumps\n", + "function as it is used multiple times - click here.\n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def enable_ntp(_redfishobj, ntp_servers, DISABLE_RESOURCE_DIR):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " print(json.dumps(ethernet_data, indent=4, sort_keys=True))\n", + "\n", + " body = {\"Oem\": {\"Hpe\": {\"DHCPv4\": {\"UseNTPServers\": ntp_servers}, \\\n", + " \"DHCPv6\": {\"UseNTPServers\": ntp_servers}}}}\n", + " for ethernet in ethernet_data:\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " _data = _redfishobj.get(ethernet).dict\n", + " sys.stdout.write(\"\\nShowing \\'%s\\' interface after changes:\\n\" % ethernet)\n", + " print(json.dumps(_data, indent=4, sort_keys=True))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + " PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + " \n", + "
    • Once your credentials that are enter everything a redfish object is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to enable_ntp function by passing parameters such as redfishclient object and enable flag to perform required operation.
    • \n", + "
    • After getting required information Redfish.logout() closes the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally use the following commented values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + "\n", + " When running remotely connect using the secured (https://) address,\n", + " account name, and password to send https requests\n", + "
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " https://10.0.0.100
    \n", + " https://ilo.hostname\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'ilorest'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mgetpass\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m redfish_client\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mredfish_object\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m RedfishClient\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01milorest\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mexceptions\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m ServerDownOrUnreachableError\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'ilorest'" + ] + } + ], + "source": [ + "import getpass\n", + "from ilorest import redfish_client\n", + "from ilorest.redfish_object import RedfishClient\n", + "from ilorest.exceptions import ServerDownOrUnreachableError\n", + "\n", + "def main():\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # Properties\n", + " # NTP Servers Enable/Disable Flag\n", + " NTP_SERVERS = True\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " enable_ntp(REDFISHOBJ, NTP_SERVERS, DISABLE_RESOURCE_DIR)\n", + " REDFISHOBJ.logout()\n", + " \n", + "if __name__ == \"__main__\":\n", + " main()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb new file mode 100644 index 0000000..6863fa4 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/find_ilo_mac_address.ipynb @@ -0,0 +1,232 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3dfca749-3331-47de-9d47-c705fdbfd813", + "metadata": { + "tags": [] + }, + "source": [ + "

    Find Ilo Mac Address

    " + ] + }, + { + "cell_type": "markdown", + "id": "ac00ccdd-3ac6-49f0-87eb-4f9c9dc185a2", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to find_ilo_mac_address!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "3a347c8c-d1fb-4ccf-94aa-73d7d0f42199", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17541bb6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "d83f828e-a91e-4efc-b70f-e14a01b3cd44", + "metadata": {}, + "source": [ + "
    \n", + "

    2.This is our find_ilo_mac_address function overview, in the end this will give us about finding ilo mac address related information.

    \n", + "

    Let me give you a walk through of it!

    \n", + "
      \n", + "
    1. For the identification of a device, its mac address is very much required. If you have the Systems Management Homepage installed, you can find out by clicking \"Management Processor\" and then check the Physical Address field.
    2. \n", + "
    3. If we don't have a resource directory, information about the ethernet data is stored inside the managers json object. Through managers_response variable we are making a http GET operation to and trying to obtain the virtual media about iLO system.
    4. \n", + "
    5. Ethernet interface gives the response for that member about the ilo mac address
    6. \n", + "
    7. If the resource directory is present, then we will simply iterate through all instances inside resources and if the ethernet interface is present in @odata.type attribute then we will store information about ethernet interface in ethernet_data dictionary and break out of iteration.
    8. \n", + "
    9. Finally, we get iLo Network Manager Interface and iLO Mac Address as output.
    10. \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e307a7c-e9e0-4033-a9be-374e7ade9e0a", + "metadata": {}, + "outputs": [], + "source": [ + "def find_ilo_mac_address(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " for iface in ethernet_data:\n", + " sys.stdout.write(\"iLO Network Manager Interface: \\'%s\\'\\n\" % ethernet_data[iface]['Id'])\n", + " sys.stdout.write(\"\\tiLO Mac Address: \\'%s\\'\\n\" % ethernet_data[iface].get('MACAddress'))\n" + ] + }, + { + "cell_type": "markdown", + "id": "d4e940e6-887e-4e35-8f77-bc331ade4485", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + " PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", + "
      \n", + "
    • Once you enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server
    • \n", + "
    • If server is down or Unreachable we get \"server not reachable\" message!
    • \n", + "
    • and Once everything is done you are automatically logged out with .logout()
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "615ad0b4-156f-478d-b6cb-8a12ad7117c3", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6398fb6f-5672-4075-bf73-8af549f172de", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter iLO IP address: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Username: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " find_ilo_mac_address(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "8bd8051b-cc81-4dca-8b8f-c86202b35880", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb new file mode 100644 index 0000000..9f25e3d --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/flash_firmware_by_uefi.ipynb @@ -0,0 +1,398 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

    Uploading Firmware to the iLO Repository For Flashing

    " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of uploading firmware to the iLO Repository for flashings
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import json\n", + "import argparse\n", + "from random import randint\n", + "\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "import logging\n", + "from redfish import redfish_logger\n", + "\n", + "from ilorest_util import get_resource_directory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "102138e9", + "metadata": {}, + "outputs": [], + "source": [ + "LOGGERFILE = \"RedfishApiExamples.log\"\n", + "LOGGERFORMAT = \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n", + "LOGGER = redfish_logger(LOGGERFILE, LOGGERFORMAT, logging.DEBUG)" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about upload_firmware function

    \n", + " \n", + "1. The function upload_firmware takes in parameters such as _redfishobj, firmware_loc, comp_type, update_repo, and update_target..
    \n", + "
    \n", + " \n", + "2. It uploads firmware to a specified location using the Redfish API and HTTP POST request.
    \n", + "
    \n", + "\n", + "3. The function first obtains the UpdateService URI and HttpPushUri using the _redfishobj and then reads the firmware file as binary data.
    \n", + "
    \n", + "\n", + "4. It creates a payload containing the session key, JSON data, and the firmware file in multipart-form data format..
    \n", + "
    \n", + "5. Finally, the function sends the payload as an HTTP POST request to the specified path and returns an appropriate response based on the HTTP status code.\n", + "
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def upload_firmware(_redfishobj, firmware_loc, comp_type, update_repo=True, update_target=False):\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + "\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #resource directory is not available so we will navigate through paths manually\n", + " update_service_uri = _redfishobj.root.obj['UpdateService']['@odata.id']\n", + " else:\n", + " #obtain all account instances from resource directory\n", + " for instance in resource_instances:\n", + " if '#UpdateService.' in instance['@odata.type']:\n", + " update_service_uri = instance['@odata.id']\n", + "\n", + " print (update_service_uri)\n", + "\n", + " update_service_response = _redfishobj.get(update_service_uri)\n", + "\n", + " path = update_service_response.obj.HttpPushUri\n", + " print (path)\n", + "\n", + " body = []\n", + "\n", + " json_data = {'UpdateRepository': update_repo, 'UpdateTarget': update_target, 'ETag': 'atag', 'Section': 0}\n", + " session_key = _redfishobj.session_key\n", + "\n", + " #ImageLocation = \"c:\\\\test\"\n", + " #filename = \"I41_2.40_08_10_2020.fwpkg\"\n", + " #ImagePath = os.path.join(ImageLocation, filename)\n", + " #file_name = os.path.basename(firmware_loc)\n", + " #print (ImagePath)\n", + " with open(firmware_loc, 'rb') as fle:\n", + " output = fle.read()\n", + "\n", + " session_tuple = ('sessionKey', session_key)\n", + " parameters_tuple = ('parameters', json.dumps(json_data))\n", + " file_tuple = ('file', (filename, output, 'application/octet-stream'))\n", + "\n", + " #Build the payload from each multipart-form data tuple\n", + " body.append(session_tuple)\n", + " body.append(parameters_tuple)\n", + " body.append(file_tuple)\n", + " #print (body)\n", + "\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " print ('Begin upload....please wait...')\n", + " # We pass the whole list payload to post\n", + " resp = _redfishobj.post(path, body, headers=header)\n", + "\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to upload firmware...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Upload complete!\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2b320019", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is about create task function

    \n", + " \n", + "1. The function create_task takes in parameters such as _redfishobj, firmware_loc, and tpm_flag.
    \n", + "
    \n", + " \n", + "2. It creates a new task for applying firmware updates using the Redfish API and HTTP POST request.
    \n", + "
    \n", + "\n", + "3. The function first obtains the session key and creates the necessary header dictionary for the HTTP request.It then checks if there are any current tasks in the task queue before creating a new task with a random ID and the given firmware file name.
    \n", + "
    \n", + "\n", + "4. The task is created using the update_task dictionary and sent as an HTTP POST request to the specified path.
    \n", + "
    \n", + "5. Finally, the function returns an appropriate response based on the HTTP status code.\n", + "
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "bcac4f85", + "metadata": {}, + "source": [ + "
    \n", + "

    4. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • The path to the firmware file to upload (-c/--component)
    • \n", + "
    • The iLO IP of the server (-i/--ilo)
    • \n", + "
    • The iLO username to login (-u/--user)
    • \n", + "
    • The iLO password to log in (-p/--password)
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09f2bc6b", + "metadata": {}, + "outputs": [], + "source": [ + "def create_task(_redfishobj, firmware_loc, tpm_flag=True):\n", + "\n", + " session_key = _redfishobj.session_key\n", + " #Create our header dictionary\n", + " header = {'Cookie': 'sessionKey=' + session_key}\n", + "\n", + " updatable_by = ['Uefi']\n", + " task_path = '/redfish/v1/UpdateService/UpdateTaskQueue/'\n", + " file_name = os.path.basename(firmware_loc)\n", + "\n", + " task_resp = _redfishobj.get(task_path)\n", + " if not task_resp.obj[\"Members@odata.count\"]:\n", + " print (\"No current tasks, proceed to create new task\")\n", + "\n", + "\n", + " update_task = {'Name': 'Update-%s-%s' % (str(randint(0, 1000000)), \\\n", + " file_name), 'Command': 'ApplyUpdate',\\\n", + " 'Filename': file_name, 'UpdatableBy': updatable_by, 'TPMOverride': tpm_flag}\n", + "\n", + " resp = _redfishobj.post(task_path, update_task, headers=header)\n", + " #print (resp)\n", + " if resp.status == 400:\n", + " sys.stderr.write(\"Failed to create update task queue...\")\n", + " elif not resp.status in [200, 201]:\n", + " sys.stderr.write(\"An http response of '%s' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Task Queue Creation complete!\\n\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + "\n", + " # Initialize parser\n", + " parser = argparse.ArgumentParser(description = \"Script to upload and flash NVMe FW\")\n", + "\n", + " parser.add_argument(\n", + " '-c',\n", + " '--component',\n", + " dest='comp_path',\n", + " action=\"store\",\n", + " required=True,\n", + " help=\"The path to the firmware file to upload\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-s',\n", + " '--session_key',\n", + " dest='session_key',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"Http session key for the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-i',\n", + " '--ilo',\n", + " dest='ilo_ip',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO IP of the server\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-u',\n", + " '--user',\n", + " dest='ilo_user',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO username to login\",\n", + " default=None)\n", + " parser.add_argument(\n", + " '-p',\n", + " '--password',\n", + " dest='ilo_pass',\n", + " action=\"store\",\n", + " required=False,\n", + " help=\"iLO password to log in.\",\n", + " default=None)\n", + "\n", + " options = parser.parse_args()\n", + "\n", + " system_url = \"https://\" + options.ilo_ip\n", + " print (system_url)\n", + "\n", + " # Upload the firmware file to the iLO Repository\n", + " update_repo_flag = True\n", + " # Update the system with the firmware file\n", + " update_target_flag = False\n", + "\n", + " comp_type = 'C'\n", + " tpm_flag = True\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = True\n", + " #system_url = \"https://\" + \"15.146.46.49\"\n", + " #session_id = \"515b196969f7d879886ee4a2da4ccba8\"\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " if options.session_key:\n", + " redfish_obj = RedfishClient(base_url=system_url, session_key= options.session_key)\n", + " else:\n", + " redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass)\n", + " # Login with the Redfish client\n", + " redfish_obj.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " upload_firmware(redfish_obj, options.comp_path, comp_type, update_repo_flag, update_target_flag)\n", + " if comp_type == 'C':\n", + " create_task(redfish_obj, options.comp_path, tpm_flag)\n", + "\n", + " redfish_obj.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb new file mode 100644 index 0000000..241130f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/generate_csr.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "042acf39", + "metadata": { + "tags": [] + }, + "source": [ + "

    Generating a certificate signing request for HPE iLO systems

    " + ] + }, + { + "cell_type": "markdown", + "id": "7b34599c", + "metadata": {}, + "source": [ + "
    \n", + "Hello there.!
    Welcome to python-iLOrest-library
    Here is an example to generate_csr!!!
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "e7338dfb", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c9837f2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "034daf66", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is our generate csr function overview, in the end we will be able to make a certificate signing request.


    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", + "\n", + "1. In the generate_csr function we are first using resource_instances variable to obtain information about the resource directory by using get_resource_directory module.\n", + "
    \n", + " \n", + "2. In the ILO rest api the information about Http certificates is stored inside the managers json object.\n", + " And now through managers_response variable, we are making a http GET operation to and trying to obtain the certificates of signing of iLO system.\n", + "
    \n", + "\n", + "3. In the system managers members response object with different odata_id we get a security service uri .\n", + " Then again an http GET request is made and response is stored in security_service_response.\n", + " Then we will make a http_cert_response by using csr_uri through security_service_response and then using http_cert_response we will get generate_csr_uri.\n", + "
    \n", + "\n", + "4. Else i.e; resource directory is enabled then we will simply iterate through all instances inside resources \n", + " and if HpeHttpsCert attribute is present in @odata.type attribute then we'll set csr_uri and get generate csr uri of the target.\n", + "
    \n", + "\n", + "5. If generate_csr_uri exists, then we will define the body and send a post request through redfish object. After generating the csr, we can obtain the csr_response using get method for csr_uri. csr_response contains CertificateSigningRequest. \n", + "\n", + "
    \n", + "6. If you get the result, then it is successful. if you don't get the result, then there is an error.\n", + " \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "644bd708", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_csr(_redfishobj, csr_file, csr_properties):\n", + "\n", + " csr_uri = None\n", + " generate_csr_uri = None\n", + "\n", + " resource_instances = _redfishobj.get_resource_directory()\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links\\\n", + " ['SecurityService']['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " csr_uri = security_service_response.obj.Links['HttpsCert']['@odata.id']\n", + " https_cert_response = _redfishobj.get(csr_uri)\n", + " generate_csr_uri = https_cert_response.obj['Actions']['#HpeHttpsCert.GenerateCSR']\\\n", + " ['target']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeHttpsCert.' in instance['@odata.type']:\n", + " csr_uri = instance['@odata.id']\n", + " generate_csr_uri = _redfishobj.get(csr_uri).obj['Actions']\\\n", + " ['#HpeHttpsCert.GenerateCSR']['target']\n", + " break\n", + "\n", + " if generate_csr_uri:\n", + " body = dict()\n", + " body[\"Action\"] = \"HpeHttpsCert.GenerateCSR\"\n", + " body[\"City\"] = csr_properties[\"City\"]\n", + " body[\"CommonName\"] = csr_properties[\"CommonName\"]\n", + " body[\"Country\"] = csr_properties[\"Country\"]\n", + " body[\"OrgName\"] = csr_properties[\"OrgName\"]\n", + " body[\"OrgUnit\"] = csr_properties[\"OrgUnit\"]\n", + " body[\"State\"] = csr_properties[\"State\"]\n", + " resp = _redfishobj.post(generate_csr_uri, body)\n", + " if resp.status in [200, 201]:\n", + " sys.stdout.write(\"Generating CSR, this may take a few minutes\\n\")\n", + " sys.stdout.write(\"Sleeping for 5 minutes...\\n\")\n", + " time.sleep(600)\n", + " csr_resp = _redfishobj.get(csr_uri).dict['CertificateSigningRequest']\n", + " with open(csr_file, 'wb') as csroutput:\n", + " csroutput.write(csr_resp)\n", + " sys.stdout.write(\"CSR Data saved to file: '%s'\\n\" % csr_file)\n", + " else:\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended\n", + " #info error message to see what went wrong\n", + " if resp.status not in [200, 201]:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO \"\\\n", + " \"Extended Message Info...\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "2da11ba0", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + " Let me give you a walk through of it!\n", + "
    \n", + " Enter your ilo url,Username,Password here.
    \n", + "\n", + "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "
    \n", + " \n", + "2. RedfishClient class takes 3 parameters iLO url, Username,Password and returns a redfish object.
    \n", + "
    \n", + "\n", + "3. Once you enter everything a redfish obejct is created with the help of RedfishClient class.
    \n", + "
    \n", + "\n", + "4. ow we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", + "
    \n", + "5. Then we call generate_csr with our redfish object.
    \n", + " \n", + "\n", + "6. REDFISHOBJ.logout() will take care of logging you out of the ilo.\n", + "\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "06934cbc", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally : use the following values
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address,account name, and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46b3e899", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Name: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter password: \")\n", + "\n", + " #CSR Dictionary, each value should be updated to reflect the desired CSR\n", + " CSR_DICT = {\"City\" : input(\"Enter city:\"), \"CommonName\": input(\"Enter name:\"), \"Country\": input(\"Enter country :\"), \\\n", + " \"OrgName\": input(\"Enter organization :\"), \"OrgUnit\": input(\"Enter unit :\"), \"State\": input(\"Enter state:\")}\n", + "\n", + " #After CSR is generated, a file will be created and the CSR will be downloaded\n", + " CSR_FILE = \"csr.txt\"\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " generate_csr(REDFISHOBJ, CSR_FILE, CSR_DICT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "12c33902", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_SmartArray_EncryptionSettings.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_SmartArray_EncryptionSettings.ipynb new file mode 100644 index 0000000..2da33ee --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_SmartArray_EncryptionSettings.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "24f88e8b", + "metadata": {}, + "source": [ + "

    Smart Array Encryption Settings On HPE ILO Systems

    " + ] + }, + { + "cell_type": "markdown", + "id": "91296f4e", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of example of gathering the smart array encryption settings on HPE iLO systems
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "98f640a8", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c954abda", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "e8336308", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about gathering the smart array encryption settings on HPE iLO systems

    \n", + " \n", + "1. The function get_SmartArray_EncryptionSettings retrieves encryption settings for Smart Storage Array Controllers from a Redfish service.
    \n", + "
    \n", + " \n", + "2.It first checks if the resource directory is disabled or empty, and if so, it navigates through the Redfish service object to obtain the necessary URIs for Smart Storage Array Controllers
    \n", + "
    \n", + "\n", + "3. If the resource directory is enabled and not empty, the function uses the resource directory to find the relevant URI for Smart Storage Array Controllers.
    \n", + "
    \n", + "\n", + "4. It retrieves detailed information about each Smart Storage Array Controller and stores it in the smartarraycontrollers dictionary using the controller's @odata.id as the key.
    \n", + "
    \n", + "5. The function prints the encryption properties for each Smart Storage Array Controller, specifically the properties listed in the desired_properties list.\n", + "
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e85045dc", + "metadata": {}, + "outputs": [], + "source": [ + "def get_SmartArray_EncryptionSettings(_redfishobj, desired_properties):\n", + "\n", + " smartstorage_response = []\n", + " smartarraycontrollers = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " systems_uri = _redfishobj.root.obj['Systems']['@odata.id']\n", + " systems_response = _redfishobj.get(systems_uri)\n", + " systems_members_uri = next(iter(systems_response.obj['Members']))['@odata.id']\n", + " systems_members_response = _redfishobj.get(systems_members_uri)\n", + " smart_storage_uri = systems_members_response.obj.Oem.Hpe.Links\\\n", + " ['SmartStorage']['@odata.id']\n", + " smart_storage_arraycontrollers_uri = _redfishobj.get(smart_storage_uri).obj.Links\\\n", + " ['ArrayControllers']['@odata.id']\n", + " smartstorage_response = _redfishobj.get(smart_storage_arraycontrollers_uri).obj['Members']\n", + " else:\n", + " for instance in resource_instances:\n", + " #Use Resource directory to find the relevant URI\n", + " if '#HpeSmartStorageArrayControllerCollection.' in instance['@odata.type']:\n", + " smartstorage_uri = instance['@odata.id']\n", + " smartstorage_response = _redfishobj.get(smartstorage_uri).obj['Members']\n", + " break\n", + "\n", + " for controller in smartstorage_response:\n", + " smartarraycontrollers[controller['@odata.id']] = _redfishobj.get(controller['@odata.id']).\\\n", + " obj\n", + " sys.stdout.write(\"Encryption Properties for Smart Storage Array Controller \\'%s\\' : \\n\" \\\n", + " % smartarraycontrollers[controller['@odata.id']].get('Id'))\n", + " for data in smartarraycontrollers[controller['@odata.id']]:\n", + " if data in desired_properties:\n", + " sys.stdout.write(\"\\t %s : %s\\n\" % (data, smartarraycontrollers[controller\\\n", + " ['@odata.id']].get(data)))" + ] + }, + { + "cell_type": "markdown", + "id": "c776e47a", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "2e71e12a", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05fc8da8", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + " #list of desired properties related to Smart Array controller encryption\n", + " DESIRED_PROPERTIES = [\"Name\", \"Model\", \"SerialNumber\", \"EncryptionBootPasswordSet\",\\\n", + " \"EncryptionCryptoOfficerPasswordSet\",\\\n", + " \"EncryptionLocalKeyCacheEnabled\", \"EncryptionMixedVolumesEnabled\",\\\n", + " \"EncryptionPhysicalDriveCount\", \"EncryptionRecoveryParamsSet\",\\\n", + " \"EncryptionStandaloneModeEnabled\", \"EncryptionUserPasswordSet\"]\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_SmartArray_EncryptionSettings(REDFISHOBJ, DESIRED_PROPERTIES)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "123c6927", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_schema.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_schema.ipynb new file mode 100644 index 0000000..d4b1149 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/get_schema.ipynb @@ -0,0 +1,220 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "15565395", + "metadata": {}, + "source": [ + "

    System Schema Data

    " + ] + }, + { + "cell_type": "markdown", + "id": "bd7d6791", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of obtaining system schema data
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "4ca0edc7", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1805d6fa", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "404a5487", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about obtaining system schema data

    \n", + " \n", + "1. The function takes a parameter, _redfishobj, which represents the Redfish service object used to interact with the API.
    \n", + "
    \n", + " \n", + "2.It initializes two variables: schema_members_uris and schema_members_expanded. schema_members_uris is an empty list that will store the URIs of schema members, while schema_members_expanded is an empty dictionary that will hold the expanded schema information.
    \n", + "
    \n", + "\n", + "3. It retrieves the URI for the root JSON schema from the Redfish service object (_redfishobj) and makes a GET request to obtain the schema response. The response contains a list of member URIs that point to individual schemas.
    \n", + "
    \n", + "\n", + "4. The function iterates through each member URI, retrieves the schema data, and expands the URI link for sub-schemas with the actual schema information. The expanded schema data is stored in the schema_members_expanded dictionary using the member URI as the key.
    \n", + "
    \n", + "5. The function iterates through each member URI, retrieves the schema data, and expands the URI link for sub-schemas with the actual schema information. The expanded schema data is stored in the schema_members_expanded dictionary using the member URI as the key.\n", + "
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "780095b1", + "metadata": {}, + "outputs": [], + "source": [ + "def get_schema(_redfishobj):\n", + " schema_members_uris = []\n", + " schema_members_expanded = {}\n", + "\n", + " schema_uri = _redfishobj.root.obj['JsonSchemas']['@odata.id']\n", + " schema_response = _redfishobj.get(schema_uri)\n", + " schema_members_uris = schema_response.obj['Members']\n", + " for member in schema_members_uris:\n", + " data = _redfishobj.get(member['@odata.id']).dict\n", + " instance_id = data['Location'].index(next(iter(data['Location'])))\n", + " schema_uri = data['Location'][instance_id]['Uri']\n", + " schema = _redfishobj.get(schema_uri).dict\n", + " #I am just replacing the URI link for the sub-schema with the actual schema. You will\n", + " #see EVERYTHING\n", + " _tmp = {schema_uri + ' ->': schema}\n", + " data['Location'][instance_id]['Uri'] = _tmp\n", + " schema_members_expanded[member['@odata.id']] = data\n", + "\n", + " print(json.dumps(schema_members_expanded, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "071606d1", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "275fe668", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1f63d79", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " get_schema(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "8d740355", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb new file mode 100644 index 0000000..6722a6a --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/sessions.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

    Manually Managing Sessions With Redfish

    " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of manually managing sessions with Redfish
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from six.moves import urllib\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about sessions function

    \n", + " \n", + "1. This function creates a new session with an iLO server using provided login credentials..
    \n", + "
    \n", + " \n", + "2. The function sends a POST request to the /redfish/v1/Sessions endpoint to create the session..
    \n", + "
    \n", + "\n", + "3. If the session is created successfully (response code 201), the function prints the session URI and X-Auth Token key..
    \n", + "
    \n", + "\n", + "4. The function also sends a DELETE request to the session URI to terminate the session.
    \n", + "
    \n", + "5. If the session creation fails, the function prints an error message and tries to access the iLO Extended Message Info for more details..
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def sessions(_redfishobj, login_account, login_password):\n", + "\n", + " new_session = {\"UserName\": login_account, \"Password\": login_password}\n", + " response = _redfishobj.post('/redfish/v1/Sessions', new_session)\n", + "\n", + " if response.status == 201:\n", + " print(\"Success!\\n\")\n", + " session_uri = response.getheader(\"location\")\n", + " session_uri = urllib.parse.urlparse(session_uri)\n", + " sys.stdout.write(\"\\tSession \" + session_uri.path + \" created.\\n\")\n", + " x_auth_token = response.getheader(\"x-auth-token\")\n", + " sys.stdout.write(\"\\tThis is the session X-Auth Token key \" + x_auth_token + \".\\n\")\n", + " print(json.dumps(response.dict, indent=4, sort_keys=True))\n", + "\n", + " # Delete the created session\n", + " sys.stdout.write(\"\\tTerminating this session.\\n\")\n", + " sessresp = _redfishobj.delete(session_uri.path)\n", + " print(json.dumps(sessresp.dict, indent=4, sort_keys=True))\n", + " else:\n", + " sys.stderr.write(\"ERROR: failed to create a session.\\n\")\n", + " try:\n", + " print(json.dumps(sessresp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended\"\n", + " \" Message Info...\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
  425. Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
  426. \n", + "
  427. If server is down or Unreachable we get server not reachable message!
  428. \n", + "
  429. If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
  430. \n", + "
  431. After getting required information Redfish.logout() closses the particular session and logs us out of the system.
  432. \n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
    \n", + "
    Instructions
    \n", + "
      \n", + "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", + "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", + "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", + "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " sessions(REDFISHOBJ, LOGIN_ACCOUNT, LOGIN_PASSWORD)#calling sessions function" + ] + }, + { + "cell_type": "markdown", + "id": "316c3f0e", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb new file mode 100644 index 0000000..05a95a6 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_PrimaryKeyServer.ipynb @@ -0,0 +1,297 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

    Set_ESKM_PrimaryKeyServer

    " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of set_ESKM_PrimaryKeyServer
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "#This is to take passwords as input securely\n", + "import getpass\n" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about set_ESKM_PrimaryKeyServer function

    \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "1. This function sets the primary key server for the HPE ESKM service.
    \n", + "
    \n", + " \n", + "2. It takes three arguments: _redfishobj (an object representing the Redfish service), primary_key_server_address (a string representing the IP address or hostname of the primary key server), and primary_key_server_port (an integer representing the port number of the primary key server).
    \n", + "
    \n", + "\n", + "3. It uses the get_resource_directory function to find the relevant ESKM URI, which is used to make a POST request to set the primary key server.
    \n", + "
    \n", + "\n", + "4. If the POST request is successful (returns an HTTP status code of 200), the function prints a success message and the JSON response from the server.
    \n", + "
    \n", + "5. If the POST request is unsuccessful, the function prints an error message and, if available, the extended error information from the server response.\n", + "
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def set_ESKM_PrimaryKeyServer(_redfishobj, primary_key_server_address, primary_key_server_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + "\n", + " body[\"PrimaryKeyServerAddress\"] = primary_key_server_address\n", + " body[\"PrimaryKeyServerPort\"] = int(primary_key_server_port)\n", + "\n", + " resp = _redfishobj.post(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
    \n", + "
    Instructions
    \n", + "
      \n", + "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", + "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", + "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", + "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " # When running on the server locally use the following commented values\n", + " #SYSTEM_URL = None\n", + " #LOGIN_ACCOUNT = None\n", + " #LOGIN_PASSWORD = None\n", + "\n", + " # When running remotely connect using the secured (https://) address,\n", + " # account name, and password to send https requests\n", + " # SYSTEM_URL acceptable examples:\n", + " # \"https://10.0.0.100\"\n", + " # \"https://ilo.hostname\"\n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " PRIMARY_KEY_SERVER_ADDRESS = \"192.168.1.1\"\n", + " PRIMARY_KEY_SERVER_PORT = \"9000\"\n", + "\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_ESKM_PrimaryKeyServer(REDFISHOBJ, PRIMARY_KEY_SERVER_ADDRESS, PRIMARY_KEY_SERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb new file mode 100644 index 0000000..aa3296f --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_ESKM_username_password.ipynb @@ -0,0 +1,290 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

    Setting the ESKM username and password for HPE iLO systems

    " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of setting the ESKM username and password for HPE iLO systems
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about ESKM_username_pass function

    \n", + " \n", + "1. The function sets up an Electronic Software Key Manager (ESKM) on an iLO (Integrated Lights Out) server using the Redfish API.
    \n", + "
    \n", + " \n", + "2. It takes several input parameters including ESKM username, password, account group, primary key server address, and primary key server port.
    \n", + "
    \n", + "\n", + "3. It first attempts to locate the URI for the ESKM resource either by using the Redfish Resource Directory or by manually navigating through the Redfish API.br>\n", + "
    \n", + "\n", + "4. If the ESKM URI is found, the function constructs a JSON payload containing the ESKM configuration information and primary key server details and sends it as a PATCH request to the ESKM resource.
    \n", + "
    \n", + "5. If the PATCH request is successful (i.e., returns an HTTP status code of 200), the function prints out a success message along with the response payload, otherwise it prints out an error message.\n", + "
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def ESKM_username_pass(_redfishobj, eskm_username, eskm_password, eskm_accountgroup, \\\n", + " eskm_primarykeyserver_addr, eskm_primarykeyserver_port):\n", + "\n", + " eskm_uri = None\n", + " body = dict()\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " security_service_uri = managers_members_response.obj.Oem.Hpe.Links['SecurityService']\\\n", + " ['@odata.id']\n", + " security_service_response = _redfishobj.get(security_service_uri)\n", + " eskm_uri = security_service_response.obj.Links['ESKM']['@odata.id']\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#HpeESKM.' in instance['@odata.type']:\n", + " eskm_uri = instance['@odata.id']\n", + " break\n", + "\n", + " if eskm_uri:\n", + " body[\"KeyManagerConfig\"] = dict()\n", + " body[\"KeyManagerConfig\"][\"LoginName\"] = eskm_username\n", + " body[\"KeyManagerConfig\"][\"Password\"] = eskm_password\n", + " body[\"KeyManagerConfig\"][\"AccountGroup\"] = eskm_accountgroup\n", + " body[\"KeyManagerConfig\"][\"ESKMLocalCACertificateName\"] = \"\"\n", + " body[\"PrimaryKeyServerAddress\"] = eskm_primarykeyserver_addr\n", + " body[\"PrimaryKeyServerPort\"] = eskm_primarykeyserver_port\n", + " resp = _redfishobj.patch(eskm_uri, body)\n", + " #If iLO responds with soemthing outside of 200 or 201 then lets check the iLO extended info\n", + " #error message to see what went wrong\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success!\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
    \n", + "
    Instructions
    \n", + "
      \n", + "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", + "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", + "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", + "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + "\n", + " ESKM_USERNAME = \"admin\"\n", + " ESKM_PASSWORD = \"password\"\n", + " ESKM_ACCOUNTGROUP = \"group\"\n", + " ESKM_PRIMARYKEYSERVER_ADDR = \"192.168.1.10\"\n", + " ESKM_PRIMARYKEYSERVER_PORT = 5927\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\\n", + " password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \\\n", + " ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "a73f3528", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb new file mode 100644 index 0000000..99263c6 --- /dev/null +++ b/examples/Jupyter_notebooks/HPECTY/B VENKAT RAHUL/set_active_ilo_nic.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f815c9a7", + "metadata": {}, + "source": [ + "

    Setting the active Manager NIC

    " + ] + }, + { + "cell_type": "markdown", + "id": "2a3a9755", + "metadata": {}, + "source": [ + "
    \n", + "Hello User.!
    Welcome to python-iLOrest-library
    This is an example of setting the active Manager NIC
    As you are here let's get it done easily.
    \n", + " To perform this u need to have python-ilorest-library installed in your machine.
    \n", + " And please keep your username and password handy!\n", + "
    \n", + " Also do execute each successive cell once to avoid any errors!\n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "cc555954", + "metadata": {}, + "source": [ + "
    \n", + "

    1. Below we are importing all the necessary python libraries

    \n", + "
      \n", + "
    • sys
    • \n", + "
    • json
    • \n", + "
    • redfish
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cff3ead6", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import json\n", + "from redfish import RedfishClient\n", + "from redfish.rest.v1 import ServerDownOrUnreachableError\n", + "\n", + "from get_resource_directory import get_resource_directory\n", + "#This is to take passwords as input securely\n", + "import getpass" + ] + }, + { + "cell_type": "markdown", + "id": "b41f56eb", + "metadata": {}, + "source": [ + "
    \n", + "

    2. This is about set_active_ilo_nic function

    \n", + " \n", + "\n", + "1. This function is used to enable/disable Ethernet interfaces on an iLO (Integrated Lights Out) management interface.
    \n", + "
    \n", + " \n", + "2. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
    \n", + "
    \n", + "\n", + "3. The function first gets a list of available Ethernet interfaces using the Redfish API, which is a standard RESTful interface for managing servers.
    \n", + "
    \n", + "\n", + "4. If the PATCH request is successful (HTTP status 200), the function prints a success message and the response body, which contains information about the updated Ethernet interface.
    \n", + "
    \n", + "5. Finally, the function reminds the user that they need to reset iLO for the change to take effect.
    \n", + " \n", + "\n", + "\n", + "\n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b99181a4", + "metadata": {}, + "outputs": [], + "source": [ + "def set_active_ilo_nic(_redfishobj):\n", + "\n", + " ethernet_data = {}\n", + "\n", + " resource_instances = get_resource_directory(_redfishobj)\n", + " if DISABLE_RESOURCE_DIR or not resource_instances:\n", + " #if we do not have a resource directory or want to force it's non use to find the\n", + " #relevant URI\n", + " managers_uri = _redfishobj.root.obj['Managers']['@odata.id']\n", + " managers_response = _redfishobj.get(managers_uri)\n", + " managers_members_uri = next(iter(managers_response.obj['Members']))['@odata.id']\n", + " managers_members_response = _redfishobj.get(managers_members_uri)\n", + " manager_ethernet_interfaces = managers_members_response.obj['EthernetInterfaces']\\\n", + " ['@odata.id']\n", + " manager_ethernet_interfaces_response = _redfishobj.get(manager_ethernet_interfaces)\n", + " manager_ethernet_interfaces_members = manager_ethernet_interfaces_response.\\\n", + " obj['Members']\n", + " for _member in manager_ethernet_interfaces_members:\n", + " _tmp = _redfishobj.get(_member['@odata.id']).obj\n", + " ethernet_data[_member['@odata.id']] = _tmp\n", + " else:\n", + " #Use Resource directory to find the relevant URI\n", + " for instance in resource_instances:\n", + " if '#EthernetInterfaceCollection.' in instance['@odata.type'] and 'Managers' in \\\n", + " instance['@odata.id']:\n", + " ethernet_uri = instance['@odata.id']\n", + " ethernet_interfaces = _redfishobj.get(ethernet_uri).obj['Members']\n", + " for _ethernet_interface in ethernet_interfaces:\n", + " ethernet_data[_ethernet_interface['@odata.id']] = _redfishobj.\\\n", + " get(_ethernet_interface['@odata.id']).dict\n", + " break\n", + "\n", + " if ethernet_data:\n", + " print(\"\\n\\nShowing all available ethernet management interfaces before changes:\\n\\n\")\n", + " for interface in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Management Inteface \\'%s\\'\\n\" % ethernet_data\\\n", + " [interface].get('Id'))\n", + " sys.stdout.write(\"\\t\\'Interface Enabled\\': %s\\n\" % ethernet_data[interface].\\\n", + " get('InterfaceEnabled'))\n", + "\n", + " for ethernet in ethernet_data:\n", + " sys.stdout.write(\"Ethernet Interface: %s\\n\" % ethernet)\n", + " ans = input(\"Would you like to enable/disable this interface? (enable/disable)\\n\")\n", + " if \"en\" in ans:\n", + " body = {\"InterfaceEnabled\": True}\n", + " else:\n", + " body = {\"InterfaceEnabled\": False}\n", + " resp = _redfishobj.patch(ethernet, body)\n", + " if resp.status == 400:\n", + " try:\n", + " print(json.dumps(resp.obj['error']['@Message.ExtendedInfo'], indent=4, \\\n", + " sort_keys=True))\n", + " except Exception as excp:\n", + " sys.stderr.write(\"A response error occurred, unable to access iLO Extended \"\\\n", + " \"Message Info...\")\n", + " elif resp.status != 200:\n", + " sys.stderr.write(\"An http response of \\'%s\\' was returned.\\n\" % resp.status)\n", + " else:\n", + " print(\"Success! You will need to reset iLO for this change to take effect.\\n\")\n", + " print(json.dumps(resp.dict, indent=4, sort_keys=True))\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "id": "031a5cbe", + "metadata": {}, + "source": [ + "
    \n", + "

    3. This is Main function overview.

    \n", + "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE TO PROCEED FURTHER
    \n", + "
      \n", + "
    • Once your credentials that are enter everything a redfish obejct is created with the help of RedfishClient class and a session is created and now you will be logged in to the server.
    • \n", + "
    • If server is down or Unreachable we get server not reachable message!
    • \n", + "
    • If not then we make a call to mount_virtual_media_iso to obtain virtual media related info of system.
    • \n", + "
    • After getting required information Redfish.logout() closses the particular session and logs us out of the system.
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "c8cd2ffd", + "metadata": {}, + "source": [ + "
    \n", + " When running on the server locally,use the following values:
    \n", + " SYSTEM_URL = None
    \n", + " LOGIN_ACCOUNT = None
    \n", + " LOGIN_PASSWORD = None
    \n", + " When running remotely connect using the secured (https://) address, account name and password to send https requests
    \n", + " SYSTEM_URL acceptable examples:
    \n", + " \"https://10.0.0.100\"
    \n", + " \"https://ilo.hostname\"\n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "77edbde3", + "metadata": {}, + "source": [ + "
    \n", + "
    Instructions
    \n", + "
      \n", + "
    • When prompted for ACCOUNT_LOGIN_NAME, enter redfish standard username here as iLO GUI actually considers this to be 'UserName'
    • \n", + "
    • When prompted for ACCOUNT_USER_NAME, enter redfish login here iLO GUI actually considers this to be 'LoginName'
    • \n", + "
    • Role_ID: It is a predefined role for the user which can take \"Administrator\" or \"ReadOnly\" or \"Operator\" as input. For more informaion on roles and privilages refere the table in the next cell.
    • \n", + "
    • For more clarification on the above points please visit iLO Users Documentation
    • \n", + "
    \n", + "
    " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0b490052", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ServerDownOrUnreachableError' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 22\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 21\u001b[0m \u001b[38;5;66;03m# Create a Redfish client object\u001b[39;00m\n\u001b[0;32m---> 22\u001b[0m REDFISHOBJ \u001b[38;5;241m=\u001b[39m \u001b[43mRedfishClient\u001b[49m(base_url\u001b[38;5;241m=\u001b[39mSYSTEM_URL, username\u001b[38;5;241m=\u001b[39mLOGIN_ACCOUNT, \\\n\u001b[1;32m 23\u001b[0m password\u001b[38;5;241m=\u001b[39mLOGIN_PASSWORD)\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n", + "\u001b[0;31mNameError\u001b[0m: name 'RedfishClient' is not defined", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 26\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# Login with the Redfish client\u001b[39;00m\n\u001b[1;32m 25\u001b[0m REDFISHOBJ\u001b[38;5;241m.\u001b[39mlogin()\n\u001b[0;32m---> 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[43mServerDownOrUnreachableError\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m excp:\n\u001b[1;32m 27\u001b[0m sys\u001b[38;5;241m.\u001b[39mstderr\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mERROR: server not reachable or does not support RedFish.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 28\u001b[0m sys\u001b[38;5;241m.\u001b[39mexit()\n", + "\u001b[0;31mNameError\u001b[0m: name 'ServerDownOrUnreachableError' is not defined" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " \n", + " SYSTEM_URL = input(\"Enter System URL: \")\n", + " LOGIN_ACCOUNT = input(\"Enter Login account: \")\n", + " LOGIN_PASSWORD = getpass.getpass(\"Enter your password: \")\n", + " # flag to force disable resource directory. Resource directory and associated operations are\n", + " # intended for HPE servers.\n", + " DISABLE_RESOURCE_DIR = False\n", + "\n", + " try:\n", + " # Create a Redfish client object\n", + " REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \\password=LOGIN_PASSWORD)\n", + " # Login with the Redfish client\n", + " REDFISHOBJ.login()\n", + " except ServerDownOrUnreachableError as excp:\n", + " sys.stderr.write(\"ERROR: server not reachable or does not support RedFish.\\n\")\n", + " sys.exit()\n", + "\n", + " set_active_ilo_nic(REDFISHOBJ)\n", + " REDFISHOBJ.logout()" + ] + }, + { + "cell_type": "markdown", + "id": "316c3f0e", + "metadata": {}, + "source": [ + "
    \n", + " In case you need help 🔗 links to relevant resources :\n", + "
    \n", + " 1.Python-ilorest-library: LINK
    \n", + " 2.HPE ilorest-api explorer: LINK
    \n", + " 3.REST API: LINK
    \n", + " 4.Changing Boot Setting Documentation: LINK
    \n", + " \n", + "
    " + ] + }, + { + "cell_type": "markdown", + "id": "acc45fbf", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 323f4091474af53ef963cdab9d25126e46c32faf Mon Sep 17 00:00:00 2001 From: DharitriNandi <91819742+DharitriNandi@users.noreply.github.com> Date: Tue, 30 May 2023 20:42:55 +0530 Subject: [PATCH 047/159] Add files via upload --- .../ahs_syslog_iml/clear_ahs_data.ipynb | 47 ++++++++++++------- .../clear_ilo_iel_iml_log.ipynb | 20 ++++---- .../ahs_syslog_iml/set_syslogserver.ipynb | 24 +++++----- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb index 8d3ee2f..df85393 100644 --- a/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb +++ b/example_jupyter_notebooks/ahs_syslog_iml/clear_ahs_data.ipynb @@ -7,7 +7,7 @@ "tags": [] }, "source": [ - "# Clearing AHS data for HPE iLO systems" + "

    Clearing AHS data for HPE iLO systems

    " ] }, { @@ -15,7 +15,7 @@ "id": "88f096f8", "metadata": {}, "source": [ - "
    \n", + "
    \n", "Welcome to python-iLOrest-library
    Here is an example to Clearing AHS(Active Health System) data!!!
    \n", " This Jupyter Notebook will contains a example code to demonstrate how to clear AHS data. This code is written in Python and uses the redfish library to perform the required operations

    As you are here let's get it done easily.
    \n", " To perform this u need to have python-ilorest-library installed in your machine.
    \n", @@ -33,22 +33,33 @@ "tags": [] }, "source": [ - "
    \n", - "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", "
  433. sys \n", "
  434. \n", "
  435. json
  436. \n", "
  437. redfish
  438. \n", - " \n", "
    " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "8ce9142d", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'redfish'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_21748/2847628525.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msys\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mRedfishClient\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mredfish\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mv1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mServerDownOrUnreachableError\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mget_resource_directory\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mget_resource_directory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'redfish'" + ] + } + ], "source": [ "import sys\n", "import json\n", @@ -63,8 +74,8 @@ "id": "b9615aea", "metadata": {}, "source": [ - "
    \n", - "

    2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


    \n", + "
    \n", + "

    2. This is our clear_ahs_data to function overview, in the end this will clear ahs data.


    \n", " \n", " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", "\n", @@ -83,7 +94,7 @@ " and if bios attribute is present in @odata.type attribute then we'll set active_health_system_uri and get active_health_system_response settings of the user through redfish object and then then set the path to post the action of clearing ahs data that we will perform.\n", "
    \n", "\n", - "5. We will post the active_health_system_clear_log_uri and the body to the redfish Client through Redfish Object\n", + "5. We will post the active_health_system_clear_log_uri and the body to the Redfish Client through Redfish Object\n", "\n", " Ultimately if the operation was successful without any errors then get the Success. If not we get the occured error.\n", "\n", @@ -92,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "16042277", "metadata": {}, "outputs": [], @@ -147,17 +158,17 @@ "id": "6e7543eb", "metadata": {}, "source": [ - "
    \n", - "

    3. This is Main function overview.

    \n", + "
    \n", + "

    3. This is Main function overview.

    \n", " There is a hierarchy involved in iLO Rest Api. So we are simply following the hierarchy present to change the settings.
    \n", "\n", - "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", + "1. The rest opertions are handled by Redfish object which is created by Redfish Client
    \n", "
    \n", " \n", - "2. RedfishClient class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", + "2. Redfish Client class takes 3 parameters iLO url, Username, Password and returns a redfish object.
    \n", "
    \n", "\n", - "3. Once you enter everything a redfish object is created with the help of RedfishClient class.
    \n", + "3. Once you enter everything a redfish object is created with the help of Redfish Client class.
    \n", "
    \n", "\n", "4. Now we try to Login with the help of REDFISHOBJ, if it is successful a session is created and you are logged in, But if Server is not avaialbe we get an error saying \"server unreachable\"
    \n", @@ -203,7 +214,7 @@ "id": "1557bfee", "metadata": {}, "source": [ - "
    \n", + "
    \n", " When running on the server locally : use the following values
    \n", " SYSTEM_URL = None
    \n", " LOGIN_ACCOUNT = None
    \n", @@ -220,7 +231,7 @@ "id": "e685a623", "metadata": {}, "source": [ - "
    In case you need help 🔗 links to relevant resources :\n", + "
    In case you need help 🔗 links to relevant resources :\n", "
    \n", " 1.Python-ilorest-library:LINK
    \n", " 2.Hpe ilorest-api explorer:LINK
    \n", diff --git a/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb index 19de2bd..4ce85cb 100644 --- a/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb +++ b/example_jupyter_notebooks/ahs_syslog_iml/clear_ilo_iel_iml_log.ipynb @@ -7,7 +7,7 @@ "tags": [] }, "source": [ - "# CLEAR iLO LOGS" + "

    Clear iLO Logs

    " ] }, { @@ -15,7 +15,7 @@ "id": "898cbb84", "metadata": {}, "source": [ - "
    \n", + "
    \n", "Welcome to python-iLOrest-library
    Here is an example to for clearing out the iLO event log and management log at server side!
    As you are here let's get it done easily.
    \n", " To perform this you need to have python-ilorest-library installed in your machine.
    \n", " And please keep your username and password handy!\n", @@ -28,8 +28,8 @@ "id": "98f3c2dd", "metadata": {}, "source": [ - "
    \n", - "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", "
  439. sys \n", "
  440. \n", "
  441. json
  442. \n", @@ -59,8 +59,8 @@ "id": "ef3013ef", "metadata": {}, "source": [ - "
    \n", - "

    2. This cell gives overview about of the function used to clear event logs such as IML and IEL logs.


    \n", + "
    \n", + "

    2. This cell gives overview about of the function used to clear event logs such as IML and IEL logs.


    \n", "The IML provides a record of historical events that have occurred on the server and the IEL is the iLO event log provides record of significant events detected by iLO.\n", " \n", "1. When the resource directory is disabled then we simply navigate through the API for obtaining the relevant uri.\n", @@ -141,8 +141,8 @@ "id": "331b8289", "metadata": {}, "source": [ - "
    \n", - "

    3. The Main function


    \n", + "
    \n", + "

    3. The Main function


    \n", "The Main function: PLEASE ENTER YOU LOGIN CREDENTIALS HERE.
    \n", " \n", "1. The rest opertions are handled by redfish object which is created by RedfishClient
    \n", @@ -195,7 +195,7 @@ "id": "f120e784", "metadata": {}, "source": [ - "
    \n", + "
    \n", " When running on the server locally : use the following values
    \n", " SYSTEM_URL = None
    \n", " LOGIN_ACCOUNT = None
    \n", @@ -212,7 +212,7 @@ "id": "f702c0ae", "metadata": {}, "source": [ - "
    In case you need help 🔗 links to relevant resources :\n", + "
    In case you need help 🔗 links to relevant resources :\n", "
    \n", " 1.Python-ilorest-library:LINK
    \n", " 2.Hpe ilorest-api explorer:LINK
    \n", diff --git a/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb b/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb index 14a772b..4629d62 100644 --- a/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb +++ b/example_jupyter_notebooks/ahs_syslog_iml/set_syslogserver.ipynb @@ -5,7 +5,7 @@ "id": "b92b79fb", "metadata": {}, "source": [ - "# Setting remote syslog server" + "

    Setting remote syslog server

    " ] }, { @@ -13,7 +13,7 @@ "id": "2ed959e3", "metadata": {}, "source": [ - "
    \n", + "
    \n", "Welcome to python-iLOrest-library
    Here is an example to Setting remote syslog server
    \n", " This Jupyter Notebook will contains a example code to demonstrate how to set remote syslog server. This code is written in Python and uses the redfish library to perform the required operations
    As you are here let's get it done easily.
    \n", " To perform this you need to have python-ilorest-library installed in your machine.
    \n", @@ -29,8 +29,8 @@ "id": "3a91bf91", "metadata": {}, "source": [ - "
    \n", - "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", + "
    \n", + "

    1. Below we are importing all the necessary modules from the ilorest library.


    \n", "
  443. sys \n", "
  444. \n", "
  445. json
  446. \n", @@ -62,8 +62,8 @@ "id": "6393e74d", "metadata": {}, "source": [ - "
    \n", - "

    2. This is our set_syslog function overview


    \n", + "
    \n", + "

    2. This is our set_syslog function overview


    \n", " This function sets the remote syslog server and enables remote syslog on an iLO system.

    \n", "1. It takes two parameters:\n", "