From eb2aa990facf5d8973aece0e594772e5ecbcec7c Mon Sep 17 00:00:00 2001 From: "th.l" <thl-cmk@outlook.com> Date: Thu, 11 Jul 2024 21:49:01 +0200 Subject: [PATCH] update project --- README.md | 2 +- mkp/vsphere_topo-0.0.3-20240711.mkp | Bin 0 -> 7281 bytes .../vsphere_topo/agent_based/packages.py | 93 ++++++++++++------ .../vsphere_topo/lib/utils.py | 21 +++- .../vsphere_topo/rulesets/packages.py | 34 +++++-- source/packages/vsphere_topo | 2 +- 6 files changed, 109 insertions(+), 43 deletions(-) create mode 100644 mkp/vsphere_topo-0.0.3-20240711.mkp diff --git a/README.md b/README.md index d12b93e..53f352c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/vsphere_topo-0.0.2-20240709.mkp "vsphere_topo-0.0.2-20240709.mkp" +[PACKAGE]: ../../raw/master/mkp/vsphere_topo-0.0.3-20240711.mkp "vsphere_topo-0.0.3-20240711.mkp" # vSphere Topology Visualization This plugin uses the data from the _VMware ESX via vSphere_ spezial agent to create a topolofy of the vSphere environment. diff --git a/mkp/vsphere_topo-0.0.3-20240711.mkp b/mkp/vsphere_topo-0.0.3-20240711.mkp new file mode 100644 index 0000000000000000000000000000000000000000..be24721712f3b21055ae229868bc21e987abbc9d GIT binary patch literal 7281 zcmb`L(?cB&13>fgvc0^pY}@9|_Ts9wY%RN+ZM)@KwsCW-Zg$<e-|vt3-p=EBIuD03 z78!<?FVO}LdLiQIvB{tOQezsdBdWfYY^M-FTP%11T>U{`cXMvR&<rpkk1b-%ag13? zN+kp8J#E&Le#W7aFi^;yQYP2nA;z}j4wCJI;WiV?m978daV9Cawpk2~)P@9JnR!3y zeE&?<)!prfce%Seeff34{{eo1Mgd5a{p$hBB|<zy)0<#nDIS;OcRoc^doTL0qd5}5 zKrR!@9aR*$sgU}6%g%=60*Qm(WPkKS_@Nlfk$faC<tK{5l}J-h9>}jzZo!TMaeli> zWmI)vMILWqKRQLwibRg<)yw_8UCV-7o|<@k%fp|6Y6eJHR&qp_e_<_ov*7}>cr>B_ z&{IP)dUfk^h4VY^cnU!7RT3r?%FSF6lT<NwKF0XH?;-;U>+np(<ut)SHlUCg>&Z-< zF<nbEdfir3Hf|RT6tL(Wb+3ROqJPpzzMWM&xrWa!PmQM-qH?Eyq`^#Vd9oK&LlP4D zC0p}mmnW->2h#XgN$G<UBtooiBb0)IKAZO`R!D3Z43NTtx3!GaTr68`<nrG7^sHL* zg32M1qpf@cxACxWNIH-3;bWWhI-sZ97Yh_nz5p)7&Xb_v3UYlOXBg6oDGeZLz?muM zi&OJYAYcz}=GXGBt!v#p^?vi)=IhNfa+rq9{qBXDJU8-5%>8L~^crJEzrtmW96z0+ zI0kaZz%8`C>gvH7)6Vc;gJqCQ%>F$xc6l8{{_Xqx3VOB03GXZXxS|9T-a|<d>K~v9 zb5Ip#ylIJMTHNU$xO6D7v=Sjk<1pfT?WfS%)c2L_cgj7zf8Yx|?zo&-mN)~Q&%PS; z&oEl)ekiKCG%%B1Q3zDkh^P%?u$i3^H7B(^s%cgl1*)YIu<8z~*`eh&>)G6&+NYi4 zP#&QIN*ZBF)8dWF<p(*%53f2v6XrCAO-cXfgZsdGwZN~heXF2tv5Nns<Ts-pVyDD% zu6A;I`M}V(@BEbapMQXm-$0<vs{=^iDLG{Bh2e17XYW%AhU;t^RATX5?1ClP#}*tZ zWYR%<hp(UE+J2Mm`LRXq!VP;NL>23~;TtOuzpCzj9D1SL1N-u_|K(*Jt(OS=v}{54 zT*vrjQWR07WYj^tDjpBUAL5F%^B$y4!Vn~Yr1blnox9LBAMjGt>JNNuc-H2%EBvm^ zk%_ms_(`y1;wzV{Ztf>`T2)CK6Oy+&^flZdmt6slj?X4!avU)9D7$o8kP8MBEQJp0 zwwX}u@E}7~bRMF6yW<k^o-xJ%*L^!|RmNkE`<+nG?u4{?1C0mBzdxP8W6$(u_e0&= zVP6F(lPKA0wm%YX(;pc<s(|P7uar141tp8cra3Kac<zUChw|wcWoCOBY6zM(&ieXO zrvk<MeV#Jp6i*hz#fbZZ0X;L9f`PQ#oh%&sP1A{03iVkONE(kso<@oY>wU>$3&siL zP1sM(6}l6cD^#f)2)->KME`jSbMR~l>xGzK6Qs&HI|BNVc^!hkk1Z3qr`Uov#n714 z3P#H$FfOCm_PZRyZ%w}tJ_ya|$7_hQ6m$FHdZg=K26@|v%@Ei5NP_cj&S$e|g8zPs zh%yNqGML&%YO})!P8*>DcCx=luvN!n`XT+r=%z#OW?>*moG1#&5Nu1i>&pY?ZpztG z)_+$OZ8_>W7|M})`*$dr6X@^pvKMBZPho7bmT%S16?nQwML4d37vZF6Fn;vX_`Y|0 z8{uzE9>CAiGTo%8qO`6#Ib!s7z41r%<@)qq9@Zz&*Wc0<N=_osmwq?<IZ&W6L2ZXT zKv+xgzH;lf+~aNk8WN@ly}kh>kaQLLK9-+XKQYWbPaiGQef6e?8eNZ@6MLID_;I;j z+rD_S{bpfzOV5i}!e?xp7m%Z{GvYc+D#Qxiq>bM++Lw)&h1Z6ar?C_R<lX4DjWj9f zU_{yNnI6)h_CAgpj*P5PrHli9+qB?Qkl7^5HkRAxvkjuc@f57-{vlKjV{BCx^`R$v zO_~L+Wl4~tUWi}IU5IhI(LM|zhg!j`x1TcWt{V*H!VZ{!U5_KQhn2%XFMC8!xsu&$ z77wNry*K`M85HMsDn!e7Qv?GKc6h_}qwv#$at-m*B7qROKM~i69pwV`sc32|Z%USo z#P)nvBBFUY<1{yNf)_NwrLp`@R=#Ej<Xs<>$>ptEm|tLFyOrcBsgk}Df1n$qZh0Hm zlaipP8Ds0aAjTxMW=ch@{^Zm*7M}>HQIRx(&qg6(3)0yb`0zLWs*k(T4;^Rix7~p$ ze{#mJm6Jy(mHDG2?W+VlroWX;xm1T2BSN=|xBQzK7F2i_l<FWO6$f_~l`nw6(7k&b z_BANC9c6akba~5opa$m?CyBV|T&Sfn^b>;&eom7h``^@A)gSh%jMyHk%a?V8S#`#{ zoixA9f3H~QnZwr~CrUs5WX?KF=S+s7=;iP0$ojm1+EZzkwbs{d+gG|iD`BqOjyw%3 zM}qYgmJfAGy%S+;^@R-5vErP!8UZ_0Aq<{b>a#rISFm6>RU|tXH!b>9&*hfv$M747 zPw|<>%qxxL{Nblnlg8dHe(tAxx5&ZXBjE00vPas|7qZzX^C;lh)QS}+!cmsgIw$Mj zn-enU^`_m`hN!abIfu8xM$giNyjAUY^hyUw%Zu(7cbZ`Jpe;)WrVl#4Q|(K<@6+6! zJcZB+^5VfB&-@s2q~NlKAAej@h}V4r^>OIniQ_M54-OAafdTcdW!7`%wJ=xcwuEY5 z-(3<eo!_<tuzkjZ(z!~+LT*go!K-!DH|@hmR4k+!MFmRQB7;4Q$D$Q8k|F2G)W$%4 zO7?)x4#<P#g$>-fJc9{Fytn5(iR?OTP|HXjII4}+-Q$WuvO(dWFYXVgIf&;6@}y(e z-Jg5%;L=I~)zYQtf9vq}J2l4?(PaodRX)oI!wvnh@^@l;i;;*dKqoOkBd>>3XW~Q^ z5#e@E{qSc#zYt=$v%=;i)PZ&Fn{+7A_CybtCW5l1W{K|9E#6tFW|At3#7j*YN;->W zHl3-#LWw4|v!R^p^9*chEnH^ljFN-FWerW2Z>_`AkH1Vccdk5Ac-7Ol*FFkvcH!ps zK2_gH<|(surXq@jo$H87=-|E$+W}09fVz0fq&@a?8+ZMYA#F)d7`{dh*e^z>L5kdV zcxmxwPWI%R$qx2*<t&W@kj%0?gVV5R8{S)K*%7jA$8)ulrEKf8{Fthx892BO!CKwv zP8+ttsbV=QfiualLerf?cR|*{ZB}6_W$ERo&Z|)k92KqGYD(3ju`o7WiSGOE?e;^d z{1(hdK}#{7SotkGUT@7n@DQX{e^$)<=Qhon#oi)TXm5bGci?y7(>Rg(P2aa4O`y}u zt1jU9j%R(}>N!PRx7N5(OFM&3Ae!bw`xl+(wA8cr`*5q*%4}u-?_db`g{Sx1cft4Q z#f!M7CrrUbe_POIzB0o>XuGLg*>=W3MZ8rPf+KN?@i|wW7W^lS<t$1z(Ln0(pE-;z zZ;xi}Tmf9LV~g9MtDg0oKNn=mTlrf%A8H5Np$hX?M9%j@ienEOt>_M=M>P}w(s?yg zXYSVLPAiVUyg4;VGdg(PKFU%|cBThW6ZBWN`=g@5qDbtxe1u{^Eyp-V+5MnT!=%k{ zxl`#15mF<+q9GE6beB2h-_lIR^W5kFJfhKyvY@Ic-zUB^bIir`H~Ms%sm8C)=MBqx zGz4cTrv8gys>U>#beHN5YZt4=UxCWAMoVB$7;Aq^c|;`DA@hGb@Ly=SG@)tu&Ij&z zIcxtooK7?4b2jno2w79NahIpyN8HM)N)$JAAvAKFNso=~6h}%4_r8S5-p$-^Wlb4v zg#xG7RJiVGnx5;_9hJPY|{)VR^S{r8Nh1kK;Zd1alLniK(hK*|O$q)1!8?Sezw z3jdD`2;pR=i03`m_G`+6?H$OgqMZ2BX+5FZ)Y`x1V&RAe$iCpMA?zXE^!(z6tqEi< z@Ke(L6k1q?#G<%H@a`=S<>7NGQvkE+ruX0Ad<6f%W|C*z{N1zQ?A_9sE{5%O>n{=G z@J^`~E`mr-G6Q@G;gF-seYCeAJ$5eV!y)$Bm<ImPEf`_>9;G|F#A#i>U0q3Zt$tZV zu~7p~piLKe-v~iImX+iJ6qP552c;~pQ6;8@WTKhP+)Lo?+^91O74_6EVQJDRFt>!0 z5{_l1GU4-1L^6R%vX{A==&T<wGzWT^WF89TQ?sAp#Lj$APQ6crBnbHx$%H}5Oy_V} z@=`BK?LT$zRge@PRPYVZXzE+2fA~vlF|PUd8V%W5rFCkMo@wV+RSqX%UTKG?YvS*$ zo^{!_1g)G*86mmSB5hhsD+fe0b)2$Z%{3dqn1+3p*gl`Ghr4%o&M;*$drMhhp4f#T zmg0g`0BebS_R*}ulux>bW#ECH^z&;|9MQ^EbvFOjqiGWkWM3iZ!{i8d<CnX8lO``3 zGt1s)&wcVe7jRV26*+hwQ_d3kBBGI>RocpM$Ch&CYZK9;87=mELy=q!=L3&+2GdiE z3t_aE(8TPVq6A)*#&B}s2JCW&c^Wl<(N(lCgAVolB<n8d4=MS5L&;NW1CAu{AcP^d zgm_=9>1)2Tf^7*bPcc#qqZM8a)l4??-^|EkF(sLlJ6uk+87&NFM;W*McPPnarEunW zYhA{%;A%>%;Edi51)>j*Sv#1>ot9-hTjeO@26e1-4~L-W&T>sspgAeQo-NScwwzPz zAemI;7SE?pUG_Mew1qY4@Z2?6-XirPF}PBa(%k_<@@9V)-X9i(D%ZB-E7?`4uMf$_ zL&;DZUO*w(X-ETlB>(n=aY!a#xC@x5#OJqUCnDi9NG+#rXIV=ji79l~iYsc0-L<sx zXFw_>ZR>J&@F`ulkofuNiQOgjxGBjpzJ)TvWK}#MJ8Z1fDYL7?RFa61{#fmLQ>MXv zHnd*~)Il09v(3DUA??CNSPyaDaH|fP)JrF`ppE395ojPCa+fE7$8~e4CetSEqW^N_ zt+@7_kJe+U(}BF9jUYnygawa0HCinw;%9nNdKsua2K9dHg~x{WfwnjOmoLb{l=o-P zP{EHr!4GHw^M~o!kSU2;UZf$K(@GOVKge&OM`dQNrDYt$ByTAMuv<Ij)U%@>)gbDQ zvntVLG87o>?MZ1(t+7#*(x2m7h|FSJ1;)*mz;?JSV~$dbL>|rY@4FN8!>yF;T%TB} z8<2)G|91JDMQv!7>ED2)ksJRwg?6>@ws;+iyQ7nc99T_j@#EX#qVp{UMC@9eUNknV zYXG?rB-jsp`QDM@2DyPiu9kLkjX!?<ERs&4>=o;Iei;@O>=E^)?|MgeXPb3i*?2<p zJNZ*q2i%{T;+?<k%gr^Cn7$iYL=$)e-|Drt>u5X>X5>nTPq{zUiRShQz31fK-JG2P z_HTI1-;b2g^vdP<C>u9G^{Pv%<B0kRs8KDZ>1z}zMHVHUwAH?eR?*q;#C2HRzctN^ z*DyR9bu*am1)mbnO4Dy*Po~FdvjrLqi_ZHjSkSx@E7=^0`Fx~=BIyzWu;z@*8s)ZR z3~MHh+<4jmPOho6X5Ad)F?K^0zb`dPu~ron;c>z;$V`*C4eMlp@>!)z5tzX+X!@Yh z9#)maMK1j;?$pKwx_^3>(=u`+Q|#KEoc>Gkts3Ux(QiQ#-%_U)tLGvNIJ%XY+jI3D z<aw1(5jn{=(^yn1(Jb(%om|Y!Zpw+$33f_sYu30n9ZXjtvho4@j0nwi=?I#3KBRo3 z3y9eX%el@pbDQ`E(kt}m!X(_cc9Kj4_FCj=WM}siud;Ftm2TK>6aA8gXHOf9&NNP? zyj8S@<xEwiwu12YBQ!Vk;r<?3vwblvf^Vhe({k71Bf7`m#ev5u6DH?nl7u~n`rzeB zO~nIsZQL`*4ta)IQ<iFLPKV_r#YqeFASR2%ijqwSF#zN;(=`g8db;_}&FWYx{+U@w z65pXd#Hg!`S!a*hi}qT6-WGdmsr1{_j}a7<tHu>5qYe`Z>9XJJNAauY$Crqqtqyk5 zc-^@+qRfuYUoqa*d8BEhIF;?hihryTM=>G*Iw|-MSLWD`<vS;yQIqRu@~{UYmuz)K zh(5T5t}NfI@=YX*%W<E<2^~19-kGfKf~7j*>+=>{f(k;rx)!BjIlh|yhIVFjmmy_O zB??y&+z;2;H>X)4_1yvJTGyY#ef}=4Hpp-Y8aI=?^fn>!(Gq)KPalIA0P;#;${~`m z_1c8*CzwY+M=3L<Zgal%S<)8*zKZ>p)3+L*Y(P$^g@k$_qh-ASxuRO09<6(t>`x1C z%IGztn)q>REO4ze#?WreJEL!Ex#a3^Z(@CB!b}e*%b3vGC-dL5fCxPmk)8YhKpWiF zdT!iQTm<%MyAOa^vOOgPGlK=Z?<$9OZF%xu3hhV2lYUtsx1Y1XNGI6t<&uSQEJtNQ z>|YOG|J_b6#v3p6-BdUy#MmqD4OVDx=wdl1>&%a?d3@1F!D8_7)Q#Rc^v=6kSb64J zocRL#ZLZ3qeiuMgd^=Kdkx5G^>H9rHOsW-ScE#y7$>GR|>sd?Y(LZ;9mIjjzK?C{< zHlNGF-LKAS`eG(r{PQ338g71&YR@d4h;WyDB@mg$h4H!+aQjzZ??ST&S?b#yC@aPD zM5d34%ia`jGa?C7W81IUw~Iz@OwZZ<hb(m4_;Ox+=R9X9XR$a#ON1nEFnR>-AT^8N z{+%axF;;C%jt`P9(3FkWx+05I{sET|vDI&CkZKjeksRDS=y!M8o3g+=FeHDS#5L0; zvps6b(1*rV+pJ#%KGdd^PbDu<9FU$RkC`7MjJOY47VPN~6cP!s@9Ei<b3l~+>eS+f zKJiDMnp2@6_$#JI<ixzoWDUG~z}++D3+qls0JN3!qr83f{NyU|lEMr!8{pmd8(Mh~ z_=o;O?s$*&AYg`&sV+JOw7*;bJVz^wfktK~c7l>kFxA2k>zdbsBH978U0~Pcny}Ca zS_vQvpY1g=_*Kw^VTnl|CuBGUk6n)Uti)cZXVaV%EOA@^zLb&&poRFIfmkgfjp+(} z%Tr{fww=iubcb>Az|IsDmX;tflK9)ll(raB>DXx0X+90^ev1J+&`2I3Nqj^PM_ny- zAHkBHlY7(Bgpady^h-H=frBK$l7o}?U|IQD{9v9tY_hYDjry&<5lT8R^Tt0f!bVFo zJYxq-qo6fx`a4OQd0ITGF;9iH(0W=idT`UbR#j#0vbEQQV})cZqcTVOq)FG>A!l_Z zMQ3H&p{)`^4~|T6h?vjLmdze3TsD#|-kzORM3DOG8*>5KHv4XKK{Smk(Ry4Ut-J^d ztY&FmRI~bkPmQz`stHrb++TdyB+8pgaY&uE>;P&ofHS@M6fK0x=?FM%5$}XGg3AhI zfuC@AYFQ$DneE~x*;hrubF2NiiRY{0_KgK(Gvy-CRt<tL{WNwxq8hi|uYe;QlfhQ3 zaTZfezrb>s@i{R`8)m|lSbP+hS$$M$z4%jU^%tBRN0ZR~)%U~6;q)ZaWS~H$U%l^z zJgOecqjUiF=O}R|a}KyvNi6Bf7X1JW_UgaLS_Vm=nR)FgWZ4fHFzk-9dq~g@Hp?(G zt%7Vf0SJo%eNxIMS;s4uw~uFBJ!&%hoI%#$W8{kdrU0(90?&U*vpAmrN<(XgKS5OD zg<X=^*tbHn;md4V=WW<tYNukrmAgKA%@liFnp6R&oz5g5>K=I)NlemLF2ms9s=VRD z6LMzPSd94z*%da?1t#jh6a-8<dSl%vk#)FnAUwE#RZa6dkFtpLj3Cyb1c}Q~8^WWF z7xK0?_t3arbwvSc2GizstE7z}F(|Ik)<a1qi(vo}2!E%BlyUQlyPDcm*z)K(R=DZH zL@=r*X)sM_YSdKODW-q;GievV4IWRUtC_Ctwn4Tjd(V=lWV|pNToLhz=<SwEWK}f) z(w1vdlA1iGWJ)oXD4{(WWC00IQf?f>+?O#&HXY^I6DJ~Sp|{Otizq`nWa^tY=HWN< zzSOW3nvVQT;Nai%9I8%ZCtxJaT(?%Jab9$*G7dJm{t<2><)0>H^{}$O4cOKJWZgq5 z0l{inX*GjftSpkb<pfY%<Ph}Zw&fS$Q2Ca%T+F-JL1)qFw){15JN;qlo0#I+hpJ!r zy3xy1UUUglzoH$dh^MRTIAgEXT<lLxwFh(7wSN8<7-5yF{4mCf2aM*gvufj#W*UAo ztRkOE63yc_)o3GfgI#M8_oR<&R!-?f{2S71(EN8j;IH3-S|34%6|Kw^Ior+YZA!xf zgB5qC&VuN{u<FMYB;I}VQA(`!LU$igEBg1dJslO>GnIw?Iw~HkZCl<-S(&JE6|Le+ zjbCNX>??Z4B(jUj4?9*Ym*OZ^cgh}R-ttkJd$G^7VW&=iaM=gROCoN+wJZ=~%r<;o zVGI}s2*O^waoudmfO*iUEc_7Y8O=7i(@Cd)tj%JsTtop<h3aj^*Rr5uRB7aM75|k_ zO^-ZrDLlioh^e-q#jN}J{w{Gh#qDp1!x&wgUCMDE9XHH9yUKHXRCaiKCY<L!y_0n? zoSC|?k4Jv5j7vp=5mio1q@W$2nN^MZ%gv`$DFhi41lLlgcP;G3gW^e87>4InfX|vE zH{DVa;7dA#R|5+rVE5lZpss18WkKT|KO>l;Qq5<P3L|$JWB8ZD1}}z1|2BTN0w`_F z2sJ*zCbn!PT$F0Lp@CJ|36q&3ml2otO8${WI6&tQ_9em}Dbv;hwTb5Xqz|m2{;#w1 zG}8qm?MMN=yk1<BXB-AY8OM<&h-mJsDChx4U1zKe92EeFH*GOv^mofQIoV^kR9P3i z7L@8)%J1XzdLq7fehP3qFqb13zT1G%6VhUKN_gY2hCel*)X1<Qg9OZZ#!LrFp<&oz zPmuw9Rh0$i_-&?)$HPl*Dx(~u#BdsUOAueZXoE+d(qG`v>E`xynGngY=SYo-?)+p( z)&d-IN#b!~%pj$*8gX&lJQuNL!as9(U6WdC!~0z}>|;Y$H>5)93dg+*FJX&Ad7rw_ zbg5mQJHqqzYBl7g^qqFj*qLAEv#+{_I{WUNxCnZ8ajCa76f)(24Mx?#EWqJ|o`22b zm@stly?6R5;Nw%D_c|zW>%U|10J=YYhX(k6=;cFo@}Uo1IwygG6zO&Ku@<M2fqR&J z2m=AOV-8{m85D`V^eLv6kvg<?J097a^pxglq2CdwdSV&9*4)Sv>AOO_Y7^ABPm^YP zeMlPlf1`6maH(t@8XvOZ{H&}}VLPGN?VboC#rSAb8L8&AqhSidBfFhK<5#qbywAl< zI1L(67aW#oJLD+xsE%uDwY8C;63?eDO@3HyPGGo4;vs*HP}REa)6aLy3JsRv{lHGQ z@&QCUOABSpjzmx#do=j-mGh_UHV<iI-WfPIM!R^a@b=Z_Q5o-V-;mBMi`0FwKhrK3 bT&`60s?q}fzfny3Rm?nhodM=A49x!k)81te literal 0 HcmV?d00001 diff --git a/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py b/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py index 401aa8f..8c70ca9 100644 --- a/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py +++ b/source/cmk_addons_plugins/vsphere_topo/agent_based/packages.py @@ -9,8 +9,14 @@ # File : vsphere_topo/agent_based/packages.py # 2024-07-10: added time taken as metric +# 2024-07-11: added clearer error message for missing section_esx_vsphere_clusters section +# added automatic workaround for backend is only picking up topologies from default folder +# -> obsoletes 'Add dummy topologies' +# added vCenter twice (once as vCenter once as vM) with different object IDs +# -> obsoletes 'Don\'t add vCenter as VM' from collections.abc import Mapping, Sequence +from pathlib import Path from time import time_ns from typing import Any @@ -29,20 +35,21 @@ from cmk_addons.plugins.vsphere_topo.lib.utils import ( EMBLEM_CLUSTER, EMBLEM_DATA_CENTER, EMBLEM_DATA_STORE, + ICON_VCENTER, LiveStatusConnection, OMD_ROOT, - PARAM_ADD_DUMMY_TOPOLOGIES, PARAM_CLUSTER, PARAM_DATA_CENTER, PARAM_DATA_STORE, PARAM_DATA_STORE_AS_SERVICE, - PARAM_DONT_ADD_VC_AS_VM, PARAM_HOST_SYSTEMS, PARAM_MAKE_DEFAULT, + PARAM_VCENTER, PARAM_VM_NAMES, RULE_SET_NAME_VSPHERE_TOPO, adjust_name, get_emblem, + get_topologies, save_data_to_file, ) @@ -63,19 +70,27 @@ def check_vsphere_topo( section_esx_vsphere_virtual_machines: Sequence[Section] | None, section_esx_vsphere_datastores: Section | None, ) -> CheckResult: - def add_host(host: str, emblem: str | None = None, link2core: bool = True): - if objects.get(host) is not None: + def add_host( + host: str, + emblem: str | None = None, + icon: str | None = None, + link2core: bool = True, + obj_id_prefix: str = '', + ): + if objects.get(f'{obj_id_prefix}{host}') is not None: return metadata = {} + if emblem or icon: + metadata = {'images': {}} + if emblem is not None: - metadata = { - 'images': { - 'emblem': emblem, # node image - }, - } + metadata['images'].update({'emblem': emblem}) # node image + + if icon is not None: + metadata['images'].update({'icon': icon}) # node icon - objects[host] = { + objects[f'{obj_id_prefix}{host}'] = { "name": host, "link": {'core': host} if link2core else {}, 'metadata': metadata, @@ -109,8 +124,14 @@ def check_vsphere_topo( objects = {} connections = [] - vsphere_host: str = host_name().strip() - add_host(host=vsphere_host) + raw_vsphere_host: str = host_name().strip() + add_host( + host=raw_vsphere_host, + obj_id_prefix='vc', + # icon='icon_topic_hosts', + icon=get_emblem(ICON_VCENTER, params.get(PARAM_VCENTER)), + ) + vsphere_host = f'vc{raw_vsphere_host}' __clusters = { 'HA': { @@ -121,7 +142,11 @@ def check_vsphere_topo( } if section_esx_vsphere_clusters is None: - yield Result(state=State.UNKNOWN, summary='Found no vSphere data centers/clusters') + yield Result( + state=State.UNKNOWN, + summary='Found no vSphere data centers/clusters. This service needs the "VMware ESX via vSphere" ' + 'option "Type of query" set to "Queried host is vCenter"' + ) return for cluster in section_esx_vsphere_clusters: @@ -133,7 +158,6 @@ def check_vsphere_topo( link2core=False, ) add_connection(data_center, vsphere_host) - add_host( host=cluster, emblem=get_emblem(EMBLEM_CLUSTER, params.get(PARAM_CLUSTER)), @@ -178,8 +202,8 @@ def check_vsphere_topo( for vm in section_esx_vsphere_virtual_machines: vm_name: str = adjust_name(vm['vm_name'], params.get(PARAM_VM_NAMES, {})) - if params.get(PARAM_DONT_ADD_VC_AS_VM) is True and vm_name.lower() == vsphere_host.lower(): - continue + # if params.get(PARAM_DONT_ADD_VC_AS_VM) is True and vm_name.lower() == vsphere_host.lower(): + # continue host_system: str = adjust_name(vm['hostsystem'], params.get(PARAM_HOST_SYSTEMS, {})) add_host(host=vm_name) add_connection(vm_name, host_system) @@ -232,8 +256,8 @@ def check_vsphere_topo( if (vm_to_data_stores := ls_connection.query(query=query)) is not None: for vm, data_stores in vm_to_data_stores: vm_name: str = adjust_name(vm, params.get(PARAM_VM_NAMES, {})) - if params.get(PARAM_DONT_ADD_VC_AS_VM) is True and vm_name.lower() == vsphere_host.lower(): - continue + # if params.get(PARAM_DONT_ADD_VC_AS_VM) is True and vm_name.lower() == vsphere_host.lower(): + # continue if vm_name in objects: data_stores = data_stores.split(',') for data_store in data_stores: @@ -250,21 +274,30 @@ def check_vsphere_topo( 'version': 1, 'name': 'vSphere', 'objects': dict(sorted(objects.items())), + # 'objects': objects, 'connections': connections, } - # workaround for missing topology - path: str = f'{OMD_ROOT}/var/check_mk/topology/data/{vsphere_host}' - if params.get(PARAM_ADD_DUMMY_TOPOLOGIES) is True: - data_sets = [ - {'version': 1, 'name': 'cdp', 'objects': {}, 'connections': []}, - {'version': 1, 'name': 'lldp', 'objects': {}, 'connections': []}, - {'version': 1, 'name': 'static', 'objects': {}, 'connections': []}, - {'version': 1, 'name': 'l3v4', 'objects': {}, 'connections': []}, - data_set_vsphere - ] - else: - data_sets = [data_set_vsphere] + data_sets = [] + + # workaround for backend is only picking up topologies from default folder + path: str = f'{OMD_ROOT}/var/check_mk/topology/data/default' + if Path(path).exists(): + dummy_topology = {'version': 1, 'name': 'vSphere', 'objects': {}, 'connections': []} + save_data_to_file( + data=dummy_topology, + file='data_vsphere.json', + make_default=params.get(PARAM_MAKE_DEFAULT, False), + path=path, + ) + + for topology in get_topologies(): + data_sets.append({'version': 1, 'name': topology, 'objects': {}, 'connections': []}) + # end workaround + data_sets.append(data_set_vsphere) + + path: str = f'{OMD_ROOT}/var/check_mk/topology/data/{raw_vsphere_host}' + for data_set in data_sets: file: str = f'data_{data_set["name"].lower()}.json' save_data_to_file( diff --git a/source/cmk_addons_plugins/vsphere_topo/lib/utils.py b/source/cmk_addons_plugins/vsphere_topo/lib/utils.py index f32e717..2e8ca1d 100644 --- a/source/cmk_addons_plugins/vsphere_topo/lib/utils.py +++ b/source/cmk_addons_plugins/vsphere_topo/lib/utils.py @@ -8,8 +8,8 @@ # Date : 2024-07-06 # File : vsphere_topo/lib/utils.py -from collections.abc import Mapping, MutableMapping, MutableSequence -from json import dumps as json_dunps +from collections.abc import Mapping, MutableMapping, MutableSequence, Sequence +from json import dumps as json_dunps, loads as json_loads from os import environ from pathlib import Path from typing import Any, Final, Tuple @@ -20,6 +20,8 @@ EMBLEM_CLUSTER: Final[str] = 'icon_plugins_hw' EMBLEM_DATA_CENTER: Final[str] = 'icon_cloud' EMBLEM_DATA_STORE: Final[str] = 'icon_services_green' +ICON_VCENTER: Final[str] = 'icon_topic_hosts' + PARAM_ADD_DUMMY_TOPOLOGIES: Final[str] = 'add_dummy_topologies' PARAM_CHANGE_CASE: Final[str] = 'change_case' PARAM_CLUSTER: Final[str] = 'cluster' @@ -38,6 +40,10 @@ PARAM_NO_EMBLEM: Final[str] = 'no_emblem' PARAM_PREFIX: Final[str] = 'prefix' PARAM_UPPER: Final[str] = 'upper' PARAM_VM_NAMES: Final[str] = 'vm_names' +PARAM_VCENTER: Final[str] = 'vcenter_icon' + +PICTURE_TYPE_EMBLEM: Final[str] = 'emblem' +PICTURE_TYPE_ICON: Final[str] = 'icon' RULE_SET_NAME_VSPHERE_TOPO: Final[str] = 'vsphere_topo' @@ -110,6 +116,17 @@ def save_data_to_file(data: Mapping, path: str, file: str, make_default: bool) - Path(f'{parent_path}/default').symlink_to(target=Path(path), target_is_directory=True) +def get_topologies() -> Sequence[str | None]: + path: str = f'{OMD_ROOT}/var/check_mk/topology/data/default' + if not Path(path).exists(): + return [] + + files = [f for f in Path(path).glob('*.json') if f.is_file()] + return [ + json_loads(Path(file).read_text()).get('name') for file in files if + json_loads(Path(file).read_text()).get('name') is not None + ] + # # live status # diff --git a/source/cmk_addons_plugins/vsphere_topo/rulesets/packages.py b/source/cmk_addons_plugins/vsphere_topo/rulesets/packages.py index 800fdae..bcbb4e5 100644 --- a/source/cmk_addons_plugins/vsphere_topo/rulesets/packages.py +++ b/source/cmk_addons_plugins/vsphere_topo/rulesets/packages.py @@ -48,6 +48,10 @@ from cmk_addons.plugins.vsphere_topo.lib.utils import ( PARAM_UPPER, PARAM_VM_NAMES, RULE_SET_NAME_VSPHERE_TOPO, + PARAM_VCENTER, + ICON_VCENTER, + PICTURE_TYPE_EMBLEM, + PICTURE_TYPE_ICON, ) adjust_names_elements: Mapping[str, DictElement] = { @@ -75,25 +79,25 @@ adjust_names_elements: Mapping[str, DictElement] = { } -def get_emblem_element(default_emblem) -> Sequence[CascadingSingleChoiceElement]: +def get_emblem_element(default_emblem: str, picture_type: str) -> Sequence[CascadingSingleChoiceElement]: return [ CascadingSingleChoiceElement( name=PARAM_NO_EMBLEM, - title=Title('No custom emblem'), + title=Title(f'No custom {picture_type}'), parameter_form=FixedValue( value=True, - label=Label('No custom emblem will be used') + label=Label(f'No custom {picture_type} will be used') )), CascadingSingleChoiceElement( name=PARAM_DEFAULT_EMBLEM, - title=Title('Use default emblem'), + title=Title(f'Use default {picture_type}'), parameter_form=FixedValue( value=True, - label=Label(f'Emblem "{default_emblem}" will be used') + label=Label(f'"{default_emblem}" will be used as {picture_type}') )), CascadingSingleChoiceElement( name=PARAM_CUSTOM_EMBLEM, - title=Title('Use custom emblem'), + title=Title(f'Use custom {picture_type}'), parameter_form=String( custom_validate=(LengthInRange(min_value=1),), prefill=DefaultValue(default_emblem), @@ -114,10 +118,20 @@ def _parameter_form() -> Dictionary: title=Title('Adjust VM names'), elements=adjust_names_elements )), + PARAM_VCENTER: DictElement( + parameter_form=CascadingSingleChoice( + title=Title('vCenter Icon'), + elements=get_emblem_element(ICON_VCENTER, PICTURE_TYPE_ICON), + prefill=DefaultValue(PARAM_DEFAULT_EMBLEM), + help_text=Help( + 'Here you can change the icon for the vCenter object. If you use the built-in icons prefix ' + 'the name with "icon_"' + ), + )), PARAM_CLUSTER: DictElement( parameter_form=CascadingSingleChoice( title=Title('Cluster emblem'), - elements=get_emblem_element(EMBLEM_CLUSTER), + elements=get_emblem_element(EMBLEM_CLUSTER, PICTURE_TYPE_EMBLEM), prefill=DefaultValue(PARAM_DEFAULT_EMBLEM), help_text=Help( 'Here you can change the picture for the cluster. If you use the built-in icons prefix ' @@ -127,7 +141,7 @@ def _parameter_form() -> Dictionary: PARAM_DATA_CENTER: DictElement( parameter_form=CascadingSingleChoice( title=Title('Datacenter emblem'), - elements=get_emblem_element(EMBLEM_DATA_CENTER), + elements=get_emblem_element(EMBLEM_DATA_CENTER, PICTURE_TYPE_EMBLEM), prefill=DefaultValue(PARAM_DEFAULT_EMBLEM), help_text=Help( 'Here you can change the picture for the datacenter. If you use the built-in icons prefix ' @@ -137,7 +151,7 @@ def _parameter_form() -> Dictionary: PARAM_DATA_STORE: DictElement( parameter_form=CascadingSingleChoice( title=Title('Datastore emblem'), - elements=get_emblem_element(EMBLEM_DATA_STORE), + elements=get_emblem_element(EMBLEM_DATA_STORE, PICTURE_TYPE_EMBLEM), prefill=DefaultValue(PARAM_DEFAULT_EMBLEM), help_text=Help( 'Here you can change the picture for the datastore. If you use the built-in icons prefix ' @@ -165,6 +179,7 @@ def _parameter_form() -> Dictionary: value=True )), PARAM_DONT_ADD_VC_AS_VM: DictElement( + render_only=True, parameter_form=FixedValue( title=Title('Don\'t add vCenter as VM'), label=Label('The vCenter will not be added as VM'), @@ -175,6 +190,7 @@ def _parameter_form() -> Dictionary: value=True )), PARAM_ADD_DUMMY_TOPOLOGIES: DictElement( + render_only=True, parameter_form=FixedValue( title=Title('Add dummy topologies'), label=Label('Adds empty CDP, LLDP, L3v4 and STATIC topology'), diff --git a/source/packages/vsphere_topo b/source/packages/vsphere_topo index 142ae81..d748247 100644 --- a/source/packages/vsphere_topo +++ b/source/packages/vsphere_topo @@ -12,7 +12,7 @@ 'vsphere_topo/graphing/packages.py']}, 'name': 'vsphere_topo', 'title': 'vSphere Topologie', - 'version': '0.0.2-20240709', + 'version': '0.0.3-20240711', 'version.min_required': '2.3.0b1', 'version.packaged': 'cmk-mkp-tool 0.2.0', 'version.usable_until': '2.4.0b1'} -- GitLab