From f3fcae5fb18e473c1825971d47d743ac64cf122c Mon Sep 17 00:00:00 2001 From: "th.l" <thl-cmk@outlook.com> Date: Mon, 23 Dec 2024 13:08:33 +0100 Subject: [PATCH] added local address/as/identifier for bgp_topology --- README.md | 2 +- mkp/bgp_peer-2.2.7-20241220.mkp | Bin 0 -> 16676 bytes source/agent_based/bgp_peer.py | 99 +++++++++++++++++++-------- source/agent_based/utils/bgp_peer.py | 71 +++++++++++-------- source/packages/bgp_peer | 2 +- 5 files changed, 116 insertions(+), 58 deletions(-) create mode 100644 mkp/bgp_peer-2.2.7-20241220.mkp diff --git a/README.md b/README.md index 484e5d1..9c1a93f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/bgp_peer-2.2.5-20240615.mkp "bgp_peer-2.2.5-20240615.mkp" +[PACKAGE]: ../../raw/master/mkp/bgp_peer-2.2.7-20241220.mkp "bgp_peer-2.2.7-20241220.mkp" # BGP Peer Check plugin to monitor the status of BGP peers and inventory plugin for static BGP peer data. diff --git a/mkp/bgp_peer-2.2.7-20241220.mkp b/mkp/bgp_peer-2.2.7-20241220.mkp new file mode 100644 index 0000000000000000000000000000000000000000..59ad0bae187747e0679c5abc9c59425e5d6ea64c GIT binary patch literal 16676 zcmZttV{k4^6R?ZMUa@W4wrv|Lwr$&4v28ndY}>Z&WIykB&Yz8cQ`J*bGt;P^?rR95 zp@2G+EzLoGuYIkZ4>^+z{rSFOY}9lmGZQV6yw;-@hdM9kudiz*+I1JbPu(ajA{*Dl z60wsSCsj^kKXG1PZ_;)Df)MsYQg+~PH}MR~cG(aoN&-brfh9<K^izM`;836}cyJc` z6QTX$WrBY4SaV{ny^J+dp!*QSj~3l#yl>woxH%q(DjvK4W}mBUu9ICdS}ACK8ry!^ z)XO)%d`3@)%TRQ{xJMF%5zwa_IkiA>Y`fJBZ^&@yi|(-B4*<#N@icUq8UcEL_vySZ zJCVH8IU^@?Yqp0W-F#>1SN2CD*BJ_KArm$u_0n5(suMOYN!Ldfi%4D%jjzEtY8wQ> zvJfCteVX|?d)Hsu0(w5J6_wf_4m-RtJf#jGY|zB7)~oU|Y<)zdp6GaS--kD%*H?D8 zJ%Bfd?cgN!Ai7a$b1Wi#nM~_udd;QA*p2qc1c6=<S_#=T$@n!2bwY%$hNY$k&}43e zTU`rDYe@?gT7*}pkeG__Q8cagdiLCM(*gyyfX2G&Xf)m(FU9BTa40m}ZO%#I^R?f) zN_3!O1oV5oMtvycF$wmHNS*Qv#v~eAr)Hu0Ht7?Kh~4+S+HRC#Ww+WuXSU8F+o4cK z&2c#5a&R!&A|EN;K=}?{MFB)}sRXmgCyo&P<HB3*9p*$n5tvUu$UkvyHv>AJ(J3-- zh9fG|oVnrvqM2qpVrY7fm3?;TSjJAS&U@tD4t`{m%P}I{M*ui^H2=_p{Wx}JW}fFg z@mFIMMnur>md0j0&*{u_Z*?czKH~3H)!nXJAY}Hp8QafD;?rU+8o>okcs!}WU>5)( z=hz41ozn2R#cAi<yMJMOppG#<-V{8<^7!2jj#6-JSMVfTl<muRJ<V|B1)u1-q6Q}V zd#-Ef@sI@Vhgu_l+ItMzNfkBF&JF+Aev9-0-P0%ax$QQa^r%Mw((+tTD4{7&uXgPO z#MAwTEpZh5uaC=RhdWv*z5^5pKuTK~FCDBsv{yP+%D}$BszAkdke%FjvpGD?Hp{BE z;XcUo=*RX{j5P&_n{mpT2C~T&oxpI2ih#4U@4fz-!sv_z<?dwu+W2(C{j>`RBCZGr zxifslUG9TI5`XP?#NH9}%kia;kDUVi)1Mh19{cmxz2P@6fzgZEm)LARc?Shm`%Y|v z_N{R3E90Jv{CEH5yRP3{>!uIFz%==m17KZq9V~lk0NOL(y(+wtHAuGU-dCVwviyVX z^RFiptIS{)S#ElUp_z##_#wJRVp#Pn(`~;FSeBz8$Efm{E|8XH`5s6`{T?RUiUE<I z83Pq)8H6yP0B8>f^v?3P7f2dv*eaAc&#V~)n^`MQR)9~5c7<Ybk|N3sToGIcwl@WC zmO`V4Vqr}cY0tf$;a(-w6FTE1Gf6vxSWOWnBT7@HrsVDDVt*eY`B$0)ryR=P{o8*1 z$y@$c=frgF>i3&oYJbq)`uG06m3$ET*PRu~$54S#CFa-AB7TJNr`7hm_HcI1eU)d{ zV8wMQ_v^R#{JanM`rzzr12%4JFU|H==mau&MP=nzh2Sc`1Y=8fonGrX{$2)_+3yA2 z4zWw+W$^O#3KHXrhmmFHrq-7cLKMHN1?eFLb*y>B0yO{iR3Mm2xkv=~ge#K=2-Irs zB5O1s9?91#w6Gv4lV~8MicvVZ%fIKaujq#@&93bkb<R|>%n&;DTE1!LMwLlZ<%Bj} zaEUwykO8KGAlIGyHMaam1g$Ks(X7Hio?)jxA?B(b(#`sa8)p}m@N`CIh1Pzu98<nj zkp$Dh;*y*Z4o?8iE@0-G{=Be7hgGzoI@4pl<q~w*rUe#V6c~NVT1~42{FgvD)eh_> zoH5vp=}*P+g`j<*B~`Q~4NJK1qPheGkmjBj$E7u^h~+l$$OAI>MVKr5%!1gX@A38( zakF(NZhWjqeV&KHZR^|;i9okVSmajfYvTLP2xzoFS}0D~MUNmWLwJ?hNzK|q54gMp z$+}ihVCrB$`V6}DUp#m=iUh7>v!$31@;L0IOR}4={UjO*PE>?ox1dYRYF-eY-aaSx zTz`Mm{yAam{*Zx|=>fiv%Xb;HCUBoI3`802nyq$d*K^zqAP=BU>|UU0qB!@zeT+k= z+%me)-SD8=-h%X~L1DvEX5peY<g)pZLv*{lHjZdc5Z6)_T);sKTKmIHama3U+6-T4 z9UO|_<wQoRk*=8E4K5lpGYY6OGW~Y{3Nb7v#A<JqPJtzq!bNJDCoZZFrnf?GK$y_# zwvTaFrQp`W5caa)%5^M^PY*`@%Z7<*f4c+7d8@rv1S!72lMHbN>WF*|sAJrOK?5E= z4!?6UAS~boC2IrrORpHFfQe1sIG|7xSa=8z7=q&GBEkeD6C785U|HaTi}0W1qD^CP zbqJ^LZ?iu$w!LfnOjB*I4C##ac1d>iyKc}sXdN)1BQh@aKrjywyC&~_8wQG^4r{fk zWCf4x>6InfskhTWHhitKmC~gYVNb}WJ?p!qJ|Zno!eK`RqE-PW5@CVU`vyL@*gy1f z5XcEz_IfAcN)gf4t)f(*lNsJCfl>9j1Uq?3I$bbwl&cL_#7+lnZXoG{#?N>pRpxS- zPuC6HZiT}IwBR`}!CBcNRR)M??)WY^FLy1I#u=(}5GZRG_#I4QUR!PC*$~<EZ7?!Z zmN$oC0copT7<Ra`5^110=^pZPzx6thFo&rWCpjqKoU8dg?-TjMPWXj;171TuAVNGh zS=q`dmrDjl3DRT*28NYfn{+AZCA2%E-TK%<RP}MVnpb-;vpSyT+WCWu_+<O+PlH+B zss{}G+*x$8Ybv_o^&CsvDsORFY~LE@yCgA2{e`Y@0!9&ktik*>-}+GAoPBK8iVBRH zuy{6eAGFJ8(@TU5(~-J+J?;miAE|IGqTrsyTw36s#lkX)i#pT(L3}HyxIC2PI2BU3 z^I~VD*)dKjcbF5d23$iBa=9#NtLs%H)~a^M_`3+a?CNFb_51)+<1nk}?6<2vL7KZC z8oM6O-@mPe`B}DfPqW7uQU^cTBxZwDh%AQs``^$d;cIs0BYCoGS6M`38>iZrTU#B! zb~HW5=*S$L&;3hM_4x`p&%r4e2mErnn;?RJxzpqMyskW(07t1PeSLf^Z$^)y`F9XF zUMBs<WeP~|tB$80?{fdlfJ?z6NBjFs%-DgvMXwUj?A1v^ynyZZBah$ssZ(H5jw@{p zzu$P!i*;^zY^bXXbb~SnWx*~zg(C@;mL%FvRjR>Mg__W3$*j98dpfRMBj>y=*|uoU z5!$Vlw%SvWYoC^<8cm1TI9DY2FPnY$A<F217%Ct;5C3qSmr$vR4k3c<ttlWp{h`b% z4Nn3KXtj)=H2A<XT<!$7r`@t0_=yscKg`^Z*fPZcuVHqIn~zl4k^y9^Ia}&il=GMa z&<VI^DW6?l_XbB^+NsF}RnfMz#mLCA%9JOs<q_@p-ox9j92NNqD<g?7C;CaCfdKA{ z`|fkk>jZtJYQPa&qNj}O24ulBo3*!U+9uMW&a3XN4b2OGyIX3SS5h?0(RkM_kJ0=# zX8vuQ;3}fAHAy31Mw`)PFSqcAi=OxY+sG2jkBa-J=D&g(Yd+y|BG|Z}N0prbsub>) zhI5LXQ7w0zfvY$Y#u7^6Ob7!xt7=yZ7G;h#s}Afjsl^UmiH$$IV5yP#XZV;w%Z(!o zxGDv&?D%hz3zG+j3#o2f>NqO6Y{b}-!|V_#hp4xq=%OE>S(qF~>7NQ>Hh!bcsf#q^ z<1uqdLyZe9T<HO5(#a7&Ogoo>`6=K%$(ufXi};orO`Sj&SuMy1^e2WVYEI?K6LJ4K zTWTlQ_&mJ2YhE_5!R>@71g%(Z$SMWmR03@J8x?VttRmKby%bMY|8Tka=#NOtkLQT` zwL&3My5MqZ;4Xtowgy6!K?))2FO%Z34Ug^0%vu<Obg0y#P&wAm8C4F`q+jZViW8Wn zUD5}hG4D9U5V+4Kl583V0bf6;i{!YuO?;wUu<fiz!Q#)qH1e|BQrlVzI4-iz9^{n0 z5MoN78lagpPH+$Vf5H3|xhhnW9rZA^lEDL0YI|s^#mqtgnnCy&Vs0vO{_*PAue*E8 zmHoyT8~MX&1wLAkU~bUANWMP+ex%;;R$NKD#!?hrtPjxA4&w*M$^d=R<a7=}JU5tR z$$vIn6VA5ES@)CY@0Z<-G45HhDBH8`_V!a)7(5mdlgD!gm5&+O*lBhkG>`2%4h$%H z2!p2euv<Vn{f2dx3_2A@{96rxV{g961g<OSj98vsqk2yFT-7(qq~;4rDypiu28CJ6 z$3S*3hePY*{&+x-isflC#tJ43LxdK6iDd6;UHdTctI7KhkYu~8lQ!Yb6@D#scS*hQ zdDov^x)1u7qQ+{W%wwSRE$YxPOZoQU;4ncdwu$5UQnBXo#?b^@<yPY+#TOAVoMQgu zni;d!y3T)k@VZ=Oa@`#^-L%2$2{Qj0i;mDEELda%@eOqL(g@|Ma2r*<oa4%192wBb z-;UKdII`Xur(xD)Hi&9szF{jf8u80>UYx?JH`4QzWf3$4<tOedA<EB-2h!6tJr71$ zTfp2;D>1m+Yms1Jh@7k9^R_+*8pT($<<a!Et3$6@Hc}PbEsRJV{>iye(Wz?4&2^Ew zq8U_tyQFlsL=<jybxfcJ6G-f48Z(Ss>ILbHLp}xVsR;**1+=Mo$y@4VO3SX7eNnfo zkmi3XF8nmJu9iPt=vSlfP*1-{MxlT{K~j*jw07x<NtA9}*mgG1YbV$4${Z84+t9hV zFGodocH5EU+LImggxQxIwV>nz11DO#17m~35>u69Ewr=H8F}tmADK`*7;Y~xy=!+> zLH%T>O}~OOuViRP{u8@@CkyUr(*Xynly4EaSFHXJr9kI*P%Ey;vdEdemE7%c`_}sW zZZ#I=eBjEVojE!Rf*y#Z=1hv_Yv#fant8j02pZO*7z2G64Ci7R3;a?t)TOS6&DKdE zc^q>+U=;jgsLbHJ%f7P+66TiGZm~l%keidIS4_Sy!#}Rd+RdHe$SoZ(T^L?yN|TqH zv_9ZC=V?u^kbT6v05gT^Gv<iQj2iU*Z+vsbuPXZye;)~U&Dx^1Kq%Z<go_%<54syo z+|w`{+=|wHyvo&4Z|u0@jXxc0Ybjr#yr;W^MNfiq56jl`?1`t}m_>EW1_fTCP_wR4 zcW+Rsyuyh~sT#y)Odk3XsY!N`aXl}Jvumu7_3(R6N;4eL`GEO(C~<fw;fL*USs+qG z+OyP8w&1E9cM?c#*BAzZ9r@}^Dw|j;^4GILwq=MYKJ1?rZ5n3eAk+n*{Ol;KL<9TM z&b`iNaaokHvDB{Q%}3{IwpE|~W9G!`ynd7FMt+OGIog>D>h_48`bR{#d5|s6sS~&( z^f6Apt;BAR@)KeR$C&pHi0tq<n=f;P(1FB4f=^K>$kDlMTP6~<<;f8GG%#$)44WHb zioP(XFd<Z^3V;2m3S22UK!1J>O-w}?xqn>|QPB(ucZmd+x77Pfe?X(~8quU^S(;D! zz_2MN8Vxir`5l`4EskJQ(!W^i2Q@snddsvS*GxzHVT(>+F)>A}>)@+Fu1dkPo-Zfr zPdrBRecq<=OIm}nTxUp*1Kesi?(R$f;Wl$|YA~;id)P#R8~lTw{5}n=6I#Ry7*t2} zWPTAY<#oJTvWN0=224oWKYJNMJ33Xt6P@qB>1RUMAj+Mz_tG|R8UTc-@>jI6*TG4T zN8&{ajCCO?v2jN|spZD$5eLn6F^0E5sfrk@E#9Ee$188d!M{CISOtY0Sm#*jg}=lB z?y#zlbh7e1v=K()vu|4NWqQ{{4-|}4T~VZpzLQp@fom)%UYxG9-?z$-f6Fi`nkfk^ zP=zMr_*l%6W!E$F8hs@AYq*Bza!n(GHXh+3+douEc-B2A*-1A3dlE;*y~=g0+b-)7 zUFUwO*TX39(yb3zPH>}af{8I=W|a=~O{8JEY^f2EZ2Jz<Nj_&t*tzY+8NKlJK~NqY zvjde)z?*N=pXTPwd~DD7^5jBZdEKnPtA@P^;iZ02(wJ=8+JXP3cl~B{ML$7q{nl3( zSk8YVShKd0pWN{*VrQ6Cb^P8Vc>Ero?_&t&`YqxRQiKR}tsySVL-bA3)VU@s{sOX% zd30Ov^dOhUmAvYRU5&^H%w6Wuvf8&~+MI&#fqnt@M_3t;_awUwk9W0K_pc{c@2{^G zkA8Z6yf=+u8KJ9qe!R&&48D)OOK1pvN$#(>5^%Da?;GE1G^YI;H>+vLiI01OW}IAD zA|hT3{kQ3^XTxF`d}>eU+fNJZlaK7i4fuUndi%z0yYBEZ=shRQ3LW^9yl2w-&Z@oN zA7{;amBiCypX7xCQ>i0m^tJ2Diar+^4h1L}VO758QE{#w(K!g3Efl&J_v&kR<xX<6 zx!C1@vZ>(`cs%Goew)i=FaIvf>tqR`;Z>yE(KeDiyld3~Ma+!LHmsD%9xjqG4P)h6 zK@qoIwGV5c8p8mEaFcLjNvOZ)D$ZB#gRr(+>ZC3Yf9F-g4MwN$#HPD+9w`BQd38b& zjh$Z6rZq)V?1qEZC!!sjHne^qGBbBaq|iO$P2yJ5%kSt<@Rir;IKsP8VSLk^NTo2! z>y@`$nA?p<O}RP-Dg-O3CdNa&zP8Ep6J!y<BL=i>wKGl-%vK;fI)`zdq84*5T+@S~ z3)0;bsGklBSMfS_P>VYez2qCkl@`zwVe?z+9Td_b9J8XEcv6}k;DqprD0zlc1l&PW z(ke&eXeq>8%l703F(MPwb1IG*^(xkYVWg5*M4Me&M;<mJx@)X~o`<h3j#TTV;00+3 zf#1tr9H_s!MYrOY`lv!b_jV@dDG&hNrb%M|1>?FDAq^imG*vPIkyL>g+xBZ9!M0Q$ z@!2)SH}uCSSX{5=N>L3k6^B7Z6@lZ(z;UANc`B4o=b0`PKB|+|S4Q6;_=&V;{EG)! zdAF|ZixX%JJS7p1U5#u&A?TmBE9DDVeb&^d`X%sghg|ZSPpOk%tWlW2Wf-Pi&{X60 zs@1i3#|@Rvv_0Mi>~sEQPTus5g0VNdd0QQ?k!j3aKh${LQ>>6HVpm2QLPOE(d1&#J zGjzPX2S{JH8lJ)2(x$$t%CRhU?!#m4_XXhCl}a;n7x*+X$;$}={7&zQ#FzaxhJt)2 z#F3BGX%EFxI02Q!$td|iyrgG1|0D1+;;_FHw_>Y46)vO}ei-%IjMESP>Tj&5q|*z} z?`0zJeyUx4H+K@DpQD^W9}}b8?<T>kH*y&sK<!^NZT5Y84ySj?m7wu~M~$tEtzr57 zYSaOjQenR5O46nGKhC-FsM#KUNBN{#EysgNQR~TpWh~_bYqSF^_TL)NuN9~_OJtzQ zbdGIdIyy%6G0U-6)wy4P-2%V-KmJ@RZ&mO5{<>SNn{>7R@?f&v`)7Xdg1-1uc@TrA zp4}V5t<rx)MJ90JW#4S8Mn?BN&RZU>8dLV-(}a9Y+R`k#F^Tb(-<k6+ym2l}h;r&s zcP*m<TTRTw$8RpklT1alvz<-lidh5(86LbEYIbMrN*83HZW%HCsU!-07qBqJ${&#r zMwBw{zUJMQj2xK8Wo0-814E=Y!;&p9UT<t_Ycuiuj0$q*ghr4L+7Ci+zrEZe0*<eU zm@g<?Hg;idJg)2$V1>Y>M;ZjJQOC3jEgDi98&%skV#zqTF|eS!B%HkS$jmQD1U+We zBHMIPIfU}(3QA>l;S}G7ia9bFkl$@s#Z-@wCv6OdEyi5|Y52k^`kmPAsky?Q9v6?- zyK3cJ_rMH^{;cU5GT`E^J&$bLdio;#1}o+Iu41oCPQ#eI>#iC^ZCiETO;vdR!vfyC zw*+w3uJNCy9G_=G(@<yxCkD_gqvqgPQmAgt+N0eVtR5fNSGtSd6=|39zLs5Ki+EEr zF2g^DP9*M@c6227!RS?To$ibx2w610gYyCWTuTNLO-%o2t`v!CztAyY$+%b-n@4Un zK00HeK?(_Bnfc9fGx7=M{#H6wez5RKQy!1mddP_vgk*EAD@kk*QB7k9#(oYywCKGQ z0N^{<(@5H7Expb{!r|7_so^QF25F!cW3F`kNCbQ6VFYTaj|CefUggnx`QRHj^(F8c zQV@GO1HIPZ^d>p>l~116G;J7ayls-r>>FdqFcGvM0@ep>w>kk927j4uAU>cO2-2<= zy{tCEI=nLcHj4X(58B*@ucxX#e8<0zt^AIu(xybLNZh?3qM*|Z122#uD*Iw*<R&O^ zb}{z&<tA2veU58oCq{{UND;`lf@b;Shs^iei;rT6B(Pdr+bb)Y|COV^_9YN3;T%oS zwPdOrCm-o`2sga}2e?QJl<!P9vl}1l8;Q?z!Adu8HIL(6gA_@kPH<uCi%Ke)?K;=4 ztq0!8R<t&|Q(8a$*E+Cun@TaSC9amK9~L2>QtRyXDJ+$DTR<--R_+k<*swipn}g*} z_b9^6csUfw+C7tKVx{q4rc+DF>0MTPM4f6LYVmqPfbc6c`M#6LhwpQM(<9mWSj#&O z{)z>qhEO^@9<%=VqfozyjSyWsxN#ed0L-i-BXG;VzvcZM*25{_@4VwTCI|SsX9t17 zI0~|-aJp-HLS~HU2<hoUK)<AfW31K##-_M>h5tB3p?_(@*&@9JnX3m1fsq9E9Fxmq z&avO=_0R)EG~N0l-nLp$1QF4-;;mn9pKx#MDC>kQFFqVU<&=V-RcBo%t2GPO-2VAz z(C(HBn<@;9D&HO?<^vn<^+1+E+Eu=`Z89)LC)RoYLb8UqoWoLnk^O3)m#5!dewM2d z7k`OB_`(W|-m^otm05R|{VD`@aUM33{(bP_m&Zv*qd9L@CrSta1vES|W9xs+$W29z zR(;SGrE*pvBYwhNVU32PZDc(*5zOdYU*;0dxL;-Cyj-0!ZlM##p_$ehe0>gojdIwx zoXIEP9j}=;t0P6ui?IxSon`e5H6;-n8a3}s@8;@%X-<QPFpVZkVcLmETn&%X^_(uM z?2CikkX2s>^8XBt(3m&81f^)B`RNX8yJ&%OLfE(}j{Wd?Ypl3qwfUMJgdKLkKBs_z zKVZoLUWMEi8-nVjQ*#gDZNMd{m@l@z|M<}qi1>Ml7)j-g@3n*d#N;_s;eE|fQ=Lz$ z+B^pPP<5)&DQ}>j?e+b`lbO#VQ7bx1;m~JIxjSk#ZkbfxP1yLuP-)-!@9$ut2J@LX zbZSk$m-bpJV3{4?VSgQD+s_4KXXGC3O=j|{!1}FtH0%!N_m}d!=I$3MH(Q@-`28=G zokRf4sW)YP#K5=Ui#rF*a@0m?Fg`}9n85v2nJvNM?cWz?LyW$w_ee-;+e^`V(J_1Y zd?Dr<795XLm>l?gy%tv^AR3~EnqVGWof2oc(dN>VA^zNhpC=c?L4*&vccw;p_yU;? zHqQhZ`-=tvmd~iBpztN}wQY~(Y4_+oJ<P0|)G!~-x`p0YVSyxtCFg~*mS$p^(k}im z=07m3<;xN`EAHs@SSl_+gKfVNQr$JhMVx;gpq{O<_D3>i6sLRjA%C(4kL2ih^?6U) zTunhc%tlWqvzksHG3xSQ@APm6n>JR4>Z?%(+2dpT5fuhEsu56lfBEQw=0#!)Y-3_f z@NLir8#aoNzRgd5Afap`WAU^@CR1uAWVSdlVnY!QIL24Q_N>KRBoWU|rM37qhP6sv zmlvcMkuY_r*bX_A@)3s89n{zsJSR%llG!#E@6q&5AnfoOc?ndZ`lP9=nJ7fe-YzZ} zXo|6J*h$XY#R61zizsq=kCkJC4rT*D@sd>obJ&Ktdpj#@J>u2RspdT6`OHkXXTQ}F z36^WnR8`bibdymqdRM`mXa!GNxtn~^u>dOfqvcyWwEb$g(@Us|0}?mERZuvdnu%Uh z%bR7~^&$?(9G}vHR+JMx0pZR0P8!UiR@c#zo75o`sXR$&*<3|}2wJi^xy&Tao7YWW zBdP_OZArk;9oW7RGL28SUayB=BVX0^=1*AVUC+9FpA$EW7wX@#J#Xb#)2F>EUt&Gp zy!y0!0Fm761&w;_&lEooi`!>YdOa<=9iHhy-twSg4|L|qSCMzPd~Cw)jk+0nTtw6W zX>&m_(qqu*e_C0w-s&tZ(@{g&6{CSqYmzS%jzQXX3Wl2-K#krab1UNMHIcMck<?YO zbOqw)Lo|J)gBw;ZC%OQcy<9l)L@zGF40{hT18Mm<xgWLvk~%drJ1)1<ooDrbJ_}rZ zB67p)3e##m|ElPJ_gb~@ZxnVY+Il}>m<pKXc544<=$&!z6bQS*jBZ$^eqi;8Fkfc5 z#@CndA5RfV4Foe*pB#-#(Vyk$9Yu%sI^2~F5-kMD%mq1RaqolyZ@(pto;DXHAOmau zy)#&eeb5hl)0hFO{h}W@-A7dzE4o|Z;~vCdWIy}UpU0j!izW4_t8Q0ZW+ZbnWRo_V zc*nR4aL056ridcD87;0du=n*+j6d-o=e0g{?&f9cgC7JtPHmc&c!?R*8!~Hikpld% z@=`dQ6-dy^_CiS}W6NqGS!jNIy`Ssw?#X-LolT0!`gO_-5N?HZW%P8#&tnDM!kK_A zCftsm6mr;)gO4X#ysN0W?Plw)wOi$7uKX(Zn^`O=4}~@sotU|1Ecd^8@LnO1kB*{D zH=SJv@?jBVeFysTGC_I~j)9B5j1T3eh;-^d!;?|EpAKvFPps-VydvVl=sjyn8<fk+ zSB13)f7)@f$A1nU-b+d>n{wtpQJ`$D0B5hQwA=rC*%O5{k_&r#nYni`JQuv`w=jLZ z-nS?u0~>v97vSV?Xx0oPab~>{Nha6U&d*GC^k>D_^hz)>EdMz(bttT{;Kc-?JM15i zM4$Aq$oxy-my3HT6tD>NpUk$It$r$UyA7gM3lgk@5h6IS#2)QrgB&FGc~G!JbK8Lx z`!bNw9YnBbzM%p#NH^m(_<pRK2-hj`4mu_Z-+~#NaDTLDUJwDSLj;H$OOE`12NuW8 zG*Q_F&w$lqY#wRNb(jJl2!HV?r@(cR5PWlB%sqo1)g|=d#LfHPfYgVz!5S)DmlXGI z84<oi^39aFmdJ<s-+${SCu0u~VL%ITwOai*fzZbkAK^K~gdUN<Q4!9Ut)VOR;ZY}2 ze(&Zm(l0H0F3Vh`W-Fwd2qeZD=#EZC1p!E<$UZ(UTsxqF?P8O#y9H?UB_BaR{t2j@ zjqZC02hMP#U}$;b=#Xh_GqATvoYHaRFfq-1l){h?Xw`~I5ESy;M24YOi04mWp6#cH zG7WwpBqYgqGbTdZ{JuxIJ?#Z2wrdYaW8k*YmQvV7Dv|6lf2C+oFK(<**V<tN-yFiv zT38hMVL_U%VrV`G#EEDfJH(tmYb5!h*Jh;vrtA|aBM><_KM0T9tRw{m=-hVxNpo|4 zjqyu3ij4h0ECjo3=KNf)g=N2NSG-$5?%@>?W=i=Hh1a%ips4sC{*^Y1fYSLrQ%w^b zBYL;#@iA<KXTby>ko*Q$pK8dUEfgRSJfr_94@i*l{=XaEf(FW2GimzUE!YhR_}8ir zq;vxnP#x&`^(@M>HnPQB8m&D4ZA9+cvDBsvH;Td-FaN|20Tm%6m+RLX!~}&cB;b?} zC%6|+*CU=GE4jC70ao84D8B*)hWJMKY+Xv&?5ApC8dOd2I?DE!H^Qk4VG^bX4K(R1 zW3$Vv$e0l#5rMd?woE8HpLZoVfDk`83NL5LVvH#QC8hWy6*l9pT#RB6n~gh=Js2?0 zfz2Y63AhjyU>_}~R!WL{VtD}j01r)1L!Sc6;b*i?;Wiy;bhNmTz+$=PuN`}84j>JW zilgfq@v65eKO0)85}pF{jMG?eriK1z7y`JE>^ln{PFyEgZ`Cg-EC3-)4)nuha$Xw+ zFK!iUuLbiS#l4WgW-$r_EC}{>Hp}PFmzP0!{Q<`YW?icPyYIm~a@^<2T%m(vOrIf6 zG0Mh{eLT>4aAaDIftL}@GQ(<Z!!{v?Gf{~Ilmd&g*levza{}Mc8OT?Q1d<@*<`L^C z+408wJ@$Xhm=xEh@&A~0-dYj%07bqB@Yz~zvVKBzNFLnOe}Z&$q~OdRjQ@OwPPgel z^<hA@0hr4hY_EYMmw;t|>Pl}?^O<&K&5HiPeS<aX+H(Zi1a$m?DBYn93GG}T?XX<7 zfz8Q&n)g~l*jQ_Iu!M4U(gg+U7===0*=NKUHGxZWo+d_enzzD?y*A-PJj&e*GU08s zR>wU=>fQPi4c-$O)L}Rr6Hih4KYxb}0O;2I=kAWa*79Lq156lDd77@1hX3u3;ziVc zM&&<e#KPS?(J-;w)#A0wYg1DyKt`#t#VYlZFo|=_c<8;h&6c}x6ry5H#xBCBK0&q_ zPnk*G(^)+h4yChgfx8V=P82>pvRYSPA>!~|_#{3c--Y1@A<!P&N$8I=UNv~e{7S=P zEx9Rv2tWXM8iM+prNkN0H#J2Mh{Sb`jiOL9bT-%0Pt$m9f}fj406Ra%cL|FLLU`U8 zVKp6SNlxU=3oIN~8$=wE$XCqSBlUNF;Z;iGtJXINEDES)jD3PU1mx3y5`e}17U$I% z&y@}YrftaIOSu(eRFDM6EkAZ(B9cvLE_)iP7XiqehO<!abdZ2X9ZJ9Y72r~>tcp_5 z8WO#KbY1o+Li;O8tkf8_er|ME@PU$;I{Eo1@wsI()}Z4(MXDQPyLG~M>U?6|M{k86 zeocw=t#`$~5XMY^a~3Kzk}QDMJ)lPDgWLi6I5GRMzx>T|i7<nimw*G>px+0Zw>CU| z?Yw@}Z8AY&{d}WU!CbGKE-QZ!7lgd>t-*N;!H7D=BZ)RtahPcJ8RQ>Kx6MeZImu6$ zy5D_AN(8lIo2@7<=PrlB<E=>IQ+~)e40&XPQg@6}pkLAaGAJ#+PgK=qXHbc`(JWBL zbu_~a+2uPYbrGZ#(lhT4m<_KrWsZ<}xfQgKzYZnl7qpo=gaaLDf9t0#h!Z#}q~xrW zlQWl!$=UvILr4m*JNrX0@dMG_O8BT>9^5F8zQ6khICv{mKXtb8wBE+P=GvuvKYEA1 zAXLA_hYa@OzLVS+hXPqe51;;TIw-&Iuac4Jd%@<IoYBOe5tJhTQCmdfGZyokwjKq% zYc@J@5vM*4@Er0}e$c)G4n=8s;vs&YkJtGvLrq$6m7=S^@5zN(2y|?eg0PAnOtU69 z`Z}`r;jk%Jl!9s>Pz(rlXtfKRpAgn9YYdnkL+f_FvwDrGP5JG&4Ox3+CUL1SyX{g_ zxG&J<fB^lUU=LgAZg}FKh;<4$=eN0ody2I(9*P0Lgtmo`7}%`Ud9YL8L;qfEx7+GW zO}K<9ECt|gN$ZN#?UJi7xY1%<Jlg2Bz0iF?uW{RGNgqyUM5igp58<}nBp-4u%Q_|- z^>F$N{gd?5K1#w9qfjKZ4K)9jl9?$q*<#dk6~@?;G+pC%SC6oSm=SstoPVSh(78-O zR{u_H(~LZX6#sUYynxp29D|<lcFx-KH!le)Tc{w#69YLk`$i0#V8XDBwySR9u%r2q zbgPvq0g_(^mCP0&*k}LBm_zJ-0@^JuehZcC3Y;G%06gE81GR(KF&%p;B;jyG8<8!c zN(kT1wY@@Pu|Jho5UCBA-KnB5roRcDgrMGB{>V5YFQ-p7dOu5C$>UOqwzLb%BzPbE zIfK}2aV=~J2{j&4p**MLvkmX1IvMuwX!v2x(J}5Iss+;F=uVj9)jnMDWGCZ4VtmBH z-7@!h9`!Z~8CRRPoN(Z4xIK+`A4hY_AH=N%to~h?Dwh$Dr|^_Wj{r%GB(&n&<T1il zVfcCrj6JYWc<CG6^hXkWg-3~n$~SBh&4#%3Z`u(%H3#-EP0>~d<dZHA0CHilx+*CS zGOoN-sT2rA5zxF~@odEy#Nx51+Y5WFnJSxWDweQjW1BiDwjYug0X{M?b(s4Q0yP9h zS3J(+XZu$%!2<?8oHMpC{=HGR1bOWo&efJ)N1{xB`>X-KiHBU_=nnJ_Hg@Y7@Oz4k zI@<^sdRyW73d@UTcUS4I$<@%M_YS(TCS0Dpl^7DvmCbMvV~-Xd3pzb|7t~N}gnwUQ zS^OS`DNI0_g|oZ<)ytb9OF#e?aW<alYRL|QeXd@2yWuVU%&h)zz%w~K6bJo}a;3K@ zyWb&Fi03$Ny~W~AF0sC)?Y0FO9umLN<YGRw%055{B`iKJgOqoq7&nO%r@2yoQ)C!O zEV-H|dc?uwnADC#Kgq}KJHx}rS<EVN8}QBnTb$Ah7TlA{Zx;cY8wLXY2gpmrIKq># zi53^`kXf6bfe6XCSdK`q60NJb=5*bJ6-ybJ5i@UY%?EJfGxHskP|J7x_bO@q3g(lL z1-styY%f@euE6zarMA%Rq2@bpKTcA=ljaGkL&rP1#dt~d>5c?xtO?|F1lFV=x1jJY zI3gRg5B8Gsldy*7y(Bad7Z=VkfE7I!FRF3*!yfPDTq^1rI!hR3^r~_+_h|kRw`&xF zkG=3q*cKOHtbxGi=83?L0rAI`B%s>|<nYrv2Gr*3d>k#*xIKv8rWNS_9jpGI5$wr; za{H>={`^C#V&~Uc`Q?|D0<`J=_e&2sew=`yMChaKb@%UA%TM0Q7<MN3?`%J2BhK&a zE)m~%dXXM3o}PDqBF<LhwQnPQu+Syd<!?p&42`}6i&>ZHvcL#KO<BUD^TqZ12j6EP z@3zlNTF~tzubVZ>S;ZZO+=`!n!@I*dsm4D2{ovi;F|%wf`aVR!PTubnW)?FRtQZi^ zr9)Q8TM`g}S7H`4pdkMTRV(JMOr9Vp_W#Gc9s{4%+sA#Zm`>cyr;*9rv>AOY;cs%n z#zZwb@;A;9JB|IjBzJ1HcJcuN$*_fsq2D8p7c7PfEiuP~d~*Wr?c}gOe)PC*@Hiu8 zcZ)n7Mb79$BiaD~B++?Q5!EWbVte_B-o@`6Ft*h%&j}LC5ki9_uJoS%f(rHL)D)v2 zgZvPIwWjoT+tA3fJUC`lv3{v$ZDnt&u-`WCK5i`mSJLG&THb;%6iBK|JZMF}5I+q@ z;3wC|<G#J+SEzU<mi8{J{eiD?P&6>Qcg?!cHbBeifv@yxZ>x!~{M;kg3EuE}X4q6k zxqH~ADHTSO$~U)|0R5&U=0(~m?R0a}KVm>gv#K*}xX(pm5SUQWW9w96hOZ`gi!w^5 zTSX)!=ufgYw6yZ4X<U?OTBuyD?K@`t=bR5_Otmr?Hr{B(V|@;>v!CL0Hh3iH+cSfl zXZCy`@uaMMz}TQ@AizyePjX7n+5FKAFiI-ub$enIEt?$F$xG#w6_y+at32NYLR3YJ z{vWa%cutg(;`T9xKsEu}3y(srHbe5>`MlGq1>=<u;Le7+iS-A92DxJdd8sGmFLAS& z1-%MPEzO3?zAJJ*^%{fp7YIP$q?$iSyX&0iPih8vYSIi^o#}cN1i|M(4;HC3z~6Yo z-Y>>VQw`_+K8#s$^$6!M8mkwlNj3hhD7_>wYX}<8)cRbn$E=d8?j7ck=rW?eg6MHA z&=;;~WF6ui<Fj9>XfgG|bX#^Mg+MxMk((qF431A;P0brnhMDBI$gCJ6GQv{jxKZ5z zvyW!)&m~W#MU@La2tDMP@3$yDGl6dpVEw4c@}^ZXfYV#`WcsM_R%}bF$K9yVQ3bg4 zn9f%7bGHjju7D{<CE{)_^C=emUc&xYhV|Nm*{oC)e6f*qm&NnfU+&#FQ4>^Ss|2ZD zOMywKgpllX9i&lDEgw<hTA`;$z+2gRthnyw7J*5)(5Zg^S4^f^3v)@;3jjCu!aG9> z!62~O7V(4rsuxEEXSREoO1`TPCD$Y50|76N7@b9(=vdVeFkq*d?J!>`?mVU(J#E0C z)vXPEd%F}z3cvz(1~1lezOi(9c5aHdumcAvDNtCqH?ANo({o(}Um{6^mZ<FM%=-`X z*t%Gi?3@S{>2auLd_<sEBoeRKT;XA^rtywFomO#qh9J{pBx98Y!C$i_bMEO?Q+s(9 zB1`Lpk(B&OT&Z3Q8s1*<TRUxgclxaFqGRU$bmmq(FP%^-b^H-bZmTcI;s1)!xWXWa zXnLQcVE`w6{VD+x=yn7gY1?;)Rw{EX5(?IEWua;E{8-6rG!`WAarZ|YLX084qySrD z1`unR&)tmLVzvX<I@=)4_PrjXrq!tY@g?C#XGwuPs-m>gbM4xgNmWslIV$SBySt%5 z{Ft+?)%XeiFO7kYk4pb9eX(@-e!m4YS3B;1x%1*8WIpbme6<~Xt!C~O-MmEH36PBV zKC5_{@&E11*6*gm1=aCIAz1$xWHvEalK<laQDQSFOLQme2~%hjY2=iqJUsKRL{VUZ z=eKq_9L?C`(@7naOf@_KD2KT;J&YdX!~6mcbw2QuJt3xtGAMj#blb&!k@Jqa=gKFg zegQn&t*l})OX?QR0yQARL&2(Wa6b%oEj63<w%sS8dMt6M?2#$^Ml+a-@(_S3l^dp! z^?Q`ZcZf8YMjW4Fnh}Na0Xsln7W9Nn+Jp#toU%WqF%t^L1mfMH>d_Ku{SQZ#DED{1 zxkf<uKMpg-HabI(3EUsPpF#WPIy?N_VkKP5qAXdP03EP|`Uw^;!hPR)PK=><b!mEx z8+!jl3IfGv6MFyU<j&WWLN}JWY9G^iXct(bLB#=%Ov)zT`V(-bG_#$L5<&}=On-l% z@U{hRf0_cBo){rERYbi-d;?Y;#(!j_STY*tL^vx|;jA%c=BU2a8QmQ&j4l>r{mX)R zg2Qp(uM32bHv&6*=>KyyJf4+0wqfhb5$r|af%+N3Z+bsO*)6aBw$2R}nV8BAYdG>W zcV4j20Mb=5Q5AFq(Bb-f3fNzxhl6#4=pLV!IJng1#~&7u*&`@)Xq!HaH0T=F!}JAe z<hqJC%9eclF3FpulDM{<PZpsvm|omb5R;PN^(VpS9Um!3#ty2zwPVEHr2QSzDC_BG zbLhV?J1=*csB4|Oun9YT(%-Xn!|9005BJ-$2~3k=3{vC)kI!sb#RLX7S$k7sNZ&VN zDD*!i=fy`MF2ksCh-SWF3TL_g8(!e5TaNE1d~Ana8#@{jY2>A7!x;1RS2d~RJe3t1 z{-)UWCp4O}9I2Qh-_)a$$r^TJV_ip)Rk8_st&0yrZ|aw|s|WPblRPLHS9{)2x4c|e z;l88IE-*u0r<SGh53n+-^KOsp_uKrJqc(5BsaH6(%XVhNXgx18Jo?OE<!MY{Sfvik zphyYYNf9zsMEE=omfjR-fh;E6tyLumVK`htN<SFdm!F#%@%Ym)hT$JBUctWutB1gL zu1j}-TPErA>JN3$XEf?H0d>ktfUst0m!Z~GZqQCOW>Gg#gEw2zoBSVx$OSY|4doW` zYu2>H3U(?cEmB!E&9XC7+;;amgPszN=_rLXHAdQzHtitSrxHFxzDme)ZS*>K=oP)) zKXosx0`b=V$)T~cCU$69dL>`3*9DA8rf>xhBR%SonJC)3)aH}A<_)Dz4MV36(J*O} z!$QBb;9HiLJ0*Ok0h8CQnDHFzD{_`Cku3}>Oe>{8cDYd1(uqI$1solW#SFVW%xCFj z8FsKR#FHWe9hiAFqsWME&58g>GQOzh@eS`w-%@e=luX4D<0B?eJOOwkB@7BXK#x5h z<|dC;%%zNxq!{Yi)SAKVI*j7vSqSEI3S@w2JhbKmS2RLWN>j-#Oxm7W^jWCIgp$qB zw=3UaNN$&*-JvBCg6OGo#!>@StdJEoR*;N45)us&5cs)jjBrWQi@NMR4<8c!Qb#|d z_ti1|z+9ZovBwYn0q9BBOpT5WUA#X<$(lK<6V`zplq{CuepkO-<BTkhA`T`TXQ>^p zVf)hp$6tm2A!WQ3dElRDq9s1cC$-;dr?t}`PNaPkPkbo*Bo!)NLlaI%@7Xi6ETD&h z2d6^6GaY49Z1o1+Zv2GdMj67CYnuY}!%(A|_dFb>?ag1^G{qU+0NGloP2In!Fy<Er zsDLjHomZe0^wD*vG-<6o2&_LLB#N{|h}S&XDy)(t>5f|rWv6un!;UNF4qJOwPFp~n z^tWOflMZUQVhjA}3vEHp5mmTq!bTq3F+4AiC_Qv|4(JIavW-bkurUYm1%0MsSlptM zE)sBAVHqU_1GX&20U{TvaKtAN8_ZG%cCB0alxI{axsG+Jsg;~yc?7B)qk%)Ka;S%d zy8gU}@O{*W@PUqIYghI}G|^vS^NDp#<;?0CmbCdFBe1v|Wyk6ey9*HP9nQQT-5RB+ zRTBxx(rF`;=P(V{)M$QW!s^C8=fP%XX0Cj0fBa8~)l@{C@r%^6ffI62%d`)bh`Av| z0@TH<S(&r<^bKibEwp*e`lorm#)CtM0}iRP)*3c>ij(hqg8pkydU$_4t{WJj9z$Jn zI(BbL9)+maZies*C0AMBjY8rZ*_JfLEFtVRLfWip&3c@<&=Z!dM=G@~hZb^!^@!M< zt`hbB1q`mG51Z+u4w%a)qAFROU#|vT#ix@O)ltid3ui_czU0-wI?hZEk15o4x%y<J zU}E=KDZ;(@;XwFY1o8Ld2tY<USuTI|{XY61R;TGN*AGPWj<MQutE_VNATOlfjMiWz z#_=kWh3fP+9u^!F5VEO{x-9I<O?p698XZjjl1ABmscAXGRcr0jy|cOI=<19Ph|X@B zi`#92HS#;*WLigM6m~c>Yz~GBSTt#(3y+MQNXxIAZmG0BjFC!ndD%}(@5daY{hM@W za1g@1dyc9{PE`~21l?oY|1E)C=MdnFGMkoYxKbNF(HU#AKL>oht~<jCH;9$zE)(oq za=Ea_ph466osi)pF}~#1rXVe>p(jApcEt=&vQD6Y8|CM=EWsIml3@!IhY5HmJw&lJ z{INFHB>y6~oj>F<Hb68futwlv&vURQUKJ)?k45+3cTgEMv~2({Yn@%|YmlC?X}46z z)$r5SW6JIXO_0Dh#cf2>=EUD68BwNB3WUF)kP75kI;9+2E8=U7O{QJRpRp(d<KuWc zVZxStUD`Gd8VCn<L4r>{%ID1@)X9eXGl`8wF{+>#%HN<s=WNC24KE;z;|C|cSYi8r z(2+2_gQ4-{9y*u1>nbjKg<Eq5JOQ^?z+)3u6GUb02m>aK+l9Bh&t1g01lNL+$oe(7 z%<YQK0f`E{G3ePCS{)1(1KWHCej}m^d)*wKlo^syw1CvOfcGXwT{-W5{Lx*-)Hz{U z3aE8gDMj_%W2i>|E}KYtc~8!xS@0{A&e2`Y0yZ$iOkeLt!s*PviQt^LgTTYP^8T5e zvzD%Sf`F<@xN?&lp4D1~(TPd3jmimr&`+=){^rGQ*5iq$nreI}J8N4fWAr%p*M&oB z=QN#b5N*)5W?`WkL9Q!3?*Ntze}`KkG}H@J!!uM>Cu!z420NDs6P1y<E$eHDo`e%% zpjqWMJ254tmn$ZCg^YwFF7%A||IwhbED|;Hc0fanm2g7U+!7p5THfb$s<FEJ&}>z% z@e@%G+GK3+8=kYJKk8VSF0wK|>PrAR+q;<*9ZH2jjba|sJS-265b|grL^+?CZCWWl zN~Fv_v0?e$V<XZ2_lb3nA3l)WsIv8;bY5}I;5`({Cm_}O{4BoHFP!AvxF4?{WSK}F z8t<(!Y3DL4h!sud9Jdo}Z8IpdTwm<OEOkE!X~K;=GB#-(M&)~7F{0ctULm&?>7|}% zA?6Tjh}c$!Z=O^BlXz-w$6j$wq#c>qd`dcH?*QZ7AX#|FJOqnQ7DTle92k$&m3yBD z2NnEN?Sx6HU18KZ`4MmH=eKPQ<+?`m=xxjTQ=(`QO<*8PMIQc?;oaW@ozy2jxP_UE z)nzK}a!L#v+I-VV#<vzaHvvl>uuAms<<JJf#I8b$-K6H|i;I+P43ppEblDmSstRyN zOWsM-00>5VTwUtLugXGErAtc2a7o|g+2%*6`x=jIe8RwvT*^r?a8aab*Cf`|&S~Gw zU+h=^?mf4k=Nq7F&tLDL2BF7SfAV0Z$Ddb$i|;&pq@_dyTdWBjo&yEX#gN@JsqM|V zzPQ#GSa)70z!6$FPImqodppL#E&G9!-$&4CkM?Fm^)<#E^h20@wZ25dFK}%Uu3wMI zZcgNbSy&Vf^7d>evvT*kqZf&vCw{07E*~39kAbrH`QRkJotpKG<=~T}#_@nyX{+kL zG`$u8aB6o!)6a8hH^?y^T6xo{7$vr~wj?2D&$DiepQ7L)T)i$;_`a)ChEHm|o{3^T zBsV2t%z4!$cR5$B?_>Vcl4GL$lUo)nf<{;aO8c$Ocq-~ytmS^@<wer9f*~O<wcxHO z$CWEIE@ZZy5a<>7Pu3*bZG=gwhYfGnOP~E8wJyJfokd_3d=Z8ryAYky$4VR?My(4U zzi|^m*Nz?Ab^3tw8vV5XTbK2)$_iaRG`Fs|61$B*SQ$2vm&C`dGrfFh{P8Eo#A?@F z*6G2PgNQH)5yv*N;2zgh5uE{3qJH`l8pH`{{_<c~*JYF6KVR<U{3mt+RUNa=mm|JR z1Hv<p53IGlTrIFh+F&%8$1*E480e4(4Hu86W%eurSOvhmydyqTyY*$?;=J+uU8W0{ zT1`h*b-WE{J#I#(CGrImcQk4qcwx{!uC3XOl?It`Z^L)l03qjnN^R~<5(@a3-2=us zy2tVY|IPiGoN#%%pQyHH@|2#jZ+WL7L*JZs>pkGU_H?X{0I*r<?kqMvg)YaIu4=%S z48s9rl}{D=t79s7jmS$<xVdDToqEgGkbp0Ss^JeWhxd$kB8FxB=_9ts?>X;q*S>qp z%<N19Mx-UGos~Zw!B?|6srSN2Ot)FTCp?F^V*9?5TXR2vGNa;rzei%>E7ipjKGS?y z8?s>I+m}j{{&fky(+15GIP56D+?`=|RzHu=1aJIj>@Ez53525nVcX4pcOQg!=dZ=C zI^i}<3ZyY8G8i*qLj)`{muulF!XTDsaWe4f`}!sZc=n_<=p#beoIAQ@us^@=3pib` zS2qn@o^$y)6K)E8N4IIK|A3x@EGYpq1@A&QBj}+>sZQ4(Af1x(yb&R<M|c7&{=OS? zIk0r~sG6J7Gf;jf=$e1#pGciQfn%-H9eh?}DW`|b9}VpFDBDVU-k0l|iu&nV?f;La z!vDWe#~|%~^Gxvd)1>$O!}7D({rkm3dT#T-Ps9eBw+tLVUcY@raPIxT_N?!|yT5i{ zzwl4LJZqn{&+3foxeAUc;9D{ukF@Q>ldCsW`i8?es$K0GV*}3rvD(uwto%KWuznU} zHPU$JiFM_q(?aIQHMd)JJ%o`uH5a!Bsbud~Ah{?}I*j7j8a^AjC%OJ(0(Q!s-b+7w zJK^&Su}%nCQ0{?G@>2V>@w>WmJta%#dtPUc^xI)k!w<b?T>h-f3bdy)X<Yx*w)L${ zAP)}_=ZxmSzreGWeeg=tt%jp9GiN@M3tExA<ge==53c|9jHN)JJD}m6!<WE%6=zaA z74anGGb0b9-R|K>v85y|?iT2wXs9@0#w|(J28eJ@UDGjapTP{Xq<4PTjBO!AUn}Y% z5d?<wP+BEQnGg41!rG;PhmfUDe7}Wc71>RdARH1!C`(AvF%MHYF$jyjor&UY7g4|4 zwH~sK>B8UFrgXUSdcl`o*PNi%23)Ki=l1PWg9Q9v`*P}`!otNJ9<jpbwDu}pRm)Jg zR2I{|u<G~!OwphBna?DutagfX|9t-Gb=z*2*A79egjf1HhMk!!UEZfRkG;n+j(d4- gR@}EtY_mt`BeEFNOTNFFFa2jf`r@Vu!vsbK03BBGwEzGB literal 0 HcmV?d00001 diff --git a/source/agent_based/bgp_peer.py b/source/agent_based/bgp_peer.py index 0a3bfe1..df8172b 100644 --- a/source/agent_based/bgp_peer.py +++ b/source/agent_based/bgp_peer.py @@ -35,6 +35,7 @@ # 2023-08-17: fix removed internal_item form check_default_parameters (THX mail[at]bastian-kuhn[dot]de) # added warning if internal_item is missing in params # 2024-06-07: fixed crash on configured state mapping +# 2024-12-20: added local address/as/identifier for bgp_topology # Example Agent Output: # BGP4-MIB @@ -53,7 +54,7 @@ # import time -from typing import Dict, Optional +from typing import Dict, List from cmk.base.plugins.agent_based.agent_based_api.v1 import ( register, @@ -83,24 +84,38 @@ from cmk.base.plugins.agent_based.utils.bgp_peer import ( ) -def parse_bgp_peer(string_table: StringTable) -> Optional[Dict[str, BgpPeer]]: +def parse_bgp_peer(string_table: List[StringTable]) -> Dict[str, BgpPeer] | None: peer_table = {} - for entry in string_table: - remote_addr, peer_state, admin_state, remote_as, in_updates, out_updates, in_messages, out_messages, \ - fsm_established_transitions, fsm_established_time, in_update_elapsed_time = entry + try: + peer_info, local_info = string_table + except ValueError: + return + + try: + local_as, local_id = local_info[0] + except (IndexError, ValueError): + local_as, local_id = None, None + + for entry in peer_info: + remote_addr, remote_id, peer_state, admin_state, local_addr, remote_as, in_updates, out_updates, \ + in_messages, out_messages, fsm_established_transitions, fsm_established_time, in_update_elapsed_time = entry bgp_peer = bgp_get_peer_entry( - remote_addr=remote_addr, - peer_state=peer_state, admin_state=admin_state, - remote_as=remote_as, - in_updates=in_updates, - out_updates=out_updates, + fsm_established_time=fsm_established_time, + fsm_established_transitions=fsm_established_transitions, in_messages=in_messages, + in_update_elapsed_time=in_update_elapsed_time, + in_updates=in_updates, + local_addr=local_addr, out_messages=out_messages, - fsm_established_transitions=fsm_established_transitions, - fsm_established_time=fsm_established_time, - in_update_elapsed_time=in_update_elapsed_time + out_updates=out_updates, + peer_state=peer_state, + remote_addr=remote_addr, + remote_as=remote_as, + remote_id=remote_id, + local_as=local_as, + local_id=local_id, ) if bgp_peer: peer_table.update(bgp_peer) @@ -124,6 +139,19 @@ def discovery_bgp_peer(params, section: Dict[str, BgpPeer]) -> DiscoveryResult: yield Service(item=item, parameters=parameters) +def bgp_peer_base_info(peer: BgpPeer) -> GeneratorExit: + for message, value in [ + ('Local AS:', peer.local_as), + ('Local address:', peer.local_addr), + ('Local identifier:', peer.local_id), + ('Remote AS:', peer.remote_as), + ('Remote address:', peer.remote_addr), + ('Remote identifier:', peer.remote_id), + ]: + if value is not None: + yield Result(state=State.OK, notice=f'{message} {value}') + + def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult: if not params.get('internal_item'): yield Result( @@ -165,6 +193,7 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult: if peer.admin_state == 1: # shutdown yield Result(state=State(params['admindown']), summary=f'Admin state: {bgp_adminstate(peer.admin_state)}') + yield from bgp_peer_base_info(peer) return yield Result( @@ -180,6 +209,7 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult: ) if not peer.peer_state == 6: # not established + yield from bgp_peer_base_info(peer) return if peer.fsm_established_time: # if peer is established use fsm_established_time as uptime @@ -231,26 +261,37 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult: if value is not None: yield Metric(name=f'bgp_peer_{key}', value=value, boundaries=(0, None)) + yield from bgp_peer_base_info(peer) + register.snmp_section( name='bgp_peer', parse_function=parse_bgp_peer, - fetch=SNMPTree( - base='.1.3.6.1.2.1.15.3.1', # BGP4-MIB::BgpPeerEntry - oids=[ - '7', # bgpPeerRemoteAddr - '2', # bgpPeerState - '3', # bgpPeerAdminStatus - '9', # bgpPeerRemoteAs - '10', # bgpPeerInUpdates - '11', # bgpPeerOutUpdates - '12', # bgpPeerInTotalMessages - '13', # bgpPeerOutTotalMessages - '15', # bgpPeerFsmEstablishedTransitions - '16', # bgpPeerFsmEstablishedTime - '24', # bgpPeerInUpdateElapsedTime - ] - ), + fetch=[ + SNMPTree( + base='.1.3.6.1.2.1.15.3.1', # BGP4-MIB::BgpPeerEntry + oids=[ + '7', # bgpPeerRemoteAddr + '1', # bgpPeerIdentifier + '2', # bgpPeerState + '3', # bgpPeerAdminStatus + '5', # bgpPeerLocalAddr + '9', # bgpPeerRemoteAs + '10', # bgpPeerInUpdates + '11', # bgpPeerOutUpdates + '12', # bgpPeerInTotalMessages + '13', # bgpPeerOutTotalMessages + '15', # bgpPeerFsmEstablishedTransitions + '16', # bgpPeerFsmEstablishedTime + '24', # bgpPeerInUpdateElapsedTime + ]), + SNMPTree( + base='.1.3.6.1.2.1.15', # BGP4-MIB + oids=[ + '2', # bgpLocalAs + '4', # bgpIdentifier (local) + ]) + ], detect=exists('.1.3.6.1.2.1.15.3.1.1.*') ) diff --git a/source/agent_based/utils/bgp_peer.py b/source/agent_based/utils/bgp_peer.py index 616f18c..f801802 100644 --- a/source/agent_based/utils/bgp_peer.py +++ b/source/agent_based/utils/bgp_peer.py @@ -26,7 +26,7 @@ import requests import json import ipaddress -from typing import List, Tuple, Optional, Dict, TypedDict +from typing import List, Tuple, Dict, TypedDict from dataclasses import dataclass @@ -39,22 +39,28 @@ class BgpPeerItem(TypedDict): @dataclass class BgpPeer: - peer_state: int # peer_statestr: str + accepted_prefixes: int | None + admin_state: int | None admin_statestr: str - metric_rate: List[Tuple[str, int]] - metric_count: List[Tuple[str, int]] + description: str | None + device_admin_limit: bool | None + fsm_established_time: int | None item: BgpPeerItem - admin_state: Optional[int] - fsm_established_time: Optional[int] - device_admin_limit: Optional[bool] - prefix_admin_limit: Optional[int] - prefix_threshold: Optional[int] - prefix_clear_threshold: Optional[int] - accepted_prefixes: Optional[int] - peer_unavail_reason: Optional[int] - peer_unavail_reason_str: Optional[str] - description: Optional[str] + local_addr: str | None + metric_count: List[Tuple[str, int]] + metric_rate: List[Tuple[str, int]] + peer_state: int + peer_unavail_reason: int | None + peer_unavail_reason_str: str | None + prefix_admin_limit: int | None + prefix_clear_threshold: int | None + prefix_threshold: int | None + remote_as: str | None + remote_addr: str | None + remote_id: str | None + local_as: str | None + local_id: str | None class InvBgpPeer(TypedDict): @@ -70,8 +76,8 @@ class InvBgpPeer(TypedDict): last_error_code: str last_error: str status_columns: Dict[str, str] - address_family: Optional[str] - fsm_established_time: Optional[int] + address_family: str | None + fsm_established_time: int | None def sec2hr(seconds): @@ -212,19 +218,24 @@ def bgp_get_ip_address_from_oid(oid_end): def bgp_get_peer_entry( + peer_state: str, remote_addr: str, remote_as: str, - peer_state: str, fsm_established_transitions: str, - fsm_established_time: Optional[str] = None, - admin_state: Optional[str] = None, - in_updates: Optional[str] = None, - out_updates: Optional[str] = None, - in_messages: Optional[str] = None, - out_messages: Optional[str] = None, - in_update_elapsed_time: Optional[str] = None, - description: Optional[str] = None, -) -> Optional[Dict[str, BgpPeer]]: + admin_state: str | None = None, + description: str | None = None, + fsm_established_time: str | None = None, + in_messages: str | None = None, + in_update_elapsed_time: str | None = None, + in_updates: str | None = None, + local_addr: str | None = None, + local_as: str | None = None, + local_id: str | None = None, + out_messages: str | None = None, + out_updates: str | None = None, + remote_id: str | None = None, + +) -> Dict[str, BgpPeer] | None: bgp_peer = BgpPeer( peer_state=int(peer_state), @@ -247,7 +258,13 @@ def bgp_get_peer_entry( accepted_prefixes=None, peer_unavail_reason=0, peer_unavail_reason_str='', - description=description if description else '' + description=description if description else '', + local_addr=local_addr, + remote_as=remote_as, + remote_addr=remote_addr, + remote_id=remote_id, + local_as=local_as, + local_id=local_id, ) for key, value in [ diff --git a/source/packages/bgp_peer b/source/packages/bgp_peer index e7ae3d6..9a52f1b 100644 --- a/source/packages/bgp_peer +++ b/source/packages/bgp_peer @@ -37,7 +37,7 @@ 'web': ['plugins/views/inv_bgp_peer.py']}, 'name': 'bgp_peer', 'title': 'BGP Peer', - 'version': '2.2.5-20240615', + 'version': '2.2.7-20241220', 'version.min_required': '2.3.0b1', 'version.packaged': 'cmk-mkp-tool 0.2.0', 'version.usable_until': '2.4.0b1'} -- GitLab